public static bool RewriteUninterpretedOnDiseq(VerificationTask vt, Dictionary <string, Declaration> progDict, List <string> InequalProc = null) { if (InequalProc == null || InequalProc.Count == 0) { if (vt.Result != VerificationResult.Error) { return(true); } var fRenamer = new FunctionCallMapper(x => progDict.Get(x.Name.Replace(vt.Right.Name, vt.Left.Name)) as Function); fRenamer.Visit(vt.Left.Proc); return(false); } if (InequalProc.Contains(vt.Left.Name.Split('.')[1]) && InequalProc.Contains(vt.Right.Name.Split('.')[1])) { var fRenamer = new FunctionCallMapper(x => progDict.Get(x.Name.Replace(vt.Right.Name, vt.Left.Name)) as Function); fRenamer.Visit(vt.Left.Proc); return(false); } return(true); }
/// <summary> /// Checks if two version of f are equivalnt /// Every procedure that is not inlined will be replaced by their specs (even unreachable ones) /// </summary> /// <param name="f"></param> the index of the fn /// <param name="inlinedFns1"></param> list of fns in side1 to inline /// <param name="inlinedFns2"></param> list of fns in side2 to inline /// <param name="is_recursive"></param> whether f is recursive (or part of mutual recursion). Should be used for determining whether we can do differential inlining. /// <returns></returns> public static bool RVTCheckEq(int f, HashSet <int> inlinedFns1, HashSet <int> inlinedFns2, bool is_recursive) { //name of the function string n1Name = fnIndexToName1[f]; var n1 = cg.NodeOfName(n1Name); var n2Name = funs.Get(n1.Name); if (n1Name == null || n2Name == null) { return(false); } var n2 = cg.NodeOfName(n2Name); Console.Write("Checking (" + n1.Name + ", " + n2.Name + ")."); if (is_recursive) { Console.WriteLine(" These are recursive."); } else { Console.WriteLine(" These are non recursive."); } string eqpName = Transform.mkEqProcName(n1.Name, n2.Name); Duple <Procedure, Implementation> eqp = null; List <Variable> outputVars = new List <Variable>(); if (eqProcsCreated.ContainsKey(eqpName)) { var tmp = eqProcsCreated[eqpName]; eqp = tmp.fst; outputVars = tmp.snd; } else { return(false); } // if any visible output VerificationTask vt; if (eqp != null) { vt = new VerificationTask(eqp.snd, n1.Impl, n2.Impl, outputVars); } //it may be that these functions have no comparable effect. if so, don't generate a verification task else //we'll split their uninterpreted functions, but otherwise don't generate a verification task { vt = new VerificationTask(null, n1.Impl, n2.Impl); vt.Result = SDiff.VerificationResult.Error; SDiff.Boogie.Process.RewriteUninterpretedOnDiseq(vt, SDiff.Boogie.Process.BuildProgramDictionary(mergedProgram.TopLevelDeclarations.ToList())); } //The inline:spec inlines a procedure with {:inline 1} 1 times and then uses the spec for deeper calls var boogieOptions = "-z3multipleErrors /typeEncoding:m -timeLimit:" + Options.Timeout + " -removeEmptyBlocks:0 -inline:spec " + Options.BoogieUserOpts; SDiff.Boogie.Process.InitializeBoogie(boogieOptions); //VC.ConditionGeneration vcgen = BoogieVerify.InitializeVC(mergedProgram); // dictionary of all program AST objects by name SDiff.Boogie.Process.BuildProgramDictionary(mergedProgram.TopLevelDeclarations.ToList()); // Call RVTRunVerification Task bool crashed; var result = 1; if (eqp != null) { result = RVTRunVerificationTask(vt, null, mergedProgram, inlinedFns1, inlinedFns2, out crashed); } return(result == 1); }