Beispiel #1
0
 public void InferDominatorDependency(Block currBlock, VarSet dependsSet)
 {
     if (dataOnly)
     {
         return;
     }
     // assignment under a branch is dependent on all the variables in the branch's conditional
     if (dominatedBy.Keys.Contains(currBlock))
     {
         foreach (var dominator in dominatedBy[currBlock])
         {
             if (branchCondVars.ContainsKey(dominator))
             {
                 foreach (var v in branchCondVars[dominator])
                 {
                     dependsSet.Add(v);
                     // it is also dependends on all that v depends on *at the point of branching*
                     if (worklist.stateSpace.ContainsKey(dominator.TransferCmd))
                     {
                         var domDep = worklist.stateSpace[dominator.TransferCmd];
                         if (domDep.ContainsKey(v))
                         {
                             dependsSet.UnionWith(domDep[v]);
                         }
                     }
                 }
             }
         }
     }
 }
Beispiel #2
0
        public override GotoCmd VisitGotoCmd(GotoCmd node)
        {
            Block        currBlock    = worklist.cmdBlocks[node];
            Dependencies dependencies = worklist.GatherPredecessorsState(node, currBlock);

            var succs = node.labelTargets;

            if (succs.Count > 1)
            { // here we create branchCondVars
                if (!branchCondVars.ContainsKey(currBlock))
                {
                    branchCondVars[currBlock] = new VarSet();
                }

                foreach (var succ in succs.Where(s => s.Cmds.Count > 0 && s.Cmds[0] is AssumeCmd))
                {
                    branchCondVars[currBlock].UnionWith(Utils.VariableUtils.ExtractVars(succ.Cmds[0]));
                }
            }

            if (worklist.Assign(node, dependencies))
            {
                worklist.Propagate(node);
            }
            return(node);
        }
Beispiel #3
0
        public override Cmd VisitHavocCmd(HavocCmd node)
        {
            Block        currBlock    = worklist.cmdBlocks[node];
            Dependencies dependencies = worklist.GatherPredecessorsState(node, currBlock);

            // Havoc x translates to x <- *
            foreach (var v in node.Vars.Select(x => x.Decl))
            {
                dependencies[v] = new VarSet();
                dependencies[v].Add(Utils.VariableUtils.NonDetVar);

                InferDominatorDependency(currBlock, dependencies[v]);

                if (changedProcs.Contains(nodeToImpl[node].Proc) || changedBlocks.Contains(currBlock)) // native taint
                {
                    if (Analysis.DacMerged == null || IsImpactedSummary(nodeToImpl[node].Proc, v))
                    {
                        dependencies[v].Add(Utils.VariableUtils.BottomUpTaintVar);
                    }
                }
            }

            if (worklist.Assign(node, dependencies))
            {
                worklist.Propagate(node);
            }
            return(node);
        }
Beispiel #4
0
 public override Variable VisitVariable(Variable node)
 {
     if (!ProcReadSet.ContainsKey(currentProc))
     {
         ProcReadSet[currentProc] = new VarSet();
     }
     //if (node is GlobalVariable || proc.InParams.Contains(node)) // only consider globals and formals in the read set
     ProcReadSet[currentProc].Add(node);
     return(node);
 }
