mirror of
https://github.com/Z3Prover/z3
synced 2025-04-15 13:28:47 +00:00
add user propagator functionality
This commit is contained in:
parent
1e7a9e3e61
commit
506f8f88aa
|
@ -25,6 +25,8 @@ using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Microsoft.Z3
|
namespace Microsoft.Z3
|
||||||
{
|
{
|
||||||
|
|
||||||
|
using Z3_context = System.IntPtr;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The main interaction with Z3 happens via the Context.
|
/// The main interaction with Z3 happens via the Context.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -77,6 +79,23 @@ namespace Microsoft.Z3
|
||||||
InitContext();
|
InitContext();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Internal Constructor. It is used from UserPropagator
|
||||||
|
/// </summary>
|
||||||
|
internal Context(Z3_context ctx)
|
||||||
|
: base()
|
||||||
|
{
|
||||||
|
lock (creation_lock)
|
||||||
|
{
|
||||||
|
is_external = true;
|
||||||
|
m_ctx = ctx;
|
||||||
|
InitContext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_external = false;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Symbols
|
#region Symbols
|
||||||
|
@ -669,6 +688,16 @@ namespace Microsoft.Z3
|
||||||
CheckContextMatch(range);
|
CheckContextMatch(range);
|
||||||
return new FuncDecl(this, prefix, null, range);
|
return new FuncDecl(this, prefix, null, range);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Declare a function to be processed by the user propagator plugin.
|
||||||
|
/// </summary>
|
||||||
|
public FuncDecl MkUserPropagatorFuncDecl(string name, Sort[] domain, Sort range)
|
||||||
|
{
|
||||||
|
using var _name = MkSymbol(name);
|
||||||
|
var fn = Native.Z3_solver_propagate_declare(nCtx, _name.NativeObject, AST.ArrayLength(domain), AST.ArrayToNative(domain), range.NativeObject);
|
||||||
|
return new FuncDecl(this, fn);
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Bound Variables
|
#region Bound Variables
|
||||||
|
@ -4978,11 +5007,14 @@ namespace Microsoft.Z3
|
||||||
m_n_err_handler = null;
|
m_n_err_handler = null;
|
||||||
IntPtr ctx = m_ctx;
|
IntPtr ctx = m_ctx;
|
||||||
m_ctx = IntPtr.Zero;
|
m_ctx = IntPtr.Zero;
|
||||||
Native.Z3_del_context(ctx);
|
if (!is_external)
|
||||||
|
Native.Z3_del_context(ctx);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
GC.ReRegisterForFinalize(this);
|
GC.ReRegisterForFinalize(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ Author:
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
|
|
||||||
// Todo: fresh, created, declare user function, register_cb, decide,
|
// Todo: decide,
|
||||||
|
|
||||||
--*/
|
--*/
|
||||||
|
|
||||||
|
@ -50,14 +50,20 @@ namespace Microsoft.Z3
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public delegate void EqEh(Expr term, Expr value);
|
public delegate void EqEh(Expr term, Expr value);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Delegate type for when a new term using a registered function symbol is created internally
|
||||||
|
/// </summary>
|
||||||
|
public delegate void CreatedEh(Expr term);
|
||||||
|
|
||||||
Solver solver;
|
Solver solver;
|
||||||
|
Context ctx;
|
||||||
GCHandle gch;
|
GCHandle gch;
|
||||||
Z3_solver_callback callback;
|
Z3_solver_callback callback = IntPtr.Zero;
|
||||||
FixedEh fixed_eh;
|
FixedEh fixed_eh;
|
||||||
Action final_eh;
|
Action final_eh;
|
||||||
EqEh eq_eh;
|
EqEh eq_eh;
|
||||||
EqEh diseq_eh;
|
EqEh diseq_eh;
|
||||||
|
CreatedEh created_eh;
|
||||||
|
|
||||||
|
|
||||||
static void _push(voidp ctx, Z3_solver_callback cb) {
|
static void _push(voidp ctx, Z3_solver_callback cb) {
|
||||||
|
@ -65,6 +71,7 @@ namespace Microsoft.Z3
|
||||||
var prop = (UserPropagator)gch.Target;
|
var prop = (UserPropagator)gch.Target;
|
||||||
prop.callback = cb;
|
prop.callback = cb;
|
||||||
prop.Push();
|
prop.Push();
|
||||||
|
prop.callback = IntPtr.Zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _pop(voidp ctx, Z3_solver_callback cb, uint num_scopes) {
|
static void _pop(voidp ctx, Z3_solver_callback cb, uint num_scopes) {
|
||||||
|
@ -72,21 +79,25 @@ namespace Microsoft.Z3
|
||||||
var prop = (UserPropagator)gch.Target;
|
var prop = (UserPropagator)gch.Target;
|
||||||
prop.callback = cb;
|
prop.callback = cb;
|
||||||
prop.Pop(num_scopes);
|
prop.Pop(num_scopes);
|
||||||
|
prop.callback = IntPtr.Zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
static voidp _fresh(voidp ctx, Z3_context new_context) {
|
static voidp _fresh(voidp _ctx, Z3_context new_context) {
|
||||||
var gch = GCHandle.FromIntPtr(ctx);
|
var gch = GCHandle.FromIntPtr(_ctx);
|
||||||
var prop = (UserPropagator)gch.Target;
|
var prop = (UserPropagator)gch.Target;
|
||||||
throw new Z3Exception("fresh is NYI");
|
var ctx = new Context(new_context);
|
||||||
|
var prop1 = prop.Fresh(ctx);
|
||||||
|
return GCHandle.ToIntPtr(GCHandle.Alloc(prop1));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _fixed(voidp ctx, Z3_solver_callback cb, Z3_ast _term, Z3_ast _value) {
|
static void _fixed(voidp ctx, Z3_solver_callback cb, Z3_ast _term, Z3_ast _value) {
|
||||||
var gch = GCHandle.FromIntPtr(ctx);
|
var gch = GCHandle.FromIntPtr(ctx);
|
||||||
var prop = (UserPropagator)gch.Target;
|
var prop = (UserPropagator)gch.Target;
|
||||||
var term = Expr.Create(prop.solver.Context, _term);
|
using var term = Expr.Create(prop.solver.Context, _term);
|
||||||
var value = Expr.Create(prop.solver.Context, _value);
|
using var value = Expr.Create(prop.solver.Context, _value);
|
||||||
prop.callback = cb;
|
prop.callback = cb;
|
||||||
prop.fixed_eh(term, value);
|
prop.fixed_eh(term, value);
|
||||||
|
prop.callback = IntPtr.Zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _final(voidp ctx, Z3_solver_callback cb) {
|
static void _final(voidp ctx, Z3_solver_callback cb) {
|
||||||
|
@ -94,24 +105,36 @@ namespace Microsoft.Z3
|
||||||
var prop = (UserPropagator)gch.Target;
|
var prop = (UserPropagator)gch.Target;
|
||||||
prop.callback = cb;
|
prop.callback = cb;
|
||||||
prop.final_eh();
|
prop.final_eh();
|
||||||
|
prop.callback = IntPtr.Zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _eq(voidp ctx, Z3_solver_callback cb, Z3_ast a, Z3_ast b) {
|
static void _eq(voidp ctx, Z3_solver_callback cb, Z3_ast a, Z3_ast b) {
|
||||||
var gch = GCHandle.FromIntPtr(ctx);
|
var gch = GCHandle.FromIntPtr(ctx);
|
||||||
var prop = (UserPropagator)gch.Target;
|
var prop = (UserPropagator)gch.Target;
|
||||||
var s = Expr.Create(prop.solver.Context, a);
|
using var s = Expr.Create(prop.solver.Context, a);
|
||||||
var t = Expr.Create(prop.solver.Context, b);
|
using var t = Expr.Create(prop.solver.Context, b);
|
||||||
prop.callback = cb;
|
prop.callback = cb;
|
||||||
prop.eq_eh(s, t);
|
prop.eq_eh(s, t);
|
||||||
|
prop.callback = IntPtr.Zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _diseq(voidp ctx, Z3_solver_callback cb, Z3_ast a, Z3_ast b) {
|
static void _diseq(voidp ctx, Z3_solver_callback cb, Z3_ast a, Z3_ast b) {
|
||||||
var gch = GCHandle.FromIntPtr(ctx);
|
var gch = GCHandle.FromIntPtr(ctx);
|
||||||
var prop = (UserPropagator)gch.Target;
|
var prop = (UserPropagator)gch.Target;
|
||||||
var s = Expr.Create(prop.solver.Context, a);
|
using var s = Expr.Create(prop.solver.Context, a);
|
||||||
var t = Expr.Create(prop.solver.Context, b);
|
using var t = Expr.Create(prop.solver.Context, b);
|
||||||
prop.callback = cb;
|
prop.callback = cb;
|
||||||
prop.diseq_eh(s, t);
|
prop.diseq_eh(s, t);
|
||||||
|
prop.callback = IntPtr.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _created(voidp ctx, Z3_solver_callback cb, Z3_ast a) {
|
||||||
|
var gch = GCHandle.FromIntPtr(ctx);
|
||||||
|
var prop = (UserPropagator)gch.Target;
|
||||||
|
using var t = Expr.Create(prop.solver.Context, a);
|
||||||
|
prop.callback = cb;
|
||||||
|
prop.created_eh(t);
|
||||||
|
prop.callback = IntPtr.Zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -121,8 +144,17 @@ namespace Microsoft.Z3
|
||||||
{
|
{
|
||||||
gch = GCHandle.Alloc(this);
|
gch = GCHandle.Alloc(this);
|
||||||
solver = s;
|
solver = s;
|
||||||
|
ctx = solver.Context;
|
||||||
var cb = GCHandle.ToIntPtr(gch);
|
var cb = GCHandle.ToIntPtr(gch);
|
||||||
Native.Z3_solver_propagate_init(solver.Context.nCtx, solver.NativeObject, cb, _push, _pop, _fresh);
|
Native.Z3_solver_propagate_init(ctx.nCtx, solver.NativeObject, cb, _push, _pop, _fresh);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Propagator constructor from a context. It is used from inside of Fresh.
|
||||||
|
/// </summary>
|
||||||
|
public UserPropagator(Context ctx)
|
||||||
|
{
|
||||||
|
this.ctx = ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -130,7 +162,8 @@ namespace Microsoft.Z3
|
||||||
/// </summary>
|
/// </summary>
|
||||||
~UserPropagator()
|
~UserPropagator()
|
||||||
{
|
{
|
||||||
gch.Free();
|
if (gch != null)
|
||||||
|
gch.Free();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -152,7 +185,7 @@ namespace Microsoft.Z3
|
||||||
/// Declare combination of assigned expressions a conflict
|
/// Declare combination of assigned expressions a conflict
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void Conflict(params Expr[] terms) {
|
void Conflict(params Expr[] terms) {
|
||||||
Propagate(terms, solver.Context.MkFalse());
|
Propagate(terms, ctx.MkFalse());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -160,7 +193,7 @@ namespace Microsoft.Z3
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void Propagate(Expr[] terms, Expr conseq) {
|
void Propagate(Expr[] terms, Expr conseq) {
|
||||||
var nTerms = Z3Object.ArrayToNative(terms);
|
var nTerms = Z3Object.ArrayToNative(terms);
|
||||||
Native.Z3_solver_propagate_consequence(solver.Context.nCtx, this.callback, (uint)nTerms.Length, nTerms, 0u, null, null, conseq.NativeObject);
|
Native.Z3_solver_propagate_consequence(ctx.nCtx, this.callback, (uint)nTerms.Length, nTerms, 0u, null, null, conseq.NativeObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -172,7 +205,8 @@ namespace Microsoft.Z3
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
this.fixed_eh = value;
|
this.fixed_eh = value;
|
||||||
Native.Z3_solver_propagate_fixed(solver.Context.nCtx, solver.NativeObject, _fixed);
|
if (solver != null)
|
||||||
|
Native.Z3_solver_propagate_fixed(ctx.nCtx, solver.NativeObject, _fixed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,7 +218,8 @@ namespace Microsoft.Z3
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
this.final_eh = value;
|
this.final_eh = value;
|
||||||
Native.Z3_solver_propagate_final(solver.Context.nCtx, solver.NativeObject, _final);
|
if (solver != null)
|
||||||
|
Native.Z3_solver_propagate_final(ctx.nCtx, solver.NativeObject, _final);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,7 +231,8 @@ namespace Microsoft.Z3
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
this.eq_eh = value;
|
this.eq_eh = value;
|
||||||
Native.Z3_solver_propagate_eq(solver.Context.nCtx, solver.NativeObject, _eq);
|
if (solver != null)
|
||||||
|
Native.Z3_solver_propagate_eq(ctx.nCtx, solver.NativeObject, _eq);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,7 +244,21 @@ namespace Microsoft.Z3
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
this.diseq_eh = value;
|
this.diseq_eh = value;
|
||||||
Native.Z3_solver_propagate_diseq(solver.Context.nCtx, solver.NativeObject, _diseq);
|
if (solver != null)
|
||||||
|
Native.Z3_solver_propagate_diseq(ctx.nCtx, solver.NativeObject, _diseq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set created callback
|
||||||
|
/// </summary>
|
||||||
|
public CreatedEh Created
|
||||||
|
{
|
||||||
|
set
|
||||||
|
{
|
||||||
|
this.created_eh = value;
|
||||||
|
if (solver != null)
|
||||||
|
Native.Z3_solver_propagate_created(ctx.nCtx, solver.NativeObject, _created);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,7 +266,12 @@ namespace Microsoft.Z3
|
||||||
/// Track assignments to a term
|
/// Track assignments to a term
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Register(Expr term) {
|
public void Register(Expr term) {
|
||||||
Native.Z3_solver_propagate_register(solver.Context.nCtx, solver.NativeObject, term.NativeObject);
|
if (this.callback != IntPtr.Zero) {
|
||||||
|
Native.Z3_solver_propagate_register_cb(ctx.nCtx, callback, term.NativeObject);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Native.Z3_solver_propagate_register(ctx.nCtx, solver.NativeObject, term.NativeObject);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue