mirror of
https://github.com/Z3Prover/z3
synced 2025-04-08 02:15:19 +00:00
fix bug in conflict clause generation in seq-branch-variable
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
4c408165ab
commit
ce8862d415
|
@ -71,6 +71,7 @@ VERBOSE=True
|
|||
DEBUG_MODE=False
|
||||
SHOW_CPPS = True
|
||||
VS_X64 = False
|
||||
VS_ARM = False
|
||||
LINUX_X64 = True
|
||||
ONLY_MAKEFILES = False
|
||||
Z3PY_SRC_DIR=None
|
||||
|
@ -99,6 +100,7 @@ USE_OMP=True
|
|||
FPMATH="Default"
|
||||
FPMATH_FLAGS="-mfpmath=sse -msse -msse2"
|
||||
|
||||
|
||||
def check_output(cmd):
|
||||
out = subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()[0]
|
||||
if out != None:
|
||||
|
@ -1557,6 +1559,8 @@ class DotNetDLLComponent(Component):
|
|||
if IS_WINDOWS:
|
||||
if VS_X64:
|
||||
cscCmdLine.extend(['/platform:x64'])
|
||||
elif VS_ARM:
|
||||
cscCmdLine.extend(['/platform:arm'])
|
||||
else:
|
||||
cscCmdLine.extend(['/platform:x86'])
|
||||
else:
|
||||
|
@ -1997,6 +2001,8 @@ class DotNetExampleComponent(ExampleComponent):
|
|||
out.write('\t%s /out:%s /reference:%s /debug:full /reference:System.Numerics.dll' % (CSC, exefile, dll))
|
||||
if VS_X64:
|
||||
out.write(' /platform:x64')
|
||||
elif VS_ARM:
|
||||
out.write(' /platform:arm')
|
||||
else:
|
||||
out.write(' /platform:x86')
|
||||
for csfile in get_cs_files(self.ex_dir):
|
||||
|
@ -2186,18 +2192,21 @@ def mk_config():
|
|||
'AR_FLAGS=/nologo\n'
|
||||
'LINK_FLAGS=/nologo /MDd\n'
|
||||
'SLINK_FLAGS=/nologo /LDd\n')
|
||||
if not VS_X64:
|
||||
config.write(
|
||||
'CXXFLAGS=/c /Zi /nologo /W3 /WX- /Od /Oy- /D WIN32 /D _DEBUG /D Z3DEBUG %s /D _CONSOLE /D _TRACE /D _WINDOWS /Gm- /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /analyze- /arch:SSE2\n' % extra_opt)
|
||||
config.write(
|
||||
'LINK_EXTRA_FLAGS=/link /DEBUG /MACHINE:X86 /SUBSYSTEM:CONSOLE /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE /NXCOMPAT\n'
|
||||
'SLINK_EXTRA_FLAGS=/link /DEBUG /MACHINE:X86 /SUBSYSTEM:WINDOWS /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE:NO\n')
|
||||
else:
|
||||
if VS_X64:
|
||||
config.write(
|
||||
'CXXFLAGS=/c /Zi /nologo /W3 /WX- /Od /Oy- /D WIN32 /D _AMD64_ /D _DEBUG /D Z3DEBUG %s /D _CONSOLE /D _TRACE /D _WINDOWS /Gm- /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /analyze-\n' % extra_opt)
|
||||
config.write(
|
||||
'LINK_EXTRA_FLAGS=/link /DEBUG /MACHINE:X64 /SUBSYSTEM:CONSOLE /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE /NXCOMPAT\n'
|
||||
'SLINK_EXTRA_FLAGS=/link /DEBUG /MACHINE:X64 /SUBSYSTEM:WINDOWS /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE:NO\n')
|
||||
elif VS_ARM:
|
||||
print "ARM on VS is unsupported"
|
||||
exit(1)
|
||||
else:
|
||||
config.write(
|
||||
'CXXFLAGS=/c /Zi /nologo /W3 /WX- /Od /Oy- /D WIN32 /D _DEBUG /D Z3DEBUG %s /D _CONSOLE /D _TRACE /D _WINDOWS /Gm- /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /analyze- /arch:SSE2\n' % extra_opt)
|
||||
config.write(
|
||||
'LINK_EXTRA_FLAGS=/link /DEBUG /MACHINE:X86 /SUBSYSTEM:CONSOLE /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE /NXCOMPAT\n'
|
||||
'SLINK_EXTRA_FLAGS=/link /DEBUG /MACHINE:X86 /SUBSYSTEM:WINDOWS /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE:NO\n')
|
||||
else:
|
||||
# Windows Release mode
|
||||
LTCG=' /LTCG' if SLOW_OPTIMIZE else ''
|
||||
|
@ -2209,18 +2218,23 @@ def mk_config():
|
|||
% LTCG)
|
||||
if TRACE:
|
||||
extra_opt = '%s /D _TRACE ' % extra_opt
|
||||
if not VS_X64:
|
||||
config.write(
|
||||
'CXXFLAGS=/nologo /c%s /Zi /W3 /WX- /O2 /Oy- /D _EXTERNAL_RELEASE /D WIN32 /D NDEBUG %s /D _CONSOLE /D _WINDOWS /D ASYNC_COMMANDS /Gm- /EHsc /MD /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /analyze- /arch:SSE2\n' % (GL, extra_opt))
|
||||
config.write(
|
||||
'LINK_EXTRA_FLAGS=/link%s /DEBUG /MACHINE:X86 /SUBSYSTEM:CONSOLE /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE /NXCOMPAT\n'
|
||||
'SLINK_EXTRA_FLAGS=/link%s /DEBUG /MACHINE:X86 /SUBSYSTEM:WINDOWS /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE:NO\n' % (LTCG, LTCG))
|
||||
else:
|
||||
if VS_X64:
|
||||
config.write(
|
||||
'CXXFLAGS=/c%s /Zi /nologo /W3 /WX- /O2 /D _EXTERNAL_RELEASE /D WIN32 /D NDEBUG %s /D _LIB /D _WINDOWS /D _AMD64_ /D _UNICODE /D UNICODE /Gm- /EHsc /MD /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /TP\n' % (GL, extra_opt))
|
||||
config.write(
|
||||
'LINK_EXTRA_FLAGS=/link%s /MACHINE:X64 /SUBSYSTEM:CONSOLE /INCREMENTAL:NO /STACK:8388608\n'
|
||||
'SLINK_EXTRA_FLAGS=/link%s /MACHINE:X64 /SUBSYSTEM:WINDOWS /INCREMENTAL:NO /STACK:8388608\n' % (LTCG, LTCG))
|
||||
elif VS_ARM:
|
||||
print "ARM on VS is unsupported"
|
||||
exit(1)
|
||||
else:
|
||||
config.write(
|
||||
'CXXFLAGS=/nologo /c%s /Zi /W3 /WX- /O2 /Oy- /D _EXTERNAL_RELEASE /D WIN32 /D NDEBUG %s /D _CONSOLE /D _WINDOWS /D ASYNC_COMMANDS /Gm- /EHsc /MD /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /analyze- /arch:SSE2\n' % (GL, extra_opt))
|
||||
config.write(
|
||||
'LINK_EXTRA_FLAGS=/link%s /DEBUG /MACHINE:X86 /SUBSYSTEM:CONSOLE /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE /NXCOMPAT\n'
|
||||
'SLINK_EXTRA_FLAGS=/link%s /DEBUG /MACHINE:X86 /SUBSYSTEM:WINDOWS /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE:NO\n' % (LTCG, LTCG))
|
||||
|
||||
|
||||
|
||||
# End of Windows VS config.mk
|
||||
if is_verbose():
|
||||
|
@ -2446,6 +2460,9 @@ def mk_makefile():
|
|||
if VS_X64:
|
||||
print(" platform: x64\n")
|
||||
print("To build Z3, open a [Visual Studio x64 Command Prompt], then")
|
||||
elif VS_ARM:
|
||||
print(" platform: ARM\n")
|
||||
print("To build Z3, open a [Visual Studio ARM Command Prompt], then")
|
||||
else:
|
||||
print(" platform: x86")
|
||||
print("To build Z3, open a [Visual Studio Command Prompt], then")
|
||||
|
|
|
@ -30,6 +30,7 @@ Revision History:
|
|||
#include"for_each_ast.h"
|
||||
#include"decl_collector.h"
|
||||
#include"smt2_util.h"
|
||||
#include"seq_decl_plugin.h"
|
||||
|
||||
// ---------------------------------------
|
||||
// smt_renaming
|
||||
|
@ -160,6 +161,7 @@ class smt_printer {
|
|||
unsigned m_num_lets;
|
||||
arith_util m_autil;
|
||||
bv_util m_bvutil;
|
||||
seq_util m_sutil;
|
||||
family_id m_basic_fid;
|
||||
family_id m_bv_fid;
|
||||
family_id m_arith_fid;
|
||||
|
@ -247,6 +249,10 @@ class smt_printer {
|
|||
}
|
||||
|
||||
if (m_is_smt2) {
|
||||
if (is_sort_symbol && sym == symbol("String")) {
|
||||
m_out << "String";
|
||||
return;
|
||||
}
|
||||
if (is_sort_symbol && sym != symbol("BitVec")) {
|
||||
m_out << "(" << sym << " ";
|
||||
}
|
||||
|
@ -397,6 +403,7 @@ class smt_printer {
|
|||
bool is_int, pos;
|
||||
buffer<symbol> names;
|
||||
unsigned bv_size;
|
||||
zstring s;
|
||||
unsigned num_args = n->get_num_args();
|
||||
func_decl* decl = n->get_decl();
|
||||
if (m_autil.is_numeral(n, val, is_int)) {
|
||||
|
@ -415,6 +422,19 @@ class smt_printer {
|
|||
display_rational(val, is_int);
|
||||
}
|
||||
}
|
||||
else if (m_sutil.str.is_string(n, s)) {
|
||||
std::string encs = s.encode();
|
||||
m_out << "\"";
|
||||
for (unsigned i = 0; i < encs.length(); ++i) {
|
||||
if (encs[i] == '\"') {
|
||||
m_out << "\"\"";
|
||||
}
|
||||
else {
|
||||
m_out << encs[i];
|
||||
}
|
||||
}
|
||||
m_out << "\"";
|
||||
}
|
||||
else if (m_bvutil.is_numeral(n, val, bv_size)) {
|
||||
if (m_is_smt2) {
|
||||
m_out << "(_ bv" << val << " " << bv_size << ")";
|
||||
|
@ -797,6 +817,7 @@ public:
|
|||
m_num_lets(0),
|
||||
m_autil(m),
|
||||
m_bvutil(m),
|
||||
m_sutil(m),
|
||||
m_logic(logic),
|
||||
m_AUFLIRA("AUFLIRA"),
|
||||
// It's much easier to read those testcases with that.
|
||||
|
|
|
@ -437,7 +437,12 @@ br_status seq_rewriter::mk_seq_contains(expr* a, expr* b, expr_ref& result) {
|
|||
m_util.str.get_concat(a, as);
|
||||
m_util.str.get_concat(b, bs);
|
||||
bool all_values = true;
|
||||
|
||||
|
||||
if (bs.empty()) {
|
||||
result = m().mk_true();
|
||||
return BR_DONE;
|
||||
}
|
||||
|
||||
for (unsigned i = 0; all_values && i < bs.size(); ++i) {
|
||||
all_values = m().is_value(bs[i].get());
|
||||
}
|
||||
|
@ -459,6 +464,39 @@ br_status seq_rewriter::mk_seq_contains(expr* a, expr* b, expr_ref& result) {
|
|||
result = m().mk_false();
|
||||
return BR_DONE;
|
||||
}
|
||||
|
||||
unsigned lenA = 0, lenB = 0;
|
||||
bool lA = min_length(as.size(), as.c_ptr(), lenA);
|
||||
if (lA) {
|
||||
bool lB = min_length(bs.size(), bs.c_ptr(), lenB);
|
||||
if (lenB > lenA) {
|
||||
result = m().mk_false();
|
||||
return BR_DONE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (as.empty()) {
|
||||
result = m().mk_eq(b, m_util.str.mk_empty(m().get_sort(b)));
|
||||
return BR_REWRITE2;
|
||||
}
|
||||
|
||||
unsigned offs = 0;
|
||||
unsigned sz = as.size();
|
||||
expr* b0 = bs[0].get();
|
||||
expr* bL = bs[bs.size()-1].get();
|
||||
for (; offs < as.size() && m().are_distinct(b0, as[offs].get()); ++offs) {};
|
||||
for (; sz > offs && m().are_distinct(bL, as[sz-1].get()); --sz) {}
|
||||
if (offs == sz) {
|
||||
result = m().mk_eq(b, m_util.str.mk_empty(m().get_sort(b)));
|
||||
return BR_REWRITE2;
|
||||
}
|
||||
if (offs > 0 || sz < as.size()) {
|
||||
SASSERT(sz > offs);
|
||||
result = m_util.str.mk_contains(m_util.str.mk_concat(sz-offs, as.c_ptr()+offs), b);
|
||||
return BR_REWRITE2;
|
||||
}
|
||||
|
||||
return BR_FAILED;
|
||||
}
|
||||
|
||||
|
|
|
@ -222,16 +222,16 @@ public:
|
|||
str(seq_util& u): u(u), m(u.m), m_fid(u.m_fid) {}
|
||||
|
||||
sort* mk_seq(sort* s) { parameter param(s); return m.mk_sort(m_fid, SEQ_SORT, 1, ¶m); }
|
||||
sort* mk_string_sort() { return m.mk_sort(m_fid, _STRING_SORT, 0, 0); }
|
||||
app* mk_empty(sort* s) { return m.mk_const(m.mk_func_decl(m_fid, OP_SEQ_EMPTY, 0, 0, 0, (expr*const*)0, s)); }
|
||||
sort* mk_string_sort() const { return m.mk_sort(m_fid, _STRING_SORT, 0, 0); }
|
||||
app* mk_empty(sort* s) const { return m.mk_const(m.mk_func_decl(m_fid, OP_SEQ_EMPTY, 0, 0, 0, (expr*const*)0, s)); }
|
||||
app* mk_string(zstring const& s);
|
||||
app* mk_string(symbol const& s) { return u.seq.mk_string(s); }
|
||||
app* mk_char(char ch);
|
||||
app* mk_concat(expr* a, expr* b) { expr* es[2] = { a, b }; return m.mk_app(m_fid, OP_SEQ_CONCAT, 2, es); }
|
||||
app* mk_concat(expr* a, expr* b) const { expr* es[2] = { a, b }; return m.mk_app(m_fid, OP_SEQ_CONCAT, 2, es); }
|
||||
app* mk_concat(expr* a, expr* b, expr* c) { return mk_concat(a, mk_concat(b, c)); }
|
||||
expr* mk_concat(unsigned n, expr* const* es) { if (n == 1) return es[0]; SASSERT(n > 1); return m.mk_app(m_fid, OP_SEQ_CONCAT, n, es); }
|
||||
expr* mk_concat(expr_ref_vector const& es) { return mk_concat(es.size(), es.c_ptr()); }
|
||||
app* mk_length(expr* a) { return m.mk_app(m_fid, OP_SEQ_LENGTH, 1, &a); }
|
||||
expr* mk_concat(unsigned n, expr* const* es) const { if (n == 1) return es[0]; SASSERT(n > 1); return m.mk_app(m_fid, OP_SEQ_CONCAT, n, es); }
|
||||
expr* mk_concat(expr_ref_vector const& es) const { return mk_concat(es.size(), es.c_ptr()); }
|
||||
app* mk_length(expr* a) const { return m.mk_app(m_fid, OP_SEQ_LENGTH, 1, &a); }
|
||||
app* mk_substr(expr* a, expr* b, expr* c) { expr* es[3] = { a, b, c }; return m.mk_app(m_fid, OP_SEQ_EXTRACT, 3, es); }
|
||||
app* mk_contains(expr* a, expr* b) { expr* es[2] = { a, b }; return m.mk_app(m_fid, OP_SEQ_CONTAINS, 2, es); }
|
||||
app* mk_prefix(expr* a, expr* b) { expr* es[2] = { a, b }; return m.mk_app(m_fid, OP_SEQ_PREFIX, 2, es); }
|
||||
|
|
|
@ -99,22 +99,29 @@ namespace smt {
|
|||
This method may update m_antecedents, m_todo_js and m_todo_eqs.
|
||||
*/
|
||||
void conflict_resolution::eq_justification2literals(enode * lhs, enode * rhs, eq_justification js) {
|
||||
ast_manager& m = get_manager();
|
||||
SASSERT(m_antecedents);
|
||||
TRACE("conflict_detail", tout << mk_pp(lhs->get_owner(), m) << " = " << mk_pp(rhs->get_owner(), m);
|
||||
switch (js.get_kind()) {
|
||||
case eq_justification::AXIOM: tout << " axiom\n"; break;
|
||||
case eq_justification::EQUATION:
|
||||
tout << " was asserted\nliteral: "; m_ctx.display_literal(tout, js.get_literal()); tout << "\n";
|
||||
break;
|
||||
case eq_justification::JUSTIFICATION: tout << " justification\n"; break;
|
||||
case eq_justification::CONGRUENCE: tout << " congruence\n"; break;
|
||||
default: break;
|
||||
});
|
||||
|
||||
switch(js.get_kind()) {
|
||||
case eq_justification::AXIOM:
|
||||
TRACE("conflict_detail", tout << "#" << lhs->get_owner_id() << " = " << rhs->get_owner_id() << " axiom\n";);
|
||||
break;
|
||||
case eq_justification::EQUATION:
|
||||
TRACE("conflict_detail", tout << "#" << lhs->get_owner_id() << " = " << rhs->get_owner_id() << " was asserted\n"
|
||||
<< "literal: "; m_ctx.display_literal(tout, js.get_literal()); tout << "\n";);
|
||||
m_antecedents->push_back(js.get_literal());
|
||||
break;
|
||||
case eq_justification::JUSTIFICATION:
|
||||
TRACE("conflict_detail", tout << "#" << lhs->get_owner_id() << " = " << rhs->get_owner_id() << " justification\n";);
|
||||
mark_justification(js.get_justification());
|
||||
break;
|
||||
case eq_justification::CONGRUENCE: {
|
||||
TRACE("conflict_detail", tout << "#" << lhs->get_owner_id() << " = " << rhs->get_owner_id() << " congruence\n";);
|
||||
CTRACE("dyn_ack_target", !lhs->is_eq(), tout << "dyn_ack_target2: " << lhs->get_owner_id() << " " << rhs->get_owner_id() << "\n";);
|
||||
m_dyn_ack_manager.used_cg_eh(lhs->get_owner(), rhs->get_owner());
|
||||
unsigned num_args = lhs->get_num_args();
|
||||
|
@ -206,7 +213,6 @@ namespace smt {
|
|||
justification_vector::iterator it = m_todo_js.begin() + old_js_qhead;
|
||||
justification_vector::iterator end = m_todo_js.end();
|
||||
for (; it != end; ++it) {
|
||||
TRACE("conflict_detail", tout << "unmarking: " << *it << "\n";);
|
||||
(*it)->unset_mark();
|
||||
}
|
||||
m_todo_js.shrink(old_js_qhead);
|
||||
|
@ -371,11 +377,9 @@ namespace smt {
|
|||
tout << "conflict_lvl: " << m_conflict_lvl << " scope_lvl: " << m_ctx.get_scope_level() << " base_lvl: " << m_ctx.get_base_level()
|
||||
<< " search_lvl: " << m_ctx.get_search_level() << "\n";
|
||||
tout << "js.kind: " << js.get_kind() << "\n";
|
||||
tout << "consequent: " << consequent << "\n";
|
||||
for (unsigned i = 0; i < m_assigned_literals.size(); ++i) {
|
||||
tout << m_assigned_literals[i] << " ";
|
||||
}
|
||||
tout << "\n";
|
||||
tout << "consequent: " << consequent << ": ";
|
||||
m_ctx.display_literal_verbose(tout, consequent); tout << "\n";
|
||||
m_ctx.display(tout, js); tout << "\n";
|
||||
);
|
||||
|
||||
// m_conflict_lvl can be smaller than m_ctx.get_search_level() when:
|
||||
|
@ -416,12 +420,12 @@ namespace smt {
|
|||
|
||||
TRACE("conflict",
|
||||
tout << "before minimization:\n";
|
||||
m_ctx.display_literals(tout, m_lemma.size(), m_lemma.c_ptr());
|
||||
m_ctx.display_literals(tout, m_lemma);
|
||||
tout << "\n";);
|
||||
|
||||
TRACE("conflict_verbose",
|
||||
tout << "before minimization:\n";
|
||||
m_ctx.display_literals_verbose(tout, m_lemma.size(), m_lemma.c_ptr());
|
||||
m_ctx.display_literals_verbose(tout, m_lemma);
|
||||
tout << "\n";);
|
||||
|
||||
if (m_params.m_minimize_lemmas)
|
||||
|
@ -429,12 +433,16 @@ namespace smt {
|
|||
|
||||
TRACE("conflict",
|
||||
tout << "after minimization:\n";
|
||||
m_ctx.display_literals(tout, m_lemma.size(), m_lemma.c_ptr());
|
||||
m_ctx.display_literals(tout, m_lemma);
|
||||
tout << "\n";);
|
||||
|
||||
TRACE("conflict_verbose",
|
||||
tout << "after minimization:\n";
|
||||
m_ctx.display_literals_verbose(tout, m_lemma.size(), m_lemma.c_ptr());
|
||||
m_ctx.display_literals_verbose(tout, m_lemma);
|
||||
tout << "\n";);
|
||||
|
||||
TRACE("conflict_bug",
|
||||
m_ctx.display_literals_verbose(tout, m_lemma);
|
||||
tout << "\n";);
|
||||
|
||||
literal_vector::iterator it = m_lemma.begin();
|
||||
|
@ -1423,7 +1431,7 @@ namespace smt {
|
|||
}
|
||||
|
||||
end_unsat_core:
|
||||
TRACE("unsat_core", tout << "assumptions:\n"; m_ctx.display_literals(tout, m_assumptions.size(), m_assumptions.c_ptr()); tout << "\n";);
|
||||
TRACE("unsat_core", tout << "assumptions:\n"; m_ctx.display_literals(tout, m_assumptions); tout << "\n";);
|
||||
reset_unmark_and_justifications(0, 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -114,7 +114,6 @@ namespace smt {
|
|||
|
||||
void mark_justification(justification * js) {
|
||||
if (!js->is_marked()) {
|
||||
TRACE("conflict_detail", tout << "marking: " << js << "\n";);
|
||||
js->set_mark();
|
||||
m_todo_js.push_back(js);
|
||||
}
|
||||
|
@ -126,7 +125,7 @@ namespace smt {
|
|||
std::swap(n1, n2);
|
||||
enode_pair p(n1, n2);
|
||||
if (m_already_processed_eqs.insert_if_not_there(p)) {
|
||||
TRACE("conflict_detail", tout << "marking eq #" << p.first->get_owner_id() << " = #" <<
|
||||
TRACE("conflict_detail_verbose", tout << "marking eq #" << p.first->get_owner_id() << " = #" <<
|
||||
p.second->get_owner_id() << "\n";);
|
||||
m_todo_eqs.push_back(p);
|
||||
SASSERT(m_already_processed_eqs.contains(p));
|
||||
|
@ -168,9 +167,8 @@ namespace smt {
|
|||
void eq_justification2literals(enode * lhs, enode * rhs, eq_justification js);
|
||||
void eq_branch2literals(enode * n1, enode * n2);
|
||||
void eq2literals(enode * n1, enode * n2);
|
||||
void justification2literals_core(justification * js, literal_vector & result);
|
||||
void justification2literals_core(justification * js, literal_vector & result) ;
|
||||
void unmark_justifications(unsigned old_js_qhead);
|
||||
void justification2literals(justification * js, literal_vector & result);
|
||||
|
||||
literal_vector m_tmp_literal_vector;
|
||||
|
||||
|
@ -256,6 +254,9 @@ namespace smt {
|
|||
literal_vector::const_iterator end_unsat_core() const {
|
||||
return m_assumptions.end();
|
||||
}
|
||||
|
||||
void justification2literals(justification * js, literal_vector & result);
|
||||
|
||||
};
|
||||
|
||||
inline void mark_literals(conflict_resolution & cr, unsigned sz, literal const * ls) {
|
||||
|
|
|
@ -295,7 +295,7 @@ namespace smt {
|
|||
|
||||
void context::assign_core(literal l, b_justification j, bool decision) {
|
||||
TRACE("assign_core", tout << (decision?"decision: ":"propagating: ") << l << " ";
|
||||
display_literal(tout, l); tout << " level: " << m_scope_lvl << "\n";
|
||||
display_literal_verbose(tout, l); tout << " level: " << m_scope_lvl << "\n";
|
||||
display(tout, j););
|
||||
SASSERT(l.var() < static_cast<int>(m_b_internalized_stack.size()));
|
||||
m_assigned_literals.push_back(l);
|
||||
|
|
|
@ -1176,8 +1176,18 @@ namespace smt {
|
|||
|
||||
void display_literals(std::ostream & out, unsigned num_lits, literal const * lits) const;
|
||||
|
||||
void display_literals(std::ostream & out, literal_vector const& lits) const {
|
||||
display_literals(out, lits.size(), lits.c_ptr());
|
||||
}
|
||||
|
||||
void display_literal_verbose(std::ostream & out, literal lit) const;
|
||||
|
||||
void display_literals_verbose(std::ostream & out, unsigned num_lits, literal const * lits) const;
|
||||
|
||||
void display_literals_verbose(std::ostream & out, literal_vector const& lits) const {
|
||||
display_literals_verbose(out, lits.size(), lits.c_ptr());
|
||||
}
|
||||
|
||||
void display_watch_list(std::ostream & out, literal l) const;
|
||||
|
||||
void display_watch_lists(std::ostream & out) const;
|
||||
|
|
|
@ -96,6 +96,10 @@ namespace smt {
|
|||
display_compact(out, num_lits, lits, m_bool_var2expr.c_ptr());
|
||||
}
|
||||
|
||||
void context::display_literal_verbose(std::ostream & out, literal lit) const {
|
||||
display_literals_verbose(out, 1, &lit);
|
||||
}
|
||||
|
||||
void context::display_literals_verbose(std::ostream & out, unsigned num_lits, literal const * lits) const {
|
||||
display_verbose(out, m_manager, num_lits, lits, m_bool_var2expr.c_ptr(), "\n");
|
||||
}
|
||||
|
@ -599,12 +603,16 @@ namespace smt {
|
|||
case b_justification::CLAUSE: {
|
||||
clause * cls = j.get_clause();
|
||||
out << "clause ";
|
||||
display_literals(out, cls->get_num_literals(), cls->begin_literals());
|
||||
if (cls) display_literals_verbose(out, cls->get_num_literals(), cls->begin_literals());
|
||||
break;
|
||||
}
|
||||
case b_justification::JUSTIFICATION:
|
||||
out << "justification";
|
||||
case b_justification::JUSTIFICATION: {
|
||||
out << "justification ";
|
||||
literal_vector lits;
|
||||
const_cast<conflict_resolution&>(*m_conflict_resolution).justification2literals(j.get_justification(), lits);
|
||||
display_literals_verbose(out, lits.size(), lits.c_ptr());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
|
|
|
@ -258,6 +258,11 @@ final_check_status theory_seq::final_check_eh() {
|
|||
TRACE("seq", tout << ">>propagate_automata\n";);
|
||||
return FC_CONTINUE;
|
||||
}
|
||||
if (check_contains()) {
|
||||
++m_stats.m_propagate_contains;
|
||||
TRACE("seq", tout << ">>propagate_contains\n";);
|
||||
return FC_CONTINUE;
|
||||
}
|
||||
if (is_solved()) {
|
||||
TRACE("seq", tout << ">>is_solved\n";);
|
||||
return FC_DONE;
|
||||
|
@ -288,7 +293,7 @@ bool theory_seq::branch_variable() {
|
|||
unsigned id = e.id();
|
||||
|
||||
s = find_branch_start(2*id);
|
||||
TRACE("seq", tout << s << " " << 2*id << ": " << e.ls() << " = " << e.rs() << "\n";);
|
||||
TRACE("seq", tout << s << " " << id << ": " << e.ls() << " = " << e.rs() << "\n";);
|
||||
bool found = find_branch_candidate(s, e.dep(), e.ls(), e.rs());
|
||||
insert_branch_start(2*id, s);
|
||||
if (found) {
|
||||
|
@ -337,15 +342,15 @@ bool theory_seq::find_branch_candidate(unsigned& start, dependency* dep, expr_re
|
|||
return false;
|
||||
}
|
||||
|
||||
TRACE("seq", tout << mk_pp(l, m) << ": " << get_context().get_scope_level() << " - start:" << start << "\n";);
|
||||
|
||||
expr_ref v0(m);
|
||||
v0 = m_util.str.mk_empty(m.get_sort(l));
|
||||
literal_vector lits;
|
||||
if (can_be_equal(ls.size() - 1, ls.c_ptr() + 1, rs.size(), rs.c_ptr())) {
|
||||
if (l_false != assume_equality(l, v0)) {
|
||||
TRACE("seq", tout << mk_pp(l, m) << " " << v0 << "\n";);
|
||||
return true;
|
||||
}
|
||||
lits.push_back(~mk_eq_empty(l));
|
||||
}
|
||||
for (; start < rs.size(); ++start) {
|
||||
unsigned j = start;
|
||||
|
@ -370,14 +375,31 @@ bool theory_seq::find_branch_candidate(unsigned& start, dependency* dep, expr_re
|
|||
all_units &= m_util.str.is_unit(rs[j]);
|
||||
}
|
||||
if (all_units) {
|
||||
context& ctx = get_context();
|
||||
literal_vector lits;
|
||||
lits.push_back(~mk_eq_empty(l));
|
||||
for (unsigned i = 0; i < rs.size(); ++i) {
|
||||
if (can_be_equal(ls.size() - 1, ls.c_ptr() + 1, rs.size() - i - 1, rs.c_ptr() + i + 1)) {
|
||||
v0 = mk_concat(i + 1, rs.c_ptr());
|
||||
lits.push_back(~mk_eq(l, v0, false));
|
||||
}
|
||||
}
|
||||
for (unsigned i = 0; i < lits.size(); ++i) {
|
||||
switch (ctx.get_assignment(lits[i])) {
|
||||
case l_true: break;
|
||||
case l_false: start = 0; return true;
|
||||
case l_undef: ctx.force_phase(~lits[i]); start = 0; return true;
|
||||
}
|
||||
}
|
||||
set_conflict(dep, lits);
|
||||
TRACE("seq", tout << mk_pp(l, m) << " " << v0 << "\n";);
|
||||
TRACE("seq",
|
||||
tout << "start: " << start << "\n";
|
||||
for (unsigned i = 0; i < lits.size(); ++i) {
|
||||
ctx.display_literal_verbose(tout << lits[i] << ": ", lits[i]);
|
||||
tout << "\n";
|
||||
ctx.display(tout, ctx.get_justification(lits[i].var()));
|
||||
tout << "\n";
|
||||
});
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -429,10 +451,19 @@ lbool theory_seq::assume_equality(expr* l, expr* r) {
|
|||
if (n1->get_root() == n2->get_root()) {
|
||||
return l_true;
|
||||
}
|
||||
if (ctx.is_diseq(n1, n2)) {
|
||||
return l_false;
|
||||
}
|
||||
if (false && ctx.is_diseq_slow(n1, n2)) {
|
||||
return l_false;
|
||||
}
|
||||
ctx.mark_as_relevant(n1);
|
||||
ctx.mark_as_relevant(n2);
|
||||
ctx.assume_eq(n1, n2);
|
||||
return l_undef;
|
||||
if (!ctx.assume_eq(n1, n2)) {
|
||||
return l_false;
|
||||
}
|
||||
return ctx.get_assignment(mk_eq(l, r, false));
|
||||
//return l_undef;
|
||||
}
|
||||
|
||||
|
||||
|
@ -483,29 +514,50 @@ bool theory_seq::propagate_length_coherence(expr* e) {
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool theory_seq::check_length_coherence(expr* e) {
|
||||
if (is_var(e) && m_rep.is_root(e)) {
|
||||
expr_ref emp(m_util.str.mk_empty(m.get_sort(e)), m);
|
||||
expr_ref head(m), tail(m);
|
||||
if (!propagate_length_coherence(e) &&
|
||||
l_false == assume_equality(e, emp)) {
|
||||
if (!check_length_coherence0(e)) {
|
||||
expr_ref emp(m_util.str.mk_empty(m.get_sort(e)), m);
|
||||
expr_ref head(m), tail(m);
|
||||
// e = emp \/ e = unit(head.elem(e))*tail(e)
|
||||
mk_decompose(e, head, tail);
|
||||
expr_ref conc = mk_concat(head, tail);
|
||||
propagate_is_conc(e, conc);
|
||||
assume_equality(tail, emp);
|
||||
}
|
||||
else if (!get_context().at_base_level()) {
|
||||
m_trail_stack.push(push_replay(alloc(replay_length_coherence, m, e)));
|
||||
if (propagate_is_conc(e, conc)) {
|
||||
assume_equality(tail, emp);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool theory_seq::check_length_coherence0(expr* e) {
|
||||
if (is_var(e) && m_rep.is_root(e)) {
|
||||
expr_ref emp(m_util.str.mk_empty(m.get_sort(e)), m);
|
||||
if (propagate_length_coherence(e) ||
|
||||
l_false != assume_equality(e, emp)) {
|
||||
if (!get_context().at_base_level()) {
|
||||
m_trail_stack.push(push_replay(alloc(replay_length_coherence, m, e)));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool theory_seq::check_length_coherence() {
|
||||
|
||||
obj_hashtable<expr>::iterator it = m_length.begin(), end = m_length.end();
|
||||
#if 1
|
||||
for (; it != end; ++it) {
|
||||
expr* e = *it;
|
||||
if (check_length_coherence0(e)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
it = m_length.begin();
|
||||
#endif
|
||||
for (; it != end; ++it) {
|
||||
expr* e = *it;
|
||||
if (check_length_coherence(e)) {
|
||||
|
@ -570,14 +622,19 @@ void theory_seq::propagate_non_empty(literal lit, expr* s) {
|
|||
propagate_lit(0, 1, &lit, ~mk_eq_empty(s));
|
||||
}
|
||||
|
||||
void theory_seq::propagate_is_conc(expr* e, expr* conc) {
|
||||
bool theory_seq::propagate_is_conc(expr* e, expr* conc) {
|
||||
TRACE("seq", tout << mk_pp(conc, m) << " is non-empty\n";);
|
||||
context& ctx = get_context();
|
||||
literal lit = ~mk_eq_empty(e);
|
||||
SASSERT(ctx.get_assignment(lit) == l_true);
|
||||
propagate_lit(0, 1, &lit, mk_eq(e, conc, false));
|
||||
expr_ref e1(e, m), e2(conc, m);
|
||||
new_eq_eh(m_dm.mk_leaf(assumption(lit)), ctx.get_enode(e1), ctx.get_enode(e2));
|
||||
if (ctx.get_assignment(lit) == l_true) {
|
||||
propagate_lit(0, 1, &lit, mk_eq(e, conc, false));
|
||||
expr_ref e1(e, m), e2(conc, m);
|
||||
new_eq_eh(m_dm.mk_leaf(assumption(lit)), ctx.get_enode(e1), ctx.get_enode(e2));
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool theory_seq::is_nth(expr* e) const {
|
||||
|
@ -717,6 +774,23 @@ bool theory_seq::check_extensionality() {
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
\brief check negated contains constriants.
|
||||
*/
|
||||
bool theory_seq::check_contains() {
|
||||
context & ctx = get_context();
|
||||
for (unsigned i = 0; !ctx.inconsistent() && i < m_ncs.size(); ++i) {
|
||||
if (solve_nc(i)) {
|
||||
if (i + 1 != m_ncs.size()) {
|
||||
nc n = m_ncs[m_ncs.size()-1];
|
||||
m_ncs.set(i, n);
|
||||
--i;
|
||||
}
|
||||
m_ncs.pop_back();
|
||||
}
|
||||
}
|
||||
return m_new_propagation || ctx.inconsistent();
|
||||
}
|
||||
/*
|
||||
- Eqs = 0
|
||||
- Diseqs evaluate to false
|
||||
|
@ -762,20 +836,31 @@ void theory_seq::linearize(dependency* dep, enode_pair_vector& eqs, literal_vect
|
|||
|
||||
|
||||
void theory_seq::propagate_lit(dependency* dep, unsigned n, literal const* _lits, literal lit) {
|
||||
if (lit == true_literal) return;
|
||||
|
||||
context& ctx = get_context();
|
||||
ctx.mark_as_relevant(lit);
|
||||
literal_vector lits(n, _lits);
|
||||
|
||||
if (lit == false_literal) {
|
||||
set_conflict(dep, lits);
|
||||
return;
|
||||
}
|
||||
|
||||
ctx.mark_as_relevant(lit);
|
||||
enode_pair_vector eqs;
|
||||
linearize(dep, eqs, lits);
|
||||
TRACE("seq", ctx.display_detailed_literal(tout, lit);
|
||||
tout << " <- "; ctx.display_literals_verbose(tout, lits.size(), lits.c_ptr()); if (!lits.empty()) tout << "\n"; display_deps(tout, dep););
|
||||
TRACE("seq",
|
||||
tout << "assert:";
|
||||
ctx.display_detailed_literal(tout, lit);
|
||||
tout << " <- "; ctx.display_literals_verbose(tout, lits);
|
||||
if (!lits.empty()) tout << "\n"; display_deps(tout, dep););
|
||||
justification* js =
|
||||
ctx.mk_justification(
|
||||
ext_theory_propagation_justification(
|
||||
get_id(), ctx.get_region(), lits.size(), lits.c_ptr(), eqs.size(), eqs.c_ptr(), lit));
|
||||
|
||||
m_new_propagation = true;
|
||||
ctx.assign(lit, js);
|
||||
ctx.assign(lit, js);
|
||||
}
|
||||
|
||||
void theory_seq::set_conflict(dependency* dep, literal_vector const& _lits) {
|
||||
|
@ -783,7 +868,7 @@ void theory_seq::set_conflict(dependency* dep, literal_vector const& _lits) {
|
|||
enode_pair_vector eqs;
|
||||
literal_vector lits(_lits);
|
||||
linearize(dep, eqs, lits);
|
||||
TRACE("seq", display_deps(tout, lits, eqs););
|
||||
TRACE("seq", display_deps(tout << "assert conflict:", lits, eqs););
|
||||
m_new_propagation = true;
|
||||
ctx.set_conflict(
|
||||
ctx.mk_justification(
|
||||
|
@ -800,7 +885,7 @@ void theory_seq::propagate_eq(dependency* dep, enode* n1, enode* n2) {
|
|||
enode_pair_vector eqs;
|
||||
linearize(dep, eqs, lits);
|
||||
TRACE("seq",
|
||||
tout << mk_pp(n1->get_owner(), m) << " = " << mk_pp(n2->get_owner(), m) << " <- \n";
|
||||
tout << "assert:" << mk_pp(n1->get_owner(), m) << " = " << mk_pp(n2->get_owner(), m) << " <- \n";
|
||||
display_deps(tout, dep);
|
||||
);
|
||||
|
||||
|
@ -1484,6 +1569,30 @@ bool theory_seq::solve_ne(unsigned idx) {
|
|||
return updated;
|
||||
}
|
||||
|
||||
bool theory_seq::solve_nc(unsigned idx) {
|
||||
context& ctx = get_context();
|
||||
nc const& n = m_ncs[idx];
|
||||
|
||||
dependency* deps = n.deps();
|
||||
expr_ref c = canonize(n.contains(), deps);
|
||||
|
||||
CTRACE("seq", c != n.contains(), tout << n.contains() << " => " << c << "\n";);
|
||||
|
||||
if (m.is_true(c)) {
|
||||
literal_vector lits;
|
||||
set_conflict(deps, lits);
|
||||
return true;
|
||||
}
|
||||
if (m.is_false(c)) {
|
||||
return true;
|
||||
}
|
||||
if (c != n.contains()) {
|
||||
m_ncs.push_back(nc(c, deps));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
theory_seq::cell* theory_seq::mk_cell(cell* p, expr* e, dependency* d) {
|
||||
cell* c = alloc(cell, p, e, d);
|
||||
m_all_cells.push_back(c);
|
||||
|
@ -1747,6 +1856,20 @@ void theory_seq::display(std::ostream & out) const {
|
|||
out << "Exclusions:\n";
|
||||
m_exclude.display(out);
|
||||
}
|
||||
|
||||
if (!m_length.empty()) {
|
||||
obj_hashtable<expr>::iterator it = m_length.begin(), end = m_length.end();
|
||||
for (; it != end; ++it) {
|
||||
expr* e = *it;
|
||||
rational lo(-1), hi(-1);
|
||||
lower_bound(e, lo);
|
||||
upper_bound(e, hi);
|
||||
if (lo.is_pos() || !hi.is_minus_one()) {
|
||||
out << mk_pp(e, m) << " [" << lo << ":" << hi << "]\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void theory_seq::display_equations(std::ostream& out) const {
|
||||
|
@ -2360,7 +2483,7 @@ void theory_seq::propagate_in_re(expr* n, bool is_true) {
|
|||
propagate_lit(0, 1, &lit, lits[1]);
|
||||
}
|
||||
else {
|
||||
TRACE("seq", ctx.display_literals_verbose(tout, lits.size(), lits.c_ptr()); tout << "\n";);
|
||||
TRACE("seq", ctx.display_literals_verbose(tout, lits); tout << "\n";);
|
||||
ctx.mk_th_axiom(get_id(), lits.size(), lits.c_ptr());
|
||||
}
|
||||
}
|
||||
|
@ -2393,7 +2516,7 @@ static theory_mi_arith* get_th_arith(context& ctx, theory_id afid, expr* e) {
|
|||
}
|
||||
}
|
||||
|
||||
bool theory_seq::lower_bound(expr* _e, rational& lo) {
|
||||
bool theory_seq::lower_bound(expr* _e, rational& lo) const {
|
||||
context& ctx = get_context();
|
||||
expr_ref e(m_util.str.mk_length(_e), m);
|
||||
theory_mi_arith* tha = get_th_arith(ctx, m_autil.get_family_id(), e);
|
||||
|
@ -2402,7 +2525,7 @@ bool theory_seq::lower_bound(expr* _e, rational& lo) {
|
|||
return m_autil.is_numeral(_lo, lo) && lo.is_int();
|
||||
}
|
||||
|
||||
bool theory_seq::upper_bound(expr* _e, rational& hi) {
|
||||
bool theory_seq::upper_bound(expr* _e, rational& hi) const {
|
||||
context& ctx = get_context();
|
||||
expr_ref e(m_util.str.mk_length(_e), m);
|
||||
theory_mi_arith* tha = get_th_arith(ctx, m_autil.get_family_id(), e);
|
||||
|
@ -2411,7 +2534,7 @@ bool theory_seq::upper_bound(expr* _e, rational& hi) {
|
|||
return m_autil.is_numeral(_hi, hi) && hi.is_int();
|
||||
}
|
||||
|
||||
bool theory_seq::get_length(expr* e, rational& val) {
|
||||
bool theory_seq::get_length(expr* e, rational& val) const {
|
||||
context& ctx = get_context();
|
||||
theory* th = ctx.get_theory(m_autil.get_family_id());
|
||||
if (!th) return false;
|
||||
|
@ -2705,7 +2828,6 @@ literal theory_seq::mk_eq_empty(expr* _e, bool phase) {
|
|||
literal lit = mk_eq(e, emp, false);
|
||||
ctx.force_phase(phase?lit:~lit);
|
||||
ctx.mark_as_relevant(lit);
|
||||
TRACE("seq", tout << mk_pp(e, m) << " = empty\n";);
|
||||
return lit;
|
||||
}
|
||||
|
||||
|
@ -2718,7 +2840,7 @@ void theory_seq::add_axiom(literal l1, literal l2, literal l3, literal l4, liter
|
|||
if (l3 != null_literal && l3 != false_literal) { ctx.mark_as_relevant(l3); lits.push_back(l3); }
|
||||
if (l4 != null_literal && l4 != false_literal) { ctx.mark_as_relevant(l4); lits.push_back(l4); }
|
||||
if (l5 != null_literal && l5 != false_literal) { ctx.mark_as_relevant(l5); lits.push_back(l5); }
|
||||
TRACE("seq", ctx.display_literals_verbose(tout << "axiom: ", lits.size(), lits.c_ptr()); tout << "\n";);
|
||||
TRACE("seq", ctx.display_literals_verbose(tout << "assert: ", lits); tout << "\n";);
|
||||
m_new_propagation = true;
|
||||
++m_stats.m_add_axiom;
|
||||
ctx.mk_th_axiom(get_id(), lits.size(), lits.c_ptr());
|
||||
|
@ -2775,8 +2897,8 @@ void theory_seq::propagate_eq(dependency* deps, literal_vector const& _lits, exp
|
|||
new_eq_eh(deps, n1, n2);
|
||||
}
|
||||
TRACE("seq",
|
||||
ctx.display_literals_verbose(tout, lits.size(), lits.c_ptr());
|
||||
tout << " => " << mk_pp(e1, m) << " = " << mk_pp(e2, m) << "\n";);
|
||||
tout << "assert: " << mk_pp(e1, m) << " = " << mk_pp(e2, m) << "<- \n";
|
||||
ctx.display_literals_verbose(tout, lits););
|
||||
justification* js =
|
||||
ctx.mk_justification(
|
||||
ext_theory_eq_propagation_justification(
|
||||
|
@ -2848,10 +2970,15 @@ void theory_seq::assign_eh(bool_var v, bool is_true) {
|
|||
}
|
||||
else if (!canonizes(false, e)) {
|
||||
propagate_non_empty(lit, e2);
|
||||
#if 0
|
||||
dependency* dep = m_dm.mk_leaf(assumption(lit));
|
||||
m_ncs.push_back(nc(expr_ref(e, m), dep));
|
||||
#else
|
||||
propagate_lit(0, 1, &lit, ~mk_literal(m_util.str.mk_prefix(e2, e1)));
|
||||
if (add_contains2contains(e, change)) {
|
||||
add_atom(e);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else if (is_accept(e)) {
|
||||
|
@ -2921,7 +3048,7 @@ void theory_seq::new_diseq_eh(theory_var v1, theory_var v2) {
|
|||
expr_ref eq(m.mk_eq(e1, e2), m);
|
||||
m_rewrite(eq);
|
||||
if (!m.is_false(eq)) {
|
||||
TRACE("seq", tout << "new disequality: " << eq << "\n";);
|
||||
TRACE("seq", tout << "new disequality " << get_context().get_scope_level() << ": " << eq << "\n";);
|
||||
|
||||
literal lit = mk_eq(e1, e2, false);
|
||||
|
||||
|
@ -2980,6 +3107,7 @@ void theory_seq::push_scope_eh() {
|
|||
m_trail_stack.push(value_trail<theory_seq, unsigned>(m_axioms_head));
|
||||
m_eqs.push_scope();
|
||||
m_nqs.push_scope();
|
||||
m_ncs.push_scope();
|
||||
m_atoms_lim.push_back(m_atoms.size());
|
||||
}
|
||||
|
||||
|
@ -2992,6 +3120,7 @@ void theory_seq::pop_scope_eh(unsigned num_scopes) {
|
|||
m_exclude.pop_scope(num_scopes);
|
||||
m_eqs.pop_scope(num_scopes);
|
||||
m_nqs.pop_scope(num_scopes);
|
||||
m_ncs.pop_scope(num_scopes);
|
||||
m_atoms.resize(m_atoms_lim[m_atoms_lim.size()-num_scopes]);
|
||||
m_atoms_lim.shrink(m_atoms_lim.size()-num_scopes);
|
||||
m_rewrite.reset();
|
||||
|
@ -3196,7 +3325,7 @@ bool theory_seq::add_accept2step(expr* acc, bool& change) {
|
|||
if (has_undef) {
|
||||
return true;
|
||||
}
|
||||
TRACE("seq", ctx.display_literals_verbose(tout, lits.size(), lits.c_ptr()); tout << "\n";);
|
||||
TRACE("seq", ctx.display_literals_verbose(tout, lits); tout << "\n";);
|
||||
for (unsigned i = 0; i < lits.size(); ++i) {
|
||||
SASSERT(ctx.get_assignment(lits[i]) == l_false);
|
||||
lits[i].neg();
|
||||
|
@ -3353,7 +3482,6 @@ void theory_seq::propagate_not_prefix(expr* e) {
|
|||
|
||||
void theory_seq::propagate_not_prefix2(expr* e) {
|
||||
context& ctx = get_context();
|
||||
//std::cout << mk_pp(e, m) << " " << ctx.get_scope_level() << "\n";
|
||||
expr* e1, *e2;
|
||||
VERIFY(m_util.str.is_prefix(e, e1, e2));
|
||||
literal lit = ctx.get_literal(e);
|
||||
|
@ -3423,7 +3551,7 @@ bool theory_seq::add_prefix2prefix(expr* e, bool& change) {
|
|||
switch (ctx.get_assignment(e2_is_emp)) {
|
||||
case l_true:
|
||||
TRACE("seq", tout << mk_pp(e, m) << ": " << mk_pp(e2, m) << " = empty\n";
|
||||
ctx.display_literals_verbose(tout, 1, &e2_is_emp); tout << "\n"; );
|
||||
ctx.display_literal_verbose(tout, e2_is_emp); tout << "\n"; );
|
||||
return false; // done
|
||||
case l_undef:
|
||||
// ctx.force_phase(e2_is_emp);
|
||||
|
|
|
@ -191,6 +191,27 @@ namespace smt {
|
|||
expr_ref const& r() const { return m_r; }
|
||||
};
|
||||
|
||||
class nc {
|
||||
expr_ref m_contains;
|
||||
dependency* m_dep;
|
||||
public:
|
||||
nc(expr_ref const& c, dependency* dep):
|
||||
m_contains(c),
|
||||
m_dep(dep) {}
|
||||
nc(nc const& other):
|
||||
m_contains(other.m_contains),
|
||||
m_dep(other.m_dep) {}
|
||||
nc& operator=(nc const& other) {
|
||||
if (this != &other) {
|
||||
m_contains = other.m_contains;
|
||||
m_dep = other.m_dep;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
dependency* deps() const { return m_dep; }
|
||||
expr_ref const& contains() const { return m_contains; }
|
||||
};
|
||||
|
||||
class apply {
|
||||
public:
|
||||
virtual ~apply() {}
|
||||
|
@ -263,12 +284,14 @@ namespace smt {
|
|||
unsigned m_add_axiom;
|
||||
unsigned m_extensionality;
|
||||
unsigned m_fixed_length;
|
||||
unsigned m_propagate_contains;
|
||||
};
|
||||
ast_manager& m;
|
||||
dependency_manager m_dm;
|
||||
solution_map m_rep; // unification representative.
|
||||
scoped_vector<eq> m_eqs; // set of current equations.
|
||||
scoped_vector<ne> m_nqs; // set of current disequalities.
|
||||
scoped_vector<nc> m_ncs; // set of non-contains constraints.
|
||||
unsigned m_eq_id;
|
||||
|
||||
seq_factory* m_factory; // value factory
|
||||
|
@ -335,12 +358,14 @@ namespace smt {
|
|||
bool split_variable(); // split a variable
|
||||
bool is_solved();
|
||||
bool check_length_coherence();
|
||||
bool check_length_coherence0(expr* e);
|
||||
bool check_length_coherence(expr* e);
|
||||
bool fixed_length();
|
||||
bool fixed_length(expr* e);
|
||||
bool propagate_length_coherence(expr* e);
|
||||
|
||||
bool check_extensionality();
|
||||
bool check_contains();
|
||||
bool solve_eqs(unsigned start);
|
||||
bool solve_eq(expr_ref_vector const& l, expr_ref_vector const& r, dependency* dep);
|
||||
bool simplify_eq(expr_ref_vector& l, expr_ref_vector& r, dependency* dep);
|
||||
|
@ -362,6 +387,7 @@ namespace smt {
|
|||
expr_ref mk_concat(expr* e1, expr* e2, expr* e3) { return expr_ref(m_util.str.mk_concat(e1, e2, e3), m); }
|
||||
bool solve_nqs(unsigned i);
|
||||
bool solve_ne(unsigned i);
|
||||
bool solve_nc(unsigned i);
|
||||
|
||||
struct cell {
|
||||
cell* m_parent;
|
||||
|
@ -452,9 +478,9 @@ namespace smt {
|
|||
|
||||
|
||||
// arithmetic integration
|
||||
bool lower_bound(expr* s, rational& lo);
|
||||
bool upper_bound(expr* s, rational& hi);
|
||||
bool get_length(expr* s, rational& val);
|
||||
bool lower_bound(expr* s, rational& lo) const;
|
||||
bool upper_bound(expr* s, rational& hi) const;
|
||||
bool get_length(expr* s, rational& val) const;
|
||||
|
||||
void mk_decompose(expr* e, expr_ref& head, expr_ref& tail);
|
||||
expr_ref mk_skolem(symbol const& s, expr* e1, expr* e2 = 0, expr* e3 = 0, sort* range = 0);
|
||||
|
@ -494,7 +520,7 @@ namespace smt {
|
|||
void ensure_nth(literal lit, expr* s, expr* idx);
|
||||
bool canonizes(bool sign, expr* e);
|
||||
void propagate_non_empty(literal lit, expr* s);
|
||||
void propagate_is_conc(expr* e, expr* conc);
|
||||
bool propagate_is_conc(expr* e, expr* conc);
|
||||
void propagate_acc_rej_length(literal lit, expr* acc_rej);
|
||||
bool propagate_automata();
|
||||
void add_atom(expr* e);
|
||||
|
|
Loading…
Reference in a new issue