Beispiel #5
0
        public void AbstractNonTaintedImplementations()
        {
            var impls        = program.TopLevelDeclarations.OfType <Implementation>();
            var taintedImpls =
                impls.Where(x =>
                            allDeps[x.Proc].Values.Any(d => Utils.VariableUtils.IsTainted(d))
                            );
            var nonTaintedImpls = new HashSet <Implementation>();

            if (false)
            {
                throw new NotImplementedException("Don't exercise abstraction as it causes mismatch of signatures on two sides");
                //TODO: We get into parsing problems (print_tokens\(source,v2)) when one side is abstracted, and we get
                //different modsets later given the implementation for one and stub for another
                new HashSet <Implementation>(impls.Where(x => !taintedImpls.Contains(x))); //make a copy since topleveldecl changes
                nonTaintedImpls
                .Iter(x =>
                {
                    var modset = new VarSet(allDeps[x.Proc].ModSet());
                    Utils.VariableUtils.PruneLocals(x, modset);
                    modset.RemoveWhere(v => x.Proc.OutParams.Contains(v));
                    x.Proc.Modifies = modset.Select(v => IdentifierExpr.Ident(v)).ToList();
                    Utils.DependenciesUtils.AddCalleeDependencySpecs(program, x.Proc, allDeps[x.Proc]);
                }
                      );
                Console.WriteLine("[Abstract non-taint] Abstracted {0} procedures [{1}]", nonTaintedImpls.Count(),
                                  String.Join(",", nonTaintedImpls.Select(x => x.Name)));
            }

            //get the number of tainted outputs (outputs whose summaries are potentially changed)
            var outvars         = new List <Variable>();
            var botTaintOutVars = new List <Variable>();

            program.TopLevelDeclarations.OfType <Procedure>().Iter(x =>
            {
                if (!allDeps.ContainsKey(x))
                {
                    return;
                }
                allDeps[x].Keys.Iter(y => outvars.Add(y));
                var procBottomUpTaintVars = new List <Variable>();
                allDeps[x].Keys.Where(k => allDeps[x][k].Contains(Utils.VariableUtils.BottomUpTaintVar)).Iter(y => procBottomUpTaintVars.Add(y));
                botTaintOutVars.AddRange(procBottomUpTaintVars);
                //new: add an annotation to indicate that none of the variables are bottom up tainted
                var ens        = new Ensures(true, (Expr)Expr.True);
                ens.Attributes = new QKeyValue(Token.NoToken, "bottomup_tainted_vars",
                                               procBottomUpTaintVars.Select(v => (object)v.Name).ToList(), null);
                x.Ensures.Add(ens);
            });
            Console.WriteLine("#outputs with no bottomuptaint / #outputs = {0} / {1} ", outvars.Count - botTaintOutVars.Count, outvars.Count);

            //Do the removal after you are done with nonTaintedImpls, otherwise that becomes an empty set
            program.RemoveTopLevelDeclarations(x => nonTaintedImpls.Contains(x));
        }
Beispiel #6
0
        private VarSet InferCalleeOutputDependancy(CallCmd cmd, Variable output, Dependencies state, List <VarSet> inputExpressionsDependency)
        {
            if (Analysis.DacMerged != null && !IsImpactedOutput(cmd.Proc, output))
            {
                return(new VarSet());
            }

            if (!paramNameToIndex.ContainsKey(cmd.Proc))
            {
                paramNameToIndex[cmd.Proc] = new Dictionary <string, int>();
                for (int i = 0; i < cmd.Proc.InParams.Count; ++i)
                {
                    var p = cmd.Proc.InParams[i];
                    paramNameToIndex[cmd.Proc][p.Name] = i;
                }
            }

            var outputDependency        = ProcDependencies[cmd.Proc][output]; // output is dependent on a set of formals and globals
            var inferedOutputDependency = new VarSet();

            foreach (var dependentOn in outputDependency) // foreach (formal parameter p\global g) o_i is dependent upon
            {
                if (dependentOn is GlobalVariable)        // global
                {                                         // add in the global's dependency set
                    inferedOutputDependency.Add(dependentOn);
                    if (state.ContainsKey(dependentOn))
                    {
                        inferedOutputDependency.UnionWith(state[dependentOn]);
                    }
                    continue;
                }

                var inputIndex = 0;
                if (inputExpressionsDependency.Count == 0)
                {
                    continue;
                }

                //inputIndex = cmd.Proc.InParams.FindIndex(p => p.Name == dependentOn.Name);
                if (paramNameToIndex[cmd.Proc].ContainsKey(dependentOn.Name))
                {
                    inputIndex = paramNameToIndex[cmd.Proc][dependentOn.Name];
                }
                if (inputIndex >= 0) // formal parameter
                // replace the formal with the actual's dependency set
                {
                    inferedOutputDependency.UnionWith(inputExpressionsDependency[inputIndex]);
                }
            }

            return(inferedOutputDependency);
        }
