3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-06-16 19:06:17 +00:00

use IEnumerator and format

This commit is contained in:
Nikolaj Bjorner 2022-06-28 14:24:05 -07:00
parent 556f0d7b5f
commit 798a4ee86e

View file

@ -37,280 +37,306 @@ namespace Microsoft.Z3
/// <summary> /// <summary>
/// Propagator context for .Net /// Propagator context for .Net
/// </summary> /// </summary>
public class UserPropagator public class UserPropagator
{ {
/// <summary> /// <summary>
/// Delegate type for fixed callback /// Delegate type for fixed callback
/// </summary> /// </summary>
public delegate void FixedEh(Expr term, Expr value); public delegate void FixedEh(Expr term, Expr value);
/// <summary> /// <summary>
/// Delegate type for equality or disequality callback /// Delegate type for equality or disequality callback
/// </summary> /// </summary>
public delegate void EqEh(Expr term, Expr value); public delegate void EqEh(Expr term, Expr value);
/// <summary> /// <summary>
/// Delegate type for when a new term using a registered function symbol is created internally /// Delegate type for when a new term using a registered function symbol is created internally
/// </summary> /// </summary>
public delegate void CreatedEh(Expr term); public delegate void CreatedEh(Expr term);
/// <summary> /// <summary>
/// Delegate type for callback into solver's branching /// Delegate type for callback into solver's branching
/// <param name="term">A bit-vector or Boolean used for branching</param> /// <param name="term">A bit-vector or Boolean used for branching</param>
/// <param name="idx">If the term is a bit-vector, then an index into the bit-vector being branched on</param> /// <param name="idx">If the term is a bit-vector, then an index into the bit-vector being branched on</param>
/// <param name="phase">Set phase to -1 (false) or 1 (true) to override solver's phase</param> /// <param name="phase">Set phase to -1 (false) or 1 (true) to override solver's phase</param>
/// </summary> /// </summary>
public delegate void DecideEh(ref Expr term, ref uint idx, ref int phase); public delegate void DecideEh(ref Expr term, ref uint idx, ref int phase);
// access managed objects through a static array. // access managed objects through a static array.
// thread safety is ignored for now. // thread safety is ignored for now.
static List<UserPropagator> propagators = new List<UserPropagator>(); static List<UserPropagator> propagators = new List<UserPropagator>();
int id; int id;
Solver solver; Solver solver;
Context ctx; Context ctx;
Z3_solver_callback callback = IntPtr.Zero; 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; CreatedEh created_eh;
DecideEh decide_eh; DecideEh decide_eh;
void Callback(Action fn, Z3_solver_callback cb) { void Callback(Action fn, Z3_solver_callback cb)
this.callback = cb; {
try { this.callback = cb;
fn(); try
} {
catch { fn();
// TBD: add debug log or exception handler }
} catch
finally { {
this.callback = IntPtr.Zero; // TBD: add debug log or exception handler
} }
} finally
{
this.callback = IntPtr.Zero;
}
}
static void _push(voidp ctx, Z3_solver_callback cb) { static void _push(voidp ctx, Z3_solver_callback cb)
var prop = propagators[ctx.ToInt32()]; {
prop.Callback(() => prop.Push(), cb); var prop = propagators[ctx.ToInt32()];
} prop.Callback(() => prop.Push(), cb);
}
static void _pop(voidp ctx, Z3_solver_callback cb, uint num_scopes) {
var prop = propagators[ctx.ToInt32()];
prop.Callback(() => prop.Pop(num_scopes), cb);
}
static voidp _fresh(voidp _ctx, Z3_context new_context) {
var prop = propagators[_ctx.ToInt32()];
var ctx = new Context(new_context);
var prop1 = prop.Fresh(prop.ctx);
return new IntPtr(prop1.id);
}
static void _fixed(voidp ctx, Z3_solver_callback cb, Z3_ast _term, Z3_ast _value) { static void _pop(voidp ctx, Z3_solver_callback cb, uint num_scopes)
var prop = propagators[ctx.ToInt32()]; {
using var term = Expr.Create(prop.ctx, _term); var prop = propagators[ctx.ToInt32()];
using var value = Expr.Create(prop.ctx, _value); prop.Callback(() => prop.Pop(num_scopes), cb);
prop.Callback(() => prop.fixed_eh(term, value), cb); }
}
static void _final(voidp ctx, Z3_solver_callback cb) { static voidp _fresh(voidp _ctx, Z3_context new_context)
var prop = propagators[ctx.ToInt32()]; {
prop.Callback(() => prop.final_eh(), cb); var prop = propagators[_ctx.ToInt32()];
} var ctx = new Context(new_context);
var prop1 = prop.Fresh(prop.ctx);
return new IntPtr(prop1.id);
}
static void _eq(voidp ctx, Z3_solver_callback cb, Z3_ast a, Z3_ast b) { static void _fixed(voidp ctx, Z3_solver_callback cb, Z3_ast _term, Z3_ast _value)
var prop = propagators[ctx.ToInt32()]; {
using var s = Expr.Create(prop.ctx, a); var prop = propagators[ctx.ToInt32()];
using var t = Expr.Create(prop.ctx, b); using var term = Expr.Create(prop.ctx, _term);
prop.Callback(() => prop.eq_eh(s, t), cb); 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) { static void _final(voidp ctx, Z3_solver_callback cb)
var prop = propagators[ctx.ToInt32()]; {
using var s = Expr.Create(prop.ctx, a); var prop = propagators[ctx.ToInt32()];
using var t = Expr.Create(prop.ctx, b); prop.Callback(() => prop.final_eh(), cb);
prop.Callback(() => prop.diseq_eh(s, t), cb); }
}
static void _created(voidp ctx, Z3_solver_callback cb, Z3_ast a) { static void _eq(voidp ctx, Z3_solver_callback cb, Z3_ast a, Z3_ast b)
var prop = propagators[ctx.ToInt32()]; {
using var t = Expr.Create(prop.ctx, a); var prop = propagators[ctx.ToInt32()];
prop.Callback(() => prop.created_eh(t), cb); using var s = Expr.Create(prop.ctx, a);
} using var t = Expr.Create(prop.ctx, b);
prop.Callback(() => prop.eq_eh(s, t), cb);
}
static void _decide(voidp ctx, Z3_solver_callback cb, ref Z3_ast a, ref uint idx, ref int phase) { static void _diseq(voidp ctx, Z3_solver_callback cb, Z3_ast a, Z3_ast b)
var prop = propagators[ctx.ToInt32()]; {
var t = Expr.Create(prop.ctx, a); var prop = propagators[ctx.ToInt32()];
var u = t; using var s = Expr.Create(prop.ctx, a);
prop.callback = cb; using var t = Expr.Create(prop.ctx, b);
prop.decide_eh(ref t, ref idx, ref phase); prop.Callback(() => prop.diseq_eh(s, t), cb);
prop.callback = IntPtr.Zero; }
if (u != t)
a = t.NativeObject; static void _created(voidp ctx, Z3_solver_callback cb, Z3_ast a)
} {
var prop = propagators[ctx.ToInt32()];
using var t = Expr.Create(prop.ctx, a);
prop.Callback(() => prop.created_eh(t), cb);
}
static void _decide(voidp ctx, Z3_solver_callback cb, ref Z3_ast a, ref uint idx, ref int phase)
{
var prop = propagators[ctx.ToInt32()];
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> /// <summary>
/// Propagator constructor from a solver class. /// Propagator constructor from a solver class.
/// </summary> /// </summary>
public UserPropagator(Solver s) public UserPropagator(Solver s)
{ {
id = propagators.Count; id = propagators.Count;
propagators.Add(this); propagators.Add(this);
solver = s; solver = s;
ctx = solver.Context; ctx = solver.Context;
Native.Z3_solver_propagate_init(ctx.nCtx, solver.NativeObject, new IntPtr(id), _push, _pop, _fresh); Native.Z3_solver_propagate_init(ctx.nCtx, solver.NativeObject, new IntPtr(id), _push, _pop, _fresh);
} }
/// <summary> /// <summary>
/// Propagator constructor from a context. It is used from inside of Fresh. /// Propagator constructor from a context. It is used from inside of Fresh.
/// </summary> /// </summary>
public UserPropagator(Context _ctx) public UserPropagator(Context _ctx)
{ {
id = propagators.Count; id = propagators.Count;
propagators.Add(this); propagators.Add(this);
solver = null; solver = null;
ctx = _ctx; ctx = _ctx;
} }
/// <summary> /// <summary>
/// Release provate memory. /// Release provate memory.
/// </summary> /// </summary>
~UserPropagator() ~UserPropagator()
{ {
propagators[id] = null; propagators[id] = null;
if (solver == null) if (solver == null)
ctx.Dispose(); ctx.Dispose();
} }
/// <summary> /// <summary>
/// Virtual method for push. It must be overwritten by inherited class. /// Virtual method for push. It must be overwritten by inherited class.
/// </summary> /// </summary>
public virtual void Push() { throw new Z3Exception("Push method should be overwritten"); } public virtual void Push() { throw new Z3Exception("Push method should be overwritten"); }
/// <summary> /// <summary>
/// Virtual method for pop. It must be overwritten by inherited class. /// Virtual method for pop. It must be overwritten by inherited class.
/// </summary> /// </summary>
public virtual void Pop(uint n) { throw new Z3Exception("Pop method should be overwritten"); } public virtual void Pop(uint n) { throw new Z3Exception("Pop method should be overwritten"); }
/// <summary> /// <summary>
/// Virtual method for fresh. It can be overwritten by inherited class. /// Virtual method for fresh. It can be overwritten by inherited class.
/// </summary> /// </summary>
public virtual UserPropagator Fresh(Context ctx) { return new UserPropagator(ctx); } public virtual UserPropagator Fresh(Context ctx) { return new UserPropagator(ctx); }
/// <summary> /// <summary>
/// Declare combination of assigned expressions a conflict /// Declare combination of assigned expressions a conflict
/// </summary> /// </summary>
public void Conflict(params Expr[] terms) { public void Conflict(params Expr[] terms)
Propagate(terms, ctx.MkFalse()); {
Propagate(terms, ctx.MkFalse());
}
/// <summary>
/// Declare combination of assigned expressions a conflict
/// </summary>
public void Conflict(IEnumerable<Expr> terms)
{
Propagate(terms, ctx.MkFalse());
} }
/// <summary> /// <summary>
/// Propagate consequence /// Propagate consequence
/// </summary> /// </summary>
public void Propagate(Expr[] terms, Expr conseq) { public void Propagate(IEnumerable<Expr> terms, Expr conseq)
var nTerms = Z3Object.ArrayToNative(terms); {
var nTerms = Z3Object.ArrayToNative(terms.ToArray());
Native.Z3_solver_propagate_consequence(ctx.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);
} }
/// <summary> /// <summary>
/// Set fixed callback /// Set fixed callback
/// </summary> /// </summary>
public FixedEh Fixed public FixedEh Fixed
{ {
set set
{ {
this.fixed_eh = value; this.fixed_eh = value;
if (solver != null) if (solver != null)
Native.Z3_solver_propagate_fixed(ctx.nCtx, solver.NativeObject, _fixed); Native.Z3_solver_propagate_fixed(ctx.nCtx, solver.NativeObject, _fixed);
} }
} }
/// <summary> /// <summary>
/// Set final callback /// Set final callback
/// </summary> /// </summary>
public Action Final public Action Final
{ {
set set
{ {
this.final_eh = value; this.final_eh = value;
if (solver != null) if (solver != null)
Native.Z3_solver_propagate_final(ctx.nCtx, solver.NativeObject, _final); Native.Z3_solver_propagate_final(ctx.nCtx, solver.NativeObject, _final);
} }
} }
/// <summary> /// <summary>
/// Set equality event callback /// Set equality event callback
/// </summary> /// </summary>
public EqEh Eq public EqEh Eq
{ {
set set
{ {
this.eq_eh = value; this.eq_eh = value;
if (solver != null) if (solver != null)
Native.Z3_solver_propagate_eq(ctx.nCtx, solver.NativeObject, _eq); Native.Z3_solver_propagate_eq(ctx.nCtx, solver.NativeObject, _eq);
} }
} }
/// <summary> /// <summary>
/// Set disequality event callback /// Set disequality event callback
/// </summary> /// </summary>
public EqEh Diseq public EqEh Diseq
{ {
set set
{ {
this.diseq_eh = value; this.diseq_eh = value;
if (solver != null) if (solver != null)
Native.Z3_solver_propagate_diseq(ctx.nCtx, solver.NativeObject, _diseq); Native.Z3_solver_propagate_diseq(ctx.nCtx, solver.NativeObject, _diseq);
} }
} }
/// <summary> /// <summary>
/// Set created callback /// Set created callback
/// </summary> /// </summary>
public CreatedEh Created public CreatedEh Created
{ {
set set
{ {
this.created_eh = value; this.created_eh = value;
if (solver != null) if (solver != null)
Native.Z3_solver_propagate_created(ctx.nCtx, solver.NativeObject, _created); Native.Z3_solver_propagate_created(ctx.nCtx, solver.NativeObject, _created);
} }
} }
/// <summary> /// <summary>
/// Set decision callback /// Set decision callback
/// </summary> /// </summary>
public DecideEh Decide public DecideEh Decide
{ {
set set
{ {
this.decide_eh = value; this.decide_eh = value;
if (solver != null) if (solver != null)
Native.Z3_solver_propagate_decide(ctx.nCtx, solver.NativeObject, _decide); Native.Z3_solver_propagate_decide(ctx.nCtx, solver.NativeObject, _decide);
} }
} }
/// <summary> /// <summary>
/// Set the next decision /// Set the next decision
/// </summary> /// </summary>
public void NextSplit(Expr e, uint idx, int phase) public void NextSplit(Expr e, uint idx, int phase)
{ {
Native.Z3_solver_next_split(ctx.nCtx, this.callback, e.NativeObject, idx, phase); Native.Z3_solver_next_split(ctx.nCtx, this.callback, e.NativeObject, idx, phase);
} }
/// <summary> /// <summary>
/// Track assignments to a term /// Track assignments to a term
/// </summary> /// </summary>
public void Register(Expr term) { public void Register(Expr term)
if (this.callback != IntPtr.Zero) { {
Native.Z3_solver_propagate_register_cb(ctx.nCtx, callback, term.NativeObject); if (this.callback != IntPtr.Zero)
{
Native.Z3_solver_propagate_register_cb(ctx.nCtx, callback, term.NativeObject);
} }
else { else
Native.Z3_solver_propagate_register(ctx.nCtx, solver.NativeObject, term.NativeObject); {
Native.Z3_solver_propagate_register(ctx.nCtx, solver.NativeObject, term.NativeObject);
} }
} }
} }
} }