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