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]); } } } } } } }
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); }
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); }
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); }
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)); }
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); }
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); }
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)); }
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); }
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); }
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); }
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)); }
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])); }