/** Create a symbolic transformer. */ public Transformer CreateTransformer(FuncDecl[] _RelParams, Term[] _IndParams, Term _Formula) { Transformer t = new Transformer(); t.RelParams = _RelParams; t.IndParams = _IndParams; t.Formula = _Formula; t.owner = this; return t; }
/** Create a relation (nullary relational transformer) */ public Transformer CreateRelation(Term[] _IndParams, Term _Formula) { return CreateTransformer(new FuncDecl[0], _IndParams, _Formula); }
/** Assert a background axiom. Background axioms can be used to provide the * theory of auxilliary functions or relations. All symbols appearing in * background axioms are considered global, and may appear in both transformer * and relational solutions. Semantically, a solution to the RPFP gives * an interpretation of the unknown relations for each interpretation of the * auxilliary symbols that is consistent with the axioms. Axioms should be * asserted before any calls to Push. They cannot be de-asserted by Pop. */ public void AssertAxiom(Term t) { ctx.AddAxiom(t); }
private Term ExtractSmallerVCsRec(TermDict< Term> memo, Term t, List<Term> small, Term lbl = null) { Term res; if (memo.TryGetValue(t, out res)) return res; var kind = t.GetKind(); if (kind == TermKind.App) { var f = t.GetAppDecl(); if (f.GetKind() == DeclKind.Implies){ var lhs = t.GetAppArgs()[0]; if(lhs.GetKind() == TermKind.App){ var r = lhs.GetAppDecl(); if (r.GetKind() == DeclKind.And) { Term q = t.GetAppArgs()[1]; var lhsargs = lhs.GetAppArgs(); for (int i = lhsargs.Length-1; i >= 0; --i) { q = ctx.MkImplies(lhsargs[i], q); } res = ExtractSmallerVCsRec(memo, q, small,lbl); goto done; } if (r.GetKind() == DeclKind.Label) { var arg = lhs; arg = lhs.GetAppArgs()[0]; if (!(arg.GetKind() == TermKind.App && arg.GetAppDecl().GetKind() == DeclKind.Uninterpreted)) goto normal; if (!(annotationInfo.ContainsKey(arg.GetAppDecl().GetDeclName()) && annotationInfo[arg.GetAppDecl().GetDeclName()].type == AnnotationInfo.AnnotationType.LoopInvariant)) goto normal; var sm = ctx.MkImplies(lhs, ExtractSmallerVCsRec(memo, t.GetAppArgs()[1], small)); if (lbl != null) sm = ctx.MkImplies(lbl, sm); small.Add(sm); res = ctx.MkTrue(); goto done; } if (r.GetKind() == DeclKind.Uninterpreted) { var arg = lhs; if (!(annotationInfo.ContainsKey(arg.GetAppDecl().GetDeclName()) && annotationInfo[arg.GetAppDecl().GetDeclName()].type == AnnotationInfo.AnnotationType.LoopInvariant)) goto normal; var sm = ctx.MkImplies(lhs,ExtractSmallerVCsRec(memo,t.GetAppArgs()[1],small)); if (lbl != null) sm = ctx.MkImplies(lbl, sm); small.Add(sm); res = ctx.MkTrue(); goto done; } } normal: Term newlbl = null; if (lhs.IsLabel() && lhs.GetAppArgs()[0] == ctx.MkTrue()) newlbl = lhs; res = ctx.MkImplies(lhs,ExtractSmallerVCsRec(memo,t.GetAppArgs()[1],small,newlbl)); } else if (f.GetKind() == DeclKind.And) { res = ctx.MkApp(f,t.GetAppArgs().Select(x => ExtractSmallerVCsRec(memo, x, small)).ToArray()); } else res = t; } else res = t; done: memo.Add(t, res); return res; }
private bool EvalToFalse(RPFP rpfp, RPFP.Node root, Term expr,StratifiedInliningInfo info) { Term res = rpfp.Eval(root.Outgoing,expr); return res.Equals(ctx.MkTrue()); }
public Term Letify(Term t) { var thing = new Letifier(this); return(thing.Letify(t)); }
private bool IsVariable(Term t) { // TODO: is this right? // return t.IsFunctionApp() && t.GetAppArgs().Length == 0; return t is VCExprVar && !(t is VCExprConstant); }
private Term CollectParamsRec(TermDict<Term> memo, Term t, List<FuncDecl> parms, List<RPFP.Node> nodes, Dictionary<Term, Term> done) { Term res; if (memo.TryGetValue(t, out res)) return res; if (t.GetKind() == TermKind.App) { var f = t.GetAppDecl(); Node node; if (relationToNode.TryGetValue(f, out node)) { if (done.ContainsKey(t)) res = done[t]; else { f = SuffixFuncDecl(t, parms.Count); parms.Add(f); nodes.Add(node); done.Add(t,res); // don't count same expression twice! } } var args = t.GetAppArgs(); args = args.Select(x => CollectParamsRec(memo, x, parms, nodes, done)).ToArray(); res = ctx.CloneApp(t, args); } // TODO: handle quantifiers else res = t; memo.Add(t, res); return res; }
public void AddAxiom(Term ax) { axioms.Add(ax); }
public static bool IsFalse(this Term t) { return(t == VCExpressionGenerator.False); }
public static bool IsFunctionApp(this Term t) { return(t.GetKind() == TermKind.App && t.GetAppDecl().GetKind() == DeclKind.Uninterpreted); }
public static Sort GetSort(this Term t) { return(t.Type); }
public static string LabelName(this Term t) { return((GetAppDecl(t) as VCExprLabelOp).label); }
public static FuncDecl GetAppDecl(this Term t) { Microsoft.Boogie.VCExprAST.VCExprNAry tn = t as Microsoft.Boogie.VCExprAST.VCExprNAry; return(tn.Op); }
public static Term[] GetAppArgs(this Term t) { Microsoft.Boogie.VCExprAST.VCExprNAry tn = t as Microsoft.Boogie.VCExprAST.VCExprNAry; return(tn.ToArray()); }
/** Convert an array of clauses to an RPFP. */ public void FromClauses(Term[] clauses) { FuncDecl failName = ctx.MkFuncDecl("@Fail", ctx.MkBoolSort()); foreach(var clause in clauses){ Node foo = GetNodeFromClause(clause,failName); if(foo != null) nodes.Add(foo); } foreach (var clause in clauses) edges.Add(GetEdgeFromClause(clause,failName)); }
/** Sets the value in the counterexample of a symbol occuring in the transformer formula of * a given edge. */ public void SetValue(Edge e, Term variable, Term value) { if (e.valuation == null) e.valuation = new TermDict< Term>(); e.valuation.Add(variable, value); }
public void RemoveAxiom(Term ax) { axioms.Remove(ax); }
private Edge GetEdgeFromClause(Term t, FuncDecl failName) { Term[] args = t.GetAppArgs(); Term body = args[0]; Term head = args[1]; Term[] _IndParams; FuncDecl Name; if (head.IsFalse()) { Name = failName; _IndParams = new Term[0]; } else { _IndParams = head.GetAppArgs(); Name = head.GetAppDecl(); } for(int i = 0; i < _IndParams.Length; i++) if (!IsVariable(_IndParams[i])) { Term v = ctx.MkConst("@a" + i.ToString(), _IndParams[i].GetSort()); body = ctx.MkAnd(body, ctx.MkEq(v, _IndParams[i])); _IndParams[i] = v; } var relParams = new List<FuncDecl>(); var nodeParams = new List<RPFP.Node>(); var memo = new TermDict< Term>(); var done = new Dictionary<Term, Term>(); // note this hashes on equality, not reference! body = CollectParamsRec(memo, body, relParams, nodeParams,done); Transformer F = CreateTransformer(relParams.ToArray(), _IndParams, body); Node parent = relationToNode[Name]; return CreateEdge(parent, F, nodeParams.ToArray()); }
public Term MkApp(FuncDecl f, Term arg) { return(Function(f, arg)); }
private Term SubstPredsRec(TermDict< Term> memo, Dictionary<FuncDecl,FuncDecl> subst, Term t) { Term res; if (memo.TryGetValue(t, out res)) return res; if (t.GetKind() == TermKind.App) { var args = t.GetAppArgs(); args = args.Select(x => SubstPredsRec(memo,subst,x)).ToArray(); FuncDecl nf = null; var f = t.GetAppDecl(); if (subst.TryGetValue(f, out nf)) { res = ctx.MkApp(nf, args); } else { res = ctx.CloneApp(t, args); } } // TODO: handle quantifiers else res = t; memo.Add(t, res); return res; }
public Term MkAnd(Term arg1, Term arg2) { return(And(arg1, arg2)); }
private Term CollectGoalsRec(TermDict< Term> memo, Term t, List<Term> goals, List<Term> cruft) { Term res; if (memo.TryGetValue(t, out res)) return res; var kind = t.GetKind(); if (kind == TermKind.App) { var f = t.GetAppDecl(); if (f.GetKind() == DeclKind.Implies) { CollectGoalsRec(memo, t.GetAppArgs()[1], goals, cruft); goto done; } else if (f.GetKind() == DeclKind.And) { foreach (var arg in t.GetAppArgs()) { CollectGoalsRec(memo, arg, goals, cruft); } goto done; } else if (f.GetKind() == DeclKind.Label) { var arg = t.GetAppArgs()[0]; var r = arg.GetAppDecl(); if (r.GetKind() == DeclKind.Uninterpreted) { if (memo.TryGetValue(arg, out res)) goto done; if (!annotationInfo.ContainsKey(r.GetDeclName()) && !arg.GetAppDecl().GetDeclName().StartsWith("_solve_")) goto done; goals.Add(arg); memo.Add(arg, arg); goto done; } else return CollectGoalsRec(memo, arg, goals, cruft); } else if (f.GetKind() == DeclKind.Uninterpreted) { string name = f.GetDeclName(); if (name.StartsWith("_solve_")) { if (memo.TryGetValue(t, out res)) goto done; goals.Add(t); memo.Add(t, t); return t; } } } // else the goal must be cruft cruft.Add(t); done: res = t; // just to return something memo.Add(t, res); return res; }
public Term MkNot(Term arg1) { return(Not(arg1)); }
private void ExtractSmallerVCs(Term t, List<Term> small) { TermDict< Term> memo = new TermDict< Term>(); Term top = ExtractSmallerVCsRec(memo, t, small); small.Add(top); }
public Term MkImplies(Term arg1, Term arg2) { return(Implies(arg1, arg2)); }
private void FactorVCs(Term t, List<Term> vcs) { List<Term> small = new List<Term>(); ExtractSmallerVCs(t, small); foreach (var smm in small) { List<Term> goals = new List<Term>(); List<Term> cruft = new List<Term>(); var sm = largeblock ? MergeGoals(smm) : smm; CollectGoals(sm, goals,cruft); foreach (var goal in goals) { TermDict< Term> memo = new TermDict< Term>(); foreach (var othergoal in goals) memo.Add(othergoal, othergoal.Equals(goal) ? ctx.MkFalse() : ctx.MkTrue()); foreach (var thing in cruft) memo.Add(thing, ctx.MkTrue()); var vc = SubstRecGoals(memo, sm); vc = ctx.MkImplies(ctx.MkNot(vc), goal); vcs.Add(vc); } { TermDict< Term> memo = new TermDict< Term>(); foreach (var othergoal in goals) memo.Add(othergoal, ctx.MkTrue()); var vc = SubstRecGoals(memo, sm); if (vc != ctx.MkTrue()) { vc = ctx.MkImplies(ctx.MkNot(vc), ctx.MkFalse()); vcs.Add(vc); } } } }
public Term MkEq(Term arg1, Term arg2) { return(Eq(arg1, arg2)); }
/** Create a node in the graph. The input is a term R(v_1...v_n) * where R is an arbitrary relational symbol and v_1...v_n are * arbitary distinct variables. The names are only of mnemonic value, * however, the number and type of arguments determine the type * of the relation at this node. */ public Node CreateNode(Term t) { Node n = new Node(); // Microsoft.Boogie.VCExprAST.VCExprNAry tn = t as Microsoft.Boogie.VCExprAST.VCExprNAry; // Term[] _IndParams = tn.ToArray(); Term[] _IndParams = t.GetAppArgs(); FuncDecl Name = t.GetAppDecl(); n.Annotation = CreateRelation(_IndParams,ctx.MkTrue()); n.Bound = CreateRelation(_IndParams, ctx.MkTrue()); n.owner = this; n.number = ++nodeCount; n.Name = Name; // just to have a unique name n.Incoming = new List<Edge>(); return n; }
private Term MergeGoals(Term t) { TermDict< Term> memo = new TermDict< Term>(); return MergeGoalsRec(memo, t); }
/** Determines the value in the counterexample of a symbol occuring in the transformer formula of * a given edge. */ public Term Eval(Edge e, Term t) { if (e.valuation == null) e.valuation = new TermDict< Term>(); if (e.valuation.ContainsKey(t)) return e.valuation[t]; return null; // TODO }
private Term MergeGoalsRec(TermDict< Term> memo, Term t) { Term res; if (memo.TryGetValue(t, out res)) return res; var kind = t.GetKind(); if (kind == TermKind.App) { var f = t.GetAppDecl(); var args = t.GetAppArgs(); if (f.GetKind() == DeclKind.Implies) { res = ctx.MkImplies(args[0], MergeGoalsRec(memo, args[1])); goto done; } else if (f.GetKind() == DeclKind.And) { args = args.Select(x => MergeGoalsRec(memo, x)).ToArray(); res = ctx.MkApp(f, args); goto done; } else if (f.GetKind() == DeclKind.Label) { var arg = t.GetAppArgs()[0]; var r = arg.GetAppDecl(); if (r.GetKind() == DeclKind.Uninterpreted) { res = NormalizeGoal(arg, f); goto done; } } } res = t; done: memo.Add(t, res); return res; }
/** Do not call this. */ public void RemoveAxiom(Term t) { ctx.RemoveAxiom(t); }
private Term NormalizeGoal(Term goal, FuncDecl label) { var f = goal.GetAppDecl(); var args = goal.GetAppArgs(); int number; if (!goalNumbering.TryGetValue(f, out number)) { number = goalNumbering.Count; goalNumbering.Add(f, number); } Term[] tvars = new Term[args.Length]; Term[] eqns = new Term[args.Length]; AnnotationInfo info = null; annotationInfo.TryGetValue(f.GetDeclName(), out info); for (int i = 0; i < args.Length; i++) { string pname = (info == null) ? i.ToString() : info.argnames[i]; tvars[i] = ctx.MkConst("@a" + number.ToString() + "_" + pname, args[i].GetSort()); eqns[i] = ctx.MkEq(tvars[i], args[i]); } return ctx.MkImplies(ctx.MkAnd(eqns), ctx.MkApp(label, ctx.MkApp(f, tvars))); }
private Term BindVariables(Term t, bool universal = true) { TermDict< bool> memo = new TermDict<bool>(); List<Term> vars = new List<Term>(); CollectVariables(memo,t,vars); return universal ? ctx.MkForall(vars.ToArray(), t) : ctx.MkExists(vars.ToArray(), t); }
private Term SubstRec(TermDict< Term> memo, Term t) { Term res; if (memo.TryGetValue(t, out res)) return res; var kind = t.GetKind(); if (kind == TermKind.App) { // var f = t.GetAppDecl(); var args = t.GetAppArgs().Select(x => SubstRec(memo, x)).ToArray(); res = ctx.CloneApp(t, args); } else res = t; memo.Add(t, res); return res; }
private void CollectVariables(TermDict< bool> memo, Term t, List<Term> vars) { if (memo.ContainsKey(t)) return; if (IsVariable(t)) vars.Add(t); if (t.GetKind() == TermKind.App) { foreach (var s in t.GetAppArgs()) CollectVariables(memo, s, vars); } memo.Add(t, true); }
private Term SubstRecGoals(TermDict< Term> memo, Term t) { Term res; if (memo.TryGetValue(t, out res)) return res; var kind = t.GetKind(); if (kind == TermKind.App) { var f = t.GetAppDecl(); var args = t.GetAppArgs(); if (f.GetKind() == DeclKind.Implies){ res = SubstRecGoals(memo, args[1]); if (res != ctx.MkTrue()) res = ctx.MkImplies(args[0],res); goto done; } else if (f.GetKind() == DeclKind.And) { args = args.Select(x => SubstRecGoals(memo, x)).ToArray(); args = args.Where(x => x != ctx.MkTrue()).ToArray(); res = ctx.MkAnd(args); goto done; } else if (f.GetKind() == DeclKind.Label) { var arg = t.GetAppArgs()[0]; var r = arg.GetAppDecl(); if (r.GetKind() == DeclKind.Uninterpreted) { if (memo.TryGetValue(arg, out res)) { if(res != ctx.MkTrue()) res = ctx.MkApp(f, res); goto done; } } else { res = ctx.MkApp(f, SubstRecGoals(memo, arg)); goto done; } } // what's left could be cruft! if (memo.TryGetValue(t, out res)) { goto done; } } res = t; done: memo.Add(t, res); return res; }
private Node GetNodeFromClause(Term t, FuncDecl failName) { Term[] args = t.GetAppArgs(); Term body = args[0]; Term head = args[1]; FuncDecl Name; Term[] _IndParams; bool is_query = false; if (head.Equals(ctx.MkFalse())) { Name = failName; is_query = true; _IndParams = new Term[0]; } else { Name = head.GetAppDecl(); _IndParams = head.GetAppArgs(); } if (relationToNode.ContainsKey(Name)) return null; for (int i = 0; i < _IndParams.Length; i++) if (!IsVariable(_IndParams[i])) { Term v = ctx.MkConst("@a" + i.ToString(), _IndParams[i].GetSort()); _IndParams[i] = v; } Term foo = ctx.MkApp(Name, _IndParams); Node node = CreateNode(foo); relationToNode[Name] = node; if (is_query) node.Bound = CreateRelation(new Term[0], ctx.MkFalse()); return node; }
// TODO: this is a bit cheesy. Rather than finding the argument position // of a relational term in a transformer by linear search, better to index this // somewhere, but where? private int TransformerArgPosition(RPFP rpfp, RPFP.Node root, Term expr) { FuncDecl rel = expr.GetAppDecl(); string relname = rel.GetDeclName(); var rps = root.Outgoing.F.RelParams; for (int i = 0; i < rps.Length; i++) { string thisname = rps[i].GetDeclName(); if (thisname == relname) return i; } return -1; }
private Term SubstPreds(Dictionary<FuncDecl, FuncDecl> subst, Term t) { TermDict< Term> memo = new TermDict< Term>(); return SubstPredsRec(memo, subst, t); }
public void FindLabelsRec(HashSet<Term> memo, Term t, Dictionary<string, Term> res) { if (memo.Contains(t)) return; if (t.IsLabel()) { string l = t.LabelName(); if (!res.ContainsKey(l)) res.Add(l, t.GetAppArgs()[0]); } if (t.GetKind() == TermKind.App) { var args = t.GetAppArgs(); foreach (var a in args) FindLabelsRec(memo, a, res); } // TODO: handle quantifiers memo.Add(t); }
// This returns a new FuncDel with same sort as top-level function // of term t, but with numeric suffix appended to name. private FuncDecl SuffixFuncDecl(Term t, int n) { var name = t.GetAppDecl().GetDeclName() + "_" + n.ToString(); return ctx.MkFuncDecl(name, t.GetAppDecl()); }
private void CollectGoals(Term t, List<Term> goals, List<Term> cruft) { TermDict< Term> memo = new TermDict< Term>(); CollectGoalsRec(memo, t.GetAppArgs()[1], goals, cruft); }