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:
parent
556f0d7b5f
commit
798a4ee86e
1 changed files with 205 additions and 179 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue