3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-12 20:18:18 +00:00

merged with unstable

This commit is contained in:
Ken McMillan 2014-08-06 11:16:06 -07:00
parent 7bf87e76ea
commit c007a5e5bd
48 changed files with 537 additions and 256 deletions

View file

@ -1630,9 +1630,7 @@ public:
unsigned parent_id = Z3_get_ast_id(ctx, p.arg(0)); unsigned parent_id = Z3_get_ast_id(ctx, p.arg(0));
std::set<unsigned> const& hyps = m_proof_hypotheses.find(parent_id)->second; std::set<unsigned> const& hyps = m_proof_hypotheses.find(parent_id)->second;
print_hypotheses(out, hyps); print_hypotheses(out, hyps);
out << ").\n"; out << "))).\n";
break;
display_inference(out, "lemma", "thm", p);
break; break;
} }
case Z3_OP_PR_UNIT_RESOLUTION: case Z3_OP_PR_UNIT_RESOLUTION:

View file

@ -80,7 +80,7 @@ GPROF=False
GIT_HASH=False GIT_HASH=False
def check_output(cmd): def check_output(cmd):
return subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()[0].rstrip('\r\n') return str(subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()[0]).rstrip('\r\n')
def git_hash(): def git_hash():
try: try:
@ -764,7 +764,7 @@ class Component:
out.write('\n') out.write('\n')
mk_dir(os.path.join(BUILD_DIR, self.build_dir)) mk_dir(os.path.join(BUILD_DIR, self.build_dir))
if VS_PAR and IS_WINDOWS: if VS_PAR and IS_WINDOWS:
cppfiles = get_cpp_files(self.src_dir) cppfiles = list(get_cpp_files(self.src_dir))
dependencies = set() dependencies = set()
for cppfile in cppfiles: for cppfile in cppfiles:
dependencies.add(os.path.join(self.to_src_dir, cppfile)) dependencies.add(os.path.join(self.to_src_dir, cppfile))
@ -810,6 +810,9 @@ class Component:
def require_mem_initializer(self): def require_mem_initializer(self):
return False return False
def mk_install_deps(self, out):
return
def mk_install(self, out): def mk_install(self, out):
return return
@ -853,6 +856,9 @@ class LibComponent(Component):
out.write('\n') out.write('\n')
out.write('%s: %s\n\n' % (self.name, libfile)) out.write('%s: %s\n\n' % (self.name, libfile))
def mk_install_dep(self, out):
out.write('%s' % libfile)
def mk_install(self, out): def mk_install(self, out):
for include in self.includes2install: for include in self.includes2install:
out.write('\t@cp %s %s\n' % (os.path.join(self.to_src_dir, include), os.path.join('$(PREFIX)', 'include', include))) out.write('\t@cp %s %s\n' % (os.path.join(self.to_src_dir, include), os.path.join('$(PREFIX)', 'include', include)))
@ -935,6 +941,9 @@ class ExeComponent(Component):
def main_component(self): def main_component(self):
return self.install return self.install
def mk_install_dep(self, out):
out.write('%s' % exefile)
def mk_install(self, out): def mk_install(self, out):
if self.install: if self.install:
exefile = '%s$(EXE_EXT)' % self.exe_name exefile = '%s$(EXE_EXT)' % self.exe_name
@ -1076,6 +1085,11 @@ class DLLComponent(Component):
def require_def_file(self): def require_def_file(self):
return IS_WINDOWS and self.export_files return IS_WINDOWS and self.export_files
def mk_install_dep(self, out):
out.write('%s$(SO_EXT)' % self.dll_name)
if self.static:
out.write(' %s$(LIB_EXT)' % self.dll_name)
def mk_install(self, out): def mk_install(self, out):
if self.install: if self.install:
dllfile = '%s$(SO_EXT)' % self.dll_name dllfile = '%s$(SO_EXT)' % self.dll_name
@ -1611,7 +1625,11 @@ def mk_config():
print('Java Compiler: %s' % JAVAC) print('Java Compiler: %s' % JAVAC)
def mk_install(out): def mk_install(out):
out.write('install:\n') out.write('install: ')
for c in get_components():
c.mk_install_deps(out)
out.write(' ')
out.write('\n')
out.write('\t@mkdir -p %s\n' % os.path.join('$(PREFIX)', 'bin')) out.write('\t@mkdir -p %s\n' % os.path.join('$(PREFIX)', 'bin'))
out.write('\t@mkdir -p %s\n' % os.path.join('$(PREFIX)', 'include')) out.write('\t@mkdir -p %s\n' % os.path.join('$(PREFIX)', 'include'))
out.write('\t@mkdir -p %s\n' % os.path.join('$(PREFIX)', 'lib')) out.write('\t@mkdir -p %s\n' % os.path.join('$(PREFIX)', 'lib'))
@ -2573,16 +2591,17 @@ def mk_vs_proj(name, components):
def mk_win_dist(build_path, dist_path): def mk_win_dist(build_path, dist_path):
for c in get_components(): for c in get_components():
c.mk_win_dist(build_path, dist_path) c.mk_win_dist(build_path, dist_path)
# Add Z3Py to lib directory # Add Z3Py to bin directory
for pyc in filter(lambda f: f.endswith('.pyc'), os.listdir(build_path)): print("Adding to %s\n" % dist_path)
for pyc in filter(lambda f: f.endswith('.pyc') or f.endswith('.py'), os.listdir(build_path)):
shutil.copy(os.path.join(build_path, pyc), shutil.copy(os.path.join(build_path, pyc),
os.path.join(dist_path, 'bin', pyc)) os.path.join(dist_path, 'bin', pyc))
def mk_unix_dist(build_path, dist_path): def mk_unix_dist(build_path, dist_path):
for c in get_components(): for c in get_components():
c.mk_unix_dist(build_path, dist_path) c.mk_unix_dist(build_path, dist_path)
# Add Z3Py to lib directory # Add Z3Py to bin directory
for pyc in filter(lambda f: f.endswith('.pyc'), os.listdir(build_path)): for pyc in filter(lambda f: f.endswith('.pyc') or f.endswith('.py'), os.listdir(build_path)):
shutil.copy(os.path.join(build_path, pyc), shutil.copy(os.path.join(build_path, pyc),
os.path.join(dist_path, 'bin', pyc)) os.path.join(dist_path, 'bin', pyc))

View file

@ -269,6 +269,14 @@ namespace Microsoft.Z3
AST.ArrayLength(queries), AST.ArrayToNative(queries)); AST.ArrayLength(queries), AST.ArrayToNative(queries));
} }
BoolExpr[] ToBoolExprs(ASTVector v) {
uint n = v.Size;
BoolExpr[] res = new BoolExpr[n];
for (uint i = 0; i < n; i++)
res[i] = new BoolExpr(Context, v[i].NativeObject);
return res;
}
/// <summary> /// <summary>
/// Retrieve set of rules added to fixedpoint context. /// Retrieve set of rules added to fixedpoint context.
/// </summary> /// </summary>
@ -278,12 +286,7 @@ namespace Microsoft.Z3
{ {
Contract.Ensures(Contract.Result<BoolExpr[]>() != null); Contract.Ensures(Contract.Result<BoolExpr[]>() != null);
ASTVector v = new ASTVector(Context, Native.Z3_fixedpoint_get_rules(Context.nCtx, NativeObject)); return ToBoolExprs(new ASTVector(Context, Native.Z3_fixedpoint_get_rules(Context.nCtx, NativeObject)));
uint n = v.Size;
BoolExpr[] res = new BoolExpr[n];
for (uint i = 0; i < n; i++)
res[i] = new BoolExpr(Context, v[i].NativeObject);
return res;
} }
} }
@ -296,15 +299,27 @@ namespace Microsoft.Z3
{ {
Contract.Ensures(Contract.Result<BoolExpr[]>() != null); Contract.Ensures(Contract.Result<BoolExpr[]>() != null);
ASTVector v = new ASTVector(Context, Native.Z3_fixedpoint_get_assertions(Context.nCtx, NativeObject)); return ToBoolExprs(new ASTVector(Context, Native.Z3_fixedpoint_get_assertions(Context.nCtx, NativeObject)));
uint n = v.Size;
BoolExpr[] res = new BoolExpr[n];
for (uint i = 0; i < n; i++)
res[i] = new BoolExpr(Context, v[i].NativeObject);
return res;
} }
} }
/// <summary>
/// Parse an SMT-LIB2 file with fixedpoint rules.
/// Add the rules to the current fixedpoint context.
/// Return the set of queries in the file.
/// </summary>
public BoolExpr[] ParseFile(string file) {
return ToBoolExprs(new ASTVector(Context, Native.Z3_fixedpoint_from_file(Context.nCtx, NativeObject, file)));
}
/// <summary>
/// Similar to ParseFile. Instead it takes as argument a string.
/// </summary>
public BoolExpr[] ParseString(string s) {
return ToBoolExprs(new ASTVector(Context, Native.Z3_fixedpoint_from_string(Context.nCtx, NativeObject, s)));
}
#region Internal #region Internal
internal Fixedpoint(Context ctx, IntPtr obj) internal Fixedpoint(Context ctx, IntPtr obj)

View file

@ -899,6 +899,7 @@ def _coerce_expr_merge(s, a):
return s return s
else: else:
if __debug__: if __debug__:
_z3_assert(s1.ctx == s.ctx, "context mismatch")
_z3_assert(False, "sort mismatch") _z3_assert(False, "sort mismatch")
else: else:
return s return s
@ -1459,9 +1460,18 @@ def And(*args):
>>> And(P) >>> And(P)
And(p__0, p__1, p__2, p__3, p__4) And(p__0, p__1, p__2, p__3, p__4)
""" """
last_arg = None
if len(args) > 0:
last_arg = args[len(args)-1]
if isinstance(last_arg, Context):
ctx = args[len(args)-1]
args = args[:len(args)-1]
else:
ctx = main_ctx()
args = _get_args(args) args = _get_args(args)
ctx = _ctx_from_ast_arg_list(args) ctx_args = _ctx_from_ast_arg_list(args, ctx)
if __debug__: if __debug__:
_z3_assert(ctx_args == None or ctx_args == ctx, "context mismatch")
_z3_assert(ctx != None, "At least one of the arguments must be a Z3 expression or probe") _z3_assert(ctx != None, "At least one of the arguments must be a Z3 expression or probe")
if _has_probe(args): if _has_probe(args):
return _probe_and(args, ctx) return _probe_and(args, ctx)
@ -1480,9 +1490,18 @@ def Or(*args):
>>> Or(P) >>> Or(P)
Or(p__0, p__1, p__2, p__3, p__4) Or(p__0, p__1, p__2, p__3, p__4)
""" """
last_arg = None
if len(args) > 0:
last_arg = args[len(args)-1]
if isinstance(last_arg, Context):
ctx = args[len(args)-1]
args = args[:len(args)-1]
else:
ctx = main_ctx()
args = _get_args(args) args = _get_args(args)
ctx = _ctx_from_ast_arg_list(args) ctx_args = _ctx_from_ast_arg_list(args, ctx)
if __debug__: if __debug__:
_z3_assert(ctx_args == None or ctx_args == ctx, "context mismatch")
_z3_assert(ctx != None, "At least one of the arguments must be a Z3 expression or probe") _z3_assert(ctx != None, "At least one of the arguments must be a Z3 expression or probe")
if _has_probe(args): if _has_probe(args):
return _probe_or(args, ctx) return _probe_or(args, ctx)
@ -4128,6 +4147,7 @@ class Datatype:
""" """
if __debug__: if __debug__:
_z3_assert(isinstance(name, str), "String expected") _z3_assert(isinstance(name, str), "String expected")
_z3_assert(name != "", "Constructor name cannot be empty")
return self.declare_core(name, "is_" + name, *args) return self.declare_core(name, "is_" + name, *args)
def __repr__(self): def __repr__(self):

View file

@ -5668,7 +5668,8 @@ END_MLAPI_EXCLUDE
Each conjunct encodes values of the bound variables of the query that are satisfied. Each conjunct encodes values of the bound variables of the query that are satisfied.
In PDR mode, the returned answer is a single conjunction. In PDR mode, the returned answer is a single conjunction.
The previous call to Z3_fixedpoint_query must have returned Z3_L_TRUE. When used in Datalog mode the previous call to Z3_fixedpoint_query must have returned Z3_L_TRUE.
When used with the PDR engine, the previous call must have been either Z3_L_TRUE or Z3_L_FALSE.
def_API('Z3_fixedpoint_get_answer', AST, (_in(CONTEXT), _in(FIXEDPOINT))) def_API('Z3_fixedpoint_get_answer', AST, (_in(CONTEXT), _in(FIXEDPOINT)))
*/ */

View file

