/// <summary> /// Checks whether the assertions in the context are consistent or not. /// </summary> public static Status Check(Context ctx, List<BoolExpr> core, ref Model model, ref Expr proof, params Expr[] assumptions) { Z3_lbool r; model = null; proof = null; if (assumptions == null || assumptions.Length == 0) r = (Z3_lbool)Native.Z3_check(ctx.nCtx); else { IntPtr mdl = IntPtr.Zero, prf = IntPtr.Zero; uint core_size = 0; IntPtr[] native_core = new IntPtr[assumptions.Length]; r = (Z3_lbool)Native.Z3_check_assumptions(ctx.nCtx, (uint)assumptions.Length, AST.ArrayToNative(assumptions), ref mdl, ref prf, ref core_size, native_core); for (uint i = 0; i < core_size; i++) core.Add((BoolExpr)Expr.Create(ctx, native_core[i])); if (mdl != IntPtr.Zero) { model = new Model(ctx, mdl); } if (prf != IntPtr.Zero) { proof = Expr.Create(ctx, prf); } } switch (r) { case Z3_lbool.Z3_L_TRUE: return Status.SATISFIABLE; case Z3_lbool.Z3_L_FALSE: return Status.UNSATISFIABLE; default: return Status.UNKNOWN; } }
internal AcceptorBase(FuncDecl symbol, Expr guard, ExprSet[] lookahead) { this.symbol = symbol; this.guard = guard; this.lookahead = lookahead; this.lhs = new Pair<FuncDecl, Sequence<ExprSet>>(symbol, new Sequence<ExprSet>(lookahead)); }
//bool CSmode = false; /// <summary> /// Returns a pretty printed view of the given term. /// </summary> /// <param name="term">the given term</param> /// <param name="lookupVarName">lookup function for variable names</param> public string DescribeExpr(Expr term, Func<Expr, string> lookupVarName) { __lookupVarName = lookupVarName; var str = DescribeExpr(term); __lookupVarName = null; return str; }
/// <summary> /// Retrieves the interpretation (the assignment) of <paramref name="a"/> in the model. /// </summary> /// <param name="a">A Constant</param> /// <returns>An expression if the constant has an interpretation in the model, null otherwise.</returns> public Expr ConstInterp(Expr a) { Contract.Requires(a != null); Context.CheckContextMatch(a); return ConstInterp(a.FuncDecl); }
public Automaton<Expr> getAutomata(Z3Provider z3p, Expr universe, Expr var, Sort sort) { //Sort for pairs (input theory, BV) var bv = z3p.Z3.MkBitVecSort(BVConst.BVSIZE); var pairSort = z3p.MkTupleSort(sort, bv); var dfapair = this.Normalize().PushQuantifiers().getAutomata(z3p, new List<string>(), universe, var, sort); //Compute the new moves by dropping the last bit of every element in the phiMoves var newMoves = Automaton<Expr>.Empty.GetMoves().ToList(); foreach (var oldMove in dfapair.GetMoves()) { var oldCond = oldMove.Label; //Compute the new condition as () Expr newCond = oldCond; //Update the new set of moves newMoves.Add(new Move<Expr>(oldMove.SourceState, oldMove.TargetState, newCond)); } //Build the new dfa with the new moves var automaton = Automaton<Expr>.Create(dfapair.InitialState, dfapair.GetFinalStates(), newMoves); return automaton.Determinize(z3p).Minimize(z3p); }
internal Quantifier(Context ctx, bool isForall, Expr[] bound, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) : base(ctx) { Contract.Requires(ctx != null); Contract.Requires(body != null); Contract.Requires(patterns == null || Contract.ForAll(patterns, p => p != null)); Contract.Requires(noPatterns == null || Contract.ForAll(noPatterns, np => np != null)); Contract.Requires(bound == null || Contract.ForAll(bound, n => n != null)); Context.CheckContextMatch(noPatterns); Context.CheckContextMatch(patterns); //Context.CheckContextMatch(bound); Context.CheckContextMatch(body); if (noPatterns == null && quantifierID == null && skolemID == null) { NativeObject = Native.Z3_mk_quantifier_const(ctx.nCtx, (isForall) ? 1 : 0, weight, AST.ArrayLength(bound), AST.ArrayToNative(bound), AST.ArrayLength(patterns), AST.ArrayToNative(patterns), body.NativeObject); } else { NativeObject = Native.Z3_mk_quantifier_const_ex(ctx.nCtx, (isForall) ? 1 : 0, weight, AST.GetNativeObject(quantifierID), AST.GetNativeObject(skolemID), AST.ArrayLength(bound), AST.ArrayToNative(bound), AST.ArrayLength(patterns), AST.ArrayToNative(patterns), AST.ArrayLength(noPatterns), AST.ArrayToNative(noPatterns), body.NativeObject); } }
/// <summary> /// Z3 expr to C# pretty printer /// </summary> public CSPrettyPrinter(Context z3) { this.charSort = z3.MkBitVecSort(16); this.tt = z3.MkBool(true); this.ff = z3.MkBool(false); this.encoding = 16; }
internal AcceptorBase(FuncDecl symbol, Expr guard, int rank) { this.symbol = symbol; this.guard = guard; ExprSet[] ts = new ExprSet[rank]; for (int i = 0; i < rank; i++) ts[i] = new ExprSet(); lookahead = ts; }
/// <summary> /// Returns a pretty printed view of the given term. Uses C# compliant expression notation. /// </summary> /// <param name="term">the given term</param> /// <param name="lookupVarName">lookup function for variable names</param> public string DescribeExprCS(Expr term, Func<Expr, string> lookupVarName) { //CSmode = true; __lookupVarName = lookupVarName; var str = DescribeExpr(term); __lookupVarName = null; //CSmode = false; return str; }
/// <summary> /// Create axiom: function f is injective in the i-th argument. /// </summary> /// <remarks> /// The following axiom is produced: /// <c> /// forall (x_0, ..., x_n) finv(f(x_0, ..., x_i, ..., x_{n-1})) = x_i /// </c> /// Where, <code>finv</code>is a fresh function declaration. /// </summary> public static BoolExpr InjAxiom(Context ctx, FuncDecl f, int i) { Sort[] domain = f.Domain; uint sz = f.DomainSize; if (i >= sz) { Console.WriteLine("failed to create inj axiom"); return null; } /* declare the i-th inverse of f: finv */ Sort finv_domain = f.Range; Sort finv_range = domain[i]; FuncDecl finv = ctx.MkFuncDecl("f_fresh", finv_domain, finv_range); /* allocate temporary arrays */ Expr[] xs = new Expr[sz]; Symbol[] names = new Symbol[sz]; Sort[] types = new Sort[sz]; /* fill types, names and xs */ for (uint j = 0; j < sz; j++) { types[j] = domain[j]; names[j] = ctx.MkSymbol(String.Format("x_{0}", j)); xs[j] = ctx.MkBound(j, types[j]); } Expr x_i = xs[i]; /* create f(x_0, ..., x_i, ..., x_{n-1}) */ Expr fxs = f[xs]; /* create f_inv(f(x_0, ..., x_i, ..., x_{n-1})) */ Expr finv_fxs = finv[fxs]; /* create finv(f(x_0, ..., x_i, ..., x_{n-1})) = x_i */ Expr eq = ctx.MkEq(finv_fxs, x_i); /* use f(x_0, ..., x_i, ..., x_{n-1}) as the pattern for the quantifier */ Pattern p = ctx.MkPattern(new Expr[] { fxs }); /* create & assert quantifier */ BoolExpr q = ctx.MkForall( types, /* types of quantified variables */ names, /* names of quantified variables */ eq, 1, new Pattern[] { p } /* patterns */); return q; }
/// <summary> /// Computes an interpolant. /// </summary> /// <remarks>For more information on interpolation please refer /// too the function Z3_get_interpolant in the C/C++ API, which is /// well documented.</remarks> public BoolExpr[] GetInterpolant(Expr pf, Expr pat, Params p) { Contract.Requires(pf != null); Contract.Requires(pat != null); Contract.Requires(p != null); Contract.Ensures(Contract.Result<Expr>() != null); CheckContextMatch(pf); CheckContextMatch(pat); CheckContextMatch(p); ASTVector seq = new ASTVector(this, Native.Z3_get_interpolant(nCtx, pf.NativeObject, pat.NativeObject, p.NativeObject)); return seq.ToBoolExprArray(); }
/// <summary> /// Computes an interpolant. /// </summary> /// <remarks>For more information on interpolation please refer /// too the function Z3_compute_interpolant in the C/C++ API, which is /// well documented.</remarks> public Z3_lbool ComputeInterpolant(Expr pat, Params p, out BoolExpr[] interp, out Model model) { Contract.Requires(pat != null); Contract.Requires(p != null); Contract.Ensures(Contract.ValueAtReturn(out interp) != null); Contract.Ensures(Contract.ValueAtReturn(out model) != null); CheckContextMatch(pat); CheckContextMatch(p); IntPtr i = IntPtr.Zero, m = IntPtr.Zero; int r = Native.Z3_compute_interpolant(nCtx, pat.NativeObject, p.NativeObject, ref i, ref m); interp = new ASTVector(this, i).ToBoolExprArray(); model = new Model(this, m); return (Z3_lbool)r; }
/// <summary> /// Checks the correctness of an interpolant. /// </summary> /// <remarks>For more information on interpolation please refer /// too the function Z3_check_interpolant in the C/C++ API, which is /// well documented.</remarks> public int CheckInterpolant(Expr[] cnsts, uint[] parents, BoolExpr[] interps, out string error, Expr[] theory) { Contract.Requires(cnsts.Length == parents.Length); Contract.Requires(cnsts.Length == interps.Length + 1); IntPtr n_err_str; int r = Native.Z3_check_interpolant(nCtx, (uint)cnsts.Length, Expr.ArrayToNative(cnsts), parents, Expr.ArrayToNative(interps), out n_err_str, (uint)theory.Length, Expr.ArrayToNative(theory)); error = Marshal.PtrToStringAnsi(n_err_str); return r; }
internal Quantifier(Context ctx, bool isForall, Sort[] sorts, Symbol[] names, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null ) : base(ctx) { Contract.Requires(ctx != null); Contract.Requires(sorts != null); Contract.Requires(names != null); Contract.Requires(body != null); Contract.Requires(sorts.Length == names.Length); Contract.Requires(Contract.ForAll(sorts, s => s != null)); Contract.Requires(Contract.ForAll(names, n => n != null)); Contract.Requires(patterns == null || Contract.ForAll(patterns, p => p != null)); Contract.Requires(noPatterns == null || Contract.ForAll(noPatterns, np => np != null)); Context.CheckContextMatch(patterns); Context.CheckContextMatch(noPatterns); Context.CheckContextMatch(sorts); Context.CheckContextMatch(names); Context.CheckContextMatch(body); if (sorts.Length != names.Length) throw new Z3Exception("Number of sorts does not match number of names"); IntPtr[] _patterns = AST.ArrayToNative(patterns); if (noPatterns == null && quantifierID == null && skolemID == null) { NativeObject = Native.Z3_mk_quantifier(ctx.nCtx, (isForall) ? 1 : 0, weight, AST.ArrayLength(patterns), AST.ArrayToNative(patterns), AST.ArrayLength(sorts), AST.ArrayToNative(sorts), Symbol.ArrayToNative(names), body.NativeObject); } else { NativeObject = Native.Z3_mk_quantifier_ex(ctx.nCtx, (isForall) ? 1 : 0, weight, AST.GetNativeObject(quantifierID), AST.GetNativeObject(skolemID), AST.ArrayLength(patterns), AST.ArrayToNative(patterns), AST.ArrayLength(noPatterns), AST.ArrayToNative(noPatterns), AST.ArrayLength(sorts), AST.ArrayToNative(sorts), Symbol.ArrayToNative(names), body.NativeObject); } }
/// <summary> /// Computes an interpolant. /// </summary> /// <remarks>For more information on interpolation please refer /// too the function Z3_get_interpolant in the C/C++ API, which is /// well documented.</remarks> Expr[] GetInterpolant(Expr pf, Expr pat, Params p) { Contract.Requires(pf != null); Contract.Requires(pat != null); Contract.Requires(p != null); Contract.Ensures(Contract.Result<Expr>() != null); CheckContextMatch(pf); CheckContextMatch(pat); CheckContextMatch(p); ASTVector seq = new ASTVector(this, Native.Z3_get_interpolant(nCtx, pf.NativeObject, pat.NativeObject, p.NativeObject)); uint n = seq.Size; Expr[] res = new Expr[n]; for (uint i = 0; i < n; i++) res[i] = Expr.Create(this, seq[i].NativeObject); return res; }
internal RankedAlphabet( TreeTheory tt, string[] symbols, Dictionary<string, int> idMap, Sort alphabetSort, Sort nodeSort, int[] ranks, FuncDecl[] constructors, FuncDecl[][] accessors, FuncDecl[] testers, FuncDecl acceptor, Expr[] vars ) { this.tt = tt; this.symbols = new List<string>(symbols).AsReadOnly(); this.idMap = idMap; this.alphabetSort = alphabetSort; this.nodeSort = nodeSort; this.ranks = ranks; this.constructors = constructors; this.accessors = accessors; this.testers = testers; this.acceptor = acceptor; this.vars = vars; this.trans = tt.GetTrans(alphabetSort, alphabetSort); this.emptyAcceptor = TreeTransducer.MkEmpty(this); this.fullAcceptor = TreeTransducer.MkFull(this); this.idAut = TreeTransducer.MkId(this); this.symbolsOfRank = new Dictionary<int, List<FuncDecl>>(); for (int i = 0; i < ranks.Length; i++) { var r = ranks[i]; if (!symbolsOfRank.ContainsKey(r)) symbolsOfRank[r] = new List<FuncDecl>(); symbolsOfRank[r].Add(constructors[i]); } var attrDomain = tt.Z.MkFreshFuncDecl("_", new Sort[] { nodeSort }, tt.Z.BoolSort); this.attrExpr = tt.Z.MkApp(attrDomain, vars[0]); tt.Z.AssertAxiom(this.attrExpr, tt.Z.True, vars[0]); }
public uint GetNumeralUInt(Expr t) { var ts = t.Sort; if (t is IntNum) return ((IntNum)t).UInt; if (t is BitVecNum) return ((BitVecNum)t).UInt; //avoiding z3 bug: (GetSort(t) is TupleSort) == false even when t is a tuple if ((t.Sort.Name.ToString().StartsWith("$")) && (GetTupleLength(t.Sort) == 1)) { var v = t.Args[0]; if (v is IntNum) return ((IntNum)v).UInt; if (v is BitVecNum) return ((BitVecNum)v).UInt; throw new Exception(); } throw new Exception(); }
public UnrankedTreeInfo(Sort treeListSort, FuncDecl getNodeValue, FuncDecl getSubtrees, FuncDecl mkNode, FuncDecl mkLeaf, FuncDecl getLeafValue, FuncDecl isNode, FuncDecl isLeaf, Expr empty, FuncDecl first, FuncDecl rest, FuncDecl cons, FuncDecl isEmpty, FuncDecl isCons) { this.TreeListSort = treeListSort; this.GetNodeLabel = getNodeValue; this.GetNodeSubtrees = getSubtrees; this.MkNode = mkNode; this.EmptyTreeList = empty; this.GetFirst = first; this.GetRest = rest; this.MkCons = cons; this.IsEmpty = isEmpty; this.IsCons = isCons; this.MkLeaf = mkLeaf; this.GetLeafValue = getLeafValue; this.IsNode = isNode; this.IsLeaf = isLeaf; }
public Const(ConstDef def, FastTransducerInstance fti, Z3Provider z3p) { this.z3p = z3p; this.name = def.id.text; switch (def.sort.kind) { case (FastSortKind.Real): { sort = z3p.RealSort; break; } case (FastSortKind.Bool): { sort = z3p.BoolSort; break; } case (FastSortKind.Int): { sort = z3p.IntSort; break; } case (FastSortKind.String): { sort = z3p.MkListSort(z3p.CharSort); break; } case (FastSortKind.Tree): { foreach (var enumSort in fti.enums) { if (enumSort.name == def.sort.name.text) { sort = enumSort.sort; break; } } break; } } this.value = GenerateZ3ExprFromExpr(def.expr, fti).Simplify(); }
internal override Automaton<Expr> getAutomata(Z3Provider z3p, List<string> variables, Expr universe, Expr var, Sort sort) { //var bit1 = z3p.Z3.MkInt2Bv(1, // z3p.MkInt(1)); var bit1 = z3p.Z3.MkInt2BV(BVConst.BVSIZE, (IntExpr)z3p.MkInt(1)); //Sort for pairs (input theory, BV) var bv = z3p.Z3.MkBitVecSort(BVConst.BVSIZE); var pairSort = z3p.MkTupleSort(sort, bv); //Add the representation of the existential variable to the list of variables var newVariables = variables.ToArray().ToList(); newVariables.Insert(0, variable); //Compute the DFA for the formula phi var phiDfa = phi.getAutomata(z3p, newVariables, universe, var, sort); //Compute the new moves by dropping the last bit of every element in the phiMoves var newMoves = Automaton<Expr>.Empty.GetMoves().ToList(); foreach (var oldMove in phiDfa.GetMoves()) { var oldCond = oldMove.Label; var t = z3p.MkProj(1,var); //Compute the new conditions var newCond0 = z3p.ApplySubstitution(oldCond, t, z3p.Z3.MkBVSHL((BitVecExpr)t, (BitVecExpr)bit1)); var newCond1 = z3p.ApplySubstitution(oldCond, t, z3p.MkBvAdd( z3p.Z3.MkBVSHL((BitVecExpr)t, (BitVecExpr)bit1), bit1)); //Update the new set of moves newMoves.Add(new Move<Expr>(oldMove.SourceState, oldMove.TargetState, z3p.MkOr(z3p.Simplify(newCond0),z3p.Simplify(newCond1)))); } //Build the new dfa with the new moves return Automaton<Expr>.Create(phiDfa.InitialState, phiDfa.GetFinalStates(), newMoves); //.Determinize(z3p).MinimizeClassical(z3p, int.MaxValue,false); }
/// <summary> /// The finite set of distinct values that represent the interpretation for sort <paramref name="s"/>. /// </summary> /// <seealso cref="Sorts"/> /// <param name="s">An uninterpreted sort</param> /// <returns>An array of expressions, where each is an element of the universe of <paramref name="s"/></returns> public Expr[] SortUniverse(Sort s) { Contract.Requires(s != null); Contract.Ensures(Contract.Result<Expr[]>() != null); ASTVector nUniv = new ASTVector(Context, Native.Z3_model_get_sort_universe(Context.nCtx, NativeObject, s.NativeObject)); uint n = nUniv.Size; Expr[] res = new Expr[n]; for (uint i = 0; i < n; i++) res[i] = Expr.Create(Context, nUniv[i].NativeObject); return res; }
/// <summary> /// Alias for <c>Eval</c>. /// </summary> public Expr Evaluate(Expr t, bool completion = false) { Contract.Requires(t != null); Contract.Ensures(Contract.Result<Expr>() != null); return Eval(t, completion); }
/// <summary> /// Evaluates the expression <paramref name="t"/> in the current model. /// </summary> /// <remarks> /// This function may fail if <paramref name="t"/> contains quantifiers, /// is partial (MODEL_PARTIAL enabled), or if <paramref name="t"/> is not well-sorted. /// In this case a <c>ModelEvaluationFailedException</c> is thrown. /// </remarks> /// <param name="t">An expression</param> /// <param name="completion"> /// When this flag is enabled, a model value will be assigned to any constant /// or function that does not have an interpretation in the model. /// </param> /// <returns>The evaluation of <paramref name="t"/> in the model.</returns> public Expr Eval(Expr t, bool completion = false) { Contract.Requires(t != null); Contract.Ensures(Contract.Result<Expr>() != null); IntPtr v = IntPtr.Zero; if (Native.Z3_model_eval(Context.nCtx, NativeObject, t.NativeObject, (completion) ? 1 : 0, ref v) == 0) throw new ModelEvaluationFailedException(); else return Expr.Create(Context, v); }
/// <summary> /// Array update. /// </summary> /// <remarks> /// The node <c>a</c> must have an array sort <c>[domain -> range]</c>, /// <c>i</c> must have sort <c>domain</c>, /// <c>v</c> must have sort range. The sort of the result is <c>[domain -> range]</c>. /// The semantics of this function is given by the theory of arrays described in the SMT-LIB /// standard. See http://smtlib.org for more details. /// The result of this function is an array that is equal to <c>a</c> /// (with respect to <c>select</c>) /// on all indices except for <c>i</c>, where it maps to <c>v</c> /// (and the <c>select</c> of <c>a</c> with /// respect to <c>i</c> may be a different value). /// <seealso cref="MkArraySort"/> /// <seealso cref="MkSelect"/> /// </remarks> public ArrayExpr MkStore(ArrayExpr a, Expr i, Expr v) { Contract.Requires(a != null); Contract.Requires(i != null); Contract.Requires(v != null); Contract.Ensures(Contract.Result<ArrayExpr>() != null); CheckContextMatch(a); CheckContextMatch(i); CheckContextMatch(v); return new ArrayExpr(this, Native.Z3_mk_store(nCtx, a.NativeObject, i.NativeObject, v.NativeObject)); }
/// <summary> /// Check for subsetness of sets. /// </summary> public Expr MkSetSubset(Expr arg1, Expr arg2) { Contract.Requires(arg1 != null); Contract.Requires(arg2 != null); Contract.Ensures(Contract.Result<Expr>() != null); CheckContextMatch(arg1); CheckContextMatch(arg2); return Expr.Create(this, Native.Z3_mk_set_subset(nCtx, arg1.NativeObject, arg2.NativeObject)); }
/// <summary> /// Check for set membership. /// </summary> public Expr MkSetMembership(Expr elem, Expr set) { Contract.Requires(elem != null); Contract.Requires(set != null); Contract.Ensures(Contract.Result<Expr>() != null); CheckContextMatch(elem); CheckContextMatch(set); return Expr.Create(this, Native.Z3_mk_set_member(nCtx, elem.NativeObject, set.NativeObject)); }
/// <summary> /// Remove an element from a set. /// </summary> public Expr MkSetDel(Expr set, Expr element) { Contract.Requires(set != null); Contract.Requires(element != null); Contract.Ensures(Contract.Result<Expr>() != null); CheckContextMatch(set); CheckContextMatch(element); return Expr.Create(this, Native.Z3_mk_set_del(nCtx, set.NativeObject, element.NativeObject)); }
/// <summary> /// Take the complement of a set. /// </summary> public Expr MkSetComplement(Expr arg) { Contract.Requires(arg != null); Contract.Ensures(Contract.Result<Expr>() != null); CheckContextMatch(arg); return Expr.Create(this, Native.Z3_mk_set_complement(nCtx, arg.NativeObject)); }
/// <summary> /// Array read. /// </summary> /// <remarks> /// The argument <c>a</c> is the array and <c>i</c> is the index /// of the array that gets read. /// /// The node <c>a</c> must have an array sort <c>[domain -> range]</c>, /// and <c>i</c> must have the sort <c>domain</c>. /// The sort of the result is <c>range</c>. /// <seealso cref="MkArraySort"/> /// <seealso cref="MkStore"/> /// </remarks> public Expr MkSelect(ArrayExpr a, Expr i) { Contract.Requires(a != null); Contract.Requires(i != null); Contract.Ensures(Contract.Result<Expr>() != null); CheckContextMatch(a); CheckContextMatch(i); return Expr.Create(this, Native.Z3_mk_select(nCtx, a.NativeObject, i.NativeObject)); }
/// <summary> /// Create a Quantifier. /// </summary> public Quantifier MkQuantifier(bool universal, Expr[] boundConstants, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) { Contract.Requires(body != null); Contract.Requires(boundConstants == null || Contract.ForAll(boundConstants, n => n != null)); Contract.Requires(patterns == null || Contract.ForAll(patterns, p => p != null)); Contract.Requires(noPatterns == null || Contract.ForAll(noPatterns, np => np != null)); Contract.Ensures(Contract.Result<Quantifier>() != null); if (universal) return MkForall(boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID); else return MkExists(boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID); }