Beispiel #7
0
        public override Program VisitProgram(Program program)
        {
            var callGraph = CallGraphHelper.ComputeCallGraph(program);

            var worklist = new List <Procedure>();

            program.TopLevelDeclarations.Iter(d => { if (d is Procedure)
                                                     {
                                                         worklist.Add(d as Procedure);
                                                     }
                                              });

            int numVisited = 0;

            while (worklist.Count > 0)
            {
                currentProc = worklist.First();
                worklist.Remove(currentProc);

                if (!ProcReadSet.ContainsKey(currentProc))
                {
                    ProcReadSet[currentProc] = new VarSet();
                }

                var initialRS = new VarSet(ProcReadSet[currentProc]);

                var impl = program.Implementations.SingleOrDefault(i => i.Name == currentProc.Name);
                if (impl == null)
                {// a stub
                    ProcReadSet[currentProc].Add(Utils.VariableUtils.NonDetVar);
                    ProcReadSet[currentProc].UnionWith(currentProc.InParams);
                    ProcReadSet[currentProc].UnionWith(currentProc.OutParams);
                    currentProc.Modifies.Iter(m => ProcReadSet[currentProc].UnionWith(Utils.VariableUtils.ExtractVars(m)));
                }
                else
                {// a procedure with a body
                    Console.WriteLine("Visiting: {0} ({1}/{2})", impl.Name, ++numVisited, program.Implementations.Count());
                    Visit(impl);
                }

                if (!initialRS.SetEquals(ProcReadSet[currentProc]) && callGraph.Nodes.Contains(currentProc))
                {                                                           // the read set changed
                    worklist.AddRange(callGraph.Predecessors(currentProc)); // add all callers to WL
                }
                //GC.Collect();
            }
            ProcReadSet.Iter(prs => Utils.VariableUtils.FixFormals(program.Implementations.SingleOrDefault(i => i.Name == prs.Key.Name), prs.Value));

            return(program);
        }
Beispiel #8
0
        public override Cmd VisitCallCmd(CallCmd node)
        {
            var callee = node.Proc;

            if (!ProcReadSet.ContainsKey(callee) || ProcReadSet[callee].Count == 0) // callee has no readset
            {
                return(base.VisitCallCmd(node));
            }

            if (!ProcReadSet.ContainsKey(currentProc))
            {
                ProcReadSet[currentProc] = new VarSet();
            }

            ProcReadSet[currentProc].UnionWith(ProcReadSet[callee].Where(v => v is GlobalVariable)); // add all globals read in the callee to the read set

            return(base.VisitCallCmd(node));
        }
