mirror of
https://github.com/Z3Prover/z3
synced 2025-04-12 20:18:18 +00:00
merged with unstable
This commit is contained in:
parent
7bf87e76ea
commit
c007a5e5bd
|
@ -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:
|
||||||
|
|
|
@ -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))
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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)))
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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 << ")";
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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";
|
||||||
});
|
});
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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)));
|
||||||
|
|
109
src/qe/qe.cpp
109
src/qe/qe.cpp
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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";
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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'),
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue