mirror of
https://github.com/Z3Prover/z3
synced 2025-06-12 17:06:14 +00:00
Merge branch 'master' of https://github.com/Z3Prover/z3
This commit is contained in:
commit
424a8c69bd
38 changed files with 473 additions and 216 deletions
|
@ -73,6 +73,10 @@ class MSSSolver:
|
||||||
self.varcache[i] = Not(v)
|
self.varcache[i] = Not(v)
|
||||||
return self.varcache[i]
|
return self.varcache[i]
|
||||||
|
|
||||||
|
# Retrieve the latest model
|
||||||
|
# Add formulas that are true in the model to
|
||||||
|
# the current mss
|
||||||
|
|
||||||
def update_unknown(self):
|
def update_unknown(self):
|
||||||
self.model = self.s.model()
|
self.model = self.s.model()
|
||||||
new_unknown = set([])
|
new_unknown = set([])
|
||||||
|
@ -83,23 +87,29 @@ class MSSSolver:
|
||||||
new_unknown.add(x)
|
new_unknown.add(x)
|
||||||
self.unknown = new_unknown
|
self.unknown = new_unknown
|
||||||
|
|
||||||
def relax_core(self, core):
|
# Create a name, propositional atom,
|
||||||
assert(core <= self.soft_vars)
|
# for formula 'fml' and return the name.
|
||||||
prev = BoolVal(True)
|
|
||||||
core_list = [x for x in core]
|
def add_def(self, fml):
|
||||||
self.soft_vars -= core
|
name = Bool("%s" % fml)
|
||||||
# replace x0, x1, x2, .. by
|
self.s.add(name == fml)
|
||||||
# Or(x1, x0), Or(x2, And(x1, x0)), Or(x3, And(x2, And(x1, x0))), ...
|
return name
|
||||||
for i in range(len(core_list)-1):
|
|
||||||
x = core_list[i]
|
# replace Fs := f0, f1, f2, .. by
|
||||||
y = core_list[i+1]
|
# Or(f1, f0), Or(f2, And(f1, f0)), Or(f3, And(f2, And(f1, f0))), ...
|
||||||
prevf = And(x, prev)
|
|
||||||
prev = Bool("%s" % prevf)
|
def relax_core(self, Fs):
|
||||||
self.s.add(prev == prevf)
|
assert(Fs <= self.soft_vars)
|
||||||
zf = Or(prev, y)
|
prefix = BoolVal(True)
|
||||||
z = Bool("%s" % zf)
|
self.soft_vars -= Fs
|
||||||
self.s.add(z == zf)
|
Fs = [ f for f in Fs ]
|
||||||
self.soft_vars.add(z)
|
for i in range(len(Fs)-1):
|
||||||
|
prefix = self.add_def(And(Fs[i], prefix))
|
||||||
|
self.soft_vars.add(self.add_def(Or(prefix, Fs[i+1])))
|
||||||
|
|
||||||
|
# Resolve literals from the core that
|
||||||
|
# are 'explained', e.g., implied by
|
||||||
|
# other literals.
|
||||||
|
|
||||||
def resolve_core(self, core):
|
def resolve_core(self, core):
|
||||||
new_core = set([])
|
new_core = set([])
|
||||||
|
@ -111,6 +121,14 @@ class MSSSolver:
|
||||||
return new_core
|
return new_core
|
||||||
|
|
||||||
|
|
||||||
|
# Given a current satisfiable state
|
||||||
|
# Extract an MSS, and ensure that currently
|
||||||
|
# encoutered cores are avoided in next iterations
|
||||||
|
# by weakening the set of literals that are
|
||||||
|
# examined in next iterations.
|
||||||
|
# Strengthen the solver state by enforcing that
|
||||||
|
# an element from the MCS is encoutered.
|
||||||
|
|
||||||
def grow(self):
|
def grow(self):
|
||||||
self.mss = []
|
self.mss = []
|
||||||
self.mcs = []
|
self.mcs = []
|
||||||
|
|
|
@ -415,6 +415,7 @@ extern "C" {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mk_c(c)->m().dec_ref(to_ast(a));
|
mk_c(c)->m().dec_ref(to_ast(a));
|
||||||
|
|
||||||
Z3_CATCH;
|
Z3_CATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -286,8 +286,8 @@ namespace Microsoft.Z3
|
||||||
Contract.Ensures(Contract.Result<TupleSort>() != null);
|
Contract.Ensures(Contract.Result<TupleSort>() != null);
|
||||||
|
|
||||||
CheckContextMatch(name);
|
CheckContextMatch(name);
|
||||||
CheckContextMatch(fieldNames);
|
CheckContextMatch<Symbol>(fieldNames);
|
||||||
CheckContextMatch(fieldSorts);
|
CheckContextMatch<Sort>(fieldSorts);
|
||||||
return new TupleSort(this, name, (uint)fieldNames.Length, fieldNames, fieldSorts);
|
return new TupleSort(this, name, (uint)fieldNames.Length, fieldNames, fieldSorts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,7 +303,7 @@ namespace Microsoft.Z3
|
||||||
Contract.Ensures(Contract.Result<EnumSort>() != null);
|
Contract.Ensures(Contract.Result<EnumSort>() != null);
|
||||||
|
|
||||||
CheckContextMatch(name);
|
CheckContextMatch(name);
|
||||||
CheckContextMatch(enumNames);
|
CheckContextMatch<Symbol>(enumNames);
|
||||||
return new EnumSort(this, name, enumNames);
|
return new EnumSort(this, name, enumNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -423,7 +423,7 @@ namespace Microsoft.Z3
|
||||||
Contract.Ensures(Contract.Result<DatatypeSort>() != null);
|
Contract.Ensures(Contract.Result<DatatypeSort>() != null);
|
||||||
|
|
||||||
CheckContextMatch(name);
|
CheckContextMatch(name);
|
||||||
CheckContextMatch(constructors);
|
CheckContextMatch<Constructor>(constructors);
|
||||||
return new DatatypeSort(this, name, constructors);
|
return new DatatypeSort(this, name, constructors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -436,7 +436,7 @@ namespace Microsoft.Z3
|
||||||
Contract.Requires(Contract.ForAll(constructors, c => c != null));
|
Contract.Requires(Contract.ForAll(constructors, c => c != null));
|
||||||
Contract.Ensures(Contract.Result<DatatypeSort>() != null);
|
Contract.Ensures(Contract.Result<DatatypeSort>() != null);
|
||||||
|
|
||||||
CheckContextMatch(constructors);
|
CheckContextMatch<Constructor>(constructors);
|
||||||
return new DatatypeSort(this, MkSymbol(name), constructors);
|
return new DatatypeSort(this, MkSymbol(name), constructors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -454,7 +454,7 @@ namespace Microsoft.Z3
|
||||||
Contract.Requires(Contract.ForAll(names, name => name != null));
|
Contract.Requires(Contract.ForAll(names, name => name != null));
|
||||||
Contract.Ensures(Contract.Result<DatatypeSort[]>() != null);
|
Contract.Ensures(Contract.Result<DatatypeSort[]>() != null);
|
||||||
|
|
||||||
CheckContextMatch(names);
|
CheckContextMatch<Symbol>(names);
|
||||||
uint n = (uint)names.Length;
|
uint n = (uint)names.Length;
|
||||||
ConstructorList[] cla = new ConstructorList[n];
|
ConstructorList[] cla = new ConstructorList[n];
|
||||||
IntPtr[] n_constr = new IntPtr[n];
|
IntPtr[] n_constr = new IntPtr[n];
|
||||||
|
@ -462,7 +462,7 @@ namespace Microsoft.Z3
|
||||||
{
|
{
|
||||||
Constructor[] constructor = c[i];
|
Constructor[] constructor = c[i];
|
||||||
Contract.Assume(Contract.ForAll(constructor, arr => arr != null), "Clousot does not support yet quantified formula on multidimensional arrays");
|
Contract.Assume(Contract.ForAll(constructor, arr => arr != null), "Clousot does not support yet quantified formula on multidimensional arrays");
|
||||||
CheckContextMatch(constructor);
|
CheckContextMatch<Constructor>(constructor);
|
||||||
cla[i] = new ConstructorList(this, constructor);
|
cla[i] = new ConstructorList(this, constructor);
|
||||||
n_constr[i] = cla[i].NativeObject;
|
n_constr[i] = cla[i].NativeObject;
|
||||||
}
|
}
|
||||||
|
@ -520,7 +520,7 @@ namespace Microsoft.Z3
|
||||||
Contract.Ensures(Contract.Result<FuncDecl>() != null);
|
Contract.Ensures(Contract.Result<FuncDecl>() != null);
|
||||||
|
|
||||||
CheckContextMatch(name);
|
CheckContextMatch(name);
|
||||||
CheckContextMatch(domain);
|
CheckContextMatch<Sort>(domain);
|
||||||
CheckContextMatch(range);
|
CheckContextMatch(range);
|
||||||
return new FuncDecl(this, name, domain, range);
|
return new FuncDecl(this, name, domain, range);
|
||||||
}
|
}
|
||||||
|
@ -551,7 +551,7 @@ namespace Microsoft.Z3
|
||||||
Contract.Requires(Contract.ForAll(domain, d => d != null));
|
Contract.Requires(Contract.ForAll(domain, d => d != null));
|
||||||
Contract.Ensures(Contract.Result<FuncDecl>() != null);
|
Contract.Ensures(Contract.Result<FuncDecl>() != null);
|
||||||
|
|
||||||
CheckContextMatch(domain);
|
CheckContextMatch<Sort>(domain);
|
||||||
CheckContextMatch(range);
|
CheckContextMatch(range);
|
||||||
return new FuncDecl(this, MkSymbol(name), domain, range);
|
return new FuncDecl(this, MkSymbol(name), domain, range);
|
||||||
}
|
}
|
||||||
|
@ -582,7 +582,7 @@ namespace Microsoft.Z3
|
||||||
Contract.Requires(Contract.ForAll(domain, d => d != null));
|
Contract.Requires(Contract.ForAll(domain, d => d != null));
|
||||||
Contract.Ensures(Contract.Result<FuncDecl>() != null);
|
Contract.Ensures(Contract.Result<FuncDecl>() != null);
|
||||||
|
|
||||||
CheckContextMatch(domain);
|
CheckContextMatch<Sort>(domain);
|
||||||
CheckContextMatch(range);
|
CheckContextMatch(range);
|
||||||
return new FuncDecl(this, prefix, domain, range);
|
return new FuncDecl(this, prefix, domain, range);
|
||||||
}
|
}
|
||||||
|
@ -811,7 +811,7 @@ namespace Microsoft.Z3
|
||||||
Contract.Ensures(Contract.Result<Expr>() != null);
|
Contract.Ensures(Contract.Result<Expr>() != null);
|
||||||
|
|
||||||
CheckContextMatch(f);
|
CheckContextMatch(f);
|
||||||
CheckContextMatch(args);
|
CheckContextMatch<Expr>(args);
|
||||||
return Expr.Create(this, f, args);
|
return Expr.Create(this, f, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -884,7 +884,7 @@ namespace Microsoft.Z3
|
||||||
|
|
||||||
Contract.Ensures(Contract.Result<BoolExpr>() != null);
|
Contract.Ensures(Contract.Result<BoolExpr>() != null);
|
||||||
|
|
||||||
CheckContextMatch(args);
|
CheckContextMatch<Expr>(args);
|
||||||
return new BoolExpr(this, Native.Z3_mk_distinct(nCtx, (uint)args.Length, AST.ArrayToNative(args)));
|
return new BoolExpr(this, Native.Z3_mk_distinct(nCtx, (uint)args.Length, AST.ArrayToNative(args)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -970,7 +970,7 @@ namespace Microsoft.Z3
|
||||||
Contract.Requires(Contract.ForAll(t, a => a != null));
|
Contract.Requires(Contract.ForAll(t, a => a != null));
|
||||||
Contract.Ensures(Contract.Result<BoolExpr>() != null);
|
Contract.Ensures(Contract.Result<BoolExpr>() != null);
|
||||||
|
|
||||||
CheckContextMatch(t);
|
CheckContextMatch<BoolExpr>(t);
|
||||||
return new BoolExpr(this, Native.Z3_mk_and(nCtx, (uint)t.Length, AST.ArrayToNative(t)));
|
return new BoolExpr(this, Native.Z3_mk_and(nCtx, (uint)t.Length, AST.ArrayToNative(t)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -982,7 +982,7 @@ namespace Microsoft.Z3
|
||||||
Contract.Requires(t != null);
|
Contract.Requires(t != null);
|
||||||
Contract.Requires(Contract.ForAll(t, a => a != null));
|
Contract.Requires(Contract.ForAll(t, a => a != null));
|
||||||
Contract.Ensures(Contract.Result<BoolExpr>() != null);
|
Contract.Ensures(Contract.Result<BoolExpr>() != null);
|
||||||
CheckContextMatch(t);
|
CheckContextMatch<BoolExpr>(t);
|
||||||
return new BoolExpr(this, Native.Z3_mk_and(nCtx, (uint)t.Count(), AST.EnumToNative(t)));
|
return new BoolExpr(this, Native.Z3_mk_and(nCtx, (uint)t.Count(), AST.EnumToNative(t)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -995,7 +995,7 @@ namespace Microsoft.Z3
|
||||||
Contract.Requires(Contract.ForAll(t, a => a != null));
|
Contract.Requires(Contract.ForAll(t, a => a != null));
|
||||||
Contract.Ensures(Contract.Result<BoolExpr>() != null);
|
Contract.Ensures(Contract.Result<BoolExpr>() != null);
|
||||||
|
|
||||||
CheckContextMatch(t);
|
CheckContextMatch<BoolExpr>(t);
|
||||||
return new BoolExpr(this, Native.Z3_mk_or(nCtx, (uint)t.Length, AST.ArrayToNative(t)));
|
return new BoolExpr(this, Native.Z3_mk_or(nCtx, (uint)t.Length, AST.ArrayToNative(t)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1025,7 +1025,7 @@ namespace Microsoft.Z3
|
||||||
Contract.Requires(Contract.ForAll(t, a => a != null));
|
Contract.Requires(Contract.ForAll(t, a => a != null));
|
||||||
Contract.Ensures(Contract.Result<ArithExpr>() != null);
|
Contract.Ensures(Contract.Result<ArithExpr>() != null);
|
||||||
|
|
||||||
CheckContextMatch(t);
|
CheckContextMatch<ArithExpr>(t);
|
||||||
return (ArithExpr)Expr.Create(this, Native.Z3_mk_add(nCtx, (uint)t.Length, AST.ArrayToNative(t)));
|
return (ArithExpr)Expr.Create(this, Native.Z3_mk_add(nCtx, (uint)t.Length, AST.ArrayToNative(t)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1051,7 +1051,7 @@ namespace Microsoft.Z3
|
||||||
Contract.Requires(Contract.ForAll(t, a => a != null));
|
Contract.Requires(Contract.ForAll(t, a => a != null));
|
||||||
Contract.Ensures(Contract.Result<ArithExpr>() != null);
|
Contract.Ensures(Contract.Result<ArithExpr>() != null);
|
||||||
|
|
||||||
CheckContextMatch(t);
|
CheckContextMatch<ArithExpr>(t);
|
||||||
return (ArithExpr)Expr.Create(this, Native.Z3_mk_mul(nCtx, (uint)t.Length, AST.ArrayToNative(t)));
|
return (ArithExpr)Expr.Create(this, Native.Z3_mk_mul(nCtx, (uint)t.Length, AST.ArrayToNative(t)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1064,7 +1064,7 @@ namespace Microsoft.Z3
|
||||||
Contract.Requires(Contract.ForAll(t, a => a != null));
|
Contract.Requires(Contract.ForAll(t, a => a != null));
|
||||||
Contract.Ensures(Contract.Result<ArithExpr>() != null);
|
Contract.Ensures(Contract.Result<ArithExpr>() != null);
|
||||||
|
|
||||||
CheckContextMatch(t);
|
CheckContextMatch<ArithExpr>(t);
|
||||||
return (ArithExpr)Expr.Create(this, Native.Z3_mk_mul(nCtx, (uint)t.Count(), AST.EnumToNative(t)));
|
return (ArithExpr)Expr.Create(this, Native.Z3_mk_mul(nCtx, (uint)t.Count(), AST.EnumToNative(t)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1077,7 +1077,7 @@ namespace Microsoft.Z3
|
||||||
Contract.Requires(Contract.ForAll(t, a => a != null));
|
Contract.Requires(Contract.ForAll(t, a => a != null));
|
||||||
Contract.Ensures(Contract.Result<ArithExpr>() != null);
|
Contract.Ensures(Contract.Result<ArithExpr>() != null);
|
||||||
|
|
||||||
CheckContextMatch(t);
|
CheckContextMatch<ArithExpr>(t);
|
||||||
return (ArithExpr)Expr.Create(this, Native.Z3_mk_sub(nCtx, (uint)t.Length, AST.ArrayToNative(t)));
|
return (ArithExpr)Expr.Create(this, Native.Z3_mk_sub(nCtx, (uint)t.Length, AST.ArrayToNative(t)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2205,7 +2205,7 @@ namespace Microsoft.Z3
|
||||||
Contract.Ensures(Contract.Result<ArrayExpr>() != null);
|
Contract.Ensures(Contract.Result<ArrayExpr>() != null);
|
||||||
|
|
||||||
CheckContextMatch(f);
|
CheckContextMatch(f);
|
||||||
CheckContextMatch(args);
|
CheckContextMatch<ArrayExpr>(args);
|
||||||
return (ArrayExpr)Expr.Create(this, Native.Z3_mk_map(nCtx, f.NativeObject, AST.ArrayLength(args), AST.ArrayToNative(args)));
|
return (ArrayExpr)Expr.Create(this, Native.Z3_mk_map(nCtx, f.NativeObject, AST.ArrayLength(args), AST.ArrayToNative(args)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2315,7 +2315,7 @@ namespace Microsoft.Z3
|
||||||
Contract.Requires(args != null);
|
Contract.Requires(args != null);
|
||||||
Contract.Requires(Contract.ForAll(args, a => a != null));
|
Contract.Requires(Contract.ForAll(args, a => a != null));
|
||||||
|
|
||||||
CheckContextMatch(args);
|
CheckContextMatch<ArrayExpr>(args);
|
||||||
return (ArrayExpr)Expr.Create(this, Native.Z3_mk_set_union(nCtx, (uint)args.Length, AST.ArrayToNative(args)));
|
return (ArrayExpr)Expr.Create(this, Native.Z3_mk_set_union(nCtx, (uint)args.Length, AST.ArrayToNative(args)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2328,7 +2328,7 @@ namespace Microsoft.Z3
|
||||||
Contract.Requires(Contract.ForAll(args, a => a != null));
|
Contract.Requires(Contract.ForAll(args, a => a != null));
|
||||||
Contract.Ensures(Contract.Result<Expr>() != null);
|
Contract.Ensures(Contract.Result<Expr>() != null);
|
||||||
|
|
||||||
CheckContextMatch(args);
|
CheckContextMatch<ArrayExpr>(args);
|
||||||
return (ArrayExpr)Expr.Create(this, Native.Z3_mk_set_intersect(nCtx, (uint)args.Length, AST.ArrayToNative(args)));
|
return (ArrayExpr)Expr.Create(this, Native.Z3_mk_set_intersect(nCtx, (uint)args.Length, AST.ArrayToNative(args)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2429,7 +2429,7 @@ namespace Microsoft.Z3
|
||||||
Contract.Requires(Contract.ForAll(t, a => a != null));
|
Contract.Requires(Contract.ForAll(t, a => a != null));
|
||||||
Contract.Ensures(Contract.Result<SeqExpr>() != null);
|
Contract.Ensures(Contract.Result<SeqExpr>() != null);
|
||||||
|
|
||||||
CheckContextMatch(t);
|
CheckContextMatch<SeqExpr>(t);
|
||||||
return new SeqExpr(this, Native.Z3_mk_seq_concat(nCtx, (uint)t.Length, AST.ArrayToNative(t)));
|
return new SeqExpr(this, Native.Z3_mk_seq_concat(nCtx, (uint)t.Length, AST.ArrayToNative(t)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2593,7 +2593,7 @@ namespace Microsoft.Z3
|
||||||
Contract.Requires(Contract.ForAll(t, a => a != null));
|
Contract.Requires(Contract.ForAll(t, a => a != null));
|
||||||
Contract.Ensures(Contract.Result<ReExpr>() != null);
|
Contract.Ensures(Contract.Result<ReExpr>() != null);
|
||||||
|
|
||||||
CheckContextMatch(t);
|
CheckContextMatch<ReExpr>(t);
|
||||||
return new ReExpr(this, Native.Z3_mk_re_concat(nCtx, (uint)t.Length, AST.ArrayToNative(t)));
|
return new ReExpr(this, Native.Z3_mk_re_concat(nCtx, (uint)t.Length, AST.ArrayToNative(t)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2606,7 +2606,7 @@ namespace Microsoft.Z3
|
||||||
Contract.Requires(Contract.ForAll(t, a => a != null));
|
Contract.Requires(Contract.ForAll(t, a => a != null));
|
||||||
Contract.Ensures(Contract.Result<ReExpr>() != null);
|
Contract.Ensures(Contract.Result<ReExpr>() != null);
|
||||||
|
|
||||||
CheckContextMatch(t);
|
CheckContextMatch<ReExpr>(t);
|
||||||
return new ReExpr(this, Native.Z3_mk_re_union(nCtx, (uint)t.Length, AST.ArrayToNative(t)));
|
return new ReExpr(this, Native.Z3_mk_re_union(nCtx, (uint)t.Length, AST.ArrayToNative(t)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2621,7 +2621,7 @@ namespace Microsoft.Z3
|
||||||
{
|
{
|
||||||
Contract.Requires(args != null);
|
Contract.Requires(args != null);
|
||||||
Contract.Requires(Contract.Result<BoolExpr[]>() != null);
|
Contract.Requires(Contract.Result<BoolExpr[]>() != null);
|
||||||
CheckContextMatch(args);
|
CheckContextMatch<BoolExpr>(args);
|
||||||
return new BoolExpr(this, Native.Z3_mk_atmost(nCtx, (uint) args.Length,
|
return new BoolExpr(this, Native.Z3_mk_atmost(nCtx, (uint) args.Length,
|
||||||
AST.ArrayToNative(args), k));
|
AST.ArrayToNative(args), k));
|
||||||
}
|
}
|
||||||
|
@ -2635,7 +2635,7 @@ namespace Microsoft.Z3
|
||||||
Contract.Requires(coeffs != null);
|
Contract.Requires(coeffs != null);
|
||||||
Contract.Requires(args.Length == coeffs.Length);
|
Contract.Requires(args.Length == coeffs.Length);
|
||||||
Contract.Requires(Contract.Result<BoolExpr[]>() != null);
|
Contract.Requires(Contract.Result<BoolExpr[]>() != null);
|
||||||
CheckContextMatch(args);
|
CheckContextMatch<BoolExpr>(args);
|
||||||
return new BoolExpr(this, Native.Z3_mk_pble(nCtx, (uint) args.Length,
|
return new BoolExpr(this, Native.Z3_mk_pble(nCtx, (uint) args.Length,
|
||||||
AST.ArrayToNative(args),
|
AST.ArrayToNative(args),
|
||||||
coeffs, k));
|
coeffs, k));
|
||||||
|
@ -3386,7 +3386,7 @@ namespace Microsoft.Z3
|
||||||
|
|
||||||
CheckContextMatch(t1);
|
CheckContextMatch(t1);
|
||||||
CheckContextMatch(t2);
|
CheckContextMatch(t2);
|
||||||
CheckContextMatch(ts);
|
CheckContextMatch<Tactic>(ts);
|
||||||
|
|
||||||
IntPtr last = IntPtr.Zero;
|
IntPtr last = IntPtr.Zero;
|
||||||
if (ts != null && ts.Length > 0)
|
if (ts != null && ts.Length > 0)
|
||||||
|
@ -3577,7 +3577,7 @@ namespace Microsoft.Z3
|
||||||
Contract.Requires(t == null || Contract.ForAll(t, tactic => tactic != null));
|
Contract.Requires(t == null || Contract.ForAll(t, tactic => tactic != null));
|
||||||
Contract.Ensures(Contract.Result<Tactic>() != null);
|
Contract.Ensures(Contract.Result<Tactic>() != null);
|
||||||
|
|
||||||
CheckContextMatch(t);
|
CheckContextMatch<Tactic>(t);
|
||||||
return new Tactic(this, Native.Z3_tactic_par_or(nCtx, Tactic.ArrayLength(t), Tactic.ArrayToNative(t)));
|
return new Tactic(this, Native.Z3_tactic_par_or(nCtx, Tactic.ArrayLength(t), Tactic.ArrayToNative(t)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4810,7 +4810,7 @@ namespace Microsoft.Z3
|
||||||
}
|
}
|
||||||
|
|
||||||
[Pure]
|
[Pure]
|
||||||
internal void CheckContextMatch(IEnumerable<Z3Object> arr)
|
internal void CheckContextMatch<T>(IEnumerable<T> arr) where T : Z3Object
|
||||||
{
|
{
|
||||||
Contract.Requires(arr == null || Contract.ForAll(arr, a => a != null));
|
Contract.Requires(arr == null || Contract.ForAll(arr, a => a != null));
|
||||||
|
|
||||||
|
|
|
@ -98,7 +98,7 @@ namespace Microsoft.Z3
|
||||||
Contract.Requires(args != null);
|
Contract.Requires(args != null);
|
||||||
Contract.Requires(Contract.ForAll(args, a => a != null));
|
Contract.Requires(Contract.ForAll(args, a => a != null));
|
||||||
|
|
||||||
Context.CheckContextMatch(args);
|
Context.CheckContextMatch<Expr>(args);
|
||||||
if (IsApp && args.Length != NumArgs)
|
if (IsApp && args.Length != NumArgs)
|
||||||
throw new Z3Exception("Number of arguments does not match");
|
throw new Z3Exception("Number of arguments does not match");
|
||||||
NativeObject = Native.Z3_update_term(Context.nCtx, NativeObject, (uint)args.Length, Expr.ArrayToNative(args));
|
NativeObject = Native.Z3_update_term(Context.nCtx, NativeObject, (uint)args.Length, Expr.ArrayToNative(args));
|
||||||
|
@ -120,8 +120,8 @@ namespace Microsoft.Z3
|
||||||
Contract.Requires(Contract.ForAll(to, t => t != null));
|
Contract.Requires(Contract.ForAll(to, t => t != null));
|
||||||
Contract.Ensures(Contract.Result<Expr>() != null);
|
Contract.Ensures(Contract.Result<Expr>() != null);
|
||||||
|
|
||||||
Context.CheckContextMatch(from);
|
Context.CheckContextMatch<Expr>(from);
|
||||||
Context.CheckContextMatch(to);
|
Context.CheckContextMatch<Expr>(to);
|
||||||
if (from.Length != to.Length)
|
if (from.Length != to.Length)
|
||||||
throw new Z3Exception("Argument sizes do not match");
|
throw new Z3Exception("Argument sizes do not match");
|
||||||
return Expr.Create(Context, Native.Z3_substitute(Context.nCtx, NativeObject, (uint)from.Length, Expr.ArrayToNative(from), Expr.ArrayToNative(to)));
|
return Expr.Create(Context, Native.Z3_substitute(Context.nCtx, NativeObject, (uint)from.Length, Expr.ArrayToNative(from), Expr.ArrayToNative(to)));
|
||||||
|
@ -152,7 +152,7 @@ namespace Microsoft.Z3
|
||||||
Contract.Requires(Contract.ForAll(to, t => t != null));
|
Contract.Requires(Contract.ForAll(to, t => t != null));
|
||||||
Contract.Ensures(Contract.Result<Expr>() != null);
|
Contract.Ensures(Contract.Result<Expr>() != null);
|
||||||
|
|
||||||
Context.CheckContextMatch(to);
|
Context.CheckContextMatch<Expr>(to);
|
||||||
return Expr.Create(Context, Native.Z3_substitute_vars(Context.nCtx, NativeObject, (uint)to.Length, Expr.ArrayToNative(to)));
|
return Expr.Create(Context, Native.Z3_substitute_vars(Context.nCtx, NativeObject, (uint)to.Length, Expr.ArrayToNative(to)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -71,7 +71,7 @@ namespace Microsoft.Z3
|
||||||
Contract.Requires(constraints != null);
|
Contract.Requires(constraints != null);
|
||||||
Contract.Requires(Contract.ForAll(constraints, c => c != null));
|
Contract.Requires(Contract.ForAll(constraints, c => c != null));
|
||||||
|
|
||||||
Context.CheckContextMatch(constraints);
|
Context.CheckContextMatch<BoolExpr>(constraints);
|
||||||
foreach (BoolExpr a in constraints)
|
foreach (BoolExpr a in constraints)
|
||||||
{
|
{
|
||||||
Native.Z3_fixedpoint_assert(Context.nCtx, NativeObject, a.NativeObject);
|
Native.Z3_fixedpoint_assert(Context.nCtx, NativeObject, a.NativeObject);
|
||||||
|
@ -151,7 +151,7 @@ namespace Microsoft.Z3
|
||||||
Contract.Requires(relations != null);
|
Contract.Requires(relations != null);
|
||||||
Contract.Requires(Contract.ForAll(0, relations.Length, i => relations[i] != null));
|
Contract.Requires(Contract.ForAll(0, relations.Length, i => relations[i] != null));
|
||||||
|
|
||||||
Context.CheckContextMatch(relations);
|
Context.CheckContextMatch<FuncDecl>(relations);
|
||||||
Z3_lbool r = (Z3_lbool)Native.Z3_fixedpoint_query_relations(Context.nCtx, NativeObject,
|
Z3_lbool r = (Z3_lbool)Native.Z3_fixedpoint_query_relations(Context.nCtx, NativeObject,
|
||||||
AST.ArrayLength(relations), AST.ArrayToNative(relations));
|
AST.ArrayLength(relations), AST.ArrayToNative(relations));
|
||||||
switch (r)
|
switch (r)
|
||||||
|
|
|
@ -339,7 +339,7 @@ namespace Microsoft.Z3
|
||||||
{
|
{
|
||||||
Contract.Requires(args == null || Contract.ForAll(args, a => a != null));
|
Contract.Requires(args == null || Contract.ForAll(args, a => a != null));
|
||||||
|
|
||||||
Context.CheckContextMatch(args);
|
Context.CheckContextMatch<Expr>(args);
|
||||||
return Expr.Create(Context, this, args);
|
return Expr.Create(Context, this, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -82,7 +82,7 @@ namespace Microsoft.Z3
|
||||||
Contract.Requires(constraints != null);
|
Contract.Requires(constraints != null);
|
||||||
Contract.Requires(Contract.ForAll(constraints, c => c != null));
|
Contract.Requires(Contract.ForAll(constraints, c => c != null));
|
||||||
|
|
||||||
Context.CheckContextMatch(constraints);
|
Context.CheckContextMatch<BoolExpr>(constraints);
|
||||||
foreach (BoolExpr c in constraints)
|
foreach (BoolExpr c in constraints)
|
||||||
{
|
{
|
||||||
Contract.Assert(c != null); // It was an assume, now made an assert just to be sure we do not regress
|
Contract.Assert(c != null); // It was an assume, now made an assert just to be sure we do not regress
|
||||||
|
|
|
@ -172,10 +172,10 @@ namespace Microsoft.Z3
|
||||||
Contract.Requires(patterns == null || Contract.ForAll(patterns, p => p != null));
|
Contract.Requires(patterns == null || Contract.ForAll(patterns, p => p != null));
|
||||||
Contract.Requires(noPatterns == null || Contract.ForAll(noPatterns, np => np != null));
|
Contract.Requires(noPatterns == null || Contract.ForAll(noPatterns, np => np != null));
|
||||||
|
|
||||||
Context.CheckContextMatch(patterns);
|
Context.CheckContextMatch<Pattern>(patterns);
|
||||||
Context.CheckContextMatch(noPatterns);
|
Context.CheckContextMatch<Expr>(noPatterns);
|
||||||
Context.CheckContextMatch(sorts);
|
Context.CheckContextMatch<Sort>(sorts);
|
||||||
Context.CheckContextMatch(names);
|
Context.CheckContextMatch<Symbol>(names);
|
||||||
Context.CheckContextMatch(body);
|
Context.CheckContextMatch(body);
|
||||||
|
|
||||||
if (sorts.Length != names.Length)
|
if (sorts.Length != names.Length)
|
||||||
|
@ -212,8 +212,8 @@ namespace Microsoft.Z3
|
||||||
Contract.Requires(noPatterns == null || Contract.ForAll(noPatterns, np => np != null));
|
Contract.Requires(noPatterns == null || Contract.ForAll(noPatterns, np => np != null));
|
||||||
Contract.Requires(bound == null || Contract.ForAll(bound, n => n != null));
|
Contract.Requires(bound == null || Contract.ForAll(bound, n => n != null));
|
||||||
|
|
||||||
Context.CheckContextMatch(noPatterns);
|
Context.CheckContextMatch<Expr>(noPatterns);
|
||||||
Context.CheckContextMatch(patterns);
|
Context.CheckContextMatch<Pattern>(patterns);
|
||||||
//Context.CheckContextMatch(bound);
|
//Context.CheckContextMatch(bound);
|
||||||
Context.CheckContextMatch(body);
|
Context.CheckContextMatch(body);
|
||||||
|
|
||||||
|
|
|
@ -111,7 +111,7 @@ namespace Microsoft.Z3
|
||||||
Contract.Requires(constraints != null);
|
Contract.Requires(constraints != null);
|
||||||
Contract.Requires(Contract.ForAll(constraints, c => c != null));
|
Contract.Requires(Contract.ForAll(constraints, c => c != null));
|
||||||
|
|
||||||
Context.CheckContextMatch(constraints);
|
Context.CheckContextMatch<BoolExpr>(constraints);
|
||||||
foreach (BoolExpr a in constraints)
|
foreach (BoolExpr a in constraints)
|
||||||
{
|
{
|
||||||
Native.Z3_solver_assert(Context.nCtx, NativeObject, a.NativeObject);
|
Native.Z3_solver_assert(Context.nCtx, NativeObject, a.NativeObject);
|
||||||
|
@ -142,8 +142,8 @@ namespace Microsoft.Z3
|
||||||
Contract.Requires(constraints != null);
|
Contract.Requires(constraints != null);
|
||||||
Contract.Requires(Contract.ForAll(constraints, c => c != null));
|
Contract.Requires(Contract.ForAll(constraints, c => c != null));
|
||||||
Contract.Requires(Contract.ForAll(ps, c => c != null));
|
Contract.Requires(Contract.ForAll(ps, c => c != null));
|
||||||
Context.CheckContextMatch(constraints);
|
Context.CheckContextMatch<BoolExpr>(constraints);
|
||||||
Context.CheckContextMatch(ps);
|
Context.CheckContextMatch<BoolExpr>(ps);
|
||||||
if (constraints.Length != ps.Length)
|
if (constraints.Length != ps.Length)
|
||||||
throw new Z3Exception("Argument size mismatch");
|
throw new Z3Exception("Argument size mismatch");
|
||||||
|
|
||||||
|
|
|
@ -138,7 +138,7 @@ namespace Microsoft.Z3
|
||||||
}
|
}
|
||||||
|
|
||||||
[Pure]
|
[Pure]
|
||||||
internal static IntPtr[] EnumToNative(IEnumerable<Z3Object> a)
|
internal static IntPtr[] EnumToNative<T>(IEnumerable<T> a) where T : Z3Object
|
||||||
{
|
{
|
||||||
Contract.Ensures(a == null || Contract.Result<IntPtr[]>() != null);
|
Contract.Ensures(a == null || Contract.Result<IntPtr[]>() != null);
|
||||||
Contract.Ensures(a == null || Contract.Result<IntPtr[]>().Length == a.Count());
|
Contract.Ensures(a == null || Contract.Result<IntPtr[]>().Length == a.Count());
|
||||||
|
|
|
@ -118,6 +118,8 @@ def _get_args(args):
|
||||||
try:
|
try:
|
||||||
if len(args) == 1 and (isinstance(args[0], tuple) or isinstance(args[0], list)):
|
if len(args) == 1 and (isinstance(args[0], tuple) or isinstance(args[0], list)):
|
||||||
return args[0]
|
return args[0]
|
||||||
|
elif len(args) == 1 and isinstance(args[0], set):
|
||||||
|
return [arg for arg in args[0]]
|
||||||
else:
|
else:
|
||||||
return args
|
return args
|
||||||
except: # len is not necessarily defined when args is not a sequence (use reflection?)
|
except: # len is not necessarily defined when args is not a sequence (use reflection?)
|
||||||
|
|
|
@ -78,7 +78,10 @@ void parameter::del_eh(ast_manager & m, family_id fid) {
|
||||||
}
|
}
|
||||||
else if (is_external()) {
|
else if (is_external()) {
|
||||||
SASSERT(fid != null_family_id);
|
SASSERT(fid != null_family_id);
|
||||||
m.get_plugin(fid)->del(*this);
|
decl_plugin * plugin = m.get_plugin(fid);
|
||||||
|
if (plugin) {
|
||||||
|
plugin->del(*this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1418,9 +1421,10 @@ ast_manager::~ast_manager() {
|
||||||
}
|
}
|
||||||
it = m_plugins.begin();
|
it = m_plugins.begin();
|
||||||
for (; it != end; ++it) {
|
for (; it != end; ++it) {
|
||||||
if (*it)
|
if (*it)
|
||||||
dealloc(*it);
|
dealloc(*it);
|
||||||
}
|
}
|
||||||
|
m_plugins.reset();
|
||||||
while (!m_ast_table.empty()) {
|
while (!m_ast_table.empty()) {
|
||||||
DEBUG_CODE(std::cout << "ast_manager LEAKED: " << m_ast_table.size() << std::endl;);
|
DEBUG_CODE(std::cout << "ast_manager LEAKED: " << m_ast_table.size() << std::endl;);
|
||||||
ptr_vector<ast> roots;
|
ptr_vector<ast> roots;
|
||||||
|
@ -1430,14 +1434,22 @@ ast_manager::~ast_manager() {
|
||||||
for (; it_a != end_a; ++it_a) {
|
for (; it_a != end_a; ++it_a) {
|
||||||
ast* n = (*it_a);
|
ast* n = (*it_a);
|
||||||
switch (n->get_kind()) {
|
switch (n->get_kind()) {
|
||||||
case AST_SORT:
|
case AST_SORT: {
|
||||||
mark_array_ref(mark, to_sort(n)->get_info()->get_num_parameters(), to_sort(n)->get_info()->get_parameters());
|
sort_info* info = to_sort(n)->get_info();
|
||||||
|
if (info != 0) {
|
||||||
|
mark_array_ref(mark, info->get_num_parameters(), info->get_parameters());
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case AST_FUNC_DECL:
|
}
|
||||||
mark_array_ref(mark, to_func_decl(n)->get_info()->get_num_parameters(), to_func_decl(n)->get_info()->get_parameters());
|
case AST_FUNC_DECL: {
|
||||||
|
func_decl_info* info = to_func_decl(n)->get_info();
|
||||||
|
if (info != 0) {
|
||||||
|
mark_array_ref(mark, info->get_num_parameters(), info->get_parameters());
|
||||||
|
}
|
||||||
mark_array_ref(mark, to_func_decl(n)->get_arity(), to_func_decl(n)->get_domain());
|
mark_array_ref(mark, to_func_decl(n)->get_arity(), to_func_decl(n)->get_domain());
|
||||||
mark.mark(to_func_decl(n)->get_range(), true);
|
mark.mark(to_func_decl(n)->get_range(), true);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case AST_APP:
|
case AST_APP:
|
||||||
mark.mark(to_app(n)->get_decl(), true);
|
mark.mark(to_app(n)->get_decl(), true);
|
||||||
mark_array_ref(mark, to_app(n)->get_num_args(), to_app(n)->get_args());
|
mark_array_ref(mark, to_app(n)->get_num_args(), to_app(n)->get_args());
|
||||||
|
@ -1857,8 +1869,8 @@ void ast_manager::delete_node(ast * n) {
|
||||||
dec_array_ref(worklist, to_quantifier(n)->get_num_patterns(), to_quantifier(n)->get_patterns());
|
dec_array_ref(worklist, to_quantifier(n)->get_num_patterns(), to_quantifier(n)->get_patterns());
|
||||||
dec_array_ref(worklist, to_quantifier(n)->get_num_no_patterns(), to_quantifier(n)->get_no_patterns());
|
dec_array_ref(worklist, to_quantifier(n)->get_num_no_patterns(), to_quantifier(n)->get_no_patterns());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (m_debug_ref_count) {
|
if (m_debug_ref_count) {
|
||||||
m_debug_free_indices.insert(n->m_id,0);
|
m_debug_free_indices.insert(n->m_id,0);
|
||||||
|
|
|
@ -732,7 +732,8 @@ void datatype_decl_plugin::get_op_names(svector<builtin_name> & op_names, symbol
|
||||||
datatype_util::datatype_util(ast_manager & m):
|
datatype_util::datatype_util(ast_manager & m):
|
||||||
m_manager(m),
|
m_manager(m),
|
||||||
m_family_id(m.mk_family_id("datatype")),
|
m_family_id(m.mk_family_id("datatype")),
|
||||||
m_asts(m) {
|
m_asts(m),
|
||||||
|
m_start(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
datatype_util::~datatype_util() {
|
datatype_util::~datatype_util() {
|
||||||
|
@ -807,11 +808,11 @@ func_decl * datatype_util::get_non_rec_constructor_core(sort * ty, ptr_vector<so
|
||||||
// If there is no such constructor, then we select one that
|
// If there is no such constructor, then we select one that
|
||||||
// 2) each type T_i is not recursive or contains a constructor that does not depend on T
|
// 2) each type T_i is not recursive or contains a constructor that does not depend on T
|
||||||
ptr_vector<func_decl> const * constructors = get_datatype_constructors(ty);
|
ptr_vector<func_decl> const * constructors = get_datatype_constructors(ty);
|
||||||
ptr_vector<func_decl>::const_iterator it = constructors->begin();
|
|
||||||
ptr_vector<func_decl>::const_iterator end = constructors->end();
|
|
||||||
// step 1)
|
// step 1)
|
||||||
for (; it != end; ++it) {
|
unsigned sz = constructors->size();
|
||||||
func_decl * c = *it;
|
++m_start;
|
||||||
|
for (unsigned j = 0; j < sz; ++j) {
|
||||||
|
func_decl * c = (*constructors)[(j + m_start) % sz];
|
||||||
unsigned num_args = c->get_arity();
|
unsigned num_args = c->get_arity();
|
||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
for (; i < num_args; i++) {
|
for (; i < num_args; i++) {
|
||||||
|
@ -823,9 +824,8 @@ func_decl * datatype_util::get_non_rec_constructor_core(sort * ty, ptr_vector<so
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
// step 2)
|
// step 2)
|
||||||
it = constructors->begin();
|
for (unsigned j = 0; j < sz; ++j) {
|
||||||
for (; it != end; ++it) {
|
func_decl * c = (*constructors)[(j + m_start) % sz];
|
||||||
func_decl * c = *it;
|
|
||||||
TRACE("datatype_util_bug", tout << "non_rec_constructor c: " << c->get_name() << "\n";);
|
TRACE("datatype_util_bug", tout << "non_rec_constructor c: " << c->get_name() << "\n";);
|
||||||
unsigned num_args = c->get_arity();
|
unsigned num_args = c->get_arity();
|
||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
|
@ -964,6 +964,7 @@ void datatype_util::reset() {
|
||||||
std::for_each(m_vectors.begin(), m_vectors.end(), delete_proc<ptr_vector<func_decl> >());
|
std::for_each(m_vectors.begin(), m_vectors.end(), delete_proc<ptr_vector<func_decl> >());
|
||||||
m_vectors.reset();
|
m_vectors.reset();
|
||||||
m_asts.reset();
|
m_asts.reset();
|
||||||
|
++m_start;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -176,7 +176,8 @@ class datatype_util {
|
||||||
obj_map<sort, bool> m_is_enum;
|
obj_map<sort, bool> m_is_enum;
|
||||||
ast_ref_vector m_asts;
|
ast_ref_vector m_asts;
|
||||||
ptr_vector<ptr_vector<func_decl> > m_vectors;
|
ptr_vector<ptr_vector<func_decl> > m_vectors;
|
||||||
|
unsigned m_start;
|
||||||
|
|
||||||
func_decl * get_non_rec_constructor_core(sort * ty, ptr_vector<sort> & forbidden_set);
|
func_decl * get_non_rec_constructor_core(sort * ty, ptr_vector<sort> & forbidden_set);
|
||||||
func_decl * get_constructor(sort * ty, unsigned c_id);
|
func_decl * get_constructor(sort * ty, unsigned c_id);
|
||||||
|
|
||||||
|
|
|
@ -458,28 +458,32 @@ void macro_util::normalize_expr(app * head, expr * t, expr_ref & norm_t) const {
|
||||||
expr_ref_buffer var_mapping(m_manager);
|
expr_ref_buffer var_mapping(m_manager);
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
unsigned num_args = head->get_num_args();
|
unsigned num_args = head->get_num_args();
|
||||||
unsigned max = num_args;
|
unsigned max_var_idx = 0;
|
||||||
for (unsigned i = 0; i < num_args; i++) {
|
for (unsigned i = 0; i < num_args; i++) {
|
||||||
var * v = to_var(head->get_arg(i));
|
var const * v = to_var(head->get_arg(i));
|
||||||
if (v->get_idx() >= max)
|
if (v->get_idx() > max_var_idx)
|
||||||
max = v->get_idx() + 1;
|
max_var_idx = v->get_idx();
|
||||||
}
|
}
|
||||||
TRACE("normalize_expr_bug",
|
TRACE("normalize_expr_bug",
|
||||||
tout << "head: " << mk_pp(head, m_manager) << "\n";
|
tout << "head: " << mk_pp(head, m_manager) << "\n";
|
||||||
tout << "applying substitution to:\n" << mk_bounded_pp(t, m_manager) << "\n";);
|
tout << "applying substitution to:\n" << mk_bounded_pp(t, m_manager) << "\n";);
|
||||||
for (unsigned i = 0; i < num_args; i++) {
|
for (unsigned i = 0; i < num_args; i++) {
|
||||||
var * v = to_var(head->get_arg(i));
|
var * v = to_var(head->get_arg(i));
|
||||||
if (v->get_idx() != i) {
|
if (v->get_idx() != i) {
|
||||||
changed = true;
|
changed = true;
|
||||||
var * new_var = m_manager.mk_var(i, v->get_sort());
|
var_ref new_var(m_manager.mk_var(i, v->get_sort()), m_manager);
|
||||||
CTRACE("normalize_expr_bug", v->get_idx() >= num_args, tout << mk_pp(v, m_manager) << ", num_args: " << num_args << "\n";);
|
var_mapping.setx(max_var_idx - v->get_idx(), new_var);
|
||||||
SASSERT(v->get_idx() < max);
|
|
||||||
var_mapping.setx(max - v->get_idx() - 1, new_var);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var_mapping.setx(max - i - 1, v);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
var_mapping.setx(max_var_idx - i, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (unsigned i = num_args; i <= max_var_idx; i++)
|
||||||
|
// CMW: Won't be used, but dictates a larger binding size,
|
||||||
|
// so that the indexes between here and in the rewriter match.
|
||||||
|
// It's possible that we don't see the true max idx of all vars here.
|
||||||
|
var_mapping.setx(max_var_idx - i, 0);
|
||||||
|
|
||||||
if (changed) {
|
if (changed) {
|
||||||
// REMARK: t may have nested quantifiers... So, I must use the std order for variable substitution.
|
// REMARK: t may have nested quantifiers... So, I must use the std order for variable substitution.
|
||||||
var_subst subst(m_manager, true);
|
var_subst subst(m_manager, true);
|
||||||
|
@ -488,7 +492,7 @@ void macro_util::normalize_expr(app * head, expr * t, expr_ref & norm_t) const {
|
||||||
tout << "applying substitution to:\n" << mk_ll_pp(t, m_manager) << "\nsubstitution:\n";
|
tout << "applying substitution to:\n" << mk_ll_pp(t, m_manager) << "\nsubstitution:\n";
|
||||||
for (unsigned i = 0; i < var_mapping.size(); i++) {
|
for (unsigned i = 0; i < var_mapping.size(); i++) {
|
||||||
if (var_mapping[i] != 0)
|
if (var_mapping[i] != 0)
|
||||||
tout << "#" << i << " -> " << mk_pp(var_mapping[i], m_manager) << "\n";
|
tout << "#" << i << " -> " << mk_ll_pp(var_mapping[i], m_manager);
|
||||||
});
|
});
|
||||||
subst(t, var_mapping.size(), var_mapping.c_ptr(), norm_t);
|
subst(t, var_mapping.size(), var_mapping.c_ptr(), norm_t);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,4 +16,5 @@ def_module_params('pp',
|
||||||
('fixed_indent', BOOL, False, 'use a fixed indentation for applications'),
|
('fixed_indent', BOOL, False, 'use a fixed indentation for applications'),
|
||||||
('single_line', BOOL, False, 'ignore line breaks when true'),
|
('single_line', BOOL, False, 'ignore line breaks when true'),
|
||||||
('bounded', BOOL, False, 'ignore characters exceeding max width'),
|
('bounded', BOOL, False, 'ignore characters exceeding max width'),
|
||||||
|
('pretty_proof', BOOL, False, 'use slower, but prettier, printer for proofs'),
|
||||||
('simplify_implies', BOOL, True, 'simplify nested implications for pretty printing')))
|
('simplify_implies', BOOL, True, 'simplify nested implications for pretty printing')))
|
||||||
|
|
|
@ -144,6 +144,9 @@ zstring zstring::replace(zstring const& src, zstring const& dst) const {
|
||||||
if (length() < src.length()) {
|
if (length() < src.length()) {
|
||||||
return zstring(*this);
|
return zstring(*this);
|
||||||
}
|
}
|
||||||
|
if (src.length() == 0) {
|
||||||
|
return zstring(*this);
|
||||||
|
}
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (unsigned i = 0; i < length(); ++i) {
|
for (unsigned i = 0; i < length(); ++i) {
|
||||||
bool eq = !found && i + src.length() <= length();
|
bool eq = !found && i + src.length() <= length();
|
||||||
|
|
|
@ -29,6 +29,7 @@ Notes:
|
||||||
#include"gparams.h"
|
#include"gparams.h"
|
||||||
#include"env_params.h"
|
#include"env_params.h"
|
||||||
#include"well_sorted.h"
|
#include"well_sorted.h"
|
||||||
|
#include"pp_params.hpp"
|
||||||
|
|
||||||
class help_cmd : public cmd {
|
class help_cmd : public cmd {
|
||||||
svector<symbol> m_cmds;
|
svector<symbol> m_cmds;
|
||||||
|
@ -161,14 +162,19 @@ ATOMIC_CMD(get_proof_cmd, "get-proof", "retrieve proof", {
|
||||||
throw cmd_exception("proof is not well sorted");
|
throw cmd_exception("proof is not well sorted");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: reimplement a new SMT2 pretty printer
|
pp_params params;
|
||||||
ast_smt_pp pp(ctx.m());
|
if (params.pretty_proof()) {
|
||||||
cmd_is_declared isd(ctx);
|
ctx.regular_stream() << mk_pp(pr, ctx.m()) << std::endl;
|
||||||
pp.set_is_declared(&isd);
|
}
|
||||||
pp.set_logic(ctx.get_logic());
|
else {
|
||||||
// ctx.regular_stream() << mk_pp(pr, ctx.m()) << "\n";
|
// TODO: reimplement a new SMT2 pretty printer
|
||||||
pp.display_smt2(ctx.regular_stream(), pr);
|
ast_smt_pp pp(ctx.m());
|
||||||
ctx.regular_stream() << std::endl;
|
cmd_is_declared isd(ctx);
|
||||||
|
pp.set_is_declared(&isd);
|
||||||
|
pp.set_logic(ctx.get_logic());
|
||||||
|
pp.display_smt2(ctx.regular_stream(), pr);
|
||||||
|
ctx.regular_stream() << std::endl;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
#define PRINT_CORE() \
|
#define PRINT_CORE() \
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
#include"mpq.h"
|
#include"mpq.h"
|
||||||
#include"expr2var.h"
|
#include"expr2var.h"
|
||||||
#include"pp.h"
|
#include"pp.h"
|
||||||
#include"pp_params.hpp"
|
|
||||||
#include"iz3interp.h"
|
#include"iz3interp.h"
|
||||||
#include"iz3checker.h"
|
#include"iz3checker.h"
|
||||||
#include"iz3profiling.h"
|
#include"iz3profiling.h"
|
||||||
|
|
|
@ -72,7 +72,7 @@ namespace datalog {
|
||||||
}
|
}
|
||||||
e->get_data().m_value->push_back(cur);
|
e->get_data().m_value->push_back(cur);
|
||||||
}
|
}
|
||||||
if (cur->get_uninterpreted_tail_size() == 0) {
|
if (cur->get_positive_tail_size() == 0) {
|
||||||
func_decl *sym = cur->get_head()->get_decl();
|
func_decl *sym = cur->get_head()->get_decl();
|
||||||
bool new_info = m_facts.insert_if_not_there2(sym, Fact())->get_data().m_value.init_up(m_context, cur);
|
bool new_info = m_facts.insert_if_not_there2(sym, Fact())->get_data().m_value.init_up(m_context, cur);
|
||||||
if (new_info) {
|
if (new_info) {
|
||||||
|
@ -97,7 +97,7 @@ namespace datalog {
|
||||||
}
|
}
|
||||||
|
|
||||||
void step_bottom_up() {
|
void step_bottom_up() {
|
||||||
for(todo_set::iterator I = m_todo[m_todo_idx].begin(),
|
for(todo_set::iterator I = m_todo[m_todo_idx].begin(),
|
||||||
E = m_todo[m_todo_idx].end(); I!=E; ++I) {
|
E = m_todo[m_todo_idx].end(); I!=E; ++I) {
|
||||||
ptr_vector<rule> * rules;
|
ptr_vector<rule> * rules;
|
||||||
if (!m_body2rules.find(*I, rules))
|
if (!m_body2rules.find(*I, rules))
|
||||||
|
@ -236,7 +236,7 @@ namespace datalog {
|
||||||
return m_facts.get(m_rule->get_decl(idx), Fact::null_fact);
|
return m_facts.get(m_rule->get_decl(idx), Fact::null_fact);
|
||||||
}
|
}
|
||||||
unsigned size() const {
|
unsigned size() const {
|
||||||
return m_rule->get_uninterpreted_tail_size();
|
return m_rule->get_positive_tail_size();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,7 @@ namespace datalog {
|
||||||
if (m_context.has_facts(r->get_decl(i))) {
|
if (m_context.has_facts(r->get_decl(i))) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r->is_neg_tail(i)) {
|
if (r->is_neg_tail(i)) {
|
||||||
if (!engine.get_fact(r->get_decl(i)).is_reachable()) {
|
if (!engine.get_fact(r->get_decl(i)).is_reachable()) {
|
||||||
if (!new_tail) {
|
if (!new_tail) {
|
||||||
|
@ -53,11 +54,14 @@ namespace datalog {
|
||||||
}
|
}
|
||||||
new_tail = true;
|
new_tail = true;
|
||||||
}
|
}
|
||||||
} else if (new_tail) {
|
}
|
||||||
|
else if (new_tail) {
|
||||||
m_new_tail.push_back(r->get_tail(i));
|
m_new_tail.push_back(r->get_tail(i));
|
||||||
m_new_tail_neg.push_back(true);
|
m_new_tail_neg.push_back(true);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
SASSERT(!new_tail);
|
SASSERT(!new_tail);
|
||||||
if (!engine.get_fact(r->get_decl(i)).is_reachable()) {
|
if (!engine.get_fact(r->get_decl(i)).is_reachable()) {
|
||||||
contained = false;
|
contained = false;
|
||||||
|
|
|
@ -1573,7 +1573,8 @@ private:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expr * p = m_manager.mk_pattern(ts.size(), (app*const*)(ts.c_ptr()));
|
expr_ref p(m_manager);
|
||||||
|
p = m_manager.mk_pattern(ts.size(), (app*const*)(ts.c_ptr()));
|
||||||
if (!p || (!ignore_user_patterns() && !m_pattern_validator(num_bindings, p, children[0]->line(), children[0]->pos()))) {
|
if (!p || (!ignore_user_patterns() && !m_pattern_validator(num_bindings, p, children[0]->line(), children[0]->pos()))) {
|
||||||
set_error("invalid pattern", children[0]);
|
set_error("invalid pattern", children[0]);
|
||||||
return false;
|
return false;
|
||||||
|
@ -1581,8 +1582,11 @@ private:
|
||||||
patterns.push_back(p);
|
patterns.push_back(p);
|
||||||
}
|
}
|
||||||
else if (children[0]->string() == symbol("ex_act") && ts.size() == 1) {
|
else if (children[0]->string() == symbol("ex_act") && ts.size() == 1) {
|
||||||
app * sk_hack = m_manager.mk_app(m_sk_hack, 1, ts.c_ptr());
|
app_ref sk_hack(m_manager);
|
||||||
expr * p = m_manager.mk_pattern(1, &sk_hack);
|
sk_hack = m_manager.mk_app(m_sk_hack, 1, ts.c_ptr());
|
||||||
|
app * sk_hackp = sk_hack.get();
|
||||||
|
expr_ref p(m_manager);
|
||||||
|
p = m_manager.mk_pattern(1, &sk_hackp);
|
||||||
if (!p || (!ignore_user_patterns() && !m_pattern_validator(num_bindings, p, children[0]->line(), children[0]->pos()))) {
|
if (!p || (!ignore_user_patterns() && !m_pattern_validator(num_bindings, p, children[0]->line(), children[0]->pos()))) {
|
||||||
set_error("invalid pattern", children[0]);
|
set_error("invalid pattern", children[0]);
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -493,14 +493,14 @@ namespace sat {
|
||||||
void bceq::operator()() {
|
void bceq::operator()() {
|
||||||
if (!m_solver.m_config.m_bcd) return;
|
if (!m_solver.m_config.m_bcd) return;
|
||||||
flet<bool> _disable_bcd(m_solver.m_config.m_bcd, false);
|
flet<bool> _disable_bcd(m_solver.m_config.m_bcd, false);
|
||||||
flet<bool> _disable_min(m_solver.m_config.m_minimize_core, false);
|
flet<bool> _disable_min(m_solver.m_config.m_core_minimize, false);
|
||||||
flet<bool> _disable_opt(m_solver.m_config.m_optimize_model, false);
|
flet<bool> _disable_opt(m_solver.m_config.m_optimize_model, false);
|
||||||
flet<unsigned> _bound_maxc(m_solver.m_config.m_max_conflicts, 1500);
|
flet<unsigned> _bound_maxc(m_solver.m_config.m_max_conflicts, 1500);
|
||||||
|
|
||||||
use_list ul;
|
use_list ul;
|
||||||
solver s(m_solver.m_params, m_solver.rlimit(), 0);
|
solver s(m_solver.m_params, m_solver.rlimit(), 0);
|
||||||
s.m_config.m_bcd = false;
|
s.m_config.m_bcd = false;
|
||||||
s.m_config.m_minimize_core = false;
|
s.m_config.m_core_minimize = false;
|
||||||
s.m_config.m_optimize_model = false;
|
s.m_config.m_optimize_model = false;
|
||||||
s.m_config.m_max_conflicts = 1500;
|
s.m_config.m_max_conflicts = 1500;
|
||||||
m_use_list = &ul;
|
m_use_list = &ul;
|
||||||
|
|
|
@ -107,8 +107,8 @@ namespace sat {
|
||||||
m_gc_increment = p.gc_increment();
|
m_gc_increment = p.gc_increment();
|
||||||
}
|
}
|
||||||
m_minimize_lemmas = p.minimize_lemmas();
|
m_minimize_lemmas = p.minimize_lemmas();
|
||||||
m_minimize_core = p.minimize_core();
|
m_core_minimize = p.core_minimize();
|
||||||
m_minimize_core_partial = p.minimize_core_partial();
|
m_core_minimize_partial = p.core_minimize_partial();
|
||||||
m_optimize_model = p.optimize_model();
|
m_optimize_model = p.optimize_model();
|
||||||
m_bcd = p.bcd();
|
m_bcd = p.bcd();
|
||||||
m_dyn_sub_res = p.dyn_sub_res();
|
m_dyn_sub_res = p.dyn_sub_res();
|
||||||
|
|
|
@ -69,8 +69,8 @@ namespace sat {
|
||||||
|
|
||||||
bool m_minimize_lemmas;
|
bool m_minimize_lemmas;
|
||||||
bool m_dyn_sub_res;
|
bool m_dyn_sub_res;
|
||||||
bool m_minimize_core;
|
bool m_core_minimize;
|
||||||
bool m_minimize_core_partial;
|
bool m_core_minimize_partial;
|
||||||
bool m_optimize_model;
|
bool m_optimize_model;
|
||||||
bool m_bcd;
|
bool m_bcd;
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ namespace sat {
|
||||||
}
|
}
|
||||||
|
|
||||||
lbool mus::operator()() {
|
lbool mus::operator()() {
|
||||||
flet<bool> _disable_min(s.m_config.m_minimize_core, false);
|
flet<bool> _disable_min(s.m_config.m_core_minimize, false);
|
||||||
flet<bool> _disable_opt(s.m_config.m_optimize_model, false);
|
flet<bool> _disable_opt(s.m_config.m_optimize_model, false);
|
||||||
flet<bool> _is_active(m_is_active, true);
|
flet<bool> _is_active(m_is_active, true);
|
||||||
IF_VERBOSE(3, verbose_stream() << "(sat.mus " << s.get_core() << ")\n";);
|
IF_VERBOSE(3, verbose_stream() << "(sat.mus " << s.get_core() << ")\n";);
|
||||||
|
@ -69,7 +69,7 @@ namespace sat {
|
||||||
}
|
}
|
||||||
|
|
||||||
lbool mus::mus1() {
|
lbool mus::mus1() {
|
||||||
bool minimize_partial = s.m_config.m_minimize_core_partial;
|
bool minimize_partial = s.m_config.m_core_minimize_partial;
|
||||||
TRACE("sat", tout << "old core: " << s.get_core() << "\n";);
|
TRACE("sat", tout << "old core: " << s.get_core() << "\n";);
|
||||||
literal_vector& core = get_core();
|
literal_vector& core = get_core();
|
||||||
literal_vector& mus = m_mus;
|
literal_vector& mus = m_mus;
|
||||||
|
@ -96,7 +96,7 @@ namespace sat {
|
||||||
// IF_VERBOSE(0, verbose_stream() << "num literals: " << core << " " << mus << "\n";);
|
// IF_VERBOSE(0, verbose_stream() << "num literals: " << core << " " << mus << "\n";);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (s.m_config.m_minimize_core_partial && s.m_stats.m_restart - m_restart > m_max_restarts) {
|
if (s.m_config.m_core_minimize_partial && s.m_stats.m_restart - m_restart > m_max_restarts) {
|
||||||
IF_VERBOSE(1, verbose_stream() << "(sat restart budget exceeded)\n";);
|
IF_VERBOSE(1, verbose_stream() << "(sat restart budget exceeded)\n";);
|
||||||
set_core();
|
set_core();
|
||||||
return l_true;
|
return l_true;
|
||||||
|
@ -172,7 +172,7 @@ namespace sat {
|
||||||
|
|
||||||
lbool mus::qx(literal_set& assignment, literal_set& support, bool has_support) {
|
lbool mus::qx(literal_set& assignment, literal_set& support, bool has_support) {
|
||||||
lbool is_sat = l_true;
|
lbool is_sat = l_true;
|
||||||
if (s.m_config.m_minimize_core_partial && s.m_stats.m_restart - m_restart > m_max_restarts) {
|
if (s.m_config.m_core_minimize_partial && s.m_stats.m_restart - m_restart > m_max_restarts) {
|
||||||
IF_VERBOSE(1, verbose_stream() << "(sat restart budget exceeded)\n";);
|
IF_VERBOSE(1, verbose_stream() << "(sat restart budget exceeded)\n";);
|
||||||
return l_true;
|
return l_true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,8 +19,8 @@ def_module_params('sat',
|
||||||
('gc.k', UINT, 7, 'learned clauses that are inactive for k gc rounds are permanently deleted (only used in dyn_psm)'),
|
('gc.k', UINT, 7, 'learned clauses that are inactive for k gc rounds are permanently deleted (only used in dyn_psm)'),
|
||||||
('minimize_lemmas', BOOL, True, 'minimize learned clauses'),
|
('minimize_lemmas', BOOL, True, 'minimize learned clauses'),
|
||||||
('dyn_sub_res', BOOL, True, 'dynamic subsumption resolution for minimizing learned clauses'),
|
('dyn_sub_res', BOOL, True, 'dynamic subsumption resolution for minimizing learned clauses'),
|
||||||
('minimize_core', BOOL, False, 'minimize computed core'),
|
('core.minimize', BOOL, False, 'minimize computed core'),
|
||||||
('minimize_core_partial', BOOL, False, 'apply partial (cheap) core minimization'),
|
('core.minimize_partial', BOOL, False, 'apply partial (cheap) core minimization'),
|
||||||
('optimize_model', BOOL, False, 'enable optimization of soft constraints'),
|
('optimize_model', BOOL, False, 'enable optimization of soft constraints'),
|
||||||
('bcd', BOOL, False, 'enable blocked clause decomposition for equality extraction'),
|
('bcd', BOOL, False, 'enable blocked clause decomposition for equality extraction'),
|
||||||
('dimacs.core', BOOL, False, 'extract core from DIMACS benchmarks')))
|
('dimacs.core', BOOL, False, 'extract core from DIMACS benchmarks')))
|
||||||
|
|
|
@ -937,7 +937,7 @@ namespace sat {
|
||||||
|
|
||||||
|
|
||||||
bool solver::init_weighted_assumptions(unsigned num_lits, literal const* lits, double const* weights, double max_weight) {
|
bool solver::init_weighted_assumptions(unsigned num_lits, literal const* lits, double const* weights, double max_weight) {
|
||||||
flet<bool> _min1(m_config.m_minimize_core, false);
|
flet<bool> _min1(m_config.m_core_minimize, false);
|
||||||
m_weight = 0;
|
m_weight = 0;
|
||||||
m_blocker.reset();
|
m_blocker.reset();
|
||||||
svector<lbool> values;
|
svector<lbool> values;
|
||||||
|
@ -2015,7 +2015,7 @@ namespace sat {
|
||||||
idx--;
|
idx--;
|
||||||
}
|
}
|
||||||
reset_unmark(old_size);
|
reset_unmark(old_size);
|
||||||
if (m_config.m_minimize_core) {
|
if (m_config.m_core_minimize) {
|
||||||
if (m_min_core_valid && m_min_core.size() < m_core.size()) {
|
if (m_min_core_valid && m_min_core.size() < m_core.size()) {
|
||||||
IF_VERBOSE(1, verbose_stream() << "(sat.updating core " << m_min_core.size() << " " << m_core.size() << ")\n";);
|
IF_VERBOSE(1, verbose_stream() << "(sat.updating core " << m_min_core.size() << " " << m_core.size() << ")\n";);
|
||||||
m_core.reset();
|
m_core.reset();
|
||||||
|
|
|
@ -403,7 +403,6 @@ namespace smt {
|
||||||
// the previous levels were already inconsistent, or the inconsistency was
|
// the previous levels were already inconsistent, or the inconsistency was
|
||||||
// triggered by an axiom or justification proof wrapper, this two kinds
|
// triggered by an axiom or justification proof wrapper, this two kinds
|
||||||
// of justification are considered level zero.
|
// of justification are considered level zero.
|
||||||
|
|
||||||
if (m_conflict_lvl <= m_ctx.get_search_level()) {
|
if (m_conflict_lvl <= m_ctx.get_search_level()) {
|
||||||
TRACE("conflict", tout << "problem is unsat\n";);
|
TRACE("conflict", tout << "problem is unsat\n";);
|
||||||
if (m_manager.proofs_enabled())
|
if (m_manager.proofs_enabled())
|
||||||
|
|
|
@ -18,6 +18,8 @@ Revision History:
|
||||||
--*/
|
--*/
|
||||||
#include "smt_context.h"
|
#include "smt_context.h"
|
||||||
#include "ast_util.h"
|
#include "ast_util.h"
|
||||||
|
#include "datatype_decl_plugin.h"
|
||||||
|
#include "model_pp.h"
|
||||||
|
|
||||||
namespace smt {
|
namespace smt {
|
||||||
|
|
||||||
|
@ -31,77 +33,112 @@ namespace smt {
|
||||||
return mk_and(premises);
|
return mk_and(premises);
|
||||||
}
|
}
|
||||||
|
|
||||||
void context::extract_fixed_consequences(unsigned start, obj_map<expr, expr*>& vars, uint_set const& assumptions, expr_ref_vector& conseq) {
|
//
|
||||||
|
// The literal lit is assigned at the search level, so it follows from the assumptions.
|
||||||
|
// We retrieve the set of assumptions it depends on in the set 's'.
|
||||||
|
// The map m_antecedents contains the association from these literals to the assumptions they depend on.
|
||||||
|
// We then examine the contents of the literal lit and augment the set of consequences in one of the following cases:
|
||||||
|
// - e is a propositional atom and it is one of the variables that is to be fixed.
|
||||||
|
// - e is an equality between a variable and value that is to be fixed.
|
||||||
|
// - e is a data-type recognizer of a variable that is to be fixed.
|
||||||
|
//
|
||||||
|
void context::extract_fixed_consequences(literal lit, obj_map<expr, expr*>& vars, uint_set const& assumptions, expr_ref_vector& conseq) {
|
||||||
ast_manager& m = m_manager;
|
ast_manager& m = m_manager;
|
||||||
pop_to_search_lvl();
|
datatype_util dt(m);
|
||||||
literal_vector const& lits = assigned_literals();
|
|
||||||
unsigned sz = lits.size();
|
|
||||||
expr* e1, *e2;
|
expr* e1, *e2;
|
||||||
expr_ref fml(m);
|
expr_ref fml(m);
|
||||||
for (unsigned i = start; i < sz; ++i) {
|
if (lit == true_literal) return;
|
||||||
literal lit = lits[i];
|
expr* e = bool_var2expr(lit.var());
|
||||||
if (lit == true_literal) continue;
|
uint_set s;
|
||||||
expr* e = bool_var2expr(lit.var());
|
if (assumptions.contains(lit.var())) {
|
||||||
uint_set s;
|
s.insert(lit.var());
|
||||||
if (assumptions.contains(lit.var())) {
|
}
|
||||||
s.insert(lit.var());
|
else {
|
||||||
}
|
b_justification js = get_justification(lit.var());
|
||||||
else {
|
switch (js.get_kind()) {
|
||||||
b_justification js = get_justification(lit.var());
|
case b_justification::CLAUSE: {
|
||||||
switch (js.get_kind()) {
|
clause * cls = js.get_clause();
|
||||||
case b_justification::CLAUSE: {
|
if (!cls) break;
|
||||||
clause * cls = js.get_clause();
|
unsigned num_lits = cls->get_num_literals();
|
||||||
unsigned num_lits = cls->get_num_literals();
|
for (unsigned j = 0; j < num_lits; ++j) {
|
||||||
for (unsigned j = 0; j < num_lits; ++j) {
|
literal lit2 = cls->get_literal(j);
|
||||||
literal lit2 = cls->get_literal(j);
|
if (lit2.var() != lit.var()) {
|
||||||
if (lit2.var() != lit.var()) {
|
s |= m_antecedents.find(lit2.var());
|
||||||
s |= m_antecedents.find(lit2.var());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case b_justification::BIN_CLAUSE: {
|
break;
|
||||||
s |= m_antecedents.find(js.get_literal().var());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case b_justification::AXIOM: {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case b_justification::JUSTIFICATION: {
|
|
||||||
literal_vector literals;
|
|
||||||
m_conflict_resolution->justification2literals(js.get_justification(), literals);
|
|
||||||
for (unsigned j = 0; j < literals.size(); ++j) {
|
|
||||||
s |= m_antecedents.find(literals[j].var());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_antecedents.insert(lit.var(), s);
|
|
||||||
TRACE("context", display_literal_verbose(tout, lit); tout << " " << s << "\n";);
|
|
||||||
bool found = false;
|
|
||||||
if (vars.contains(e)) {
|
|
||||||
found = true;
|
|
||||||
fml = lit.sign()?m.mk_not(e):e;
|
|
||||||
vars.erase(e);
|
|
||||||
}
|
}
|
||||||
else if (!lit.sign() && m.is_eq(e, e1, e2)) {
|
case b_justification::BIN_CLAUSE: {
|
||||||
if (vars.contains(e2)) {
|
s |= m_antecedents.find(js.get_literal().var());
|
||||||
std::swap(e1, e2);
|
break;
|
||||||
}
|
}
|
||||||
if (vars.contains(e1) && m.is_value(e2)) {
|
case b_justification::AXIOM: {
|
||||||
found = true;
|
break;
|
||||||
fml = e;
|
}
|
||||||
vars.erase(e1);
|
case b_justification::JUSTIFICATION: {
|
||||||
}
|
literal_vector literals;
|
||||||
|
m_conflict_resolution->justification2literals(js.get_justification(), literals);
|
||||||
|
for (unsigned j = 0; j < literals.size(); ++j) {
|
||||||
|
s |= m_antecedents.find(literals[j].var());
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (found) {
|
|
||||||
fml = m.mk_implies(antecedent2fml(s), fml);
|
|
||||||
conseq.push_back(fml);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
m_antecedents.insert(lit.var(), s);
|
||||||
|
TRACE("context", display_literal_verbose(tout, lit); tout << " " << s << "\n";);
|
||||||
|
bool found = false;
|
||||||
|
if (vars.contains(e)) {
|
||||||
|
found = true;
|
||||||
|
fml = lit.sign() ? m.mk_not(e) : e;
|
||||||
|
vars.erase(e);
|
||||||
|
}
|
||||||
|
else if (!lit.sign() && m.is_eq(e, e1, e2)) {
|
||||||
|
if (vars.contains(e2)) {
|
||||||
|
std::swap(e1, e2);
|
||||||
|
}
|
||||||
|
if (vars.contains(e1) && m.is_value(e2)) {
|
||||||
|
found = true;
|
||||||
|
fml = e;
|
||||||
|
vars.erase(e1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!lit.sign() && is_app(e) && dt.is_recognizer(to_app(e)->get_decl())) {
|
||||||
|
if (vars.contains(to_app(e)->get_arg(0))) {
|
||||||
|
found = true;
|
||||||
|
fml = m.mk_eq(to_app(e)->get_arg(0), m.mk_const(dt.get_recognizer_constructor(to_app(e)->get_decl())));
|
||||||
|
vars.erase(to_app(e)->get_arg(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found) {
|
||||||
|
fml = m.mk_implies(antecedent2fml(s), fml);
|
||||||
|
conseq.push_back(fml);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void context::extract_fixed_consequences(unsigned start, obj_map<expr, expr*>& vars, uint_set const& assumptions, expr_ref_vector& conseq) {
|
||||||
|
pop_to_search_lvl();
|
||||||
|
SASSERT(!inconsistent());
|
||||||
|
literal_vector const& lits = assigned_literals();
|
||||||
|
unsigned sz = lits.size();
|
||||||
|
for (unsigned i = start; i < sz; ++i) {
|
||||||
|
extract_fixed_consequences(lits[i], vars, assumptions, conseq);
|
||||||
|
}
|
||||||
|
SASSERT(!inconsistent());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// The assignment stack is assumed consistent.
|
||||||
|
// For each Boolean variable, we check if there is a literal assigned to the
|
||||||
|
// opposite value of the reference model, and for non-Boolean variables we
|
||||||
|
// check if the current state forces the variable to be distinct from the reference value.
|
||||||
|
//
|
||||||
|
// For yet to be determined Boolean variables we furthermore force the phase to be opposite
|
||||||
|
// to the reference value in the attempt to let the sat engine emerge with a model that
|
||||||
|
// rules out as many non-fixed variables as possible.
|
||||||
|
//
|
||||||
|
|
||||||
unsigned context::delete_unfixed(obj_map<expr, expr*>& var2val, expr_ref_vector& unfixed) {
|
unsigned context::delete_unfixed(obj_map<expr, expr*>& var2val, expr_ref_vector& unfixed) {
|
||||||
ast_manager& m = m_manager;
|
ast_manager& m = m_manager;
|
||||||
ptr_vector<expr> to_delete;
|
ptr_vector<expr> to_delete;
|
||||||
|
@ -144,10 +181,15 @@ namespace smt {
|
||||||
return to_delete.size();
|
return to_delete.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define are_equal(v, k) (e_internalized(k) && e_internalized(v) && get_enode(k)->get_root() == get_enode(v)->get_root())
|
||||||
|
|
||||||
//
|
//
|
||||||
// Extract equalities that are congruent at the search level.
|
// Extract equalities that are congruent at the search level.
|
||||||
|
// Add a clause to short-circuit the congruence justifications for
|
||||||
|
// next rounds.
|
||||||
//
|
//
|
||||||
unsigned context::extract_fixed_eqs(obj_map<expr, expr*>& var2val, expr_ref_vector& conseq) {
|
unsigned context::extract_fixed_eqs(obj_map<expr, expr*>& var2val, expr_ref_vector& conseq) {
|
||||||
|
TRACE("context", tout << "extract fixed consequences\n";);
|
||||||
ast_manager& m = m_manager;
|
ast_manager& m = m_manager;
|
||||||
ptr_vector<expr> to_delete;
|
ptr_vector<expr> to_delete;
|
||||||
expr_ref fml(m), eq(m);
|
expr_ref fml(m), eq(m);
|
||||||
|
@ -155,8 +197,7 @@ namespace smt {
|
||||||
for (; it != end; ++it) {
|
for (; it != end; ++it) {
|
||||||
expr* k = it->m_key;
|
expr* k = it->m_key;
|
||||||
expr* v = it->m_value;
|
expr* v = it->m_value;
|
||||||
if (!m.is_bool(k) && e_internalized(k) && e_internalized(v) &&
|
if (!m.is_bool(k) && are_equal(k, v)) {
|
||||||
get_enode(k)->get_root() == get_enode(v)->get_root()) {
|
|
||||||
literal_vector literals;
|
literal_vector literals;
|
||||||
m_conflict_resolution->eq2literals(get_enode(v), get_enode(k), literals);
|
m_conflict_resolution->eq2literals(get_enode(v), get_enode(k), literals);
|
||||||
uint_set s;
|
uint_set s;
|
||||||
|
@ -175,9 +216,10 @@ namespace smt {
|
||||||
}
|
}
|
||||||
eq = mk_eq_atom(k, v);
|
eq = mk_eq_atom(k, v);
|
||||||
internalize_formula(eq, false);
|
internalize_formula(eq, false);
|
||||||
literal lit(get_bool_var(eq), true);
|
literal lit(get_bool_var(eq), false);
|
||||||
literals.push_back(lit);
|
literals.push_back(lit);
|
||||||
mk_clause(literals.size(), literals.c_ptr(), 0);
|
mk_clause(literals.size(), literals.c_ptr(), 0);
|
||||||
|
TRACE("context", display_literals_verbose(tout, literals.size(), literals.c_ptr()););
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (unsigned i = 0; i < to_delete.size(); ++i) {
|
for (unsigned i = 0; i < to_delete.size(); ++i) {
|
||||||
|
@ -192,6 +234,7 @@ namespace smt {
|
||||||
expr_ref_vector& unfixed) {
|
expr_ref_vector& unfixed) {
|
||||||
|
|
||||||
m_antecedents.reset();
|
m_antecedents.reset();
|
||||||
|
pop_to_base_lvl();
|
||||||
lbool is_sat = check(assumptions.size(), assumptions.c_ptr());
|
lbool is_sat = check(assumptions.size(), assumptions.c_ptr());
|
||||||
if (is_sat != l_true) {
|
if (is_sat != l_true) {
|
||||||
return is_sat;
|
return is_sat;
|
||||||
|
@ -207,6 +250,7 @@ namespace smt {
|
||||||
expr_ref_vector trail(m);
|
expr_ref_vector trail(m);
|
||||||
model_evaluator eval(*mdl.get());
|
model_evaluator eval(*mdl.get());
|
||||||
expr_ref val(m);
|
expr_ref val(m);
|
||||||
|
TRACE("context", model_pp(tout, *mdl););
|
||||||
for (unsigned i = 0; i < vars.size(); ++i) {
|
for (unsigned i = 0; i < vars.size(); ++i) {
|
||||||
eval(vars[i], val);
|
eval(vars[i], val);
|
||||||
if (m.is_value(val)) {
|
if (m.is_value(val)) {
|
||||||
|
@ -233,9 +277,17 @@ namespace smt {
|
||||||
obj_map<expr,expr*>::iterator it = var2val.begin();
|
obj_map<expr,expr*>::iterator it = var2val.begin();
|
||||||
expr* e = it->m_key;
|
expr* e = it->m_key;
|
||||||
expr* val = it->m_value;
|
expr* val = it->m_value;
|
||||||
push_scope();
|
|
||||||
unsigned current_level = m_scope_lvl;
|
|
||||||
|
|
||||||
|
TRACE("context", tout << "scope level: " << get_scope_level() << "\n";);
|
||||||
|
SASSERT(!inconsistent());
|
||||||
|
|
||||||
|
//
|
||||||
|
// The current variable is checked to be a backbone
|
||||||
|
// We add the negation of the reference assignment to the variable.
|
||||||
|
// If the variable is a Boolean, it means adding literal that has
|
||||||
|
// the opposite value of the current reference model.
|
||||||
|
// If the variable is a non-Boolean, it means adding a disequality.
|
||||||
|
//
|
||||||
literal lit;
|
literal lit;
|
||||||
if (m.is_bool(e)) {
|
if (m.is_bool(e)) {
|
||||||
lit = literal(get_bool_var(e), m.is_true(val));
|
lit = literal(get_bool_var(e), m.is_true(val));
|
||||||
|
@ -244,9 +296,20 @@ namespace smt {
|
||||||
eq = mk_eq_atom(e, val);
|
eq = mk_eq_atom(e, val);
|
||||||
internalize_formula(eq, false);
|
internalize_formula(eq, false);
|
||||||
lit = literal(get_bool_var(eq), true);
|
lit = literal(get_bool_var(eq), true);
|
||||||
|
TRACE("context", tout << mk_pp(e, m) << " " << mk_pp(val, m) << "\n";
|
||||||
|
display_literal_verbose(tout, lit); tout << "\n";
|
||||||
|
tout << "Equal: " << are_equal(e, val) << "\n";);
|
||||||
}
|
}
|
||||||
|
mark_as_relevant(lit);
|
||||||
|
push_scope();
|
||||||
assign(lit, b_justification::mk_axiom(), true);
|
assign(lit, b_justification::mk_axiom(), true);
|
||||||
flet<bool> l(m_searching, true);
|
flet<bool> l(m_searching, true);
|
||||||
|
|
||||||
|
//
|
||||||
|
// We check if the current assignment stack can be extended to a
|
||||||
|
// satisfying assignment. bounded search may decide to restart,
|
||||||
|
// in which case it returns l_undef and clears search failure.
|
||||||
|
//
|
||||||
while (true) {
|
while (true) {
|
||||||
is_sat = bounded_search();
|
is_sat = bounded_search();
|
||||||
TRACE("context", tout << "search result: " << is_sat << "\n";);
|
TRACE("context", tout << "search result: " << is_sat << "\n";);
|
||||||
|
@ -260,33 +323,78 @@ namespace smt {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (get_assignment(lit) == l_true) {
|
//
|
||||||
|
// If the state is satisfiable with the current variable assigned to
|
||||||
|
// a different value from the reference model, it is unfixed.
|
||||||
|
//
|
||||||
|
// If it is assigned above the search level we can't conclude anything
|
||||||
|
// about its value.
|
||||||
|
// extract_fixed_consequences pops the assignment stack to the search level
|
||||||
|
// so this sets up the state to retry finding fixed values.
|
||||||
|
//
|
||||||
|
// Otherwise, the variable is fixed.
|
||||||
|
// - it is either assigned at the search level to l_false, or
|
||||||
|
// - the state is l_false, which means that the variable is fixed by
|
||||||
|
// the background constraints (and does not depend on assumptions).
|
||||||
|
//
|
||||||
|
if (is_sat == l_true && get_assignment(lit) == l_true && is_relevant(lit)) {
|
||||||
var2val.erase(e);
|
var2val.erase(e);
|
||||||
unfixed.push_back(e);
|
unfixed.push_back(e);
|
||||||
|
SASSERT(!are_equal(e, val));
|
||||||
|
TRACE("context", tout << mk_pp(e, m) << " is unfixed\n";
|
||||||
|
display_literal_verbose(tout, lit); tout << "\n";
|
||||||
|
tout << "relevant: " << is_relevant(lit) << "\n";
|
||||||
|
display(tout););
|
||||||
}
|
}
|
||||||
else if (get_assign_level(lit) > get_search_level()) {
|
else if (is_sat == l_true && (get_assign_level(lit) > get_search_level() || !is_relevant(lit))) {
|
||||||
TRACE("context", tout << "Retry fixing: " << mk_pp(e, m) << "\n";);
|
TRACE("context", tout << "Retry fixing: " << mk_pp(e, m) << "\n";);
|
||||||
pop_to_search_lvl();
|
extract_fixed_consequences(num_units, var2val, _assumptions, conseq);
|
||||||
++num_reiterations;
|
++num_reiterations;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
TRACE("context", tout << "Fixed: " << mk_pp(e, m) << "\n";);
|
//
|
||||||
|
// The state can be labeled as inconsistent when the implied consequence does
|
||||||
|
// not depend on assumptions, then the conflict level sits at the search level
|
||||||
|
// which causes the conflict resolver to decide that the state is unsat.
|
||||||
|
//
|
||||||
|
if (l_false == is_sat) {
|
||||||
|
SASSERT(inconsistent());
|
||||||
|
m_conflict = null_b_justification;
|
||||||
|
m_not_l = null_literal;
|
||||||
|
}
|
||||||
|
TRACE("context", tout << "Fixed: " << mk_pp(e, m) << " " << is_sat << "\n";
|
||||||
|
if (is_sat == l_false) display(tout););
|
||||||
|
|
||||||
}
|
}
|
||||||
++num_iterations;
|
++num_iterations;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check the slow pass: it retrieves an updated model and checks if the
|
||||||
|
// values in the updated model differ from the values in the reference
|
||||||
|
// model.
|
||||||
|
//
|
||||||
bool apply_slow_pass = model_threshold <= num_iterations || num_iterations <= 2;
|
bool apply_slow_pass = model_threshold <= num_iterations || num_iterations <= 2;
|
||||||
if (apply_slow_pass) {
|
if (apply_slow_pass && is_sat == l_true) {
|
||||||
num_unfixed += delete_unfixed(var2val, unfixed);
|
num_unfixed += delete_unfixed(var2val, unfixed);
|
||||||
// The next time we check the model is after 1.5 additional iterations.
|
// The next time we check the model is after 1.5 additional iterations.
|
||||||
model_threshold *= 3;
|
model_threshold *= 3;
|
||||||
model_threshold /= 2;
|
model_threshold /= 2;
|
||||||
}
|
}
|
||||||
// repeat until we either have a model with negated literal or
|
|
||||||
// the literal is implied at base.
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Walk the assignment stack at level 1 for learned consequences.
|
||||||
|
// The current literal should be assigned at the search level unless
|
||||||
|
// the state is is_sat == l_true and the assignment to lit is l_true.
|
||||||
|
// This condition is checked above.
|
||||||
|
//
|
||||||
extract_fixed_consequences(num_units, var2val, _assumptions, conseq);
|
extract_fixed_consequences(num_units, var2val, _assumptions, conseq);
|
||||||
num_units = assigned_literals().size();
|
num_units = assigned_literals().size();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Fixed equalities can be extracted by walking all variables and checking
|
||||||
|
// if the congruence roots are equal at the search level.
|
||||||
|
//
|
||||||
if (apply_slow_pass) {
|
if (apply_slow_pass) {
|
||||||
num_fixed_eqs += extract_fixed_eqs(var2val, conseq);
|
num_fixed_eqs += extract_fixed_eqs(var2val, conseq);
|
||||||
IF_VERBOSE(1, verbose_stream() << "(get-consequences"
|
IF_VERBOSE(1, verbose_stream() << "(get-consequences"
|
||||||
|
@ -306,18 +414,72 @@ namespace smt {
|
||||||
<< " unfixed-deleted: " << num_unfixed
|
<< " unfixed-deleted: " << num_unfixed
|
||||||
<< ")\n";);
|
<< ")\n";);
|
||||||
}
|
}
|
||||||
|
TRACE("context", tout << "finishing " << mk_pp(e, m) << "\n";);
|
||||||
|
SASSERT(!inconsistent());
|
||||||
|
|
||||||
|
//
|
||||||
|
// This becomes unnecessary when the fixed consequence are
|
||||||
|
// completely extracted.
|
||||||
|
//
|
||||||
if (var2val.contains(e)) {
|
if (var2val.contains(e)) {
|
||||||
TRACE("context", tout << "Fixed value to " << mk_pp(e, m) << " was not processed\n";);
|
TRACE("context", tout << "Fixed value to " << mk_pp(e, m) << " was not processed\n";);
|
||||||
expr_ref fml(m);
|
expr_ref fml(m);
|
||||||
fml = m.mk_eq(e, var2val.find(e));
|
fml = m.mk_eq(e, var2val.find(e));
|
||||||
|
if (!m_antecedents.contains(lit.var())) {
|
||||||
|
extract_fixed_consequences(lit, var2val, _assumptions, conseq);
|
||||||
|
}
|
||||||
fml = m.mk_implies(antecedent2fml(m_antecedents[lit.var()]), fml);
|
fml = m.mk_implies(antecedent2fml(m_antecedents[lit.var()]), fml);
|
||||||
conseq.push_back(fml);
|
conseq.push_back(fml);
|
||||||
var2val.erase(e);
|
var2val.erase(e);
|
||||||
SASSERT(get_assignment(lit) == l_false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end_search();
|
end_search();
|
||||||
|
DEBUG_CODE(validate_consequences(assumptions, vars, conseq, unfixed););
|
||||||
return l_true;
|
return l_true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate, in a slow pass, that the current consequences are correctly
|
||||||
|
// extracted.
|
||||||
|
//
|
||||||
|
void context::validate_consequences(expr_ref_vector const& assumptions, expr_ref_vector const& vars,
|
||||||
|
expr_ref_vector const& conseq, expr_ref_vector const& unfixed) {
|
||||||
|
ast_manager& m = m_manager;
|
||||||
|
expr_ref tmp(m);
|
||||||
|
SASSERT(!inconsistent());
|
||||||
|
for (unsigned i = 0; i < conseq.size(); ++i) {
|
||||||
|
push();
|
||||||
|
for (unsigned j = 0; j < assumptions.size(); ++j) {
|
||||||
|
assert_expr(assumptions[j]);
|
||||||
|
}
|
||||||
|
TRACE("context", tout << "checking: " << mk_pp(conseq[i], m) << "\n";);
|
||||||
|
tmp = m.mk_not(conseq[i]);
|
||||||
|
assert_expr(tmp);
|
||||||
|
lbool is_sat = check();
|
||||||
|
SASSERT(is_sat != l_true);
|
||||||
|
pop(1);
|
||||||
|
}
|
||||||
|
model_ref mdl;
|
||||||
|
for (unsigned i = 0; i < unfixed.size(); ++i) {
|
||||||
|
push();
|
||||||
|
for (unsigned j = 0; j < assumptions.size(); ++j) {
|
||||||
|
assert_expr(assumptions[j]);
|
||||||
|
}
|
||||||
|
TRACE("context", tout << "checking unfixed: " << mk_pp(unfixed[i], m) << "\n";);
|
||||||
|
lbool is_sat = check();
|
||||||
|
SASSERT(is_sat != l_false);
|
||||||
|
if (is_sat == l_true) {
|
||||||
|
get_model(mdl);
|
||||||
|
mdl->eval(unfixed[i], tmp);
|
||||||
|
if (m.is_value(tmp)) {
|
||||||
|
tmp = m.mk_not(m.mk_eq(unfixed[i], tmp));
|
||||||
|
assert_expr(tmp);
|
||||||
|
is_sat = check();
|
||||||
|
SASSERT(is_sat != l_false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pop(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1094,7 +1094,7 @@ namespace smt {
|
||||||
\brief This method is invoked when a new disequality is asserted.
|
\brief This method is invoked when a new disequality is asserted.
|
||||||
The disequality is propagated to the theories.
|
The disequality is propagated to the theories.
|
||||||
*/
|
*/
|
||||||
void context::add_diseq(enode * n1, enode * n2) {
|
bool context::add_diseq(enode * n1, enode * n2) {
|
||||||
enode * r1 = n1->get_root();
|
enode * r1 = n1->get_root();
|
||||||
enode * r2 = n2->get_root();
|
enode * r2 = n2->get_root();
|
||||||
TRACE("add_diseq", tout << "assigning: #" << n1->get_owner_id() << " != #" << n2->get_owner_id() << "\n";
|
TRACE("add_diseq", tout << "assigning: #" << n1->get_owner_id() << " != #" << n2->get_owner_id() << "\n";
|
||||||
|
@ -1111,7 +1111,7 @@ namespace smt {
|
||||||
|
|
||||||
if (r1 == r2) {
|
if (r1 == r2) {
|
||||||
TRACE("add_diseq_inconsistent", tout << "add_diseq #" << n1->get_owner_id() << " #" << n2->get_owner_id() << " inconsistency, scope_lvl: " << m_scope_lvl << "\n";);
|
TRACE("add_diseq_inconsistent", tout << "add_diseq #" << n1->get_owner_id() << " #" << n2->get_owner_id() << " inconsistency, scope_lvl: " << m_scope_lvl << "\n";);
|
||||||
return; // context is inconsistent
|
return false; // context is inconsistent
|
||||||
}
|
}
|
||||||
|
|
||||||
// Propagate disequalities to theories
|
// Propagate disequalities to theories
|
||||||
|
@ -1145,6 +1145,7 @@ namespace smt {
|
||||||
l1 = l1->get_next();
|
l1 = l1->get_next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1400,7 +1401,9 @@ namespace smt {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
TRACE("add_diseq", display_eq_detail(tout, bool_var2enode(v)););
|
TRACE("add_diseq", display_eq_detail(tout, bool_var2enode(v)););
|
||||||
add_diseq(get_enode(lhs), get_enode(rhs));
|
if (!add_diseq(get_enode(lhs), get_enode(rhs)) && !inconsistent()) {
|
||||||
|
set_conflict(b_justification(mk_justification(eq_propagation_justification(get_enode(lhs), get_enode(rhs)))), ~l);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (d.is_theory_atom()) {
|
else if (d.is_theory_atom()) {
|
||||||
|
|
|
@ -942,7 +942,7 @@ namespace smt {
|
||||||
push_eq(n1, n2, eq_justification::mk_cg(used_commutativity));
|
push_eq(n1, n2, eq_justification::mk_cg(used_commutativity));
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_diseq(enode * n1, enode * n2);
|
bool add_diseq(enode * n1, enode * n2);
|
||||||
|
|
||||||
void assign_quantifier(quantifier * q);
|
void assign_quantifier(quantifier * q);
|
||||||
|
|
||||||
|
@ -1345,6 +1345,7 @@ namespace smt {
|
||||||
vector<bool_var> b2v, ast_translation& tr);
|
vector<bool_var> b2v, ast_translation& tr);
|
||||||
|
|
||||||
u_map<uint_set> m_antecedents;
|
u_map<uint_set> m_antecedents;
|
||||||
|
void extract_fixed_consequences(literal lit, obj_map<expr, expr*>& var2val, uint_set const& assumptions, expr_ref_vector& conseq);
|
||||||
void extract_fixed_consequences(unsigned idx, obj_map<expr, expr*>& var2val, uint_set const& assumptions, expr_ref_vector& conseq);
|
void extract_fixed_consequences(unsigned idx, obj_map<expr, expr*>& var2val, uint_set const& assumptions, expr_ref_vector& conseq);
|
||||||
|
|
||||||
unsigned delete_unfixed(obj_map<expr, expr*>& var2val, expr_ref_vector& unfixed);
|
unsigned delete_unfixed(obj_map<expr, expr*>& var2val, expr_ref_vector& unfixed);
|
||||||
|
@ -1353,6 +1354,9 @@ namespace smt {
|
||||||
|
|
||||||
expr_ref antecedent2fml(uint_set const& ante);
|
expr_ref antecedent2fml(uint_set const& ante);
|
||||||
|
|
||||||
|
void validate_consequences(expr_ref_vector const& assumptions, expr_ref_vector const& vars,
|
||||||
|
expr_ref_vector const& conseq, expr_ref_vector const& unfixed);
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
context(ast_manager & m, smt_params & fp, params_ref const & p = params_ref());
|
context(ast_manager & m, smt_params & fp, params_ref const & p = params_ref());
|
||||||
|
|
|
@ -1284,7 +1284,6 @@ namespace smt {
|
||||||
TRACE("mk_clause", tout << "creating clause:\n"; display_literals(tout, num_lits, lits); tout << "\n";);
|
TRACE("mk_clause", tout << "creating clause:\n"; display_literals(tout, num_lits, lits); tout << "\n";);
|
||||||
switch (k) {
|
switch (k) {
|
||||||
case CLS_AUX: {
|
case CLS_AUX: {
|
||||||
unsigned old_num_lits = num_lits;
|
|
||||||
literal_buffer simp_lits;
|
literal_buffer simp_lits;
|
||||||
if (!simplify_aux_clause_literals(num_lits, lits, simp_lits))
|
if (!simplify_aux_clause_literals(num_lits, lits, simp_lits))
|
||||||
return 0; // clause is equivalent to true;
|
return 0; // clause is equivalent to true;
|
||||||
|
|
|
@ -64,7 +64,7 @@ namespace smt {
|
||||||
lower(v2)->push_justification(ante, numeral::zero(), proofs_enabled());
|
lower(v2)->push_justification(ante, numeral::zero(), proofs_enabled());
|
||||||
upper(v)->push_justification(ante, numeral::zero(), proofs_enabled());
|
upper(v)->push_justification(ante, numeral::zero(), proofs_enabled());
|
||||||
|
|
||||||
TRACE("arith_fixed_propagate_eq", tout << "propagate eq: v" << v << " = v" << v2 << "\n";
|
TRACE("arith_eq", tout << "propagate eq: v" << v << " = v" << v2 << "\n";
|
||||||
display_var(tout, v);
|
display_var(tout, v);
|
||||||
display_var(tout, v2););
|
display_var(tout, v2););
|
||||||
m_stats.m_fixed_eqs++;
|
m_stats.m_fixed_eqs++;
|
||||||
|
@ -175,7 +175,7 @@ namespace smt {
|
||||||
timer.stop();
|
timer.stop();
|
||||||
ok++;
|
ok++;
|
||||||
if (ok % 100000 == 0) {
|
if (ok % 100000 == 0) {
|
||||||
TRACE("propagate_cheap_eq",
|
TRACE("arith_eq",
|
||||||
tout << total << " " << ok << " "
|
tout << total << " " << ok << " "
|
||||||
<< static_cast<double>(ok)/static_cast<double>(total)
|
<< static_cast<double>(ok)/static_cast<double>(total)
|
||||||
<< " " << timer.get_seconds() << "\n";
|
<< " " << timer.get_seconds() << "\n";
|
||||||
|
@ -216,7 +216,7 @@ namespace smt {
|
||||||
void theory_arith<Ext>::propagate_cheap_eq(unsigned rid) {
|
void theory_arith<Ext>::propagate_cheap_eq(unsigned rid) {
|
||||||
if (!propagate_eqs())
|
if (!propagate_eqs())
|
||||||
return;
|
return;
|
||||||
TRACE("propagate_cheap_eq", tout << "checking if row " << rid << " can propagate equality.\n";
|
TRACE("arith_eq", tout << "checking if row " << rid << " can propagate equality.\n";
|
||||||
display_row_info(tout, rid););
|
display_row_info(tout, rid););
|
||||||
row const & r = m_rows[rid];
|
row const & r = m_rows[rid];
|
||||||
theory_var x;
|
theory_var x;
|
||||||
|
@ -258,7 +258,7 @@ namespace smt {
|
||||||
// found equality x = y
|
// found equality x = y
|
||||||
antecedents ante(*this);
|
antecedents ante(*this);
|
||||||
collect_fixed_var_justifications(r, ante);
|
collect_fixed_var_justifications(r, ante);
|
||||||
TRACE("propagate_cheap_eq", tout << "propagate eq using x-y=0 row:\n"; display_row_info(tout, r););
|
TRACE("arith_eq", tout << "propagate eq using x-y=0 row:\n"; display_row_info(tout, r););
|
||||||
m_stats.m_offset_eqs++;
|
m_stats.m_offset_eqs++;
|
||||||
propagate_eq_to_core(x, y, ante);
|
propagate_eq_to_core(x, y, ante);
|
||||||
}
|
}
|
||||||
|
@ -299,7 +299,7 @@ namespace smt {
|
||||||
antecedents ante(*this);
|
antecedents ante(*this);
|
||||||
collect_fixed_var_justifications(r, ante);
|
collect_fixed_var_justifications(r, ante);
|
||||||
collect_fixed_var_justifications(r2, ante);
|
collect_fixed_var_justifications(r2, ante);
|
||||||
TRACE("propagate_cheap_eq", tout << "propagate eq two rows:\n";
|
TRACE("arith_eq", tout << "propagate eq two rows:\n";
|
||||||
tout << "swapped: " << swapped << "\n";
|
tout << "swapped: " << swapped << "\n";
|
||||||
tout << "x : v" << x << "\n";
|
tout << "x : v" << x << "\n";
|
||||||
tout << "x2 : v" << x2 << "\n";
|
tout << "x2 : v" << x2 << "\n";
|
||||||
|
@ -343,7 +343,7 @@ namespace smt {
|
||||||
antecedents.eqs().size(), antecedents.eqs().c_ptr(),
|
antecedents.eqs().size(), antecedents.eqs().c_ptr(),
|
||||||
_x, _y,
|
_x, _y,
|
||||||
antecedents.num_params(), antecedents.params("eq-propagate")));
|
antecedents.num_params(), antecedents.params("eq-propagate")));
|
||||||
TRACE("propagate_eq_to_core", tout << "detected equality: #" << _x->get_owner_id() << " = #" << _y->get_owner_id() << "\n";
|
TRACE("arith_eq", tout << "detected equality: #" << _x->get_owner_id() << " = #" << _y->get_owner_id() << "\n";
|
||||||
display_var(tout, x);
|
display_var(tout, x);
|
||||||
display_var(tout, y););
|
display_var(tout, y););
|
||||||
ctx.assign_eq(_x, _y, eq_justification(js));
|
ctx.assign_eq(_x, _y, eq_justification(js));
|
||||||
|
|
|
@ -97,6 +97,7 @@ namespace smt {
|
||||||
virtual void pop_scope_eh(unsigned num_scopes);
|
virtual void pop_scope_eh(unsigned num_scopes);
|
||||||
virtual final_check_status final_check_eh();
|
virtual final_check_status final_check_eh();
|
||||||
virtual void reset_eh();
|
virtual void reset_eh();
|
||||||
|
virtual void restart_eh() { m_util.reset(); }
|
||||||
virtual bool is_shared(theory_var v) const;
|
virtual bool is_shared(theory_var v) const;
|
||||||
public:
|
public:
|
||||||
theory_datatype(ast_manager & m, theory_datatype_params & p);
|
theory_datatype(ast_manager & m, theory_datatype_params & p);
|
||||||
|
|
|
@ -249,6 +249,7 @@ final_check_status theory_seq::final_check_eh() {
|
||||||
}
|
}
|
||||||
m_new_propagation = false;
|
m_new_propagation = false;
|
||||||
TRACE("seq", display(tout << "level: " << get_context().get_scope_level() << "\n"););
|
TRACE("seq", display(tout << "level: " << get_context().get_scope_level() << "\n"););
|
||||||
|
TRACE("seq_verbose", get_context().display(tout););
|
||||||
if (simplify_and_solve_eqs()) {
|
if (simplify_and_solve_eqs()) {
|
||||||
++m_stats.m_solve_eqs;
|
++m_stats.m_solve_eqs;
|
||||||
TRACE("seq", tout << ">>solve_eqs\n";);
|
TRACE("seq", tout << ">>solve_eqs\n";);
|
||||||
|
@ -1009,6 +1010,17 @@ bool theory_seq::is_nth(expr* e) const {
|
||||||
return is_skolem(m_nth, e);
|
return is_skolem(m_nth, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool theory_seq::is_nth(expr* e, expr*& e1, expr*& e2) const {
|
||||||
|
if (is_nth(e)) {
|
||||||
|
e1 = to_app(e)->get_arg(0);
|
||||||
|
e2 = to_app(e)->get_arg(1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool theory_seq::is_tail(expr* e, expr*& s, unsigned& idx) const {
|
bool theory_seq::is_tail(expr* e, expr*& s, unsigned& idx) const {
|
||||||
rational r;
|
rational r;
|
||||||
return
|
return
|
||||||
|
@ -1038,6 +1050,10 @@ expr_ref theory_seq::mk_nth(expr* s, expr* idx) {
|
||||||
return mk_skolem(m_nth, s, idx, 0, char_sort);
|
return mk_skolem(m_nth, s, idx, 0, char_sort);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expr_ref theory_seq::mk_sk_ite(expr* c, expr* t, expr* e) {
|
||||||
|
return mk_skolem(symbol("seq.if"), c, t, e, m.get_sort(t));
|
||||||
|
}
|
||||||
|
|
||||||
expr_ref theory_seq::mk_last(expr* s) {
|
expr_ref theory_seq::mk_last(expr* s) {
|
||||||
zstring str;
|
zstring str;
|
||||||
if (m_util.str.is_string(s, str) && str.length() > 0) {
|
if (m_util.str.is_string(s, str) && str.length() > 0) {
|
||||||
|
@ -1133,7 +1149,7 @@ bool theory_seq::check_extensionality() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
TRACE("seq", tout << m_lhs << " = " << m_rhs << "\n";);
|
TRACE("seq", tout << m_lhs << " = " << m_rhs << "\n";);
|
||||||
ctx.assume_eq(n1, n2);
|
ctx.assume_eq(n1, n2);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2668,6 +2684,13 @@ expr_ref theory_seq::expand(expr* e0, dependency*& eqs) {
|
||||||
}
|
}
|
||||||
else if (m.is_ite(e, e1, e2, e3)) {
|
else if (m.is_ite(e, e1, e2, e3)) {
|
||||||
literal lit(mk_literal(e1));
|
literal lit(mk_literal(e1));
|
||||||
|
#if 0
|
||||||
|
expr_ref sk_ite = mk_sk_ite(e1, e2, e3);
|
||||||
|
add_axiom(~lit, mk_eq(e2, sk_ite, false));
|
||||||
|
add_axiom( lit, mk_eq(e3, sk_ite, false));
|
||||||
|
result = sk_ite;
|
||||||
|
|
||||||
|
#else
|
||||||
switch (ctx.get_assignment(lit)) {
|
switch (ctx.get_assignment(lit)) {
|
||||||
case l_true:
|
case l_true:
|
||||||
deps = m_dm.mk_join(deps, m_dm.mk_leaf(assumption(lit)));
|
deps = m_dm.mk_join(deps, m_dm.mk_leaf(assumption(lit)));
|
||||||
|
@ -2684,6 +2707,7 @@ expr_ref theory_seq::expand(expr* e0, dependency*& eqs) {
|
||||||
tout << lit << "@ level: " << ctx.get_scope_level() << "\n";);
|
tout << lit << "@ level: " << ctx.get_scope_level() << "\n";);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else if (m_util.str.is_itos(e, e1)) {
|
else if (m_util.str.is_itos(e, e1)) {
|
||||||
rational val;
|
rational val;
|
||||||
|
@ -2902,9 +2926,13 @@ void theory_seq::add_replace_axiom(expr* r) {
|
||||||
expr_ref xty = mk_concat(x, t, y);
|
expr_ref xty = mk_concat(x, t, y);
|
||||||
expr_ref xsy = mk_concat(x, s, y);
|
expr_ref xsy = mk_concat(x, s, y);
|
||||||
literal cnt = mk_literal(m_util.str.mk_contains(a ,s));
|
literal cnt = mk_literal(m_util.str.mk_contains(a ,s));
|
||||||
|
literal a_emp = mk_eq_empty(a);
|
||||||
|
literal s_emp = mk_eq_empty(s);
|
||||||
|
add_axiom(~a_emp, mk_seq_eq(r, a));
|
||||||
add_axiom(cnt, mk_seq_eq(r, a));
|
add_axiom(cnt, mk_seq_eq(r, a));
|
||||||
add_axiom(~cnt, mk_seq_eq(a, xsy));
|
add_axiom(~s_emp, mk_seq_eq(r, a));
|
||||||
add_axiom(~cnt, mk_seq_eq(r, xty));
|
add_axiom(~cnt, a_emp, s_emp, mk_seq_eq(a, xsy));
|
||||||
|
add_axiom(~cnt, a_emp, s_emp, mk_seq_eq(r, xty));
|
||||||
tightest_prefix(s, x);
|
tightest_prefix(s, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -449,10 +449,12 @@ namespace smt {
|
||||||
bool is_var(expr* b);
|
bool is_var(expr* b);
|
||||||
bool add_solution(expr* l, expr* r, dependency* dep);
|
bool add_solution(expr* l, expr* r, dependency* dep);
|
||||||
bool is_nth(expr* a) const;
|
bool is_nth(expr* a) const;
|
||||||
|
bool is_nth(expr* a, expr*& e1, expr*& e2) const;
|
||||||
bool is_tail(expr* a, expr*& s, unsigned& idx) const;
|
bool is_tail(expr* a, expr*& s, unsigned& idx) const;
|
||||||
bool is_eq(expr* e, expr*& a, expr*& b) const;
|
bool is_eq(expr* e, expr*& a, expr*& b) const;
|
||||||
bool is_pre(expr* e, expr*& s, expr*& i);
|
bool is_pre(expr* e, expr*& s, expr*& i);
|
||||||
bool is_post(expr* e, expr*& s, expr*& i);
|
bool is_post(expr* e, expr*& s, expr*& i);
|
||||||
|
expr_ref mk_sk_ite(expr* c, expr* t, expr* f);
|
||||||
expr_ref mk_nth(expr* s, expr* idx);
|
expr_ref mk_nth(expr* s, expr* idx);
|
||||||
expr_ref mk_last(expr* e);
|
expr_ref mk_last(expr* e);
|
||||||
expr_ref mk_first(expr* e);
|
expr_ref mk_first(expr* e);
|
||||||
|
|
|
@ -112,7 +112,7 @@ class dt2bv_tactic : public tactic {
|
||||||
unsigned idx = m_t.m_dt.get_constructor_idx(f);
|
unsigned idx = m_t.m_dt.get_constructor_idx(f);
|
||||||
result = m_t.m_bv.mk_numeral(idx, bv_size);
|
result = m_t.m_bv.mk_numeral(idx, bv_size);
|
||||||
}
|
}
|
||||||
else {
|
else if (is_uninterp_const(a)) {
|
||||||
// create a fresh variable, add bounds constraints for it.
|
// create a fresh variable, add bounds constraints for it.
|
||||||
unsigned nc = m_t.m_dt.get_datatype_num_constructors(s);
|
unsigned nc = m_t.m_dt.get_datatype_num_constructors(s);
|
||||||
result = m.mk_fresh_const(f->get_name().str().c_str(), m_t.m_bv.mk_sort(bv_size));
|
result = m.mk_fresh_const(f->get_name().str().c_str(), m_t.m_bv.mk_sort(bv_size));
|
||||||
|
@ -130,6 +130,9 @@ class dt2bv_tactic : public tactic {
|
||||||
m_t.m_ext->insert(f, f_def);
|
m_t.m_ext->insert(f, f_def);
|
||||||
m_t.m_filter->insert(to_app(result)->get_decl());
|
m_t.m_filter->insert(to_app(result)->get_decl());
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
m_cache.insert(a, result);
|
m_cache.insert(a, result);
|
||||||
++m_t.m_num_translated;
|
++m_t.m_num_translated;
|
||||||
return true;
|
return true;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue