private static BoogieMethodData MethodDataFromImpl( Implementation impl, BoogieGlobalData globalData, List <Variable> extraLocalVariables = null ) { //add out params to local variables for now var locals = new List <Variable>(impl.LocVars).Union(impl.OutParams); if (extraLocalVariables != null) { locals = locals.Union(extraLocalVariables); } /* procedures and implementations do not use the same objects for the variables in the spec --> need to sync * for pre- and postcondition */ var formalProcImplSubst = Substituter.SubstitutionFromDictionary(impl.GetImplFormalMap()); var preconditions = new List <Tuple <Expr, bool> >(); foreach (var req in impl.Proc.Requires) { var e = Substituter.Apply(formalProcImplSubst, req.Condition); preconditions.Add(Tuple.Create(e, req.Free)); } var postconditions = new List <Tuple <Expr, bool> >(); foreach (var ens in impl.Proc.Ensures) { var e = Substituter.Apply(formalProcImplSubst, ens.Condition); postconditions.Add(Tuple.Create(e, ens.Free)); } return(new BoogieMethodData( globalData, new List <TypeVariable>(impl.TypeParameters), new List <Variable>(impl.InParams), locals, null, new List <IdentifierExpr>(impl.Proc.Modifies), preconditions, postconditions)); }
/// <summary> /// Compute and apply the invariants for the program using the underlying abstract domain. /// </summary> public static void ComputeProgramInvariants(Program program, Dictionary <Procedure, Implementation[]> procedureImplementations, NativeLattice lattice) { Contract.Requires(program != null); Contract.Requires(procedureImplementations != null); Contract.Requires(lattice != null); // Gather all the axioms to create the initial lattice element // Differently stated, it is the \alpha from axioms (i.e. first order formulae) to the underlyng abstract domain var initialElement = lattice.Top; Contract.Assert(initialElement != null); foreach (var decl in program.TopLevelDeclarations) { var ax = decl as Axiom; if (ax != null) { initialElement = lattice.Constrain(initialElement, ax.Expr); } } // analyze each procedure foreach (var decl in program.TopLevelDeclarations) { var proc = decl as Procedure; if (proc != null && procedureImplementations.ContainsKey(proc)) { // analyze each implementation of the procedure foreach (var impl in procedureImplementations[proc]) { // add the precondition to the axioms Substitution formalProcImplSubst = Substituter.SubstitutionFromHashtable(impl.GetImplFormalMap()); var start = initialElement; foreach (Requires pre in proc.Requires) { Expr e = Substituter.Apply(formalProcImplSubst, pre.Condition); start = lattice.Constrain(start, e); } lattice.Specialize(impl); Analyze(impl, lattice, start); lattice.Specialize(null); } } } }
//completely clobbers all the existing SCmd constraints public static Constraint ExecBlockUp(SymbolicBlock sb, Constraint consIntoBlock) { var curCons = consIntoBlock; for (int i = sb.SCmds.Count - 1; i >= 0; i--) { var curCmd = sb.SCmds[i]; var assume = curCmd.Source as AssumeCmd; if (assume != null) { curCmd.Cons = new Constraint(curCons, false); curCmd.Cons.Add(assume.Expr); } var assign = curCmd.Source as AssignCmd; if (assign != null) { curCmd.Cons = new Constraint(curCons, true); for (int j = 0; j < assign.Lhss.Count; j++) { var lhs = assign.Lhss[j]; var gamma = curCmd.Gammas[j]; var vToReplace = lhs.DeepAssignedVariable; var rExpr = gamma.Get(new StoreLhs(vToReplace)); curCmd.Cons = new Constraint(curCmd.Cons.Conjuncts.Map(y => Substituter.Apply(x => (x == vToReplace) ? rExpr : null, y)).ToArray()); } } if (assign == null && assume == null) { curCmd.Cons = new Constraint(curCons, true); } else { curCons = curCmd.Cons; } } return(curCons); }
public static void SubstituteIncarnationInInstantiationSources(Cmd cmd, Substitution incarnationSubst) { QKeyValue iter = null; if (cmd is AssignCmd assignCmd) { iter = assignCmd.Attributes; } else if (cmd is PredicateCmd predicateCmd) { iter = predicateCmd.Attributes; } while (iter != null) { if (iter.Key == "add_to_pool" && iter.Params.Count > 1) { var label = iter.Params[0] as string; if (label != null) { var newParams = new List <object> { label }; for (int i = 1; i < iter.Params.Count; i++) { var instance = iter.Params[i] as Expr; if (instance != null) { instance = Substituter.Apply(incarnationSubst, instance); newParams.Add(instance); } } iter.ClearParams(); iter.AddParams(newParams); } } iter = iter.Next; } }
// replace formal-ins and outs with a unique variable public static string ExprToTemplateGeneral(Expr expr) { var GetFin = new Func <btype, Variable>(ty => BoogieAstFactory.MkFormal("v_fin_" + ty.ToString(), ty, true)); var GetFout = new Func <btype, Variable>(ty => BoogieAstFactory.MkFormal("v_fout_" + ty.ToString(), ty, true)); var ret = Substituter.Apply(new Substitution(v => { if (v is Formal && (v as Formal).InComing) { return(Expr.Ident(GetFin(v.TypedIdent.Type))); } if (v is Formal && !(v as Formal).InComing) { return(Expr.Ident(GetFout(v.TypedIdent.Type))); } return(Expr.Ident(v)); }), expr); return(ret.ToString()); }
public static SymbolicBlock ExecBlockDown(Block b, SymbolicStore gammaIntoBlock, out SymbolicStore gammaOutOfBlock) { var duper = new Duplicator(); var sb = new SymbolicBlock(b); SymbolicStore gammaIntoCmd = gammaIntoBlock; foreach (Cmd c in b.Cmds) { var sc = new SymbolicCmd(c); if (c is AssumeCmd) { if (!((AssumeCmd)c).Expr.Equals(Expr.True)) { var tmp = ((AssumeCmd)c).Expr; sc.AddCons(((AssumeCmd)c).Expr); } } else if (c is AssignCmd) { SymbolicStore newGamma; //= new SymbolicStore(gammaIntoCmd); AssignCmd assgn = c as AssignCmd; if (assgn.Lhss.Count != assgn.Rhss.Count) { Console.WriteLine("Bizzare: uneven assignment command in ExecDown"); continue; } //each AssignCmd contains a list of assignments for (int i = 0; i < assgn.Lhss.Count; i++) { var lhsrhs = StoreLhs.Make(assgn.Lhss[i], assgn.Rhss[i]); var lhs = lhsrhs.fst; var rhs = lhsrhs.snd; Expr oldrhs; gammaIntoCmd.TryGetValue(lhs, out oldrhs); //if lhs was uninitialized, we just add the new binding to the old gamma if (oldrhs == null) { newGamma = new SymbolicStore(gammaIntoCmd); newGamma.Add(lhs, rhs); } //otherwise we have to do substitution over everything else { newGamma = new SymbolicStore(); newGamma.Add(lhs, Substituter.Apply(x => (x == lhs.Var) ? duper.VisitExpr(oldrhs) : null, rhs)); //otherwise, we need to substitute the old value for lhs into Gamma foreach (var entry in gammaIntoCmd) { if (!entry.Key.Equals(lhs)) { newGamma.Add(entry.Key, Substituter.Apply(x => (x == lhs.Var) ? duper.VisitExpr(oldrhs) : null, entry.Value)); } } } gammaIntoCmd = newGamma; sc.AddGamma(newGamma); } } else if (c is HavocCmd) { Log.Out(Log.Warning, "Help! HavocCmd in ExecBlockDown!"); } // if(sc.Gammas.Count != 0) sb.SCmds.Add(sc); } gammaOutOfBlock = gammaIntoCmd; return(sb); }
public override Expr _Substitute(Expr e, Expr orig, Expr replacement) { Substituter s = new Substituter(orig, replacement, false); return s.Substitute(e); }
public static void ProcessCounterexamplesWOSymbolicOut(SDiffCounterexamples errors, List <Variable> globals, List <Variable> eqLocVars, Implementation vtLeftProcImpl, Implementation vtRightProcImpl, List <Declaration> consts, List <Model> errModelList, string v1Name, string v2Name) { List <Expr> constraintExprs = new List <Expr>(); List <Block> listBlocksV1 = new List <Block>(); List <Block> listBlocksV2 = new List <Block>(); Model[] errModelArray = errModelList.ToArray(); var label = new GotoCmd(Token.NoToken, new List <String>() { "DONE" }); label.labelNames = new List <string>(); // label.labelTargets = new List<Block>(); label.labelNames.Add("DONE"); //label.labelTargets.Add("DONE"); // First block var labels = new List <String>(); for (int j = 0; j < errors.Count; j++) { labels.Add("Cex" + j); } labels.Add("ELSE"); var labelEntry = new GotoCmd(Token.NoToken, labels); labelEntry.labelTargets = new List <Block>(); for (int j = 0; j < errors.Count; j++) { labelEntry.labelNames.Add("Cex" + j);//labelEntry.labelTargets.Add("Cex" + j); } for (int i = 0; i < errors.Count; i++) { var impl = errors[i].Impl; var trace = errors[i].Trace; //Log.Out(Log.Normal, "Attempting symbolic execution of [" + i + "] $ " + impl.Name); if (Options.GenerateCTrace) { Log.Out(Log.Normal, "Constructing metatrace from location annotations"); var extractor = new SDiff.SymEx.TraceExtractor(); extractor.VisitTrace(trace); //Log.Out(Log.CTrace, CTrace.Make(extractor.metaTrace)); var cTrace = CTrace.Make(extractor.metaTrace, consts, errModelArray[i], v1Name, v2Name); //var cTrace = ""; if (cTrace.Trim() != "") { //note that the index for cex on the output shows 1,2,..., instead of 0,1,2.... var fname = impl.Name + "_cex_" + (i + 1) + "_out.c"; var cexOut = new TokenTextWriter(impl.Name + "_cex_" + (i + 1) + "_out.c", true); cexOut.WriteLine(cTrace); cexOut.Close(); Log.Out(Log.CTrace, "n:" + (i + 1) + ":" + fname); Log.Out(Log.CTrace, "w:" + fname); } } Log.Out(Log.Normal, "Desugaring calls"); //HACK!!!: changes havoc x; assume (x= uf(..)); --> x := uf(...) var deCall = new SDiff.SymEx.DesugarCallCmds(); trace = deCall.VisitTrace(trace); //symbolic constants var symInParams = new List <Variable>(impl.InParams); foreach (var g in globals) { symInParams.Add(g); } Log.Out(Log.Normal, "Executing trace downward"); //symbolic stores (look at symex.cs for the datastructure) // var sTrace = SDiff.SymEx.Cexecutor.ExecDown(trace, symInParams); Log.Out(Log.Normal, "Executing trace upward"); //looks at each assume to create the path constants //clean up the duplication of assignments //SDiff.SymEx.Cexecutor.ExecUp(sTrace); Log.Out(Log.Normal, "Grabbing final execution values"); // var lastStore = sTrace.LastSCmd().Gammas.Last(); // var firstCons = sTrace.FirstSCmd().Cons; // constraintExprs.Add(firstCons.Conjoin()); //#hemr - generating new strategy right here with inlining counterexamples! // Second block List <Cmd> cmdsV1_Diff_inline = new List <Cmd>(); List <Cmd> cmdsV2_Diff_inline = new List <Cmd>(); Substitution replaceScopeV1 = delegate(Variable x) { return(replaceScopeGeneric(vtLeftProcImpl, x)); }; Substitution replaceScopeV2 = delegate(Variable x) { return(replaceScopeGeneric(vtRightProcImpl, x)); }; foreach (Block currentBlock in trace) { if (currentBlock.ToString().Contains("inline$" + v1Name)) { foreach (Cmd currentCmd in currentBlock.Cmds) { Cmd newCmd = Substituter.Apply(replaceScopeV1, currentCmd); cmdsV1_Diff_inline.Add(newCmd); } } else if (currentBlock.ToString().Contains("inline$" + v2Name)) { foreach (Cmd currentCmd in currentBlock.Cmds) { Cmd newCmd = Substituter.Apply(replaceScopeV2, currentCmd); cmdsV2_Diff_inline.Add(newCmd); } } } Block blockV1 = new Block(Token.NoToken, "Cex" + i, cmdsV1_Diff_inline, label); Block blockV2 = new Block(Token.NoToken, "Cex" + i, cmdsV2_Diff_inline, label); listBlocksV1.Add(blockV1); listBlocksV2.Add(blockV2); //#hemr - displaying values related to error model (at console level) Model currentModel = errModelArray[i]; //var keys = currentModel.identifierToPartition.Keys; var keys = currentModel.Functions.Where(f => f.Arity == 0).Select(f => f.GetConstant()); } Expr disjunctionDiffCond = Expr.False; foreach (Expr currentExpr in constraintExprs) { disjunctionDiffCond = Expr.Or(disjunctionDiffCond, currentExpr); } ProcessCounterexampleForDiffInliningWOSymbolicOut(eqLocVars, vtLeftProcImpl, vtRightProcImpl, v1Name, v2Name, listBlocksV1, listBlocksV2, labelEntry); }
public static string ExprToTemplateSpecific(Expr expr, bool loop) { int cnt = 0; var inCache = new Dictionary <string, Expr>(); var outCache = new Dictionary <string, Expr>(); var inToOut = new Func <string, string>(s => s.StartsWith("in_") ? "out_" + s.Substring("in_".Length) : ""); var outToIn = new Func <string, string>(s => s.StartsWith("out_") ? "in_" + s.Substring("out_".Length) : ""); var GetFin = new Func <Variable, Expr>(v => { if (inCache.ContainsKey(v.Name)) { return(inCache[v.Name]); } if (loop && outCache.ContainsKey(inToOut(v.Name))) { return(new OldExpr(Token.NoToken, outCache[inToOut(v.Name)])); } var prefix = loop ? "v_loop_" : "v_fin_"; prefix += v.TypedIdent.Type.ToString(); prefix += string.Format("_{0}", cnt++); var outv = BoogieAstFactory.MkFormal(prefix, v.TypedIdent.Type, true); var outexpr = loop ? (Expr)(new OldExpr(Token.NoToken, Expr.Ident(outv))) : Expr.Ident(outv); inCache[v.Name] = outexpr; return(outexpr); }); var GetFout = new Func <Variable, Expr>(v => { if (outCache.ContainsKey(v.Name)) { return(outCache[v.Name]); } if (loop && inCache.ContainsKey(outToIn(v.Name)) && inCache[outToIn(v.Name)] is OldExpr) { return((inCache[outToIn(v.Name)] as OldExpr).Expr); } var prefix = loop ? "v_loop_" : "v_fout_"; prefix += v.TypedIdent.Type.ToString(); prefix += string.Format("_{0}", cnt++); var outv = BoogieAstFactory.MkFormal(prefix, v.TypedIdent.Type, false); var outexpr = Expr.Ident(outv); outCache[v.Name] = outexpr; return(outexpr); }); var ret = Substituter.Apply(new Substitution(v => { if (v is Formal && (v as Formal).InComing) { return(GetFin(v)); } if (v is Formal && !(v as Formal).InComing) { return(GetFout(v)); } return(Expr.Ident(v)); }), expr); return(ret.ToString()); }