/// <summary> /// Register predicate as recursive relation. /// </summary> public void RegisterRelation(FuncDecl f) { Contract.Requires(f != null); Context.CheckContextMatch(f); Native.Z3_fixedpoint_register_relation(Context.nCtx, NativeObject, f.NativeObject); }
internal EnumSort(Context ctx, Symbol name, Symbol[] enumNames) : base(ctx) { Contract.Requires(ctx != null); Contract.Requires(name != null); Contract.Requires(enumNames != null); int n = enumNames.Length; IntPtr[] n_constdecls = new IntPtr[n]; IntPtr[] n_testers = new IntPtr[n]; NativeObject = Native.Z3_mk_enumeration_sort(ctx.nCtx, name.NativeObject, (uint)n, Symbol.ArrayToNative(enumNames), n_constdecls, n_testers); _constdecls = new FuncDecl[n]; for (uint i = 0; i < n; i++) { _constdecls[i] = new FuncDecl(ctx, n_constdecls[i]); } _testerdecls = new FuncDecl[n]; for (uint i = 0; i < n; i++) { _testerdecls[i] = new FuncDecl(ctx, n_testers[i]); } _consts = new Expr[n]; for (uint i = 0; i < n; i++) { _consts[i] = ctx.MkApp(_constdecls[i]); } }
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)); }
/// <summary> /// Instrument the Datalog engine on which table representation to use for recursive predicate. /// </summary> public void SetPredicateRepresentation(FuncDecl f, Symbol[] kinds) { Contract.Requires(f != null); Native.Z3_fixedpoint_set_predicate_representation(Context.nCtx, NativeObject, f.NativeObject, AST.ArrayLength(kinds), Symbol.ArrayToNative(kinds)); }
/// <summary> /// Register predicate as recursive relation. /// </summary> public void RegisterRelation(FuncDecl f) { Debug.Assert(f != null); Context.CheckContextMatch(f); Native.Z3_fixedpoint_register_relation(Context.nCtx, NativeObject, f.NativeObject); }
/// <summary> /// Add table fact to the fixedpoint solver. /// </summary> public void AddFact(FuncDecl pred, params uint[] args) { Contract.Requires(pred != null); Contract.Requires(args != null); Context.CheckContextMatch(pred); Native.Z3_fixedpoint_add_fact(Context.nCtx, NativeObject, pred.NativeObject, (uint)args.Length, args); }
internal void AddFuncDecl(FuncDecl funcDecl, string name, params object[] keys) { object[] objs = new object[keys.Length + 1]; objs[0] = name; Array.Copy(keys, 0, objs, 1, keys.Length); var s = new Sequence<object>(objs); funcDecls.Add(new Sequence<object>(objs), funcDecl); }
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> /// Object comparison. /// </summary> public override bool Equals(object o) { FuncDecl casted = o as FuncDecl; if (casted == null) { return(false); } return(this == casted); }
public BinaryTreeInfo(FuncDecl mkTree, FuncDecl mkLeaf, FuncDecl getLeafValue, FuncDecl isTree, FuncDecl isLeaf, FuncDecl getLeft, FuncDecl getRight) { this.MkTree = mkTree; this.GetLeft = getLeft; this.GetRight = getRight; this.MkLeaf = mkLeaf; this.GetLeafValue = getLeafValue; this.IsTree = isTree; this.IsLeaf = isLeaf; }
/// <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; }
internal bool TryGetFuncDecl(out FuncDecl funcDecl, string name, params object[] keys) { object[] objs = new object[keys.Length + 1]; objs[0] = name; Array.Copy(keys, 0, objs, 1, keys.Length); Sequence<object> s = new Sequence<object>(objs); if (funcDecls.TryGetValue(s, out funcDecl)) return true; funcDecl = null; return false; }
/// <summary> /// Retrieves the interpretation (the assignment) of <paramref name="f"/> in the model. /// </summary> /// <param name="f">A function declaration of zero arity</param> /// <returns>An expression if the function has an interpretation in the model, null otherwise.</returns> public Expr ConstInterp(FuncDecl f) { Contract.Requires(f != null); Context.CheckContextMatch(f); if (f.Arity != 0 || Native.Z3_get_sort_kind(Context.nCtx, Native.Z3_get_range(Context.nCtx, f.NativeObject)) == (uint)Z3_sort_kind.Z3_ARRAY_SORT) throw new Z3Exception("Non-zero arity functions and arrays have FunctionInterpretations as a model. Use FuncInterp."); IntPtr n = Native.Z3_model_get_const_interp(Context.nCtx, NativeObject, f.NativeObject); if (n == IntPtr.Zero) return null; else return Expr.Create(Context, n); }
/// <summary> /// Retrieves the interpretation (the assignment) of a non-constant <paramref name="f"/> in the model. /// </summary> /// <param name="f">A function declaration of non-zero arity</param> /// <returns>A FunctionInterpretation if the function has an interpretation in the model, null otherwise.</returns> public FuncInterp FuncInterp(FuncDecl f) { Debug.Assert(f != null); Context.CheckContextMatch(f); Z3_sort_kind sk = (Z3_sort_kind)Native.Z3_get_sort_kind(Context.nCtx, Native.Z3_get_range(Context.nCtx, f.NativeObject)); if (f.Arity == 0) { IntPtr n = Native.Z3_model_get_const_interp(Context.nCtx, NativeObject, f.NativeObject); if (sk == Z3_sort_kind.Z3_ARRAY_SORT) { if (n == IntPtr.Zero) { return(null); } else { if (Native.Z3_is_as_array(Context.nCtx, n) == 0) { throw new Z3Exception("Argument was not an array constant"); } IntPtr fd = Native.Z3_get_as_array_func_decl(Context.nCtx, n); using var decl = new FuncDecl(Context, fd); return(FuncInterp(decl)); } } else { throw new Z3Exception("Constant functions do not have a function interpretation; use ConstInterp"); } } else { IntPtr n = Native.Z3_model_get_func_interp(Context.nCtx, NativeObject, f.NativeObject); if (n == IntPtr.Zero) { return(null); } else { return(new FuncInterp(Context, n)); } } }
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 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; }
/// <summary> /// Retrieves the interpretation (the assignment) of <paramref name="f"/> in the model. /// </summary> /// <param name="f">A function declaration of zero arity</param> /// <returns>An expression if the function has an interpretation in the model, null otherwise.</returns> public Expr ConstInterp(FuncDecl f) { Debug.Assert(f != null); Context.CheckContextMatch(f); if (f.Arity != 0) { throw new Z3Exception("Non-zero arity functions have FunctionInterpretations as a model. Use FuncInterp."); } IntPtr n = Native.Z3_model_get_const_interp(Context.nCtx, NativeObject, f.NativeObject); if (n == IntPtr.Zero) { return(null); } else { return(Expr.Create(Context, n)); } }
/// <summary> /// Retrieves the interpretation (the assignment) of <paramref name="f"/> in the model. /// </summary> /// <param name="f">A function declaration of zero arity</param> /// <returns>An expression if the function has an interpretation in the model, null otherwise.</returns> public Expr ConstInterp(FuncDecl f) { Contract.Requires(f != null); Context.CheckContextMatch(f); if (f.Arity != 0 || Native.Z3_get_sort_kind(Context.nCtx, Native.Z3_get_range(Context.nCtx, f.NativeObject)) == (uint)Z3_sort_kind.Z3_ARRAY_SORT) { throw new Z3Exception("Non-zero arity functions and arrays have FunctionInterpretations as a model. Use FuncInterp."); } IntPtr n = Native.Z3_model_get_const_interp(Context.nCtx, NativeObject, f.NativeObject); if (n == IntPtr.Zero) { return(null); } else { return(Expr.Create(Context, n)); } }
/// <summary> /// Retrieves the interpretation (the assignment) of a non-constant <paramref name="f"/> in the model. /// </summary> /// <param name="f">A function declaration of non-zero arity</param> /// <returns>A FunctionInterpretation if the function has an interpretation in the model, null otherwise.</returns> public FuncInterp FuncInterp(FuncDecl f) { Contract.Requires(f != null); Context.CheckContextMatch(f); Z3_sort_kind sk = (Z3_sort_kind)Native.Z3_get_sort_kind(Context.nCtx, Native.Z3_get_range(Context.nCtx, f.NativeObject)); if (f.Arity == 0) { IntPtr n = Native.Z3_model_get_const_interp(Context.nCtx, NativeObject, f.NativeObject); if (sk == Z3_sort_kind.Z3_ARRAY_SORT) { if (n == IntPtr.Zero) return null; else { if (Native.Z3_is_as_array(Context.nCtx, n) == 0) throw new Z3Exception("Argument was not an array constant"); IntPtr fd = Native.Z3_get_as_array_func_decl(Context.nCtx, n); return FuncInterp(new FuncDecl(Context, fd)); } } else { throw new Z3Exception("Constant functions do not have a function interpretation; use ConstInterp"); } } else { IntPtr n = Native.Z3_model_get_func_interp(Context.nCtx, NativeObject, f.NativeObject); if (n == IntPtr.Zero) return null; else return new FuncInterp(Context, n); } }
private void init() { Contract.Ensures(m_constructorDecl != null); Contract.Ensures(m_testerDecl != null); Contract.Ensures(m_accessorDecls != null); if (m_testerDecl != null) { return; } IntPtr constructor = IntPtr.Zero; IntPtr tester = IntPtr.Zero; IntPtr[] accessors = new IntPtr[n]; Native.Z3_query_constructor(Context.nCtx, NativeObject, n, ref constructor, ref tester, accessors); m_constructorDecl = new FuncDecl(Context, constructor); m_testerDecl = new FuncDecl(Context, tester); m_accessorDecls = new FuncDecl[n]; for (uint i = 0; i < n; i++) { m_accessorDecls[i] = new FuncDecl(Context, accessors[i]); } }
internal ListSort(Context ctx, Symbol name, Sort elemSort) : base(ctx) { Contract.Requires(ctx != null); Contract.Requires(name != null); Contract.Requires(elemSort != null); IntPtr inil = IntPtr.Zero, iisnil = IntPtr.Zero, icons = IntPtr.Zero, iiscons = IntPtr.Zero, ihead = IntPtr.Zero, itail = IntPtr.Zero; NativeObject = Native.Z3_mk_list_sort(ctx.nCtx, name.NativeObject, elemSort.NativeObject, ref inil, ref iisnil, ref icons, ref iiscons, ref ihead, ref itail); nilDecl = new FuncDecl(ctx, inil); isNilDecl = new FuncDecl(ctx, iisnil); consDecl = new FuncDecl(ctx, icons); isConsDecl = new FuncDecl(ctx, iiscons); headDecl = new FuncDecl(ctx, ihead); tailDecl = new FuncDecl(ctx, itail); nilConst = ctx.MkConst(nilDecl); }
/// <summary> /// Maps f on the argument arrays. /// </summary> /// <remarks> /// Eeach element of <c>args</c> must be of an array sort <c>[domain_i -> range_i]</c>. /// The function declaration <c>f</c> must have type <c> range_1 .. range_n -> range</c>. /// <c>v</c> must have sort range. The sort of the result is <c>[domain_i -> range]</c>. /// <seealso cref="MkArraySort"/> /// <seealso cref="MkSelect"/> /// <seealso cref="MkStore"/> /// </remarks> public ArrayExpr MkMap(FuncDecl f, params ArrayExpr[] args) { Contract.Requires(f != null); Contract.Requires(args == null || Contract.ForAll(args, a => a != null)); Contract.Ensures(Contract.Result<ArrayExpr>() != null); CheckContextMatch(f); CheckContextMatch(args); return (ArrayExpr)Expr.Create(this, Native.Z3_mk_map(nCtx, f.NativeObject, AST.ArrayLength(args), AST.ArrayToNative(args))); }
/// <summary> /// Creates a fresh constant from the FuncDecl <paramref name="f"/>. /// </summary> /// <param name="f">A decl of a 0-arity function</param> public Expr MkConst(FuncDecl f) { Contract.Requires(f != null); Contract.Ensures(Contract.Result<Expr>() != null); return MkApp(f); }
/// <summary> /// Update a datatype field at expression t with value v. /// The function performs a record update at t. The field /// that is passed in as argument is updated with value v, /// the remainig fields of t are unchanged. /// </summary> public Expr MkUpdateField(FuncDecl field, Expr t, Expr v) { return Expr.Create(this, Native.Z3_datatype_update_field( nCtx, field.NativeObject, t.NativeObject, v.NativeObject)); }
internal Parameter(Z3_parameter_kind k, FuncDecl fd) { this.kind = k; this.fd = fd; }
internal EnumSort(Context ctx, Symbol name, Symbol[] enumNames) : base(ctx) { Contract.Requires(ctx != null); Contract.Requires(name != null); Contract.Requires(enumNames != null); int n = enumNames.Length; IntPtr[] n_constdecls = new IntPtr[n]; IntPtr[] n_testers = new IntPtr[n]; NativeObject = Native.Z3_mk_enumeration_sort(ctx.nCtx, name.NativeObject, (uint)n, Symbol.ArrayToNative(enumNames), n_constdecls, n_testers); _constdecls = new FuncDecl[n]; for (uint i = 0; i < n; i++) _constdecls[i] = new FuncDecl(ctx, n_constdecls[i]); _testerdecls = new FuncDecl[n]; for (uint i = 0; i < n; i++) _testerdecls[i] = new FuncDecl(ctx, n_testers[i]); _consts = new Expr[n]; for (uint i = 0; i < n; i++) _consts[i] = ctx.MkApp(_constdecls[i]); }
/// <summary> /// Create a new function application. /// </summary> public Expr MkApp(FuncDecl f, params Expr[] args) { Contract.Requires(f != null); Contract.Requires(args == null || Contract.ForAll(args, a => a != null)); Contract.Ensures(Contract.Result<Expr>() != null); CheckContextMatch(f); CheckContextMatch(args); return Expr.Create(this, f, args); }
/// <summary> /// Retrieve the number of levels explored for a given predicate. /// </summary> public uint GetNumLevels(FuncDecl predicate) { return Native.Z3_fixedpoint_get_num_levels(Context.nCtx, NativeObject, predicate.NativeObject); }
/// <summary> /// Retrieve the cover of a predicate. /// </summary> public Expr GetCoverDelta(int level, FuncDecl predicate) { IntPtr res = Native.Z3_fixedpoint_get_cover_delta(Context.nCtx, NativeObject, level, predicate.NativeObject); return (res == IntPtr.Zero) ? null : Expr.Create(Context, res); }
internal static Expr Create(Context ctx, FuncDecl f, params Expr[] arguments) { Contract.Requires(ctx != null); Contract.Requires(f != null); Contract.Ensures(Contract.Result<Expr>() != null); IntPtr obj = Native.Z3_mk_app(ctx.nCtx, f.NativeObject, AST.ArrayLength(arguments), AST.ArrayToNative(arguments)); return Create(ctx, obj); }
/// <summary> /// Parse the given string using the SMT-LIB2 parser. /// </summary> /// <seealso cref="ParseSMTLIBString"/> /// <returns>A conjunction of assertions in the scope (up to push/pop) at the end of the string.</returns> public BoolExpr ParseSMTLIB2String(string str, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, FuncDecl[] decls = null) { Contract.Ensures(Contract.Result<BoolExpr>() != null); uint csn = Symbol.ArrayLength(sortNames); uint cs = Sort.ArrayLength(sorts); uint cdn = Symbol.ArrayLength(declNames); uint cd = AST.ArrayLength(decls); if (csn != cs || cdn != cd) throw new Z3Exception("Argument size mismatch"); return (BoolExpr)Expr.Create(this, Native.Z3_parse_smtlib2_string(nCtx, str, AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls))); }
/// <summary> /// Retrieve the cover of a predicate. /// </summary> public Expr GetCoverDelta(int level, FuncDecl predicate) { IntPtr res = Native.Z3_fixedpoint_get_cover_delta(Context.nCtx, NativeObject, level, predicate.NativeObject); return((res == IntPtr.Zero) ? null : Expr.Create(Context, res)); }
/// <summary> /// Parse the given string using the SMT-LIB parser. /// </summary> /// <remarks> /// The symbol table of the parser can be initialized using the given sorts and declarations. /// The symbols in the arrays <paramref name="sortNames"/> and <paramref name="declNames"/> /// don't need to match the names of the sorts and declarations in the arrays <paramref name="sorts"/> /// and <paramref name="decls"/>. This is a useful feature since we can use arbitrary names to /// reference sorts and declarations. /// </remarks> public void ParseSMTLIBString(string str, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, FuncDecl[] decls = null) { uint csn = Symbol.ArrayLength(sortNames); uint cs = Sort.ArrayLength(sorts); uint cdn = Symbol.ArrayLength(declNames); uint cd = AST.ArrayLength(decls); if (csn != cs || cdn != cd) throw new Z3Exception("Argument size mismatch"); Native.Z3_parse_smtlib_string(nCtx, str, AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls)); }
/// <summary> /// Query the fixedpoint solver. /// A query is an array of relations. /// The query is satisfiable if there is an instance of some relation that is non-empty. /// The query is unsatisfiable if there are no derivations satisfying any of the relations. /// </summary> public Status Query(FuncDecl[] relations) { Contract.Requires(relations != null); Contract.Requires(Contract.ForAll(0, relations.Length, i => relations[i] != null)); Context.CheckContextMatch(relations); Z3_lbool r = (Z3_lbool)Native.Z3_fixedpoint_query_relations(Context.nCtx, NativeObject, AST.ArrayLength(relations), AST.ArrayToNative(relations)); switch (r) { case Z3_lbool.Z3_L_TRUE: return Status.SATISFIABLE; case Z3_lbool.Z3_L_FALSE: return Status.UNSATISFIABLE; default: return Status.UNKNOWN; } }
/// <summary> /// Demonstrates how to initialize the parser symbol table. /// </summary> public static void ParserExample2(Context ctx) { Console.WriteLine("ParserExample2"); Symbol[] declNames = { ctx.MkSymbol("a"), ctx.MkSymbol("b") }; FuncDecl a = ctx.MkConstDecl(declNames[0], ctx.MkIntSort()); FuncDecl b = ctx.MkConstDecl(declNames[1], ctx.MkIntSort()); FuncDecl[] decls = new FuncDecl[] { a, b }; ctx.ParseSMTLIBString("(benchmark tst :formula (> a b))", null, null, declNames, decls); BoolExpr f = ctx.SMTLIBFormulas[0]; Console.WriteLine("formula: {0}", f); Check(ctx, f, Status.SATISFIABLE); }
/// <summary> /// Retrieve the number of levels explored for a given predicate. /// </summary> public uint GetNumLevels(FuncDecl predicate) { return(Native.Z3_fixedpoint_get_num_levels(Context.nCtx, NativeObject, predicate.NativeObject)); }
/// <summary> /// Add <tt>property</tt> about the <tt>predicate</tt>. /// The property is added at <tt>level</tt>. /// </summary> public void AddCover(int level, FuncDecl predicate, Expr property) { Native.Z3_fixedpoint_add_cover(Context.nCtx, NativeObject, level, predicate.NativeObject, property.NativeObject); }
/// <summary> /// Create a new function application. /// </summary> public Expr MkApp(FuncDecl f, IEnumerable<Expr> args) { Contract.Requires(f != null); Contract.Requires(args == null || Contract.ForAll(args, a => a != null)); Contract.Ensures(Contract.Result<Expr>() != null); CheckContextMatch(f); CheckContextMatch(args); return Expr.Create(this, f, args.ToArray()); }
/// <summary> /// Assert the axiom: function f is commutative. /// </summary> /// <remarks> /// This example uses the SMT-LIB parser to simplify the axiom construction. /// </remarks> private static BoolExpr CommAxiom(Context ctx, FuncDecl f) { Sort t = f.Range; Sort[] dom = f.Domain; if (dom.Length != 2 || !t.Equals(dom[0]) || !t.Equals(dom[1])) { Console.WriteLine("{0} {1} {2} {3}", dom.Length, dom[0], dom[1], t); throw new Exception("function must be binary, and argument types must be equal to return type"); } string bench = string.Format("(benchmark comm :formula (forall (x {0}) (y {1}) (= ({2} x y) ({3} y x))))", t.Name, t.Name, f.Name, f.Name); ctx.ParseSMTLIBString(bench, new Symbol[] { t.Name }, new Sort[] { t }, new Symbol[] { f.Name }, new FuncDecl[] { f }); return ctx.SMTLIBFormulas[0]; }