Beispiel #9
0
        public override Cmd VisitCallCmd(CallCmd node)
        {
            var          callee       = node.Proc;
            var          calleeImpl   = program.Implementations.FirstOrDefault(i => i.Proc == callee);
            Block        currBlock    = worklist.cmdBlocks[node];
            Dependencies dependencies = worklist.GatherPredecessorsState(node, currBlock);

            if (program.Implementations.Where(x => x.Proc == callee).Count() == 0)
            {
                Debug.Assert(false, string.Format("Stubs not {0} expected...did you run dependency.exe?", callee));
                ProcDependencies[callee] = new Dependencies();
                // all outputs+modified depend on all inputs+modified
                var outs = callee.OutParams.Union(callee.Modifies.Select(x => x.Decl));
                foreach (var v in outs)
                {
                    ProcDependencies[callee][v] = new VarSet(callee.InParams.Union(callee.Modifies.Select(x => x.Decl)));
                    //if (!detStubs /* || Utils.IsBakedInStub(callee)*/ ) //adding out == func(in) causes inconsistency for functions like malloc/det_choice etc.
                    ProcDependencies[callee][v].Add(Utils.VariableUtils.NonDetVar); // and on *
                }
            }

            if (!ProcDependencies.ContainsKey(callee))
            { // this will be continued once the callee gets analyzed
                dependencies = new Dependencies();
                if (worklist.Assign(node, dependencies))
                {
                    worklist.Propagate(node);
                }
                return(node);
            }

            var  calleeDependencies = ProcDependencies[callee];
            bool nativeTaint        = changedProcs.Contains(nodeToImpl[node].Proc) || changedBlocks.Contains(currBlock);

            var topDownTaint = new Dependencies();

            if (nativeTaint && calleeImpl != null)
            {// if the line syntactically changed, we assume all of the actuals introduce top-down taint
                foreach (var input in calleeImpl.InParams)
                {
                    topDownTaint[input] = new VarSet();
                    if (Analysis.DacMerged == null || IsImpactedInput(callee, input))
                    {
                        topDownTaint[input].Add(Utils.VariableUtils.TopDownTaintVar);
                    }
                }
            }

            // first, for f(e1,...,ek) find the dependency set of each ei
            var inputExpressionsDependency = new List <VarSet>();

            for (int i = 0; i < node.Ins.Count; ++i)
            {
                var inExpr = node.Ins[i];
                inputExpressionsDependency.Add(new VarSet());
                int current = inputExpressionsDependency.Count - 1;
                foreach (var v in Utils.VariableUtils.ExtractVars(inExpr))
                {
                    inputExpressionsDependency[current].Add(v);
                    if (dependencies.Keys.Contains(v))
                    {
                        inputExpressionsDependency[current].UnionWith(dependencies[v]);
                        if (calleeImpl != null && // not a stub
                            Utils.VariableUtils.IsTainted(dependencies[v]))
                        {                         // top down taint from input
                            var input = calleeImpl.InParams[i];
                            topDownTaint[input] = new VarSet();
                            if (Analysis.DacMerged == null || IsImpactedInput(calleeImpl.Proc, input))
                            {
                                topDownTaint[input].Add(Utils.VariableUtils.TopDownTaintVar);
                            }
                        }
                    }
                }
            }

            foreach (var g in dependencies.Keys.Where(v => v is GlobalVariable && ProcDependencies[callee].Values.Any(d => d.Contains(v))))
            {
                if (calleeImpl != null && // not a stub
                    Utils.VariableUtils.IsTainted(dependencies[g]))
                {                         // top down taint from global
                    topDownTaint[g] = new VarSet();
                    if (Analysis.DacMerged == null || IsImpactedInput(calleeImpl.Proc, g))
                    {
                        topDownTaint[g].Add(Utils.VariableUtils.TopDownTaintVar);
                    }
                }
            }

            if (calleeImpl != null)
            {
                // propagate tainted inputs\globals to the callsite
                if (!procEntryTDTaint.ContainsKey(callee))
                {
                    procEntryTDTaint[callee] = new Dependencies();
                }
                procEntryTDTaint[callee].JoinWith(topDownTaint);
            }

            // handle outputs affected by the call
            for (int i = 0; i < callee.OutParams.Count; ++i)
            {
                var formalOutput = calleeImpl.OutParams[i]; //callee.OutParams[i];
                if (!calleeDependencies.ContainsKey(formalOutput))
                {
                    continue;
                }
                var actualOutput = node.Outs[i].Decl;

                dependencies[actualOutput] = InferCalleeOutputDependancy(node, formalOutput, dependencies, inputExpressionsDependency);
                InferDominatorDependency(currBlock, dependencies[actualOutput]); // conditionals may dominate/taint the return value
                //dependencies[actualOutput].ExceptWith(nodeToImpl[node].LocVars);

                if (nativeTaint) // native taint
                {
                    if (calleeImpl == null || Analysis.DacMerged == null || IsImpactedSummary(calleeImpl.Proc, actualOutput) ||
                        !Analysis.DacSimplifier.nonImpactedSummaries.ContainsKey(calleeImpl.Proc) || !Analysis.DacSimplifier.nonImpactedSummaries[callee].Select(x => x.Name).Contains(actualOutput.Name))
                    {
                        dependencies[actualOutput].Add(Utils.VariableUtils.BottomUpTaintVar); // only applies to actual outputs (i.e. bottom up)
                    }
                }
            }

            // handle globals affected by the call
            foreach (var g in calleeDependencies.Keys)
            {
                if (!(g is GlobalVariable))
                {
                    continue;
                }
                dependencies[g] = InferCalleeOutputDependancy(node, g, dependencies, inputExpressionsDependency);
                InferDominatorDependency(currBlock, dependencies[g]); // conditionals may dominate/taint the modified globals
                //dependencies[g].ExceptWith(nodeToImpl[node].LocVars);
            }

            if (worklist.Assign(node, dependencies))
            {
                worklist.Propagate(node);
            }
            return(node);
        }
