internal NativeFuncInterp(NativeContext ctx, NativeModel mdl, Z3_func_decl decl, Z3_func_interp fi) { Debug.Assert(ctx != null); Z3_context nCtx = ctx.nCtx; Native.Z3_func_interp_inc_ref(nCtx, fi); Declaration = decl; Else = Native.Z3_func_interp_get_else(nCtx, fi); uint numEntries = Native.Z3_func_interp_get_num_entries(nCtx, fi); uint numArgs = Native.Z3_func_interp_get_arity(nCtx, fi); Entries = new Entry[numEntries]; for (uint j = 0; j < numEntries; ++j) { var entry = Native.Z3_func_interp_get_entry(nCtx, fi, j); Native.Z3_func_entry_inc_ref(nCtx, entry); Entries[j].Arguments = new Z3_ast[numArgs]; for (uint i = 0; i < numArgs; ++i) { Entries[j].Arguments[i] = Native.Z3_func_entry_get_arg(nCtx, entry, i); } Entries[j].Result = Native.Z3_func_entry_get_value(nCtx, entry); Native.Z3_func_entry_dec_ref(nCtx, entry); } Native.Z3_func_interp_dec_ref(nCtx, fi); }
/// <summary> /// Assert a constraint into the solver, and track it (in the unsat) core /// using the Boolean constant p. /// </summary> /// <remarks> /// This API is an alternative to <see cref="Check(Z3_ast[])"/> with assumptions for extracting unsat cores. /// Both APIs can be used in the same solver. The unsat core will contain a combination /// of the Boolean variables provided using <see cref="AssertAndTrack(Z3_ast[],Z3_ast[])"/> /// and the Boolean literals /// provided using <see cref="Check(Z3_ast[])"/> with assumptions. /// </remarks> public void AssertAndTrack(Z3_ast constraint, Z3_ast p) { Debug.Assert(constraint != null); Debug.Assert(p != null); Native.Z3_solver_assert_and_track(nCtx, z3solver, constraint, p); }
/// <summary> /// Unsigned less-than-equal /// </summary> /// <remarks> /// The arguments must have the same bit-vector sort. /// </remarks> public Z3_ast MkBvUle(Z3_ast t1, Z3_ast t2) { Debug.Assert(t1 != IntPtr.Zero); Debug.Assert(t2 != IntPtr.Zero); return(Native.Z3_mk_bvule(nCtx, t1, t2)); }
static void _created(voidp ctx, Z3_solver_callback cb, Z3_ast a) { var prop = (UserPropagator)GCHandle.FromIntPtr(ctx).Target; using var t = Expr.Create(prop.ctx, a); prop.Callback(() => prop.created_eh(t), cb); }
/// <summary> /// Creates the equality <paramref name="x"/> = <paramref name="y"/>. /// </summary> public Z3_ast MkEq(Z3_ast x, Z3_ast y) { Debug.Assert(x != IntPtr.Zero); Debug.Assert(y != IntPtr.Zero); return(Native.Z3_mk_eq(nCtx, x, y)); }
/// <summary> /// Create an expression representing <c>t1 iff t2</c>. /// </summary> public Z3_ast MkIff(Z3_ast t1, Z3_ast t2) { Debug.Assert(t1 != IntPtr.Zero); Debug.Assert(t2 != IntPtr.Zero); return(Native.Z3_mk_iff(nCtx, t1, t2)); }
/// <summary> /// Create a constant array. /// </summary> /// <remarks> /// The resulting term is an array, such that a <c>select</c>on an arbitrary index /// produces the value <c>v</c>. /// </remarks> public Z3_ast MkConstArray(Z3_sort domain, Z3_ast v) { Debug.Assert(domain != IntPtr.Zero); Debug.Assert(v != IntPtr.Zero); return(Native.Z3_mk_const_array(nCtx, domain, v)); }
/// <summary> /// Array read. /// </summary> /// <remarks> /// The argument <c>array</c> is the array and <c>index</c> is the index /// of the array that gets read. /// /// The node <c>array</c> must have an array sort <c>[domain -> range]</c>, /// and <c>index</c> must have the sort <c>domain</c>. /// The sort of the result is <c>range</c>. /// </remarks> public Z3_ast MkSelect(Z3_ast array, Z3_ast index) { Debug.Assert(array != IntPtr.Zero); Debug.Assert(index != IntPtr.Zero); return(Native.Z3_mk_select(nCtx, array, index)); }
/// <summary> /// Add constraints to ensure the function f can only be injective. /// Example: /// for function f : D1 x D2 -> R /// assert axioms /// forall (x1 : D1, x2 : D2) x1 = inv1(f(x1,x2)) /// forall (x1 : D1, x2 : D2) x2 = inv2(f(x1,x2)) /// </summary> /// <param name="f"></param> public void AssertInjective(Z3_func_decl f) { uint arity = Native.Z3_get_arity(nCtx, f); Z3_sort range = Native.Z3_get_range(nCtx, f); Z3_ast[] vars = new Z3_ast[arity]; Z3_sort[] sorts = new Z3_sort[arity]; Z3_symbol[] names = new Z3_symbol[arity]; for (uint i = 0; i < arity; ++i) { Z3_sort domain = Native.Z3_get_domain(nCtx, f, i); vars[i] = ntvContext.MkBound(arity - i - 1, domain); sorts[i] = domain; names[i] = Native.Z3_mk_int_symbol(nCtx, (int)i); } Z3_ast app_f = IntPtr.Zero; // Context.MkApp(f, vars); for (uint i = 0; i < arity; ++i) { Z3_sort domain = Native.Z3_get_domain(nCtx, f, i); Z3_func_decl proj = ntvContext.MkFreshFuncDecl("inv", new Z3_sort[] { range }, domain); Z3_ast body = ntvContext.MkEq(vars[i], ntvContext.MkApp(proj, app_f)); Z3_ast q = ntvContext.MkForall(names, sorts, body); Assert(q); } }
/// <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). /// </remarks> public Z3_ast MkStore(Z3_ast a, Z3_ast i, Z3_ast v) { Debug.Assert(a != IntPtr.Zero); Debug.Assert(i != IntPtr.Zero); Debug.Assert(v != IntPtr.Zero); return(Native.Z3_mk_store(nCtx, a, i, v)); }
static void _fixed(voidp ctx, Z3_solver_callback cb, Z3_ast _term, Z3_ast _value) { var prop = (UserPropagator)GCHandle.FromIntPtr(ctx).Target; using var term = Expr.Create(prop.ctx, _term); using var value = Expr.Create(prop.ctx, _value); prop.Callback(() => prop.fixed_eh(term, value), cb); }
static void _diseq(voidp ctx, Z3_solver_callback cb, Z3_ast a, Z3_ast b) { var prop = (UserPropagator)GCHandle.FromIntPtr(ctx).Target; using var s = Expr.Create(prop.ctx, a); using var t = Expr.Create(prop.ctx, b); prop.Callback(() => prop.diseq_eh(s, t), cb); }
/// <summary> /// Create an expression representing an if-then-else: <c>ite(t1, t2, t3)</c>. /// </summary> /// <param name="t1">An expression with Boolean sort</param> /// <param name="t2">An expression </param> /// <param name="t3">An expression with the same sort as <paramref name="t2"/></param> public Z3_ast MkIte(Z3_ast t1, Z3_ast t2, Z3_ast t3) { Debug.Assert(t1 != IntPtr.Zero); Debug.Assert(t2 != IntPtr.Zero); Debug.Assert(t3 != IntPtr.Zero); return(Native.Z3_mk_ite(nCtx, t1, t2, t3)); }
/// <summary> /// Get the arguments for app /// </summary> /// <param name="app"></param> /// <returns></returns> public Z3_ast[] GetAppArgs(Z3_app app) { var numArgs = GetNumArgs(app); var args = new Z3_ast[numArgs]; for (uint i = 0; i < numArgs; i++) { args[i] = GetAppArg(app, i); } return(args); }
/// <summary> /// Try get ulong from AST /// </summary> /// <param name="v"></param> /// <param name="u"></param> /// <returns></returns> public bool TryGetNumeralUInt64(Z3_ast v, out ulong u) { Debug.Assert(v != IntPtr.Zero); ulong result = u = 0; if (Native.Z3_get_numeral_uint64(nCtx, v, ref result) == 0) { return(false); } u = result; return(true); }
/// <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 Z3_ast Eval(Z3_ast t, bool completion = false) { IntPtr v = IntPtr.Zero; if (Native.Z3_model_eval(ntvContext.nCtx, NativeObject, t, (byte)(completion ? 1 : 0), ref v) == (byte)0) { throw new ModelEvaluationFailedException(); } else { return(v); } }
/// <summary> /// Try to get long from AST /// </summary> /// <param name="v"></param> /// <param name="i"></param> /// <returns></returns> public bool TryGetNumeralInt64(Z3_ast v, out long i) { Debug.Assert(v != IntPtr.Zero); long result = i = 0; if (Native.Z3_get_numeral_int64(nCtx, v, ref result) == 0) { return(false); } i = result; return(true); }
/// <summary> /// Utility to convert a vector object of ast to a .Net array /// </summary> /// <param name="vec"></param> /// <returns></returns> public Z3_ast[] ToArray(Z3_ast_vector vec) { Native.Z3_ast_vector_inc_ref(nCtx, vec); var sz = Native.Z3_ast_vector_size(nCtx, vec); var result = new Z3_ast[sz]; for (uint i = 0; i < sz; ++i) { result[i] = Native.Z3_ast_vector_get(nCtx, vec, i); } Native.Z3_ast_vector_dec_ref(nCtx, vec); return(result); }
static void _decide(voidp ctx, Z3_solver_callback cb, ref Z3_ast a, ref uint idx, ref int phase) { var prop = (UserPropagator)GCHandle.FromIntPtr(ctx).Target; var t = Expr.Create(prop.ctx, a); var u = t; prop.callback = cb; prop.decide_eh(ref t, ref idx, ref phase); prop.callback = IntPtr.Zero; if (u != t) { a = t.NativeObject; } }
/// <summary> /// Convert the interpretation of t into a sequence of array updates /// </summary> /// <param name="t"></param> /// <param name="result"></param> /// <returns>null if the argument does evaluate to a sequence of stores to an array</returns> public bool TryGetArrayValue(Z3_ast t, out ArrayValue result) { var r = Eval(t, true); // check that r is a sequence of store over a constant default array. var updates = new Dictionary <Z3_ast, Z3_ast>(); result = null; while (true) { if (ntvContext.GetAstKind(r) != Z3_ast_kind.Z3_APP_AST) { return(false); } Z3_func_decl f = ntvContext.GetAppDecl(r); var kind = ntvContext.GetDeclKind(f); if (kind == Z3_decl_kind.Z3_OP_CONST_ARRAY) { result = new ArrayValue(); result.Else = ntvContext.GetAppArg(r, 0); result.Updates = updates.ToArray(); result.Domain = updates.Keys.ToArray(); result.Range = updates.Values.ToArray(); return(true); } else if (kind == Z3_decl_kind.Z3_OP_STORE) { Debug.Assert(ntvContext.GetNumArgs(r) == 3); updates[ntvContext.GetAppArg(r, 1)] = ntvContext.GetAppArg(r, 2); r = ntvContext.GetAppArg(r, 0); } else { return(false); } } }
public extern static Z3_ast Z3_get_numerator(Z3_context a0, Z3_ast a1);
/// <summary> /// Get string for numeral ast /// </summary> /// <param name="v"></param> /// <returns></returns> public string GetNumeralString(Z3_ast v) { Debug.Assert(v != IntPtr.Zero); return(Native.Z3_get_numeral_string(nCtx, v)); }
public extern static IntPtr Z3_get_quantifier_bound_name(Z3_context a0, Z3_ast a1, uint a2);
public extern static Z3_ast Z3_get_quantifier_body(Z3_context a0, Z3_ast a1);
public extern static uint Z3_get_quantifier_num_no_patterns(Z3_context a0, Z3_ast a1);
public extern static int Z3_model_eval(Z3_context a0, Z3_model a1, Z3_ast a2, int a3, [In, Out] ref Z3_ast a4);
public extern static Z3_ast Z3_translate(Z3_context a0, Z3_ast a1, Z3_context a2);
public extern static Z3_ast Z3_substitute_vars(Z3_context a0, Z3_ast a1, uint a2, [In] Z3_ast[] a3);
public extern static Z3_ast Z3_update_term(Z3_context a0, Z3_ast a1, uint a2, [In] Z3_ast[] a3);
public extern static Z3_ast Z3_simplify_ex(Z3_context a0, Z3_ast a1, Z3_params a2);
public extern static Z3_ast Z3_simplify(Z3_context a0, Z3_ast a1);
public extern static Z3_ast Z3_get_quantifier_no_pattern_ast(Z3_context a0, Z3_ast a1, uint a2);
/// <summary> /// Same as MkForAll but defaults to "forall" = false /// Create an existential Quantifier. /// </summary> /// <param name="sorts"></param> /// <param name="names"></param> /// <param name="body"></param> /// <param name="weight"></param> /// <param name="patterns"></param> /// <param name="noPatterns"></param> /// <param name="quantifierID"></param> /// <param name="skolemID"></param> /// <returns></returns> public Z3_ast MkExists(Z3_sort[] sorts, Z3_symbol[] names, Z3_ast body, uint weight = 1, Z3_ast[] patterns = null, Z3_ast[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) { return(MkQuantifier(false, sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID)); }
public extern static void Z3_dec_ref(Z3_context a0, Z3_ast a1);
public extern static int Z3_get_numeral_int(Z3_context a0, Z3_ast a1, [In, Out] ref int a2);
/// <summary> /// Get Sort for AST /// </summary> public Z3_sort GetSort(Z3_ast ast) { Debug.Assert(ast != IntPtr.Zero); return(Native.Z3_get_sort(nCtx, ast)); }
public extern static int Z3_is_as_array(Z3_context a0, Z3_ast a1);
public extern static Z3_sort Z3_get_quantifier_bound_sort(Z3_context a0, Z3_ast a1, uint a2);
/// <summary> /// Get the AST kind from IntPtr /// </summary> public Z3_ast_kind GetAstKind(Z3_ast ast) { Debug.Assert(ast != IntPtr.Zero); return((Z3_ast_kind)Native.Z3_get_ast_kind(nCtx, ast)); }
/// <summary> /// Get App Decl from IntPtr /// </summary> public Z3_func_decl GetAppDecl(Z3_ast ast) { Debug.Assert(ast != IntPtr.Zero); return(Native.Z3_get_app_decl(nCtx, ast)); }
public extern static Z3_func_decl Z3_get_as_array_func_decl(Z3_context a0, Z3_ast a1);
public extern static uint Z3_get_quantifier_num_bound(Z3_context a0, Z3_ast a1);
/// <summary> /// Get the range IntPtr for Sort /// </summary> public Z3_sort GetArraySortRange(Z3_ast array) { Debug.Assert(array != IntPtr.Zero); return(Native.Z3_get_array_sort_range(nCtx, array)); }
public extern static IntPtr Z3_ast_to_string(Z3_context a0, Z3_ast a1);
public extern static Z3_ast Z3_get_algebraic_number_upper(Z3_context a0, Z3_ast a1, uint a2);
public extern static int Z3_get_numeral_rational_int64(Z3_context a0, Z3_ast a1, [In, Out] ref Int64 a2, [In, Out] ref Int64 a3);
/// <summary> /// Get printable string representing Z3_ast /// </summary> /// <param name="ast"></param> /// <returns></returns> public string ToString(Z3_ast ast) { Debug.Assert(ast != IntPtr.Zero); return(Native.Z3_ast_to_string(nCtx, ast)); }
public extern static void Z3_fixedpoint_assert(Z3_context a0, Z3_fixedpoint a1, Z3_ast a2);
public extern static Z3_ast Z3_get_denominator(Z3_context a0, Z3_ast a1);
public extern static int Z3_get_numeral_uint64(Z3_context a0, Z3_ast a1, [In, Out] ref UInt64 a2);
/// <summary> /// Mk an expression representing <c>not(a)</c>. /// </summary> public Z3_ast MkNot(Z3_ast a) { Debug.Assert(a != IntPtr.Zero); return(Native.Z3_mk_not(nCtx, a)); }
public extern static IntPtr Z3_get_numeral_string(Z3_context a0, Z3_ast a1);
public extern static IntPtr Z3_get_numeral_decimal_string(Z3_context a0, Z3_ast a1, uint a2);
public extern static int Z3_is_quantifier_forall(Z3_context a0, Z3_ast a1);
/// <summary> /// Create a quantified expression either forall or exists /// </summary> /// <param name="is_forall"></param> /// <param name="sorts"></param> /// <param name="names"></param> /// <param name="body"></param> /// <param name="weight"></param> /// <param name="patterns"></param> /// <param name="noPatterns"></param> /// <param name="quantifierID"></param> /// <param name="skolemID"></param> /// <returns></returns> private Z3_ast MkQuantifier(bool is_forall, Z3_sort[] sorts, Z3_symbol[] names, Z3_ast body, uint weight, Z3_ast[] patterns, Z3_ast[] noPatterns, Symbol quantifierID, Symbol skolemID) { Debug.Assert(sorts != null); Debug.Assert(names != null); Debug.Assert(body != null); Debug.Assert(sorts.Length == names.Length); Debug.Assert(sorts.All(s => s != IntPtr.Zero)); Debug.Assert(names.All(n => n != IntPtr.Zero)); Debug.Assert(patterns == null || patterns.All(p => p != IntPtr.Zero)); Debug.Assert(noPatterns == null || noPatterns.All(np => np != IntPtr.Zero)); if (noPatterns == null && quantifierID == null && skolemID == null) { return(Native.Z3_mk_quantifier(nCtx, (byte)(is_forall ? 1 : 0), weight, (uint)(patterns?.Length ?? 0), patterns, (uint)(sorts?.Length ?? 0), sorts, names, body)); } else { return(Native.Z3_mk_quantifier_ex(nCtx, (byte)(is_forall ? 1 : 0), weight, AST.GetNativeObject(quantifierID), AST.GetNativeObject(skolemID), (uint)(patterns?.Length ?? 0), patterns, (uint)(noPatterns?.Length ?? 0), noPatterns, (uint)(sorts?.Length ?? 0), sorts, names, body)); } }
public extern static uint Z3_get_quantifier_weight(Z3_context a0, Z3_ast a1);
public extern static IntPtr Z3_benchmark_to_smtlib_string(Z3_context a0, string a1, string a2, string a3, string a4, uint a5, [In] Z3_ast[] a6, Z3_ast a7);
public extern static uint Z3_get_index_value(Z3_context a0, Z3_ast a1);
/// <summary> /// Access the array default value. /// </summary> /// <remarks> /// Produces the default range value, for arrays that can be represented as /// finite maps with a default range value. /// </remarks> public Z3_ast MkDefault(Z3_ast a) { Debug.Assert(a != null); return(Native.Z3_mk_array_default(nCtx, a)); }
public extern static void Z3_fixedpoint_add_rule(Z3_context a0, Z3_fixedpoint a1, Z3_ast a2, IntPtr a3);