mirror of
https://github.com/Z3Prover/z3
synced 2025-04-11 19:53:34 +00:00
306 lines
10 KiB
C#
306 lines
10 KiB
C#
/*++
|
|
Copyright (c) 2012 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
Fixedpoints.cs
|
|
|
|
Abstract:
|
|
|
|
Z3 Managed API: Fixedpoints
|
|
|
|
Author:
|
|
|
|
Christoph Wintersteiger (cwinter) 2012-03-21
|
|
|
|
Notes:
|
|
|
|
--*/
|
|
|
|
using System;
|
|
using System.Diagnostics.Contracts;
|
|
|
|
namespace Microsoft.Z3
|
|
{
|
|
/// <summary>
|
|
/// Object for managing fixedpoints
|
|
/// </summary>
|
|
[ContractVerification(true)]
|
|
public class Fixedpoint : Z3Object
|
|
{
|
|
|
|
/// <summary>
|
|
/// A string that describes all available fixedpoint solver parameters.
|
|
/// </summary>
|
|
public string Help
|
|
{
|
|
get {
|
|
Contract.Ensures(Contract.Result<string>() != null);
|
|
return Native.Z3_fixedpoint_get_help(Context.nCtx, NativeObject);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the fixedpoint solver parameters.
|
|
/// </summary>
|
|
public Params Parameters
|
|
{
|
|
set
|
|
{
|
|
Contract.Requires(value != null);
|
|
Context.CheckContextMatch(value);
|
|
Native.Z3_fixedpoint_set_params(Context.nCtx, NativeObject, value.NativeObject);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieves parameter descriptions for Fixedpoint solver.
|
|
/// </summary>
|
|
public ParamDescrs ParameterDescriptions
|
|
{
|
|
get
|
|
{
|
|
return new ParamDescrs(Context, Native.Z3_fixedpoint_get_param_descrs(Context.nCtx, NativeObject));
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Assert a constraint (or multiple) into the fixedpoint solver.
|
|
/// </summary>
|
|
public void Assert(params BoolExpr[] constraints)
|
|
{
|
|
Contract.Requires(constraints != null);
|
|
Contract.Requires(Contract.ForAll(constraints, c => c != null));
|
|
|
|
Context.CheckContextMatch(constraints);
|
|
foreach (BoolExpr a in constraints)
|
|
{
|
|
Native.Z3_fixedpoint_assert(Context.nCtx, NativeObject, a.NativeObject);
|
|
}
|
|
}
|
|
|
|
/// <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);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add rule into the fixedpoint solver.
|
|
/// </summary>
|
|
public void AddRule(BoolExpr rule, Symbol name = null)
|
|
{
|
|
Contract.Requires(rule != null);
|
|
|
|
Context.CheckContextMatch(rule);
|
|
Native.Z3_fixedpoint_add_rule(Context.nCtx, NativeObject, rule.NativeObject, AST.GetNativeObject(name));
|
|
}
|
|
|
|
/// <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);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Query the fixedpoint solver.
|
|
/// A query is a conjunction of constraints. The constraints may include the recursively defined relations.
|
|
/// The query is satisfiable if there is an instance of the query variables and a derivation for it.
|
|
/// The query is unsatisfiable if there are no derivations satisfying the query variables.
|
|
/// </summary>
|
|
public Status Query(BoolExpr query)
|
|
{
|
|
Contract.Requires(query != null);
|
|
|
|
Context.CheckContextMatch(query);
|
|
Z3_lbool r = (Z3_lbool)Native.Z3_fixedpoint_query(Context.nCtx, NativeObject, query.NativeObject);
|
|
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>
|
|
/// 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>
|
|
/// Creates a backtracking point.
|
|
/// </summary>
|
|
/// <seealso cref="Pop"/>
|
|
public void Push()
|
|
{
|
|
Native.Z3_fixedpoint_push(Context.nCtx, NativeObject);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Backtrack one backtracking point.
|
|
/// </summary>
|
|
/// <remarks>Note that an exception is thrown if Pop is called without a corresponding <c>Push</c></remarks>
|
|
/// <seealso cref="Push"/>
|
|
public void Pop()
|
|
{
|
|
Native.Z3_fixedpoint_pop(Context.nCtx, NativeObject);
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Update named rule into in the fixedpoint solver.
|
|
/// </summary>
|
|
public void UpdateRule(BoolExpr rule, Symbol name)
|
|
{
|
|
Contract.Requires(rule != null);
|
|
|
|
Context.CheckContextMatch(rule);
|
|
Native.Z3_fixedpoint_update_rule(Context.nCtx, NativeObject, rule.NativeObject, AST.GetNativeObject(name));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve satisfying instance or instances of solver,
|
|
/// or definitions for the recursive predicates that show unsatisfiability.
|
|
/// </summary>
|
|
public Expr GetAnswer()
|
|
{
|
|
IntPtr ans = Native.Z3_fixedpoint_get_answer(Context.nCtx, NativeObject);
|
|
return (ans == IntPtr.Zero) ? null : Expr.Create(Context, ans);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve explanation why fixedpoint engine returned status Unknown.
|
|
/// </summary>
|
|
public string GetReasonUnknown()
|
|
{
|
|
Contract.Ensures(Contract.Result<string>() != null);
|
|
|
|
return Native.Z3_fixedpoint_get_reason_unknown(Context.nCtx, NativeObject);
|
|
}
|
|
|
|
/// <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);
|
|
}
|
|
|
|
/// <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>
|
|
/// Retrieve internal string representation of fixedpoint object.
|
|
/// </summary>
|
|
public override string ToString()
|
|
{
|
|
return Native.Z3_fixedpoint_to_string(Context.nCtx, NativeObject, 0, null);
|
|
}
|
|
|
|
/// <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>
|
|
/// Convert benchmark given as set of axioms, rules and queries to a string.
|
|
/// </summary>
|
|
public string ToString(BoolExpr[] queries)
|
|
{
|
|
|
|
return Native.Z3_fixedpoint_to_string(Context.nCtx, NativeObject,
|
|
AST.ArrayLength(queries), AST.ArrayToNative(queries));
|
|
}
|
|
|
|
|
|
#region Internal
|
|
internal Fixedpoint(Context ctx, IntPtr obj)
|
|
: base(ctx, obj)
|
|
{
|
|
Contract.Requires(ctx != null);
|
|
}
|
|
internal Fixedpoint(Context ctx)
|
|
: base(ctx, Native.Z3_mk_fixedpoint(ctx.nCtx))
|
|
{
|
|
Contract.Requires(ctx != null);
|
|
}
|
|
|
|
internal class DecRefQueue : Z3.DecRefQueue
|
|
{
|
|
public override void IncRef(Context ctx, IntPtr obj)
|
|
{
|
|
Native.Z3_fixedpoint_inc_ref(ctx.nCtx, obj);
|
|
}
|
|
|
|
public override void DecRef(Context ctx, IntPtr obj)
|
|
{
|
|
Native.Z3_fixedpoint_dec_ref(ctx.nCtx, obj);
|
|
}
|
|
};
|
|
|
|
internal override void IncRef(IntPtr o)
|
|
{
|
|
Context.Fixedpoint_DRQ.IncAndClear(Context, o);
|
|
base.IncRef(o);
|
|
}
|
|
|
|
internal override void DecRef(IntPtr o)
|
|
{
|
|
Context.Fixedpoint_DRQ.Add(o);
|
|
base.DecRef(o);
|
|
}
|
|
#endregion
|
|
}
|
|
}
|