@ -569,7 +569,7 @@ class smt_printer {
m_out << ")"; m_out << ")";
} }
if (m_is_smt2 && q->get_num_patterns() > 0) { if (m_is_smt2 && (q->get_num_patterns() > 0 || q->get_qid() != symbol::null)) {
m_out << "(! "; m_out << "(! ";
} }
{ {
@ -609,7 +609,11 @@ class smt_printer {
m_out << "}"; m_out << "}";
} }
} }
if (m_is_smt2 && q->get_num_patterns() > 0) {
if (q->get_qid() != symbol::null)
m_out << " :qid " << q->get_qid();
if (m_is_smt2 && (q->get_num_patterns() > 0 || q->get_qid() != symbol::null)) {
m_out << ")"; m_out << ")";
} }
m_out << ")"; m_out << ")";

View file

@ -601,6 +601,22 @@ namespace datalog {
result = mk_compare(OP_DL_LT, m_lt_sym, domain); result = mk_compare(OP_DL_LT, m_lt_sym, domain);
break; break;
case OP_DL_REP: {
if (!check_domain(0, 0, num_parameters) ||
!check_domain(1, 1, arity)) return 0;
func_decl_info info(m_family_id, k, 0, 0);
result = m_manager->mk_func_decl(symbol("rep"), 1, domain, range, info);
break;
}
case OP_DL_ABS: {
if (!check_domain(0, 0, num_parameters) ||
!check_domain(1, 1, arity)) return 0;
func_decl_info info(m_family_id, k, 0, 0);
result = m_manager->mk_func_decl(symbol("abs"), 1, domain, range, info);
break;
}
default: default:
m_manager->raise_exception("operator not recognized"); m_manager->raise_exception("operator not recognized");
return 0; return 0;

View file

@ -48,6 +48,8 @@ namespace datalog {
OP_RA_CLONE, OP_RA_CLONE,
OP_DL_CONSTANT, OP_DL_CONSTANT,
OP_DL_LT, OP_DL_LT,
OP_DL_REP,
OP_DL_ABS,
LAST_RA_OP LAST_RA_OP
}; };

View file