Beispiel #10
0
        public override Cmd VisitAssignCmd(AssignCmd node)
        {
            // gather state from all predecesors
            Block        currBlock    = worklist.cmdBlocks[node];
            Dependencies dependencies = worklist.GatherPredecessorsState(node, currBlock);

            // for assignment v1,...,vn = e1,...,en handle each vi = ei separately
            for (int i = 0; i < node.Lhss.Count; ++i)
            {
                //TODO: M := M[p := v]; -> p is LHS!
                //if (node.Rhss[i].Type.IsMap)

                //MAJOR BUG FIX M[N[y] + z] := T[4];
                var lhs     = node.Lhss[i].DeepAssignedVariable;
                var rhsVars = Utils.VariableUtils.ExtractVars(node.Rhss[i]);
                if (lhs.TypedIdent.Type.IsMap)
                {
                    Utils.VariableUtils.ExtractVars(node.Lhss[i]).Iter(x => rhsVars.Add(x)); //M[N[x]] := y; Dep(M) = {M, N, x, y}
                }
                // dependency is cut only if lhs does not appears in rhs! (cases like M := M[x := y])
                if (!rhsVars.Contains(lhs) || !dependencies.ContainsKey(lhs))
                {
                    dependencies[lhs] = new VarSet();
                }

                foreach (var rv in rhsVars)
                {
                    dependencies[lhs].Add(rv);

                    if (dependencies.ContainsKey(rv)) // a variable in rhs has dependencies
                    {
                        dependencies[lhs].UnionWith(dependencies[rv]);
                    }
                }

                InferDominatorDependency(currBlock, dependencies[lhs]);

                if (prune)
                {
                    dependencies[lhs].ExceptWith(nodeToImpl[node].LocVars);
                }

                if (taintOnly)
                {
                    dependencies[lhs].RemoveWhere(v => v != Utils.VariableUtils.BottomUpTaintVar && v != Utils.VariableUtils.TopDownTaintVar);
                }

                if (changedProcs.Contains(nodeToImpl[node].Proc) || changedBlocks.Contains(currBlock)) // native taint
                {
                    if (Analysis.DacMerged == null || IsImpactedSummary(nodeToImpl[node].Proc, lhs))
                    {
                        dependencies[lhs].Add(Utils.VariableUtils.BottomUpTaintVar);
                    }
                }
            }

            if (worklist.Assign(node, dependencies))
            {
                worklist.Propagate(node);
            }
            return(node);
        }