@ -106,7 +106,7 @@ bool float_decl_plugin::is_value(expr * n, mpf & val) {
return false; return false;
} }
bool float_decl_plugin::is_rm(expr * n, mpf_rounding_mode & val) { bool float_decl_plugin::is_rm_value(expr * n, mpf_rounding_mode & val) {
if (is_app_of(n, m_family_id, OP_RM_NEAREST_TIES_TO_AWAY)) { if (is_app_of(n, m_family_id, OP_RM_NEAREST_TIES_TO_AWAY)) {
val = MPF_ROUND_NEAREST_TAWAY; val = MPF_ROUND_NEAREST_TAWAY;
return true; return true;

View file

@ -169,7 +169,8 @@ public:
app * mk_value(mpf const & v); app * mk_value(mpf const & v);
bool is_value(expr * n) { return is_app_of(n, m_family_id, OP_FLOAT_VALUE); } bool is_value(expr * n) { return is_app_of(n, m_family_id, OP_FLOAT_VALUE); }
bool is_value(expr * n, mpf & val); bool is_value(expr * n, mpf & val);
bool is_rm(expr * n, mpf_rounding_mode & val); bool is_rm_value(expr * n, mpf_rounding_mode & val);
bool is_rm_value(expr * n) { mpf_rounding_mode t; return is_rm_value(n, t); }
mpf const & get_value(unsigned id) const { mpf const & get_value(unsigned id) const {
SASSERT(m_value_table.contains(id)); SASSERT(m_value_table.contains(id));
@ -199,6 +200,8 @@ public:
sort * mk_rm_sort() { return m().mk_sort(m_fid, ROUNDING_MODE_SORT); } sort * mk_rm_sort() { return m().mk_sort(m_fid, ROUNDING_MODE_SORT); }
bool is_float(sort * s) { return is_sort_of(s, m_fid, FLOAT_SORT); } bool is_float(sort * s) { return is_sort_of(s, m_fid, FLOAT_SORT); }
bool is_rm(sort * s) { return is_sort_of(s, m_fid, ROUNDING_MODE_SORT); } bool is_rm(sort * s) { return is_sort_of(s, m_fid, ROUNDING_MODE_SORT); }
bool is_float(expr * e) { return is_float(m_manager.get_sort(e)); }
bool is_rm(expr * e) { return is_rm(m_manager.get_sort(e)); }
unsigned get_ebits(sort * s); unsigned get_ebits(sort * s);
unsigned get_sbits(sort * s); unsigned get_sbits(sort * s);
@ -218,7 +221,7 @@ public:
app * mk_value(mpf const & v) { return m_plugin->mk_value(v); } app * mk_value(mpf const & v) { return m_plugin->mk_value(v); }
bool is_value(expr * n) { return m_plugin->is_value(n); } bool is_value(expr * n) { return m_plugin->is_value(n); }
bool is_value(expr * n, mpf & v) { return m_plugin->is_value(n, v); } bool is_value(expr * n, mpf & v) { return m_plugin->is_value(n, v); }
bool is_rm(expr * n, mpf_rounding_mode & v) { return m_plugin->is_rm(n, v); } bool is_rm_value(expr * n, mpf_rounding_mode & v) { return m_plugin->is_rm_value(n, v); }
app * mk_pzero(unsigned ebits, unsigned sbits); app * mk_pzero(unsigned ebits, unsigned sbits);
app * mk_nzero(unsigned ebits, unsigned sbits); app * mk_nzero(unsigned ebits, unsigned sbits);

View file

@ -28,9 +28,10 @@ fpa2bv_converter::fpa2bv_converter(ast_manager & m) :
m(m), m(m),
m_simp(m), m_simp(m),
m_util(m), m_util(m),
m_bv_util(m),
m_arith_util(m),
m_mpf_manager(m_util.fm()), m_mpf_manager(m_util.fm()),
m_mpz_manager(m_mpf_manager.mpz_manager()), m_mpz_manager(m_mpf_manager.mpz_manager()),
m_bv_util(m),
extra_assertions(m) { extra_assertions(m) {
m_plugin = static_cast<float_decl_plugin*>(m.get_plugin(m.mk_family_id("float"))); m_plugin = static_cast<float_decl_plugin*>(m.get_plugin(m.mk_family_id("float")));
} }
@ -268,7 +269,7 @@ void fpa2bv_converter::mk_rm_const(func_decl * f, expr_ref & result) {
result = r; result = r;
} }
else { else {
SASSERT(is_rm_sort(f->get_range())); SASSERT(is_rm(f->get_range()));
result = m.mk_fresh_const( result = m.mk_fresh_const(
#ifdef Z3DEBUG #ifdef Z3DEBUG
@ -281,6 +282,10 @@ void fpa2bv_converter::mk_rm_const(func_decl * f, expr_ref & result) {
m_rm_const2bv.insert(f, result); m_rm_const2bv.insert(f, result);
m.inc_ref(f); m.inc_ref(f);
m.inc_ref(result); m.inc_ref(result);
expr_ref rcc(m);
rcc = bu().mk_ule(result, bu().mk_numeral(4, 3));
extra_assertions.push_back(rcc);
} }
} }
@ -1847,6 +1852,55 @@ void fpa2bv_converter::mk_to_float(func_decl * f, unsigned num, expr * const * a
// Just keep it here, as there will be something else that uses it. // Just keep it here, as there will be something else that uses it.
mk_triple(args[0], args[1], args[2], result); mk_triple(args[0], args[1], args[2], result);
} }
else if (num == 3 &&
m_bv_util.is_bv(args[0]) &&
m_arith_util.is_numeral(args[1]) &&
m_arith_util.is_numeral(args[2]))
{
// Three arguments, some of them are not numerals.
SASSERT(m_util.is_float(f->get_range()));
unsigned ebits = m_util.get_ebits(f->get_range());
unsigned sbits = m_util.get_sbits(f->get_range());
expr * rm = args[0];
rational q;
if (!m_arith_util.is_numeral(args[1], q))
NOT_IMPLEMENTED_YET();
rational e;
if (!m_arith_util.is_numeral(args[2], e))
NOT_IMPLEMENTED_YET();
SASSERT(e.is_int64());
SASSERT(m_mpz_manager.eq(e.to_mpq().denominator(), 1));
mpf nte, nta, tp, tn, tz;
m_mpf_manager.set(nte, ebits, sbits, MPF_ROUND_NEAREST_TEVEN, q.to_mpq(), e.to_mpq().numerator());
m_mpf_manager.set(nta, ebits, sbits, MPF_ROUND_NEAREST_TAWAY, q.to_mpq(), e.to_mpq().numerator());
m_mpf_manager.set(tp, ebits, sbits, MPF_ROUND_TOWARD_POSITIVE, q.to_mpq(), e.to_mpq().numerator());
m_mpf_manager.set(tn, ebits, sbits, MPF_ROUND_TOWARD_NEGATIVE, q.to_mpq(), e.to_mpq().numerator());
m_mpf_manager.set(tz, ebits, sbits, MPF_ROUND_TOWARD_ZERO, q.to_mpq(), e.to_mpq().numerator());
app_ref a_nte(m), a_nta(m), a_tp(m), a_tn(m), a_tz(m);
a_nte = m_plugin->mk_value(nte);
a_nta = m_plugin->mk_value(nta);
a_tp = m_plugin->mk_value(tp);
a_tn = m_plugin->mk_value(tn);
a_tz = m_plugin->mk_value(tz);
expr_ref bv_nte(m), bv_nta(m), bv_tp(m), bv_tn(m), bv_tz(m);
mk_value(a_nte->get_decl(), 0, 0, bv_nte);
mk_value(a_nta->get_decl(), 0, 0, bv_nta);
mk_value(a_tp->get_decl(), 0, 0, bv_tp);
mk_value(a_tn->get_decl(), 0, 0, bv_tn);
mk_value(a_tz->get_decl(), 0, 0, bv_tz);
mk_ite(m.mk_eq(rm, m_bv_util.mk_numeral(BV_RM_TO_POSITIVE, 3)), bv_tn, bv_tz, result);
mk_ite(m.mk_eq(rm, m_bv_util.mk_numeral(BV_RM_TO_POSITIVE, 3)), bv_tp, result, result);
mk_ite(m.mk_eq(rm, m_bv_util.mk_numeral(BV_RM_TIES_TO_AWAY, 3)), bv_nta, result, result);
mk_ite(m.mk_eq(rm, m_bv_util.mk_numeral(BV_RM_TIES_TO_EVEN, 3)), bv_nte, result, result);
}
else if (num == 1 && m_bv_util.is_bv(args[0])) { else if (num == 1 && m_bv_util.is_bv(args[0])) {
sort * s = f->get_range(); sort * s = f->get_range();
unsigned to_sbits = m_util.get_sbits(s); unsigned to_sbits = m_util.get_sbits(s);
@ -1862,7 +1916,9 @@ void fpa2bv_converter::mk_to_float(func_decl * f, unsigned num, expr * const * a
m_bv_util.mk_extract(sz - 2, sz - to_ebits - 1, bv), m_bv_util.mk_extract(sz - 2, sz - to_ebits - 1, bv),
result); result);
} }
else if (num == 2 && is_app(args[1]) && m_util.is_float(m.get_sort(args[1]))) { else if (num == 2 &&
is_app(args[1]) &&
m_util.is_float(m.get_sort(args[1]))) {
// We also support float to float conversion // We also support float to float conversion
sort * s = f->get_range(); sort * s = f->get_range();
expr_ref rm(m), x(m); expr_ref rm(m), x(m);
@ -2016,9 +2072,10 @@ void fpa2bv_converter::mk_to_float(func_decl * f, unsigned num, expr * const * a
mk_ite(c1, v1, result, result); mk_ite(c1, v1, result, result);
} }
} }
else { else if (num == 2 &&
m_util.is_rm(args[0]),
m_arith_util.is_real(args[1])) {
// .. other than that, we only support rationals for asFloat // .. other than that, we only support rationals for asFloat
SASSERT(num == 2);
SASSERT(m_util.is_float(f->get_range())); SASSERT(m_util.is_float(f->get_range()));
unsigned ebits = m_util.get_ebits(f->get_range()); unsigned ebits = m_util.get_ebits(f->get_range());
unsigned sbits = m_util.get_sbits(f->get_range()); unsigned sbits = m_util.get_sbits(f->get_range());
@ -2044,7 +2101,6 @@ void fpa2bv_converter::mk_to_float(func_decl * f, unsigned num, expr * const * a
SASSERT(m_util.au().is_numeral(args[1])); SASSERT(m_util.au().is_numeral(args[1]));
rational q; rational q;
SASSERT(m_util.au().is_numeral(args[1]));
m_util.au().is_numeral(args[1], q); m_util.au().is_numeral(args[1], q);
mpf v; mpf v;
@ -2058,6 +2114,8 @@ void fpa2bv_converter::mk_to_float(func_decl * f, unsigned num, expr * const * a
m_util.fm().del(v); m_util.fm().del(v);
} }
else
UNREACHABLE();
SASSERT(is_well_sorted(m, result)); SASSERT(is_well_sorted(m, result));
} }

View file

@ -45,9 +45,10 @@ class fpa2bv_converter {
ast_manager & m; ast_manager & m;
basic_simplifier_plugin m_simp; basic_simplifier_plugin m_simp;
float_util m_util; float_util m_util;
bv_util m_bv_util;
arith_util m_arith_util;
mpf_manager & m_mpf_manager; mpf_manager & m_mpf_manager;
unsynch_mpz_manager & m_mpz_manager; unsynch_mpz_manager & m_mpz_manager;
bv_util m_bv_util;
float_decl_plugin * m_plugin; float_decl_plugin * m_plugin;
obj_map<func_decl, expr*> m_const2bv; obj_map<func_decl, expr*> m_const2bv;
@ -64,8 +65,9 @@ public:
bool is_float(sort * s) { return m_util.is_float(s); } bool is_float(sort * s) { return m_util.is_float(s); }
bool is_float(expr * e) { return is_app(e) && m_util.is_float(to_app(e)->get_decl()->get_range()); } bool is_float(expr * e) { return is_app(e) && m_util.is_float(to_app(e)->get_decl()->get_range()); }
bool is_rm(expr * e) { return m_util.is_rm(e); }
bool is_rm(sort * s) { return m_util.is_rm(s); }
bool is_float_family(func_decl * f) { return f->get_family_id() == m_util.get_family_id(); } bool is_float_family(func_decl * f) { return f->get_family_id() == m_util.get_family_id(); }
bool is_rm_sort(sort * s) { return m_util.is_rm(s); }
void mk_triple(expr * sign, expr * significand, expr * exponent, expr_ref & result) { void mk_triple(expr * sign, expr * significand, expr * exponent, expr_ref & result) {
SASSERT(m_bv_util.is_bv(sign) && m_bv_util.get_bv_size(sign) == 1); SASSERT(m_bv_util.is_bv(sign) && m_bv_util.get_bv_size(sign) == 1);

View file

@ -78,17 +78,23 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg {
return BR_DONE; return BR_DONE;
} }
if (num == 0 && f->get_family_id() == null_family_id && m_conv.is_rm_sort(f->get_range())) { if (num == 0 && f->get_family_id() == null_family_id && m_conv.is_rm(f->get_range())) {
m_conv.mk_rm_const(f, result); m_conv.mk_rm_const(f, result);
return BR_DONE; return BR_DONE;
} }
if (m().is_eq(f)) { if (m().is_eq(f)) {
SASSERT(num == 2); SASSERT(num == 2);
if (m_conv.is_float(args[0])) { SASSERT(m().get_sort(args[0]) == m().get_sort(args[1]));
sort * ds = f->get_domain()[0];
if (m_conv.is_float(ds)) {
m_conv.mk_eq(args[0], args[1], result); m_conv.mk_eq(args[0], args[1], result);
return BR_DONE; return BR_DONE;
} }
else if (m_conv.is_rm(ds)) {
result = m().mk_eq(args[0], args[1]);
return BR_DONE;
}
return BR_FAILED; return BR_FAILED;
} }

View file

@ -41,7 +41,7 @@ void quasi_macros::find_occurrences(expr * e) {
// we remember whether we have seen an expr once, or more than once; // we remember whether we have seen an expr once, or more than once;
// when we see it the second time, we don't have to visit it another time, // when we see it the second time, we don't have to visit it another time,
// as we are only intersted in finding unique function applications. // as we are only interested in finding unique function applications.
m_visited_once.reset(); m_visited_once.reset();
m_visited_more.reset(); m_visited_more.reset();
@ -61,7 +61,7 @@ void quasi_macros::find_occurrences(expr * e) {
case AST_VAR: break; case AST_VAR: break;
case AST_QUANTIFIER: m_todo.push_back(to_quantifier(cur)->get_expr()); break; case AST_QUANTIFIER: m_todo.push_back(to_quantifier(cur)->get_expr()); break;
case AST_APP: case AST_APP:
if (is_uninterp(cur) && !is_ground(cur)) { if (is_non_ground_uninterp(cur)) {
func_decl * f = to_app(cur)->get_decl(); func_decl * f = to_app(cur)->get_decl();
m_occurrences.insert_if_not_there(f, 0); m_occurrences.insert_if_not_there(f, 0);
occurrences_map::iterator it = m_occurrences.find_iterator(f); occurrences_map::iterator it = m_occurrences.find_iterator(f);
@ -76,6 +76,10 @@ void quasi_macros::find_occurrences(expr * e) {
} }
}; };
bool quasi_macros::is_non_ground_uninterp(expr const * e) const {
return is_non_ground(e) && is_uninterp(e);
}
bool quasi_macros::is_unique(func_decl * f) const { bool quasi_macros::is_unique(func_decl * f) const {
return m_occurrences.find(f) == 1; return m_occurrences.find(f) == 1;
} }
@ -149,6 +153,7 @@ bool quasi_macros::is_quasi_macro(expr * e, app_ref & a, expr_ref & t) const {
// Our definition of a quasi-macro: // Our definition of a quasi-macro:
// Forall X. f[X] = T[X], where f[X] is a term starting with symbol f, f is uninterpreted, // Forall X. f[X] = T[X], where f[X] is a term starting with symbol f, f is uninterpreted,
// f[X] contains all universally quantified variables, and f does not occur in T[X]. // f[X] contains all universally quantified variables, and f does not occur in T[X].
TRACE("quasi_macros", tout << "Checking for quasi macro: " << mk_pp(e, m_manager) << std::endl;);
if (is_quantifier(e) && to_quantifier(e)->is_forall()) { if (is_quantifier(e) && to_quantifier(e)->is_forall()) {
quantifier * q = to_quantifier(e); quantifier * q = to_quantifier(e);
@ -157,23 +162,23 @@ bool quasi_macros::is_quasi_macro(expr * e, app_ref & a, expr_ref & t) const {
expr * lhs = to_app(qe)->get_arg(0); expr * lhs = to_app(qe)->get_arg(0);
expr * rhs = to_app(qe)->get_arg(1); expr * rhs = to_app(qe)->get_arg(1);
if (is_uninterp(lhs) && is_unique(to_app(lhs)->get_decl()) && if (is_non_ground_uninterp(lhs) && is_unique(to_app(lhs)->get_decl()) &&
!depends_on(rhs, to_app(lhs)->get_decl()) && fully_depends_on(to_app(lhs), q)) { !depends_on(rhs, to_app(lhs)->get_decl()) && fully_depends_on(to_app(lhs), q)) {
a = to_app(lhs); a = to_app(lhs);
t = rhs; t = rhs;
return true; return true;
} else if (is_uninterp(rhs) && is_unique(to_app(rhs)->get_decl()) && } else if (is_non_ground_uninterp(rhs) && is_unique(to_app(rhs)->get_decl()) &&
!depends_on(lhs, to_app(rhs)->get_decl()) && fully_depends_on(to_app(rhs), q)) { !depends_on(lhs, to_app(rhs)->get_decl()) && fully_depends_on(to_app(rhs), q)) {
a = to_app(rhs); a = to_app(rhs);
t = lhs; t = lhs;
return true; return true;
} }
} else if (m_manager.is_not(qe) && is_uninterp(to_app(qe)->get_arg(0)) && } else if (m_manager.is_not(qe) && is_non_ground_uninterp(to_app(qe)->get_arg(0)) &&
is_unique(to_app(to_app(qe)->get_arg(0))->get_decl())) { // this is like f(...) = false is_unique(to_app(to_app(qe)->get_arg(0))->get_decl())) { // this is like f(...) = false
a = to_app(to_app(qe)->get_arg(0)); a = to_app(to_app(qe)->get_arg(0));
t = m_manager.mk_false(); t = m_manager.mk_false();
return true; return true;
} else if (is_uninterp(qe) && is_unique(to_app(qe)->get_decl())) { // this is like f(...) = true } else if (is_non_ground_uninterp(qe) && is_unique(to_app(qe)->get_decl())) { // this is like f(...) = true
a = to_app(qe); a = to_app(qe);
t = m_manager.mk_true(); t = m_manager.mk_true();
return true; return true;

View file

@ -45,6 +45,7 @@ class quasi_macros {
expr_mark m_visited_more; expr_mark m_visited_more;
bool is_unique(func_decl * f) const; bool is_unique(func_decl * f) const;
bool is_non_ground_uninterp(expr const * e) const;
bool fully_depends_on(app * a, quantifier * q) const; bool fully_depends_on(app * a, quantifier * q) const;
bool depends_on(expr * e, func_decl * f) const; bool depends_on(expr * e, func_decl * f) const;

View file

@ -323,6 +323,9 @@ MK_PARAMETRIC_UNARY_REDUCE(reduce_sign_extend, mk_sign_extend);
br_status reduce_app(func_decl * f, unsigned num, expr * const * args, expr_ref & result, proof_ref & result_pr) { br_status reduce_app(func_decl * f, unsigned num, expr * const * args, expr_ref & result, proof_ref & result_pr) {
result_pr = 0; result_pr = 0;
TRACE("bit_blaster", tout << f->get_name() << " ";
for (unsigned i = 0; i < num; ++i) tout << mk_pp(args[i], m()) << " ";
tout << "\n";);
if (num == 0 && f->get_family_id() == null_family_id && butil().is_bv_sort(f->get_range())) { if (num == 0 && f->get_family_id() == null_family_id && butil().is_bv_sort(f->get_range())) {
mk_const(f, result); mk_const(f, result);
return BR_DONE; return BR_DONE;

View file

@ -828,6 +828,12 @@ void bit_blaster_tpl<Cfg>::mk_eq(unsigned sz, expr * const * a_bits, expr * cons
template<typename Cfg> template<typename Cfg>
void bit_blaster_tpl<Cfg>::mk_rotate_left(unsigned sz, expr * const * a_bits, unsigned n, expr_ref_vector & out_bits) { void bit_blaster_tpl<Cfg>::mk_rotate_left(unsigned sz, expr * const * a_bits, unsigned n, expr_ref_vector & out_bits) {
TRACE("bit_blaster", tout << n << ": " << sz << " ";
for (unsigned i = 0; i < sz; ++i) {
tout << mk_pp(a_bits[i], m()) << " ";
}
tout << "\n";
);
n = n % sz; n = n % sz;
for (unsigned i = sz - n; i < sz; i++) for (unsigned i = sz - n; i < sz; i++)
out_bits.push_back(a_bits[i]); out_bits.push_back(a_bits[i]);
@ -974,7 +980,7 @@ void bit_blaster_tpl<Cfg>::mk_ashr(unsigned sz, expr * const * a_bits, expr * co
mk_ite(eqs.get(i - j), a_bits[sz - j - 1], out, new_out); mk_ite(eqs.get(i - j), a_bits[sz - j - 1], out, new_out);
out = new_out; out = new_out;
} }
TRACE("bit_blaster_tpl<Cfg>", tout << (sz - i - 1) << " :\n" << mk_pp(out, m()) << "\n";); TRACE("bit_blaster", tout << (sz - i - 1) << " :\n" << mk_pp(out, m()) << "\n";);
out_bits.set(sz - i - 1, out); out_bits.set(sz - i - 1, out);
} }
} }
@ -1004,7 +1010,7 @@ void bit_blaster_tpl<Cfg>::mk_ext_rotate_left_right(unsigned sz, expr * const *
out = a_bits[i]; out = a_bits[i];
for (unsigned j = 1; j < sz; j++) { for (unsigned j = 1; j < sz; j++) {
expr_ref new_out(m()); expr_ref new_out(m());
unsigned src = (Left ? (i - j) : (i + j)) % sz; unsigned src = (Left ? (sz + i - j) : (i + j)) % sz;
mk_ite(eqs.get(j), a_bits[src], out, new_out); mk_ite(eqs.get(j), a_bits[src], out, new_out);
out = new_out; out = new_out;
} }

View file

@ -21,6 +21,7 @@ Notes:
#include"poly_rewriter_def.h" #include"poly_rewriter_def.h"
#include"ast_smt2_pp.h" #include"ast_smt2_pp.h"
mk_extract_proc::mk_extract_proc(bv_util & u): mk_extract_proc::mk_extract_proc(bv_util & u):
m_util(u), m_util(u),
m_high(0), m_high(0),

View file

@ -82,7 +82,7 @@ br_status float_rewriter::mk_to_float(func_decl * f, unsigned num_args, expr * c
if (num_args == 2) { if (num_args == 2) {
mpf_rounding_mode rm; mpf_rounding_mode rm;
if (!m_util.is_rm(args[0], rm)) if (!m_util.is_rm_value(args[0], rm))
return BR_FAILED; return BR_FAILED;
rational q; rational q;
@ -109,12 +109,12 @@ br_status float_rewriter::mk_to_float(func_decl * f, unsigned num_args, expr * c
return BR_FAILED; return BR_FAILED;
} }
else if (num_args == 3 && else if (num_args == 3 &&
m_util.is_rm(m().get_sort(args[0])) && m_util.is_rm(args[0]) &&
m_util.au().is_real(args[1]) && m_util.au().is_real(args[1]) &&
m_util.au().is_int(args[2])) { m_util.au().is_int(args[2])) {
mpf_rounding_mode rm; mpf_rounding_mode rm;
if (!m_util.is_rm(args[0], rm)) if (!m_util.is_rm_value(args[0], rm))
return BR_FAILED; return BR_FAILED;
rational q; rational q;
@ -130,7 +130,6 @@ br_status float_rewriter::mk_to_float(func_decl * f, unsigned num_args, expr * c
m_util.fm().set(v, ebits, sbits, rm, q.to_mpq(), e.to_mpq().numerator()); m_util.fm().set(v, ebits, sbits, rm, q.to_mpq(), e.to_mpq().numerator());
result = m_util.mk_value(v); result = m_util.mk_value(v);
m_util.fm().del(v); m_util.fm().del(v);
// TRACE("fp_rewriter", tout << "result: " << result << std::endl; );
return BR_DONE; return BR_DONE;
} }
else { else {
@ -140,7 +139,7 @@ br_status float_rewriter::mk_to_float(func_decl * f, unsigned num_args, expr * c
br_status float_rewriter::mk_add(expr * arg1, expr * arg2, expr * arg3, expr_ref & result) { br_status float_rewriter::mk_add(expr * arg1, expr * arg2, expr * arg3, expr_ref & result) {
mpf_rounding_mode rm; mpf_rounding_mode rm;
if (m_util.is_rm(arg1, rm)) { if (m_util.is_rm_value(arg1, rm)) {
scoped_mpf v2(m_util.fm()), v3(m_util.fm()); scoped_mpf v2(m_util.fm()), v3(m_util.fm());
if (m_util.is_value(arg2, v2) && m_util.is_value(arg3, v3)) { if (m_util.is_value(arg2, v2) && m_util.is_value(arg3, v3)) {
scoped_mpf t(m_util.fm()); scoped_mpf t(m_util.fm());
@ -161,7 +160,7 @@ br_status float_rewriter::mk_sub(expr * arg1, expr * arg2, expr * arg3, expr_ref
br_status float_rewriter::mk_mul(expr * arg1, expr * arg2, expr * arg3, expr_ref & result) { br_status float_rewriter::mk_mul(expr * arg1, expr * arg2, expr * arg3, expr_ref & result) {
mpf_rounding_mode rm; mpf_rounding_mode rm;
if (m_util.is_rm(arg1, rm)) { if (m_util.is_rm_value(arg1, rm)) {
scoped_mpf v2(m_util.fm()), v3(m_util.fm()); scoped_mpf v2(m_util.fm()), v3(m_util.fm());
if (m_util.is_value(arg2, v2) && m_util.is_value(arg3, v3)) { if (m_util.is_value(arg2, v2) && m_util.is_value(arg3, v3)) {
scoped_mpf t(m_util.fm()); scoped_mpf t(m_util.fm());
@ -176,7 +175,7 @@ br_status float_rewriter::mk_mul(expr * arg1, expr * arg2, expr * arg3, expr_ref
br_status float_rewriter::mk_div(expr * arg1, expr * arg2, expr * arg3, expr_ref & result) { br_status float_rewriter::mk_div(expr * arg1, expr * arg2, expr * arg3, expr_ref & result) {
mpf_rounding_mode rm; mpf_rounding_mode rm;
if (m_util.is_rm(arg1, rm)) { if (m_util.is_rm_value(arg1, rm)) {
scoped_mpf v2(m_util.fm()), v3(m_util.fm()); scoped_mpf v2(m_util.fm()), v3(m_util.fm());
if (m_util.is_value(arg2, v2) && m_util.is_value(arg3, v3)) { if (m_util.is_value(arg2, v2) && m_util.is_value(arg3, v3)) {
scoped_mpf t(m_util.fm()); scoped_mpf t(m_util.fm());
@ -287,7 +286,7 @@ br_status float_rewriter::mk_max(expr * arg1, expr * arg2, expr_ref & result) {
br_status float_rewriter::mk_fused_ma(expr * arg1, expr * arg2, expr * arg3, expr * arg4, expr_ref & result) { br_status float_rewriter::mk_fused_ma(expr * arg1, expr * arg2, expr * arg3, expr * arg4, expr_ref & result) {
mpf_rounding_mode rm; mpf_rounding_mode rm;
if (m_util.is_rm(arg1, rm)) { if (m_util.is_rm_value(arg1, rm)) {
scoped_mpf v2(m_util.fm()), v3(m_util.fm()), v4(m_util.fm()); scoped_mpf v2(m_util.fm()), v3(m_util.fm()), v4(m_util.fm());
if (m_util.is_value(arg2, v2) && m_util.is_value(arg3, v3) && m_util.is_value(arg4, v4)) { if (m_util.is_value(arg2, v2) && m_util.is_value(arg3, v3) && m_util.is_value(arg4, v4)) {
scoped_mpf t(m_util.fm()); scoped_mpf t(m_util.fm());
@ -302,7 +301,7 @@ br_status float_rewriter::mk_fused_ma(expr * arg1, expr * arg2, expr * arg3, exp
br_status float_rewriter::mk_sqrt(expr * arg1, expr * arg2, expr_ref & result) { br_status float_rewriter::mk_sqrt(expr * arg1, expr * arg2, expr_ref & result) {
mpf_rounding_mode rm; mpf_rounding_mode rm;
if (m_util.is_rm(arg1, rm)) { if (m_util.is_rm_value(arg1, rm)) {
scoped_mpf v2(m_util.fm()); scoped_mpf v2(m_util.fm());
if (m_util.is_value(arg2, v2)) { if (m_util.is_value(arg2, v2)) {
scoped_mpf t(m_util.fm()); scoped_mpf t(m_util.fm());
@ -317,7 +316,7 @@ br_status float_rewriter::mk_sqrt(expr * arg1, expr * arg2, expr_ref & result) {
br_status float_rewriter::mk_round(expr * arg1, expr * arg2, expr_ref & result) { br_status float_rewriter::mk_round(expr * arg1, expr * arg2, expr_ref & result) {
mpf_rounding_mode rm; mpf_rounding_mode rm;
if (m_util.is_rm(arg1, rm)) { if (m_util.is_rm_value(arg1, rm)) {
scoped_mpf v2(m_util.fm()); scoped_mpf v2(m_util.fm());
if (m_util.is_value(arg2, v2)) { if (m_util.is_value(arg2, v2)) {
scoped_mpf t(m_util.fm()); scoped_mpf t(m_util.fm());

View file

@ -547,6 +547,9 @@ public:
} }
}; };
#define STRINGIZE(x) #x
#define STRINGIZE_VALUE_OF(x) STRINGIZE(x)
class get_info_cmd : public cmd { class get_info_cmd : public cmd {
symbol m_error_behavior; symbol m_error_behavior;
symbol m_name; symbol m_name;
@ -584,7 +587,11 @@ public:
ctx.regular_stream() << "(:authors \"Leonardo de Moura and Nikolaj Bjorner\")" << std::endl; ctx.regular_stream() << "(:authors \"Leonardo de Moura and Nikolaj Bjorner\")" << std::endl;
} }
else if (opt == m_version) { else if (opt == m_version) {
ctx.regular_stream() << "(:version \"" << Z3_MAJOR_VERSION << "." << Z3_MINOR_VERSION << "." << Z3_BUILD_NUMBER << "\")" << std::endl; ctx.regular_stream() << "(:version \"" << Z3_MAJOR_VERSION << "." << Z3_MINOR_VERSION << "." << Z3_BUILD_NUMBER
#ifdef Z3GITHASH
<< " - build hashcode " << STRINGIZE_VALUE_OF(Z3GITHASH)
#endif
<< "\")" << std::endl;
} }
else if (opt == m_status) { else if (opt == m_status) {
ctx.regular_stream() << "(:status " << ctx.get_status() << ")" << std::endl; ctx.regular_stream() << "(:status " << ctx.get_status() << ")" << std::endl;

View file

@ -978,13 +978,14 @@ namespace datalog {
} }
} }
void rule::get_vars(ptr_vector<sort>& sorts) const { void rule::get_vars(ast_manager& m, ptr_vector<sort>& sorts) const {
sorts.reset(); sorts.reset();
used_vars used; used_vars used;
get_used_vars(used); get_used_vars(used);
unsigned sz = used.get_max_found_var_idx_plus_1(); unsigned sz = used.get_max_found_var_idx_plus_1();
for (unsigned i = 0; i < sz; ++i) { for (unsigned i = 0; i < sz; ++i) {
sorts.push_back(used.get(i)); sort* s = used.get(i);
sorts.push_back(s?s:m.mk_bool_sort());
} }
} }

View file

@ -304,7 +304,7 @@ namespace datalog {
void norm_vars(rule_manager & rm); void norm_vars(rule_manager & rm);
void get_vars(ptr_vector<sort>& sorts) const; void get_vars(ast_manager& m, ptr_vector<sort>& sorts) const;
void to_formula(expr_ref& result) const; void to_formula(expr_ref& result) const;

View file

@ -290,7 +290,7 @@ namespace datalog {
} }
} }
TRACE("dl_dr", TRACE("dl_dr",
tout << r.get_decl()->get_name() << "\n"; tout << mk_pp(r.get_head(), m) << " :- \n";
for (unsigned i = 0; i < body.size(); ++i) { for (unsigned i = 0; i < body.size(); ++i) {
tout << mk_pp(body[i].get(), m) << "\n"; tout << mk_pp(body[i].get(), m) << "\n";
}); });

View file

@ -148,7 +148,7 @@ namespace datalog {
void mk_qrule_vars(datalog::rule const& r, unsigned rule_id, expr_ref_vector& sub) { void mk_qrule_vars(datalog::rule const& r, unsigned rule_id, expr_ref_vector& sub) {
ptr_vector<sort> sorts; ptr_vector<sort> sorts;
r.get_vars(sorts); r.get_vars(m, sorts);
// populate substitution of bound variables. // populate substitution of bound variables.
sub.reset(); sub.reset();
sub.resize(sorts.size()); sub.resize(sorts.size());
@ -421,7 +421,7 @@ namespace datalog {
ptr_vector<sort> rule_vars; ptr_vector<sort> rule_vars;
expr_ref_vector args(m), conjs(m); expr_ref_vector args(m), conjs(m);
r.get_vars(rule_vars); r.get_vars(m, rule_vars);
obj_hashtable<expr> used_vars; obj_hashtable<expr> used_vars;
unsigned num_vars = 0; unsigned num_vars = 0;
for (unsigned i = 0; i < r.get_decl()->get_arity(); ++i) { for (unsigned i = 0; i < r.get_decl()->get_arity(); ++i) {
@ -514,7 +514,7 @@ namespace datalog {
unsigned sz = r->get_uninterpreted_tail_size(); unsigned sz = r->get_uninterpreted_tail_size();
ptr_vector<sort> rule_vars; ptr_vector<sort> rule_vars;
r->get_vars(rule_vars); r->get_vars(m, rule_vars);
args.append(prop->get_num_args(), prop->get_args()); args.append(prop->get_num_args(), prop->get_args());
expr_ref_vector sub = mk_skolem_binding(*r, rule_vars, args); expr_ref_vector sub = mk_skolem_binding(*r, rule_vars, args);
if (sub.empty() && sz == 0) { if (sub.empty() && sz == 0) {
@ -803,7 +803,7 @@ namespace datalog {
func_decl* p = r.get_decl(); func_decl* p = r.get_decl();
ptr_vector<func_decl> const& succs = *dtu.get_datatype_constructors(m.get_sort(path)); ptr_vector<func_decl> const& succs = *dtu.get_datatype_constructors(m.get_sort(path));
// populate substitution of bound variables. // populate substitution of bound variables.
r.get_vars(sorts); r.get_vars(m, sorts);
sub.reset(); sub.reset();
sub.resize(sorts.size()); sub.resize(sorts.size());
for (unsigned k = 0; k < r.get_decl()->get_arity(); ++k) { for (unsigned k = 0; k < r.get_decl()->get_arity(); ++k) {
@ -1327,7 +1327,7 @@ namespace datalog {
void mk_rule_vars(rule& r, unsigned level, unsigned rule_id, expr_ref_vector& sub) { void mk_rule_vars(rule& r, unsigned level, unsigned rule_id, expr_ref_vector& sub) {
ptr_vector<sort> sorts; ptr_vector<sort> sorts;
r.get_vars(sorts); r.get_vars(m, sorts);
// populate substitution of bound variables. // populate substitution of bound variables.
sub.reset(); sub.reset();
sub.resize(sorts.size()); sub.resize(sorts.size());

View file

@ -87,7 +87,7 @@ namespace datalog {
else { else {
if (m_next_var == 0) { if (m_next_var == 0) {
ptr_vector<sort> vars; ptr_vector<sort> vars;
r.get_vars(vars); r.get_vars(m, vars);
m_next_var = vars.size() + 1; m_next_var = vars.size() + 1;
} }
v = m.mk_var(m_next_var, m.get_sort(e)); v = m.mk_var(m_next_var, m.get_sort(e));

View file

@ -26,6 +26,7 @@ Revision History:
#include "dl_mk_interp_tail_simplifier.h" #include "dl_mk_interp_tail_simplifier.h"
#include "fixedpoint_params.hpp" #include "fixedpoint_params.hpp"
#include "scoped_proof.h" #include "scoped_proof.h"
#include "model_v2_pp.h"
namespace datalog { namespace datalog {
@ -67,11 +68,17 @@ namespace datalog {
func_decl* p = m_new_funcs[i].get(); func_decl* p = m_new_funcs[i].get();
func_decl* q = m_old_funcs[i].get(); func_decl* q = m_old_funcs[i].get();
func_interp* f = model->get_func_interp(p); func_interp* f = model->get_func_interp(p);
if (!f) continue;
expr_ref body(m); expr_ref body(m);
unsigned arity_p = p->get_arity(); unsigned arity_p = p->get_arity();
unsigned arity_q = q->get_arity(); unsigned arity_q = q->get_arity();
TRACE("dl",
model_v2_pp(tout, *model);
tout << mk_pp(p, m) << "\n";
tout << mk_pp(q, m) << "\n";);
SASSERT(0 < arity_p); SASSERT(0 < arity_p);
model->register_decl(p, f); SASSERT(f);
model->register_decl(p, f->copy());
func_interp* g = alloc(func_interp, m, arity_q); func_interp* g = alloc(func_interp, m, arity_q);
if (f) { if (f) {
@ -88,11 +95,12 @@ namespace datalog {
for (unsigned j = 0; j < arity_q; ++j) { for (unsigned j = 0; j < arity_q; ++j) {
sort* s = q->get_domain(j); sort* s = q->get_domain(j);
arg = m.mk_var(j, s); arg = m.mk_var(j, s);
expr* t = arg;
if (m_bv.is_bv_sort(s)) { if (m_bv.is_bv_sort(s)) {
expr* args[1] = { arg };
unsigned sz = m_bv.get_bv_size(s); unsigned sz = m_bv.get_bv_size(s);
for (unsigned k = 0; k < sz; ++k) { for (unsigned k = 0; k < sz; ++k) {
proj = m.mk_app(m_bv.get_family_id(), OP_BIT2BOOL, 1, args); parameter p(k);
proj = m.mk_app(m_bv.get_family_id(), OP_BIT2BOOL, 1, &p, 1, &t);
sub.insert(m.mk_var(idx++, m.mk_bool_sort()), proj); sub.insert(m.mk_var(idx++, m.mk_bool_sort()), proj);
} }
} }

View file

@ -62,7 +62,7 @@ namespace datalog {
rule_ref r(const_cast<rule*>(&rl), rm); rule_ref r(const_cast<rule*>(&rl), rm);
ptr_vector<sort> sorts; ptr_vector<sort> sorts;
expr_ref_vector revsub(m), conjs(m); expr_ref_vector revsub(m), conjs(m);
rl.get_vars(sorts); rl.get_vars(m, sorts);
revsub.resize(sorts.size()); revsub.resize(sorts.size());
svector<bool> valid(sorts.size(), true); svector<bool> valid(sorts.size(), true);
for (unsigned i = 0; i < sub.size(); ++i) { for (unsigned i = 0; i < sub.size(); ++i) {
@ -117,8 +117,8 @@ namespace datalog {
rule_ref res(rm); rule_ref res(rm);
bool_rewriter bwr(m); bool_rewriter bwr(m);
svector<bool> is_neg; svector<bool> is_neg;
tgt->get_vars(sorts1); tgt->get_vars(m, sorts1);
src.get_vars(sorts2); src.get_vars(m, sorts2);
mk_pred(head, src.get_head(), tgt->get_head()); mk_pred(head, src.get_head(), tgt->get_head());
for (unsigned i = 0; i < src.get_uninterpreted_tail_size(); ++i) { for (unsigned i = 0; i < src.get_uninterpreted_tail_size(); ++i) {

View file

@ -205,7 +205,6 @@ namespace datalog {
for (unsigned i = 0; i < rules.size(); ++i) { for (unsigned i = 0; i < rules.size(); ++i) {
app* head = rules[i]->get_head(); app* head = rules[i]->get_head();
expr_ref_vector conj(m); expr_ref_vector conj(m);
unsigned n = head->get_num_args()-1;
for (unsigned j = 0; j < head->get_num_args(); ++j) { for (unsigned j = 0; j < head->get_num_args(); ++j) {
expr* arg = head->get_arg(j); expr* arg = head->get_arg(j);
if (!is_var(arg)) { if (!is_var(arg)) {

View file

@ -199,7 +199,7 @@ namespace datalog {
expr_ref fml(m), cnst(m); expr_ref fml(m), cnst(m);
var_ref var(m); var_ref var(m);
ptr_vector<sort> sorts; ptr_vector<sort> sorts;
r.get_vars(sorts); r.get_vars(m, sorts);
m_uf.reset(); m_uf.reset();
m_terms.reset(); m_terms.reset();
m_var2cnst.reset(); m_var2cnst.reset();
@ -207,9 +207,6 @@ namespace datalog {
fml = m.mk_and(conjs.size(), conjs.c_ptr()); fml = m.mk_and(conjs.size(), conjs.c_ptr());
for (unsigned i = 0; i < sorts.size(); ++i) { for (unsigned i = 0; i < sorts.size(); ++i) {
if (!sorts[i]) {
sorts[i] = m.mk_bool_sort();
}
var = m.mk_var(i, sorts[i]); var = m.mk_var(i, sorts[i]);
cnst = m.mk_fresh_const("C", sorts[i]); cnst = m.mk_fresh_const("C", sorts[i]);
m_var2cnst.insert(var, cnst); m_var2cnst.insert(var, cnst);

View file

@ -143,11 +143,8 @@ namespace datalog {
expr_ref_vector result(m); expr_ref_vector result(m);
ptr_vector<sort> sorts; ptr_vector<sort> sorts;
expr_ref v(m), w(m); expr_ref v(m), w(m);
r.get_vars(sorts); r.get_vars(m, sorts);
for (unsigned i = 0; i < sorts.size(); ++i) { for (unsigned i = 0; i < sorts.size(); ++i) {
if (!sorts[i]) {
sorts[i] = m.mk_bool_sort();
}
v = m.mk_var(i, sorts[i]); v = m.mk_var(i, sorts[i]);
m_subst.apply(2, m_deltas, expr_offset(v, is_tgt?0:1), w); m_subst.apply(2, m_deltas, expr_offset(v, is_tgt?0:1), w);
result.push_back(w); result.push_back(w);
@ -423,6 +420,11 @@ namespace datalog {
} }
TRACE("dl", tout << "inlined rules after mutual inlining:\n" << m_inlined_rules; ); TRACE("dl", tout << "inlined rules after mutual inlining:\n" << m_inlined_rules; );
for (unsigned i = 0; i < m_inlined_rules.get_num_rules(); ++i) {
rule* r = m_inlined_rules.get_rule(i);
datalog::del_rule(m_mc, *r);
}
} }
bool mk_rule_inliner::transform_rule(rule_set const& orig, rule * r0, rule_set& tgt) { bool mk_rule_inliner::transform_rule(rule_set const& orig, rule * r0, rule_set& tgt) {

View file

@ -141,7 +141,7 @@ namespace datalog {
m_cache.reset(); m_cache.reset();
m_trail.reset(); m_trail.reset();
m_eqs.reset(); m_eqs.reset();
r.get_vars(vars); r.get_vars(m, vars);
unsigned num_vars = vars.size(); unsigned num_vars = vars.size();
for (unsigned j = 0; j < utsz; ++j) { for (unsigned j = 0; j < utsz; ++j) {
tail.push_back(mk_pred(num_vars, r.get_tail(j))); tail.push_back(mk_pred(num_vars, r.get_tail(j)));

View file

@ -1120,6 +1120,7 @@ namespace qe {
st->init(fml); st->init(fml);
st->m_vars.append(m_vars.size(), m_vars.c_ptr()); st->m_vars.append(m_vars.size(), m_vars.c_ptr());
SASSERT(invariant()); SASSERT(invariant());
TRACE("qe", tout << mk_pp(m_fml, m) << " child: " << mk_pp(fml, m) << "\n";);
return st; return st;
} }
@ -1133,6 +1134,7 @@ namespace qe {
m_branch_index.insert(branch_id, index); m_branch_index.insert(branch_id, index);
st->m_vars.append(m_vars.size(), m_vars.c_ptr()); st->m_vars.append(m_vars.size(), m_vars.c_ptr());
SASSERT(invariant()); SASSERT(invariant());
//TRACE("qe", tout << mk_pp(m_fml, m) << " child: " << mk_pp(st->fml(), m) << "\n";);
return st; return st;
} }
@ -1164,6 +1166,16 @@ namespace qe {
} }
} }
expr_ref abstract_variable(app* x, expr* fml) const {
expr_ref result(m);
expr* y = x;
expr_abstract(m, 0, 1, &y, fml, result);
symbol X(x->get_decl()->get_name());
sort* s = m.get_sort(x);
result = m.mk_exists(1, &s, &X, result);
return result;
}
void display_validate(std::ostream& out) const { void display_validate(std::ostream& out) const {
if (m_children.empty()) { if (m_children.empty()) {
return; return;
@ -1171,25 +1183,53 @@ namespace qe {
expr_ref q(m); expr_ref q(m);
expr* x = m_var; expr* x = m_var;
if (x) { if (x) {
expr_abstract(m, 0, 1, &x, m_fml, q); q = abstract_variable(m_var, m_fml);
ptr_vector<expr> fmls;
expr_ref_vector fmls(m);
expr_ref fml(m);
for (unsigned i = 0; i < m_children.size(); ++i) { for (unsigned i = 0; i < m_children.size(); ++i) {
expr* fml = m_children[i]->fml(); search_tree const& child = *m_children[i];
fml = child.fml();
if (fml) { if (fml) {
// abstract free variables in children.
ptr_vector<app> child_vars, new_vars;
child_vars.append(child.m_vars.size(), child.m_vars.c_ptr());
if (child.m_var) {
child_vars.push_back(child.m_var);
}
for (unsigned j = 0; j < child_vars.size(); ++j) {
if (!m_vars.contains(child_vars[j]) &&
!new_vars.contains(child_vars[j])) {
fml = abstract_variable(child_vars[j], fml);
new_vars.push_back(child_vars[j]);
}
}
fmls.push_back(fml); fmls.push_back(fml);
} }
} }
symbol X(m_var->get_decl()->get_name()); bool_rewriter(m).mk_or(fmls.size(), fmls.c_ptr(), fml);
sort* s = m.get_sort(x);
q = m.mk_exists(1, &s, &X, q); fml = m.mk_not(m.mk_iff(q, fml));
expr_ref tmp(m);
bool_rewriter(m).mk_or(fmls.size(), fmls.c_ptr(), tmp);
expr_ref f(m.mk_not(m.mk_iff(q, tmp)), m);
ast_smt_pp pp(m); ast_smt_pp pp(m);
out << "(echo " << m_var->get_decl()->get_name() << ")\n"; out << "; eliminate " << mk_pp(m_var, m) << "\n";
out << "(push)\n"; out << "(push)\n";
pp.display_smt2(out, f); pp.display_smt2(out, fml);
out << "(pop)\n\n"; out << "(pop)\n\n";
DEBUG_CODE(
smt_params params;
params.m_simplify_bit2int = true;
params.m_arith_enum_const_mod = true;
params.m_bv_enable_int2bv2int = true;
params.m_relevancy_lvl = 0;
smt::kernel ctx(m, params);
ctx.assert_expr(fml);
lbool is_sat = ctx.check();
if (is_sat == l_true) {
std::cout << "; Validation failed:\n";
std::cout << mk_pp(fml, m) << "\n";
}
);
} }
for (unsigned i = 0; i < m_children.size(); ++i) { for (unsigned i = 0; i < m_children.size(); ++i) {
if (m_children[i]->fml()) { if (m_children[i]->fml()) {
@ -1410,13 +1450,9 @@ namespace qe {
m_solver.assert_expr(m_fml); m_solver.assert_expr(m_fml);
if (assumption) m_solver.assert_expr(assumption); if (assumption) m_solver.assert_expr(assumption);
bool is_sat = false; bool is_sat = false;
while (l_false != m_solver.check()) { while (l_true == m_solver.check()) {
is_sat = true; is_sat = true;
model_ref model; final_check();
m_solver.get_model(model);
TRACE("qe", model_v2_pp(tout, *model););
model_evaluator model_eval(*model);
final_check(model_eval);
} }
if (!is_sat) { if (!is_sat) {
@ -1466,14 +1502,30 @@ namespace qe {
private: private:
void final_check(model_evaluator& model_eval) { void final_check() {
TRACE("qe", tout << "\n";); model_ref model;
while (can_propagate_assignment(model_eval)) { m_solver.get_model(model);
propagate_assignment(model_eval); scoped_ptr<model_evaluator> model_eval = alloc(model_evaluator, *model);
while (true) {
TRACE("qe", model_v2_pp(tout, *model););
while (can_propagate_assignment(*model_eval)) {
propagate_assignment(*model_eval);
} }
VERIFY(CHOOSE_VAR == update_current(model_eval, true)); VERIFY(CHOOSE_VAR == update_current(*model_eval, true));
SASSERT(m_current->fml()); SASSERT(m_current->fml());
pop(model_eval); if (l_true != m_solver.check()) {
return;
}
m_solver.get_model(model);
model_eval = alloc(model_evaluator, *model);
search_tree* st = m_current;
update_current(*model_eval, false);
if (st == m_current) {
break;
}
}
pop(*model_eval);
} }
ast_manager& get_manager() { return m; } ast_manager& get_manager() { return m; }
@ -1633,6 +1685,7 @@ namespace qe {
nb = m_current->get_num_branches(); nb = m_current->get_num_branches();
expr_ref fml(m_current->fml(), m); expr_ref fml(m_current->fml(), m);
if (!eval(model_eval, b, branch) || branch >= nb) { if (!eval(model_eval, b, branch) || branch >= nb) {
TRACE("qe", tout << "evaluation failed: setting branch to 0\n";);
branch = rational::zero(); branch = rational::zero();
} }
SASSERT(!branch.is_neg()); SASSERT(!branch.is_neg());
@ -1694,11 +1747,12 @@ namespace qe {
} }
// //
// The current state is satisfiable // The closed portion of the formula
// and the closed portion of the formula // can be used as the quantifier-free portion,
// can be used as the quantifier-free portion. // unless the current state is unsatisfiable.
// //
if (m.is_true(fml_mixed)) { if (m.is_true(fml_mixed)) {
SASSERT(l_true == m_solver.check());
m_current = m_current->add_child(fml_closed); m_current = m_current->add_child(fml_closed);
for (unsigned i = 0; m_defs && i < m_current->num_free_vars(); ++i) { for (unsigned i = 0; m_defs && i < m_current->num_free_vars(); ++i) {
expr_ref val(m); expr_ref val(m);
@ -1708,6 +1762,7 @@ namespace qe {
if (val == x) { if (val == x) {
model_ref model; model_ref model;
lbool is_sat = m_solver.check(); lbool is_sat = m_solver.check();
if (is_sat == l_undef) return;
m_solver.get_model(model); m_solver.get_model(model);
SASSERT(is_sat == l_true); SASSERT(is_sat == l_true);
model_evaluator model_eval2(*model); model_evaluator model_eval2(*model);
@ -1890,7 +1945,7 @@ namespace qe {
vars.reset(); vars.reset();
closed = closed && (r != l_undef); closed = closed && (r != l_undef);
} }
TRACE("qe", tout << mk_ismt2_pp(fml, m) << "\n";); TRACE("qe", tout << mk_pp(fml, m) << "\n";);
m_current->add_child(fml)->reset_free_vars(); m_current->add_child(fml)->reset_free_vars();
block_assignment(); block_assignment();
} }

View file

@ -31,6 +31,7 @@ Revision History:
#include "obj_pair_hashtable.h" #include "obj_pair_hashtable.h"
#include "nlarith_util.h" #include "nlarith_util.h"
#include "model_evaluator.h" #include "model_evaluator.h"
#include "smt_kernel.h"
namespace qe { namespace qe {
@ -81,8 +82,8 @@ namespace qe {
i_solver_context& m_ctx; i_solver_context& m_ctx;
public: public:
arith_util m_arith; // initialize before m_zero_i, etc. arith_util m_arith; // initialize before m_zero_i, etc.
th_rewriter simplify;
private: private:
th_rewriter m_rewriter;
arith_eq_solver m_arith_solver; arith_eq_solver m_arith_solver;
bv_util m_bv; bv_util m_bv;
@ -102,7 +103,7 @@ namespace qe {
m(m), m(m),
m_ctx(ctx), m_ctx(ctx),
m_arith(m), m_arith(m),
m_rewriter(m), simplify(m),
m_arith_solver(m), m_arith_solver(m),
m_bv(m), m_bv(m),
m_zero_i(m_arith.mk_numeral(numeral(0), true), m), m_zero_i(m_arith.mk_numeral(numeral(0), true), m),
@ -434,7 +435,6 @@ namespace qe {
expr_ref tmp(e, m); expr_ref tmp(e, m);
simplify(tmp); simplify(tmp);
m_arith_rewriter.mk_le(tmp, mk_zero(e), result); m_arith_rewriter.mk_le(tmp, mk_zero(e), result);
TRACE("qe_verbose", tout << "mk_le " << mk_pp(result, m) << "\n";);
} }
void mk_lt(expr* e, expr_ref& result) { void mk_lt(expr* e, expr_ref& result) {
@ -521,7 +521,8 @@ namespace qe {
expr_ref result1(m), result2(m); expr_ref result1(m), result2(m);
// a*s + b*t <= 0 // a*s + b*t <= 0
expr_ref as_bt_le_0(result, m), tmp2(m), tmp3(m), tmp4(m); expr_ref as_bt_le_0(result, m), tmp2(m), asz_bt_le_0(m), tmp3(m), tmp4(m);
expr_ref b_divides_sz(m);
// a*s + b*t + (a-1)(b-1) <= 0 // a*s + b*t + (a-1)(b-1) <= 0
tmp2 = m_arith.mk_add(as_bt, slack); tmp2 = m_arith.mk_add(as_bt, slack);
@ -560,30 +561,36 @@ namespace qe {
sz = m_arith.mk_uminus(sz); sz = m_arith.mk_uminus(sz);
} }
tmp4 = mk_add(mk_mul(a1, sz), bt); tmp4 = mk_add(mk_mul(a1, sz), bt);
mk_le(tmp4, tmp3); mk_le(tmp4, asz_bt_le_0);
if (to_app(tmp3)->get_arg(0) == x && if (to_app(asz_bt_le_0)->get_arg(0) == x &&
m_arith.is_zero(to_app(tmp3)->get_arg(1))) { m_arith.is_zero(to_app(asz_bt_le_0)->get_arg(1))) {
// exists z in [0 .. |b|-2] . |b| | (z + s) && z <= 0 // exists z in [0 .. |b|-2] . |b| | (z + s) && z <= 0
// <=> // <=>
// |b| | s // |b| | s
mk_divides(abs_b, s, tmp2); mk_divides(abs_b, s, tmp2);
} }
else { else {
mk_divides(abs_b, sz, tmp2); mk_divides(abs_b, sz, b_divides_sz);
mk_and(tmp2, tmp3, tmp4); mk_and(b_divides_sz, asz_bt_le_0, tmp4);
mk_big_or(abs_b - numeral(2), x, tmp4, tmp2); mk_big_or(abs_b - numeral(2), x, tmp4, tmp2);
TRACE("qe",
tout << "b | s + z: " << mk_pp(b_divides_sz, m) << "\n";
tout << "a(s+z) + bt <= 0: " << mk_pp(asz_bt_le_0, m) << "\n";
);
} }
mk_flat_and(as_bt_le_0, tmp2, result2); mk_flat_and(as_bt_le_0, tmp2, result2);
mk_or(result1, result2, result); mk_or(result1, result2, result);
simplify(result); simplify(result);
// a*s + b*t + (a-1)(b-1) <= 0
// or exists z in [0 .. |b|-2] . |b| | (z + s) && a*n_sign(b)(s + z) + |b|t <= 0
} }
TRACE("qe", TRACE("qe",
{ {
expr_ref_vector trail(m); tout << (is_strict?"strict":"non-strict") << "\n";
tout << "is_strict: " << (is_strict?"true":"false") << "\n";
bound(m, a, t, false).pp(tout, x); bound(m, a, t, false).pp(tout, x);
tout << "\n"; tout << "\n";
bound(m, b, s, false).pp(tout, x); bound(m, b, s, false).pp(tout, x);
@ -592,10 +599,6 @@ namespace qe {
}); });
} }
void simplify(expr_ref& p) {
m_rewriter(p);
}
struct mul_lt { struct mul_lt {
arith_util& u; arith_util& u;
mul_lt(arith_qe_util& u): u(u.m_arith) {} mul_lt(arith_qe_util& u): u(u.m_arith) {}
@ -1052,7 +1055,6 @@ namespace qe {
} }
bool reduce_equation(expr* p, expr* fml) { bool reduce_equation(expr* p, expr* fml) {
TRACE("qe", tout << mk_pp(p, m) << "\n";);
numeral k; numeral k;
if (m_arith.is_numeral(p, k) && k.is_zero()) { if (m_arith.is_numeral(p, k) && k.is_zero()) {
@ -1555,9 +1557,10 @@ public:
mk_non_resolve(bounds, true, is_lower, result); mk_non_resolve(bounds, true, is_lower, result);
mk_non_resolve(bounds, false, is_lower, result); mk_non_resolve(bounds, false, is_lower, result);
m_util.simplify(result);
add_cache(x, fml, v, result, x_t.get_coeff(), x_t.get_term()); add_cache(x, fml, v, result, x_t.get_coeff(), x_t.get_term());
TRACE("qe", TRACE("qe",
tout << vl << " " << mk_pp(x, m) << "\n"; tout << vl << " " << mk_pp(x, m) << " infinite case\n";
tout << mk_pp(fml, m) << "\n"; tout << mk_pp(fml, m) << "\n";
tout << mk_pp(result, m) << "\n";); tout << mk_pp(result, m) << "\n";);
return; return;
@ -1592,18 +1595,21 @@ public:
expr_ref t(bounds.exprs(is_strict, is_lower)[index], m); expr_ref t(bounds.exprs(is_strict, is_lower)[index], m);
rational a = bounds.coeffs(is_strict, is_lower)[index]; rational a = bounds.coeffs(is_strict, is_lower)[index];
t = x_t.mk_term(a, t);
a = x_t.mk_coeff(a);
mk_bounds(bounds, x, true, is_eq, is_strict, is_lower, index, a, t, result); mk_bounds(bounds, x, true, is_eq, is_strict, is_lower, index, a, t, result);
mk_bounds(bounds, x, false, is_eq, is_strict, is_lower, index, a, t, result); mk_bounds(bounds, x, false, is_eq, is_strict, is_lower, index, a, t, result);
t = x_t.mk_term(a, t);
a = x_t.mk_coeff(a);
mk_resolve(bounds, x, x_t, true, is_eq, is_strict, is_lower, index, a, t, result); mk_resolve(bounds, x, x_t, true, is_eq, is_strict, is_lower, index, a, t, result);
mk_resolve(bounds, x, x_t, false, is_eq, is_strict, is_lower, index, a, t, result); mk_resolve(bounds, x, x_t, false, is_eq, is_strict, is_lower, index, a, t, result);
m_util.simplify(result);
add_cache(x, fml, v, result, x_t.get_coeff(), x_t.get_term()); add_cache(x, fml, v, result, x_t.get_coeff(), x_t.get_term());
TRACE("qe", TRACE("qe",
{ {
tout << vl << " " << mk_pp(x, m) << "\n"; tout << vl << " " << mk_pp(bounds.atoms(is_strict, is_lower)[index],m) << "\n";
tout << mk_pp(fml, m) << "\n"; tout << mk_pp(fml, m) << "\n";
tout << mk_pp(result, m) << "\n"; tout << mk_pp(result, m) << "\n";
} }
@ -2225,6 +2231,12 @@ public:
} }
} }
m_util.simplify(result); m_util.simplify(result);
TRACE("qe",
tout << (is_strict?"strict":"non-strict") << "\n";
tout << (is_lower?"is-lower":"is-upper") << "\n";
tout << "a: " << a << " " << mk_pp(t, m) << "\n";
tout << "b: " << b << " " << mk_pp(s, m) << "\n";
tout << mk_pp(result, m) << "\n";);
} }
// //
@ -2245,10 +2257,12 @@ public:
void mk_bounds(bounds_proc& bounds, void mk_bounds(bounds_proc& bounds,
app* x, bool is_strict, bool is_eq_ctx, bool is_strict_ctx, bool is_lower, unsigned index, app* x, bool is_strict, bool is_eq_ctx,
bool is_strict_ctx, bool is_lower, unsigned index,
rational const& a, expr* t, rational const& a, expr* t,
expr_ref& result) expr_ref& result)
{ {
TRACE("qe", tout << mk_pp(t, m) << "\n";);
SASSERT(!is_eq_ctx || !is_strict_ctx); SASSERT(!is_eq_ctx || !is_strict_ctx);
unsigned sz = bounds.size(is_strict, is_lower); unsigned sz = bounds.size(is_strict, is_lower);
expr_ref tmp(m), eq(m); expr_ref tmp(m), eq(m);
@ -2258,13 +2272,14 @@ public:
for (unsigned i = 0; i < sz; ++i) { for (unsigned i = 0; i < sz; ++i) {
app* e = bounds.atoms(is_strict, is_lower)[i]; app* e = bounds.atoms(is_strict, is_lower)[i];
expr* s = bounds.exprs(is_strict, is_lower)[i]; expr_ref s(bounds.exprs(is_strict, is_lower)[i], m);
rational b = bounds.coeffs(is_strict, is_lower)[i]; rational b = bounds.coeffs(is_strict, is_lower)[i];
if (same_strict && i == index) { if (same_strict && i == index) {
if (non_strict_real) { if (non_strict_real) {
m_util.mk_eq(a, x, t, eq); m_util.mk_eq(a, x, t, eq);
TRACE("qe", tout << "a:" << a << " x: " << mk_pp(x, m) << " t: " << mk_pp(t, m) << " eq: " << mk_pp(eq, m) << "\n";); TRACE("qe", tout << "a:" << a << " x: " << mk_pp(x, m) << "t: " <<
mk_pp(t, m) << " eq: " << mk_pp(eq, m) << "\n";);
if (is_eq_ctx) { if (is_eq_ctx) {
m_ctx.add_constraint(true, eq); m_ctx.add_constraint(true, eq);
} }
@ -2292,6 +2307,7 @@ public:
(non_strict_real && is_eq_ctx && is_strict) || (non_strict_real && is_eq_ctx && is_strict) ||
(same_strict && i < index); (same_strict && i < index);
mk_bound(result_is_strict, is_lower, a, t, b, s, tmp); mk_bound(result_is_strict, is_lower, a, t, b, s, tmp);
m_util.m_replace.apply_substitution(e, tmp.get(), result); m_util.m_replace.apply_substitution(e, tmp.get(), result);
@ -2330,14 +2346,17 @@ public:
s = x_t.mk_term(b, s); s = x_t.mk_term(b, s);
b = x_t.mk_coeff(b); b = x_t.mk_coeff(b);
m_util.mk_resolve(x, strict_resolve, a, t, b, s, tmp); m_util.mk_resolve(x, strict_resolve, a, t, b, s, tmp);
expr_ref save_result(result);
m_util.m_replace.apply_substitution(e, tmp.get(), result); m_util.m_replace.apply_substitution(e, tmp.get(), result);
m_ctx.add_constraint(true, mk_not(e), tmp); m_ctx.add_constraint(true, mk_not(e), tmp);
TRACE("qe_verbose", TRACE("qe_verbose",
tout << mk_pp(atm, m) << " "; tout << mk_pp(atm, m) << " ";
tout << mk_pp(e, m) << " ==> "; tout << mk_pp(e, m) << " ==>\n";
tout << mk_pp(tmp, m) << "\n"; tout << mk_pp(tmp, m) << "\n";
tout << "old fml: " << mk_pp(save_result, m) << "\n";
tout << "new fml: " << mk_pp(result, m) << "\n";
); );
} }
} }

View file

@ -23,6 +23,7 @@ void preprocessor_params::updt_local_params(params_ref const & _p) {
smt_params_helper p(_p); smt_params_helper p(_p);
m_macro_finder = p.macro_finder(); m_macro_finder = p.macro_finder();
m_pull_nested_quantifiers = p.pull_nested_quantifiers(); m_pull_nested_quantifiers = p.pull_nested_quantifiers();
m_refine_inj_axiom = p.refine_inj_axioms();
} }
void preprocessor_params::updt_params(params_ref const & p) { void preprocessor_params::updt_params(params_ref const & p) {

View file

@ -14,6 +14,7 @@ def_module_params(module_name='smt',
('delay_units', BOOL, False, 'if true then z3 will not restart when a unit clause is learned'), ('delay_units', BOOL, False, 'if true then z3 will not restart when a unit clause is learned'),
('delay_units_threshold', UINT, 32, 'maximum number of learned unit clauses before restarting, ingored if delay_units is false'), ('delay_units_threshold', UINT, 32, 'maximum number of learned unit clauses before restarting, ingored if delay_units is false'),
('pull_nested_quantifiers', BOOL, False, 'pull nested quantifiers'), ('pull_nested_quantifiers', BOOL, False, 'pull nested quantifiers'),
('refine_inj_axioms', BOOL, True, 'refine injectivity axioms'),
('soft_timeout', UINT, 0, 'soft timeout (0 means no timeout)'), ('soft_timeout', UINT, 0, 'soft timeout (0 means no timeout)'),
('mbqi', BOOL, True, 'model based quantifier instantiation (MBQI)'), ('mbqi', BOOL, True, 'model based quantifier instantiation (MBQI)'),
('mbqi.max_cexs', UINT, 1, 'initial maximal number of counterexamples used in MBQI, each counterexample generates a quantifier instantiation'), ('mbqi.max_cexs', UINT, 1, 'initial maximal number of counterexamples used in MBQI, each counterexample generates a quantifier instantiation'),

View file

@ -22,6 +22,7 @@ Revision History:
void theory_arith_params::updt_params(params_ref const & _p) { void theory_arith_params::updt_params(params_ref const & _p) {
smt_params_helper p(_p); smt_params_helper p(_p);
m_arith_random_initial_value = p.arith_random_initial_value(); m_arith_random_initial_value = p.arith_random_initial_value();
m_arith_random_seed = p.random_seed();
m_arith_mode = static_cast<arith_solver_id>(p.arith_solver()); m_arith_mode = static_cast<arith_solver_id>(p.arith_solver());
m_nl_arith = p.arith_nl(); m_nl_arith = p.arith_nl();
m_nl_arith_gb = p.arith_nl_gb(); m_nl_arith_gb = p.arith_nl_gb();

View file

@ -191,8 +191,10 @@ expr * datatype_factory::get_fresh_value(sort * s) {
// Approach 2) // Approach 2)
// For recursive datatypes. // For recursive datatypes.
// search for constructor... // search for constructor...
unsigned num_iterations = 0;
if (m_util.is_recursive(s)) { if (m_util.is_recursive(s)) {
while(true) { while(true) {
++num_iterations;
TRACE("datatype_factory", tout << mk_pp(get_last_fresh_value(s), m_manager) << "\n";); TRACE("datatype_factory", tout << mk_pp(get_last_fresh_value(s), m_manager) << "\n";);
ptr_vector<func_decl> const * constructors = m_util.get_datatype_constructors(s); ptr_vector<func_decl> const * constructors = m_util.get_datatype_constructors(s);
ptr_vector<func_decl>::const_iterator it = constructors->begin(); ptr_vector<func_decl>::const_iterator it = constructors->begin();
@ -212,7 +214,13 @@ expr * datatype_factory::get_fresh_value(sort * s) {
<< found_sibling << "\n";); << found_sibling << "\n";);
if (!found_sibling && m_util.is_datatype(s_arg) && m_util.are_siblings(s, s_arg)) { if (!found_sibling && m_util.is_datatype(s_arg) && m_util.are_siblings(s, s_arg)) {
found_sibling = true; found_sibling = true;
expr * maybe_new_arg = get_almost_fresh_value(s_arg); expr * maybe_new_arg = 0;
if (num_iterations <= 1) {
maybe_new_arg = get_almost_fresh_value(s_arg);
}
else {
maybe_new_arg = get_fresh_value(s_arg);
}
if (!maybe_new_arg) { if (!maybe_new_arg) {
TRACE("datatype_factory", TRACE("datatype_factory",
tout << "no argument found for " << mk_pp(s_arg, m_manager) << "\n";); tout << "no argument found for " << mk_pp(s_arg, m_manager) << "\n";);
@ -231,6 +239,7 @@ expr * datatype_factory::get_fresh_value(sort * s) {
if (found_sibling) { if (found_sibling) {
expr_ref new_value(m_manager); expr_ref new_value(m_manager);
new_value = m_manager.mk_app(constructor, args.size(), args.c_ptr()); new_value = m_manager.mk_app(constructor, args.size(), args.c_ptr());
TRACE("datatype_factory", tout << "potential new value: " << mk_pp(new_value, m_manager) << "\n";);
m_last_fresh_value.insert(s, new_value); m_last_fresh_value.insert(s, new_value);
if (!set->contains(new_value)) { if (!set->contains(new_value)) {
register_value(new_value); register_value(new_value);

View file

@ -3945,7 +3945,7 @@ namespace smt {
m_fingerprints.display(tout); m_fingerprints.display(tout);
); );
failure fl = get_last_search_failure(); failure fl = get_last_search_failure();
if (fl == TIMEOUT || fl == MEMOUT || fl == CANCELED || fl == NUM_CONFLICTS) { if (fl == TIMEOUT || fl == MEMOUT || fl == CANCELED || fl == NUM_CONFLICTS || fl == THEORY) {
// don't generate model. // don't generate model.
return; return;
} }

View file

@ -102,6 +102,7 @@ namespace smt {
if (th && th->build_models()) { if (th && th->build_models()) {
if (r->get_th_var(th->get_id()) != null_theory_var) { if (r->get_th_var(th->get_id()) != null_theory_var) {
proc = th->mk_value(r, *this); proc = th->mk_value(r, *this);
SASSERT(proc);
} }
else { else {
TRACE("model_bug", tout << "creating fresh value for #" << r->get_owner_id() << "\n";); TRACE("model_bug", tout << "creating fresh value for #" << r->get_owner_id() << "\n";);
@ -110,6 +111,7 @@ namespace smt {
} }
else { else {
proc = mk_model_value(r); proc = mk_model_value(r);
SASSERT(proc);
} }
} }
SASSERT(proc); SASSERT(proc);

View file

@ -193,7 +193,7 @@ namespace smt {
return true; return true;
} }
if (!r.get_base_var() == x && x > y) { if (r.get_base_var() != x && x > y) {
std::swap(x, y); std::swap(x, y);
k.neg(); k.neg();
} }

View file

@ -1198,6 +1198,7 @@ namespace smt {
void theory_bv::relevant_eh(app * n) { void theory_bv::relevant_eh(app * n) {
ast_manager & m = get_manager(); ast_manager & m = get_manager();
context & ctx = get_context(); context & ctx = get_context();
TRACE("bv", tout << "relevant: " << mk_pp(n, m) << "\n";);
if (m.is_bool(n)) { if (m.is_bool(n)) {
bool_var v = ctx.get_bool_var(n); bool_var v = ctx.get_bool_var(n);
atom * a = get_bv2a(v); atom * a = get_bv2a(v);

View file

@ -162,7 +162,7 @@ namespace smt {
m.register_factory(alloc(dl_factory, m_util, m.get_model())); m.register_factory(alloc(dl_factory, m_util, m.get_model()));
} }
virtual smt::model_value_proc * mk_value(smt::enode * n) { virtual smt::model_value_proc * mk_value(smt::enode * n, smt::model_generator&) {
return alloc(dl_value_proc, *this, n); return alloc(dl_value_proc, *this, n);
} }
@ -201,9 +201,8 @@ namespace smt {
if(!m_reps.find(s, r) || !m_vals.find(s,v)) { if(!m_reps.find(s, r) || !m_vals.find(s,v)) {
SASSERT(!m_reps.contains(s)); SASSERT(!m_reps.contains(s));
sort* bv = b().mk_sort(64); sort* bv = b().mk_sort(64);
// TBD: filter these from model. r = m().mk_func_decl(m_util.get_family_id(), datalog::OP_DL_REP, 0, 0, 1, &s, bv);
r = m().mk_fresh_func_decl("rep",1, &s,bv); v = m().mk_func_decl(m_util.get_family_id(), datalog::OP_DL_ABS, 0, 0, 1, &bv, s);
v = m().mk_fresh_func_decl("val",1, &bv,s);
m_reps.insert(s, r); m_reps.insert(s, r);
m_vals.insert(s, v); m_vals.insert(s, v);
add_trail(r); add_trail(r);

View file

@ -218,6 +218,7 @@ br_status bv2int_rewriter::mk_mod(expr * s, expr * t, expr_ref & result) {
if (is_bv2int(s, s1) && is_bv2int(t, t1)) { if (is_bv2int(s, s1) && is_bv2int(t, t1)) {
align_sizes(s1, t1, false); align_sizes(s1, t1, false);
result = m_bv.mk_bv2int(m_bv.mk_bv_urem(s1, t1)); result = m_bv.mk_bv2int(m_bv.mk_bv_urem(s1, t1));
TRACE("bv2int_rewriter", tout << mk_pp(result,m()) << "\n";);
return BR_DONE; return BR_DONE;
} }
@ -232,6 +233,7 @@ br_status bv2int_rewriter::mk_mod(expr * s, expr * t, expr_ref & result) {
u1 = mk_bv_add(s1, u1, false); u1 = mk_bv_add(s1, u1, false);
align_sizes(u1, t1, false); align_sizes(u1, t1, false);
result = m_bv.mk_bv2int(m_bv.mk_bv_urem(u1, t1)); result = m_bv.mk_bv2int(m_bv.mk_bv_urem(u1, t1));
TRACE("bv2int_rewriter", tout << mk_pp(result,m()) << "\n";);
return BR_DONE; return BR_DONE;
} }

View file

@ -29,6 +29,7 @@ struct cofactor_elim_term_ite::imp {
ast_manager & m; ast_manager & m;
params_ref m_params; params_ref m_params;
unsigned long long m_max_memory; unsigned long long m_max_memory;
bool m_cofactor_equalities;
volatile bool m_cancel; volatile bool m_cancel;
void checkpoint() { void checkpoint() {
@ -36,7 +37,7 @@ struct cofactor_elim_term_ite::imp {
if (memory::get_allocation_size() > m_max_memory) if (memory::get_allocation_size() > m_max_memory)
throw tactic_exception(TACTIC_MAX_MEMORY_MSG); throw tactic_exception(TACTIC_MAX_MEMORY_MSG);
if (m_cancel) if (m_cancel)
throw tactic_exception(TACTIC_MAX_MEMORY_MSG); throw tactic_exception(TACTIC_CANCELED_MSG);
} }
// Collect atoms that contain term if-then-else // Collect atoms that contain term if-then-else
@ -111,7 +112,7 @@ struct cofactor_elim_term_ite::imp {
frame & fr = m_frame_stack.back(); frame & fr = m_frame_stack.back();
expr * t = fr.m_t; expr * t = fr.m_t;
bool form_ctx = fr.m_form_ctx; bool form_ctx = fr.m_form_ctx;
TRACE("cofactor_ite_analyzer", tout << "processing, form_ctx: " << form_ctx << "\n" << mk_bounded_pp(t, m) << "\n";); TRACE("cofactor", tout << "processing, form_ctx: " << form_ctx << "\n" << mk_bounded_pp(t, m) << "\n";);
m_owner.checkpoint(); m_owner.checkpoint();
@ -150,7 +151,7 @@ struct cofactor_elim_term_ite::imp {
} }
if (i < num_args) { if (i < num_args) {
m_has_term_ite.mark(t); m_has_term_ite.mark(t);
TRACE("cofactor_ite_analyzer", tout << "saving candidate: " << form_ctx << "\n" << mk_bounded_pp(t, m) << "\n";); TRACE("cofactor", tout << "saving candidate: " << form_ctx << "\n" << mk_bounded_pp(t, m) << "\n";);
save_candidate(t, form_ctx); save_candidate(t, form_ctx);
} }
} }
@ -167,6 +168,7 @@ struct cofactor_elim_term_ite::imp {
}; };
expr * get_first(expr * t) { expr * get_first(expr * t) {
TRACE("cofactor", tout << mk_ismt2_pp(t, m) << "\n";);
typedef std::pair<expr *, unsigned> frame; typedef std::pair<expr *, unsigned> frame;
expr_fast_mark1 visited; expr_fast_mark1 visited;
sbuffer<frame> stack; sbuffer<frame> stack;
@ -225,6 +227,7 @@ struct cofactor_elim_term_ite::imp {
\brief Fuctor for selecting the term if-then-else condition with the most number of occurrences. \brief Fuctor for selecting the term if-then-else condition with the most number of occurrences.
*/ */
expr * get_best(expr * t) { expr * get_best(expr * t) {
TRACE("cofactor", tout << mk_ismt2_pp(t, m) << "\n";);
typedef std::pair<expr *, unsigned> frame; typedef std::pair<expr *, unsigned> frame;
obj_map<expr, unsigned> occs; obj_map<expr, unsigned> occs;
expr_fast_mark1 visited; expr_fast_mark1 visited;
@ -299,12 +302,17 @@ struct cofactor_elim_term_ite::imp {
} }
} }
visited.reset(); visited.reset();
CTRACE("cofactor_ite_get_best", best != 0, tout << "best num-occs: " << best_occs << "\n" << mk_ismt2_pp(best, m) << "\n";); CTRACE("cofactor", best != 0, tout << "best num-occs: " << best_occs << "\n" << mk_ismt2_pp(best, m) << "\n";);
return best; return best;
} }
void updt_params(params_ref const & p) { void updt_params(params_ref const & p) {
m_max_memory = megabytes_to_bytes(p.get_uint("max_memory", UINT_MAX)); m_max_memory = megabytes_to_bytes(p.get_uint("max_memory", UINT_MAX));
m_cofactor_equalities = p.get_bool("cofactor_equalities", true);
}
void collect_param_descrs(param_descrs & r) {
r.insert("cofactor_equalities", CPK_BOOL, "(default: true) use equalities to rewrite bodies of ite-expressions. This is potentially expensive.");
} }
void set_cancel(bool f) { void set_cancel(bool f) {
@ -354,16 +362,16 @@ struct cofactor_elim_term_ite::imp {
m_term = 0; m_term = 0;
expr * lhs; expr * lhs;
expr * rhs; expr * rhs;
if (m.is_eq(t, lhs, rhs)) { if (m_owner.m_cofactor_equalities && m.is_eq(t, lhs, rhs)) {
if (m.is_unique_value(lhs)) { if (m.is_unique_value(lhs)) {
m_term = rhs; m_term = rhs;
m_value = to_app(lhs); m_value = to_app(lhs);
TRACE("set_cofactor_atom", tout << "term:\n" << mk_ismt2_pp(m_term, m) << "\nvalue: " << mk_ismt2_pp(m_value, m) << "\n";); TRACE("cofactor", tout << "term:\n" << mk_ismt2_pp(m_term, m) << "\nvalue: " << mk_ismt2_pp(m_value, m) << "\n";);
} }
else if (m.is_unique_value(rhs)) { else if (m.is_unique_value(rhs)) {
m_term = lhs; m_term = lhs;
m_value = to_app(rhs); m_value = to_app(rhs);
TRACE("set_cofactor_atom", tout << "term:\n" << mk_ismt2_pp(m_term, m) << "\nvalue: " << mk_ismt2_pp(m_value, m) << "\n";); TRACE("cofactor", tout << "term:\n" << mk_ismt2_pp(m_term, m) << "\nvalue: " << mk_ismt2_pp(m_value, m) << "\n";);
} }
} }
// TODO: bounds // TODO: bounds
@ -467,7 +475,7 @@ struct cofactor_elim_term_ite::imp {
m_cofactor.set_cofactor_atom(neg_c); m_cofactor.set_cofactor_atom(neg_c);
m_cofactor(curr, neg_cofactor); m_cofactor(curr, neg_cofactor);
curr = m.mk_ite(c, pos_cofactor, neg_cofactor); curr = m.mk_ite(c, pos_cofactor, neg_cofactor);
TRACE("cofactor_ite", tout << "cofactor_ite step: " << step << "\n" << mk_ismt2_pp(curr, m) << "\n";); TRACE("cofactor", tout << "cofactor_ite step: " << step << "\n" << mk_ismt2_pp(curr, m) << "\n";);
} }
} }
return false; return false;
@ -522,7 +530,7 @@ struct cofactor_elim_term_ite::imp {
void cofactor(expr * t, expr_ref & r) { void cofactor(expr * t, expr_ref & r) {
unsigned step = 0; unsigned step = 0;
TRACE("cofactor_ite", tout << "cofactor target:\n" << mk_ismt2_pp(t, m) << "\n";); TRACE("cofactor", tout << "cofactor target:\n" << mk_ismt2_pp(t, m) << "\n";);
expr_ref curr(m); expr_ref curr(m);
curr = t; curr = t;
while (true) { while (true) {
@ -543,21 +551,20 @@ struct cofactor_elim_term_ite::imp {
m_cofactor(curr, neg_cofactor); m_cofactor(curr, neg_cofactor);
if (pos_cofactor == neg_cofactor) { if (pos_cofactor == neg_cofactor) {
curr = pos_cofactor; curr = pos_cofactor;
TRACE("cofactor_ite", tout << "cofactor_ite step: " << step << "\n" << mk_ismt2_pp(curr, m) << "\n";);
continue;
} }
if (m.is_true(pos_cofactor) && m.is_false(neg_cofactor)) { else if (m.is_true(pos_cofactor) && m.is_false(neg_cofactor)) {
curr = c; curr = c;
TRACE("cofactor_ite", tout << "cofactor_ite step: " << step << "\n" << mk_ismt2_pp(curr, m) << "\n";);
continue;
} }
if (m.is_false(pos_cofactor) && m.is_true(neg_cofactor)) { else if (m.is_false(pos_cofactor) && m.is_true(neg_cofactor)) {
curr = neg_c; curr = neg_c;
TRACE("cofactor_ite", tout << "cofactor_ite step: " << step << "\n" << mk_ismt2_pp(curr, m) << "\n";);
continue;
} }
else {
curr = m.mk_ite(c, pos_cofactor, neg_cofactor); curr = m.mk_ite(c, pos_cofactor, neg_cofactor);
TRACE("cofactor_ite", tout << "cofactor_ite step: " << step << "\n" << mk_ismt2_pp(curr, m) << "\n";); }
TRACE("cofactor",
tout << "cofactor_ite step: " << step << "\n";
tout << "cofactor: " << mk_ismt2_pp(c, m) << "\n";
tout << mk_ismt2_pp(curr, m) << "\n";);
} }
} }
@ -570,6 +577,7 @@ struct cofactor_elim_term_ite::imp {
void operator()(expr * t, expr_ref & r) { void operator()(expr * t, expr_ref & r) {
ptr_vector<expr> new_args; ptr_vector<expr> new_args;
SASSERT(m_frames.empty());
m_frames.push_back(frame(t, true)); m_frames.push_back(frame(t, true));
while (!m_frames.empty()) { while (!m_frames.empty()) {
m_owner.checkpoint(); m_owner.checkpoint();
@ -649,7 +657,8 @@ struct cofactor_elim_term_ite::imp {
imp(ast_manager & _m, params_ref const & p): imp(ast_manager & _m, params_ref const & p):
m(_m), m(_m),
m_params(p) { m_params(p),
m_cofactor_equalities(true) {
m_cancel = false; m_cancel = false;
updt_params(p); updt_params(p);
} }
@ -686,7 +695,8 @@ void cofactor_elim_term_ite::updt_params(params_ref const & p) {
m_imp->updt_params(p); m_imp->updt_params(p);
} }
void cofactor_elim_term_ite::get_param_descrs(param_descrs & r) { void cofactor_elim_term_ite::collect_param_descrs(param_descrs & r) {
m_imp->collect_param_descrs(r);
} }
void cofactor_elim_term_ite::operator()(expr * t, expr_ref & r) { void cofactor_elim_term_ite::operator()(expr * t, expr_ref & r) {

View file

@ -31,7 +31,7 @@ public:
virtual ~cofactor_elim_term_ite(); virtual ~cofactor_elim_term_ite();
void updt_params(params_ref const & p); void updt_params(params_ref const & p);
static void get_param_descrs(param_descrs & r); void collect_param_descrs(param_descrs & r);
void operator()(expr * t, expr_ref & r); void operator()(expr * t, expr_ref & r);

View file

@ -52,8 +52,7 @@ public:
virtual ~cofactor_term_ite_tactic() {} virtual ~cofactor_term_ite_tactic() {}
virtual void updt_params(params_ref const & p) { m_params = p; m_elim_ite.updt_params(p); } virtual void updt_params(params_ref const & p) { m_params = p; m_elim_ite.updt_params(p); }
static void get_param_descrs(param_descrs & r) { cofactor_elim_term_ite::get_param_descrs(r); } virtual void collect_param_descrs(param_descrs & r) { m_elim_ite.collect_param_descrs(r); }
virtual void collect_param_descrs(param_descrs & r) { get_param_descrs(r); }
virtual void operator()(goal_ref const & g, virtual void operator()(goal_ref const & g,
goal_ref_buffer & result, goal_ref_buffer & result,

View file

@ -43,6 +43,7 @@ void filter_model_converter::operator()(model_ref & old_model, unsigned goal_idx
if (fs.is_marked(f)) if (fs.is_marked(f))
continue; continue;
func_interp * fi = old_model->get_func_interp(f); func_interp * fi = old_model->get_func_interp(f);
SASSERT(fi);
new_model->register_decl(f, fi->copy()); new_model->register_decl(f, fi->copy());
} }
new_model->copy_usort_interps(*old_model); new_model->copy_usort_interps(*old_model);

View file

@ -166,6 +166,14 @@ public:
return e->get_data().m_value; return e->get_data().m_value;
} }
value const & operator[](key * k) const {
return find(k);
}
value & operator[](key * k) {
return find(k);
}
iterator find_iterator(Key * k) const { iterator find_iterator(Key * k) const {
return m_table.find(key_data(k)); return m_table.find(key_data(k));
} }