Beispiel #11
0
        public override Program VisitProgram(Program node)
        {
            //Console.WriteLine("Starting...");
            //Console.ReadLine();
            var orderedSCCs = CallGraphHelper.ComputeOrderedSCCs(callGraph);

            orderedSCCs.Reverse();
            int numVisited         = 0;
            ProcReadSetVisitor rsv = new ProcReadSetVisitor();

            foreach (var scc in orderedSCCs)
            {
                foreach (var proc in scc)
                {
                    var impl = node.Implementations.FirstOrDefault(i => i.Proc == proc);
                    if (impl == null)
                    {
                        continue;
                    }
                    //Console.Write("Visiting: {0} ({1}/{2}) [{3} cmds, {4} vars]", impl.Name, ++numVisited, program.Implementations.Count(), impl.Blocks.Sum(b => b.Cmds.Count + 1), impl.LocVars.Count);
                    Stopwatch        s    = Stopwatch.StartNew();
                    ManualResetEvent wait = new ManualResetEvent(false);
                    Thread           work = new Thread(new ThreadStart(() => { Visit(impl); wait.Set(); }));
                    work.Start();
                    Boolean signal = wait.WaitOne(timeOut);
                    s.Stop();
                    if (!signal)
                    {
                        work.Abort();
                        Console.WriteLine("Aborted due to timeout. Reverting to readSet");

                        // the worklist alg was interrupted, clear the worklist to be safe
                        worklist.workList.Clear();
                        worklist.stateSpace.Clear();
                        GC.Collect();

                        // compute the read set instead
                        rsv.currentProc = impl.Proc;
                        rsv.Visit(impl);

                        // turn it to dependencies (\forall r \in ReadSet: r <- ReadSet)
                        ProcDependencies[impl.Proc] = new Dependencies();
                        rsv.ProcReadSet[impl.Proc].Iter(r => ProcDependencies[impl.Proc][r] = rsv.ProcReadSet[impl.Proc]);
                        //ProcDependencies[impl.Proc].FixFormals(impl);
                    }
                    else
                    {
                        //Console.WriteLine(" {0} s", s.ElapsedMilliseconds / 1000.0);
                        // maintain the readSet (for cases where the analysis is too long and we revert to readset)
                        rsv.ProcReadSet[impl.Proc] = new VarSet();
                        rsv.ProcReadSet[impl.Proc].UnionWith(ProcDependencies[impl.Proc].Keys);
                        ProcDependencies[impl.Proc].Values.Iter(vs => rsv.ProcReadSet[impl.Proc].UnionWith(vs));
                    }
                }
                foreach (var proc in scc)
                {
                    var impl = node.Implementations.FirstOrDefault(i => i.Proc == proc);
                    if (impl == null)
                    {
                        continue;
                    }
                    Analysis.PopulateTaintLog(impl, Utils.ExtractTaint(this));
                }

                worklist.stateSpace.Clear();
                if (numVisited % 25 == 0)
                {
                    GC.Collect();
                }
            }

            // Removed. Printing directly to screen can be too huge.
            //ProcDependencies.Iter(pd => Console.Out.WriteLine(pd.Key + " : " + pd.Value));

            //node.Implementations.Iter(impl => Visit(impl));

            // compute top down taint
            orderedSCCs.Reverse();
            foreach (var scc in orderedSCCs)
            {
                //foreach (var proc in procEntryTDTaint.Keys)
                foreach (var proc in scc)
                {
                    if (!procEntryTDTaint.ContainsKey(proc))
                    {
                        continue;
                    }
                    var impl  = program.Implementations.Single(i => i.Proc == proc);
                    var entry = Utils.GetImplEntry(impl);
                    if (!worklist.stateSpace.ContainsKey(entry))
                    {
                        worklist.stateSpace[entry] = new Dependencies();
                    }
                    if (worklist.stateSpace[entry].JoinWith(procEntryTDTaint[impl.Proc]))
                    {
                        worklist.Propagate(entry);
                        Visit(impl);
                    }
                }
            }

            // the top down taint was removed from ProcDependencies so it won't flow up, so add it back in now
            procExitTDTaint.Iter(pd => ProcDependencies[pd.Key].JoinWith(pd.Value));

            // gathering the tainted scalar outputs for each procedure
            var taintedProcScalarOutputs = new Dictionary <Procedure, VarSet>();

            ProcDependencies.Iter(pd =>
            {
                var procedure    = pd.Key;
                var impl         = node.Implementations.FirstOrDefault(i => i.Proc == procedure);
                var dependencies = pd.Value;
                taintedProcScalarOutputs[procedure] = new VarSet();
                foreach (var r in impl.OutParams)
                {
                    if (r.TypedIdent.Type.IsInt && dependencies.ContainsKey(r) &&
                        (dependencies[r].Contains(Utils.VariableUtils.BottomUpTaintVar) || dependencies[r].Contains(Utils.VariableUtils.TopDownTaintVar)))
                    {
                        taintedProcScalarOutputs[procedure].Add(r);
                    }
                }
            });
            taintedProcScalarOutputs.Iter(t => Console.WriteLine("Tainted outputs for " + t.Key + " : " + t.Value));

            procEntryTDTaint.Iter(pd => Console.WriteLine("Tainted inputs/globals for " + pd.Key + " : " + pd.Value));

            // for now, before we finish running, we replace all implementation outputs with procedure outputs
            // TODO: in the future we should only use implementation inputs\outputs and lose the procedures overall
            ProcDependencies.Iter(pd =>
            {
                var impl = node.Implementations.FirstOrDefault(i => i.Proc == pd.Key);
                pd.Value.FixFormals(impl);
                foreach (var o in impl.OutParams)
                {
                    pd.Value.Remove(o);
                }
            });

            return(node);
        }
Beispiel #12
0
 public static void PopulateStatsLog(string type, Implementation impl, Variable key, VarSet value)
 {
     statsLog.Add(new Tuple <string, string, Procedure, Variable, VarSet>(type, Utils.AttributeUtils.GetImplSourceFile(impl), impl.Proc, key, value));
 }
Beispiel #13
0
        private static void AnalyzeDependencyWithUnsatCore(VCExpr programVC, Constant outConstant, Dependencies result, string procName, List <Constant> inputGuardConsts, List <Constant> outputGuardConsts)
        {
            #region Description of UNSAT core logic implemented below

            /*
             *  Given VC, I, O, o
             *  - preInp = (\wedge_{i \in I} i)
             *  - preOut = (\wedge_{o' \in O} !o') \wedge o
             *  - VC' = (preOut => VC)
             *  - checkValid preInp => VC'
             *  - if invalid return
             *  - A += !VC'
             *  - A += I
             *  - if (CheckAssumption(A, out core) != valid) ABORT
             */
            #endregion

            //Should call VerifyVC before invoking CheckAssumptions
            List <Counterexample> cexs;
            var preInp = inputGuardConsts
                         .Aggregate(VCExpressionGenerator.True, (x, y) => VC.exprGen.And(x, VC.translator.LookupVariable(y)));
            var preOut = outputGuardConsts
                         .Where(x => x != outConstant)
                         .Aggregate(VCExpressionGenerator.True, (x, y) => VC.exprGen.And(x, VC.exprGen.Not(VC.translator.LookupVariable(y))));
            preOut = VC.exprGen.And(preOut, VC.translator.LookupVariable(outConstant));
            var newVC = VC.exprGen.Implies(preOut, programVC);

            //TODO: Really really ugly way to get to the Variable in the guardOutput
            var vexpr  = (Expr)Utils.AttributeUtils.GetAttributeVals(outConstant.Attributes, RefineConsts.modSetGuradAttribute)[1];
            var vident = vexpr as IdentifierExpr;
            if (vident == null)
            {
                throw new Exception(string.Format("Illegal variable expression {0} in {1} attribute", vexpr, RefineConsts.modSetGuardName));
            }
            var v = vident.Decl;

            //check for validity (presence of all input eq implies output is equal)
            var outcome = VC.VerifyVC("RefineDependency", VC.exprGen.Implies(preInp, newVC), out cexs);
            Console.Write("-");
            if (outcome == ProverInterface.Outcome.Invalid)
            {
                Console.WriteLine("\t VC not valid, returning");
                result[v].Add(Utils.VariableUtils.NonDetVar);
                Console.WriteLine("\t Dependency of {0} =  <{1}>", v, string.Join(",", result[v]));
                return;
            }
            if (outcome == ProverInterface.Outcome.OutOfMemory ||
                outcome == ProverInterface.Outcome.TimeOut ||
                outcome == ProverInterface.Outcome.Undetermined)
            {
                Console.WriteLine("\t VC inconclusive, returning");
                result[v].Add(Utils.VariableUtils.NonDetVar);
                Console.WriteLine("\t Dependency of {0} =  <{1}>", v, string.Join(",", result[v]));
                return;
            }

            List <int> unsatClauseIdentifiers = new List <int>();
            var        assumptions            = new List <VCExpr>();
            assumptions.Add(VC.exprGen.Not(newVC));

            //Add the list of all input constants
            inputGuardConsts.ForEach(x => assumptions.Add(VC.translator.LookupVariable(x)));

            //VERY IMPORTANT: TO USE UNSAT CORE, SET ContractInfer to true in CommandLineOptions.Clo.
            outcome = ProverInterface.Outcome.Undetermined;
            outcome = VC.proverInterface.CheckAssumptions(assumptions, out unsatClauseIdentifiers, VC.handler);
            Console.Write("+");
            if (outcome == ProverInterface.Outcome.Invalid && unsatClauseIdentifiers.Count() == 0)
            {
                Console.WriteLine("Something went wrong! Unsat core with 0 elements for {0}", outConstant);
                return;
            }
            if (!unsatClauseIdentifiers.Remove(0)) //newVC should be always at 0, since it has to participate in inconsistency
            {
                Console.WriteLine("Something went wrong! The VC itself is not part of UNSAT core");
                return;
            }

            //Core may not be minimal (e.g. testdependencyDummy.bpl), need to iterate
            var core0 = unsatClauseIdentifiers.Select(i => assumptions[i]);
            var core  = new List <VCExpr>(core0);
            if (!Analysis.noMinUnsatCore)
            {
                core0
                .Iter(b =>
                {
                    core.Remove(b);
                    preInp  = core.Aggregate(VCExpressionGenerator.True, (x, y) => VC.exprGen.And(x, y));
                    outcome = VC.VerifyVC("RefineDependency", VC.exprGen.Implies(preInp, newVC), out cexs);
                    Console.Write(".");
                    if (outcome != ProverInterface.Outcome.Valid)
                    {
                        core.Add(b);
                        return;
                    }
                });
            }
            //We are about to refine the dependency of v, so we start with the empty set
            result[v] = new VarSet();
            //TODO: THIS HAS TO GO AWAY with proper variables!!!
            foreach (var ig in inputGuardConsts)
            {
                if (core.Contains(VC.translator.LookupVariable(ig)))
                {
                    IdentifierExpr iexpr = (IdentifierExpr)Utils.AttributeUtils.GetAttributeVals(ig.Attributes, RefineConsts.readSetGuradAttribute)[1];
                    result[v].Add(iexpr.Decl);
                }
            }
            Console.WriteLine("\t Dependency of {0} = <{1}>",
                              v,
                              string.Join(",", result[v]));
        }