3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-24 01:25:31 +00:00
This commit is contained in:
Christoph M. Wintersteiger 2017-06-25 20:46:14 +01:00
commit ffbf19d944
150 changed files with 851 additions and 561 deletions

82
src/smt/CMakeLists.txt Normal file
View file

@ -0,0 +1,82 @@
z3_add_component(smt
SOURCES
arith_eq_adapter.cpp
arith_eq_solver.cpp
asserted_formulas.cpp
cached_var_subst.cpp
cost_evaluator.cpp
dyn_ack.cpp
elim_term_ite.cpp
expr_context_simplifier.cpp
fingerprints.cpp
mam.cpp
old_interval.cpp
qi_queue.cpp
smt_almost_cg_table.cpp
smt_case_split_queue.cpp
smt_cg_table.cpp
smt_checker.cpp
smt_clause.cpp
smt_conflict_resolution.cpp
smt_consequences.cpp
smt_context.cpp
smt_context_inv.cpp
smt_context_pp.cpp
smt_context_stat.cpp
smt_enode.cpp
smt_farkas_util.cpp
smt_for_each_relevant_expr.cpp
smt_implied_equalities.cpp
smt_internalizer.cpp
smt_justification.cpp
smt_kernel.cpp
smt_literal.cpp
smt_model_checker.cpp
smt_model_finder.cpp
smt_model_generator.cpp
smt_quantifier.cpp
smt_quantifier_stat.cpp
smt_quick_checker.cpp
smt_relevancy.cpp
smt_setup.cpp
smt_solver.cpp
smt_statistics.cpp
smt_theory.cpp
smt_value_sort.cpp
smt2_extra_cmds.cpp
theory_arith.cpp
theory_array_base.cpp
theory_array.cpp
theory_array_full.cpp
theory_bv.cpp
theory_datatype.cpp
theory_dense_diff_logic.cpp
theory_diff_logic.cpp
theory_dl.cpp
theory_dummy.cpp
theory_fpa.cpp
theory_lra.cpp
theory_opt.cpp
theory_pb.cpp
theory_seq.cpp
theory_str.cpp
theory_utvpi.cpp
theory_wmaxsat.cpp
uses_theory.cpp
watch_list.cpp
COMPONENT_DEPENDENCIES
bit_blaster
cmd_context
euclid
fpa
grobner
lp
macros
normal_forms
parser_util
pattern
proof_checker
proto_model
simplex
substitution
)

View file

@ -0,0 +1,19 @@
z3_add_component(smt_params
SOURCES
dyn_ack_params.cpp
preprocessor_params.cpp
qi_params.cpp
smt_params.cpp
theory_arith_params.cpp
theory_array_params.cpp
theory_bv_params.cpp
theory_pb_params.cpp
theory_str_params.cpp
COMPONENT_DEPENDENCIES
ast
bit_blaster
pattern
simplifier
PYG_FILES
smt_params_helper.pyg
)

View file

@ -0,0 +1,13 @@
z3_add_component(proto_model
SOURCES
array_factory.cpp
datatype_factory.cpp
numeral_factory.cpp
proto_model.cpp
struct_factory.cpp
value_factory.cpp
COMPONENT_DEPENDENCIES
model
simplifier
smt_params
)

View file

@ -1405,6 +1405,7 @@ namespace smt {
switch (js.get_kind()) {
case b_justification::CLAUSE: {
clause * cls = js.get_clause();
TRACE("unsat_core_bug", m_ctx.display_clause_detail(tout, cls););
unsigned num_lits = cls->get_num_literals();
unsigned i = 0;
if (consequent != false_literal) {
@ -1422,8 +1423,9 @@ namespace smt {
process_antecedent_for_unsat_core(~l);
}
justification * js = cls->get_justification();
if (js)
if (js) {
process_justification_for_unsat_core(js);
}
break;
}
case b_justification::BIN_CLAUSE:

View file

@ -1034,8 +1034,10 @@ namespace smt {
lbool val = get_assignment(curr);
switch(val) {
case l_false:
TRACE("simplify_aux_clause_literals", display_literal(tout << get_assign_level(curr) << " " << get_scope_level() << " ", curr); tout << "\n"; );
simp_lits.push_back(~curr);
break; // ignore literal
break; // ignore literal
// fall through
case l_undef:
if (curr == ~prev)
return false; // clause is equivalent to true

View file

@ -0,0 +1,8 @@
z3_add_component(smt_tactic
SOURCES
ctx_solver_simplify_tactic.cpp
smt_tactic.cpp
unit_subsumption_tactic.cpp
COMPONENT_DEPENDENCIES
smt
)

View file

@ -1458,7 +1458,7 @@ namespace smt {
normalize_gain(min_gain.get_rational(), max_gain);
}
if (is_int(x_i) && !max_gain.is_rational()) {
if (is_int(x_i) && !max_gain.is_int()) {
max_gain = inf_numeral(floor(max_gain));
normalize_gain(min_gain.get_rational(), max_gain);
}
@ -1483,7 +1483,7 @@ namespace smt {
}
}
TRACE("opt",
tout << "v" << x_i << " a_ij " << a_ij << " "
tout << "v" << x_i << (is_int(x_i)?" int":" real") << " a_ij " << a_ij << " "
<< "min gain: " << min_gain << " "
<< "max gain: " << max_gain << " tighter: "
<< (is_tighter?"true":"false") << "\n";);
@ -1696,6 +1696,7 @@ namespace smt {
if (lower(x_j)) tout << "lower x_j: " << lower_bound(x_j) << " ";
tout << "value x_j: " << get_value(x_j) << "\n";
);
pivot<true>(x_i, x_j, a_ij, false);
SASSERT(is_non_base(x_i));

View file

@ -2176,8 +2176,67 @@ bool theory_seq::simplify_and_solve_eqs() {
return m_new_propagation || ctx.inconsistent();
}
void theory_seq::internalize_eq_eh(app * atom, bool_var v) {}
void theory_seq::internalize_eq_eh(app * atom, bool_var v) {
}
bool theory_seq::internalize_atom(app* a, bool) {
#if 1
return internalize_term(a);
#else
if (is_skolem(m_eq, a)) {
return internalize_term(a);
}
context & ctx = get_context();
bool_var bv = ctx.mk_bool_var(a);
ctx.set_var_theory(bv, get_id());
ctx.mark_as_relevant(bv);
expr* e1, *e2;
if (m_util.str.is_in_re(a, e1, e2)) {
return internalize_term(to_app(e1)) && internalize_re(e2);
}
if (m_util.str.is_contains(a, e1, e2) ||
m_util.str.is_prefix(a, e1, e2) ||
m_util.str.is_suffix(a, e1, e2)) {
return internalize_term(to_app(e1)) && internalize_term(to_app(e2));
}
if (is_accept(a) || is_reject(a) || is_step(a) || is_skolem(symbol("seq.is_digit"), a)) {
return true;
}
UNREACHABLE();
return internalize_term(a);
#endif
}
bool theory_seq::internalize_re(expr* e) {
expr* e1, *e2;
unsigned lc, uc;
if (m_util.re.is_to_re(e, e1)) {
return internalize_term(to_app(e1));
}
if (m_util.re.is_star(e, e1) ||
m_util.re.is_plus(e, e1) ||
m_util.re.is_opt(e, e1) ||
m_util.re.is_loop(e, e1, lc) ||
m_util.re.is_loop(e, e1, lc, uc) ||
m_util.re.is_complement(e, e1)) {
return internalize_re(e1);
}
if (m_util.re.is_union(e, e1, e2) ||
m_util.re.is_intersection(e, e1, e2) ||
m_util.re.is_concat(e, e1, e2)) {
return internalize_re(e1) && internalize_re(e2);
}
if (m_util.re.is_full(e) ||
m_util.re.is_empty(e)) {
return true;
}
if (m_util.re.is_range(e, e1, e2)) {
return internalize_term(to_app(e1)) && internalize_term(to_app(e2));
}
UNREACHABLE();
return internalize_term(to_app(e));
}
bool theory_seq::internalize_term(app* term) {
context & ctx = get_context();
@ -2962,6 +3021,7 @@ void theory_seq::deque_axiom(expr* n) {
add_length_axiom(n);
}
else if (m_util.str.is_empty(n) && !has_length(n) && !m_length.empty()) {
ensure_enode(n);
enforce_length(get_context().get_enode(n));
}
else if (m_util.str.is_index(n)) {
@ -3567,8 +3627,8 @@ void theory_seq::add_at_axiom(expr* e) {
add_axiom(~i_ge_0, i_ge_len_s, mk_eq(one, len_e, false));
add_axiom(~i_ge_0, i_ge_len_s, mk_eq(i, len_x, false));
add_axiom(i_ge_0, mk_eq(s, emp, false));
add_axiom(~i_ge_len_s, mk_eq(s, emp, false));
add_axiom(i_ge_0, mk_eq(e, emp, false));
add_axiom(~i_ge_len_s, mk_eq(e, emp, false));
}
/**
@ -3875,7 +3935,7 @@ void theory_seq::new_eq_eh(dependency* deps, enode* n1, enode* n2) {
enforce_length_coherence(n1, n2);
}
else if (n1 != n2 && m_util.is_re(n1->get_owner())) {
warning_msg("equality between regular expressions is not yet supported");
// ignore
// eautomaton* a1 = get_automaton(n1->get_owner());
// eautomaton* a2 = get_automaton(n2->get_owner());
// eautomaton* b1 = mk_difference(*a1, *a2);
@ -3995,7 +4055,7 @@ void theory_seq::relevant_eh(app* n) {
}
expr* arg;
if (m_util.str.is_length(n, arg) && !has_length(arg)) {
if (m_util.str.is_length(n, arg) && !has_length(arg) && get_context().e_internalized(arg)) {
enforce_length(get_context().get_enode(arg));
}
}

View file

@ -341,8 +341,8 @@ namespace smt {
virtual void init(context* ctx);
virtual final_check_status final_check_eh();
virtual bool internalize_atom(app* atom, bool) { return internalize_term(atom); }
virtual bool internalize_term(app*);
virtual bool internalize_atom(app* atom, bool);
virtual bool internalize_term(app*);
virtual void internalize_eq_eh(app * atom, bool_var v);
virtual void new_eq_eh(theory_var, theory_var);
virtual void new_diseq_eh(theory_var, theory_var);
@ -387,6 +387,7 @@ namespace smt {
vector<rational> const& ll, vector<rational> const& rl);
bool set_empty(expr* x);
bool is_complex(eq const& e);
bool internalize_re(expr* e);
bool check_extensionality();
bool check_contains();

View file

@ -25,6 +25,7 @@
#include<algorithm>
#include"theory_seq_empty.h"
#include"theory_arith.h"
#include"ast_util.h"
namespace smt {
@ -98,7 +99,7 @@ namespace smt {
if (defaultCharset) {
// valid C strings can't contain the null byte ('\0')
charSetSize = 255;
char_set = alloc_svect(char, charSetSize);
char_set.resize(256, 0);
int idx = 0;
// small letters
for (int i = 97; i < 123; i++) {
@ -157,8 +158,7 @@ namespace smt {
} else {
const char setset[] = { 'a', 'b', 'c' };
int fSize = sizeof(setset) / sizeof(char);
char_set = alloc_svect(char, fSize);
char_set.resize(fSize, 0);
charSetSize = fSize;
for (int i = 0; i < charSetSize; i++) {
char_set[i] = setset[i];
@ -6927,9 +6927,9 @@ namespace smt {
ast_manager & m = get_manager();
if (lenTester_fvar_map.contains(lenTester)) {
expr * fVar = lenTester_fvar_map[lenTester];
expr * toAssert = gen_len_val_options_for_free_var(fVar, lenTester, lenTesterValue);
expr_ref toAssert(gen_len_val_options_for_free_var(fVar, lenTester, lenTesterValue), m);
TRACE("str", tout << "asserting more length tests for free variable " << mk_ismt2_pp(fVar, m) << std::endl;);
if (toAssert != NULL) {
if (toAssert) {
assert_axiom(toAssert);
}
}
@ -9123,7 +9123,7 @@ namespace smt {
zstring theory_str::gen_val_string(int len, int_vector & encoding) {
SASSERT(charSetSize > 0);
SASSERT(char_set != NULL);
SASSERT(!char_set.empty());
std::string re(len, char_set[0]);
for (int i = 0; i < (int) encoding.size() - 1; i++) {
@ -9173,7 +9173,7 @@ namespace smt {
}
}
expr * theory_str::gen_val_options(expr * freeVar, expr * len_indicator, expr * val_indicator,
expr* theory_str::gen_val_options(expr * freeVar, expr * len_indicator, expr * val_indicator,
zstring lenStr, int tries) {
ast_manager & m = get_manager();
context & ctx = get_context();
@ -9194,7 +9194,7 @@ namespace smt {
// ----------------------------------------------------------------------------------------
int len = atoi(lenStr.encode().c_str());
bool coverAll = false;
vector<int_vector, true, long long> options;
vector<int_vector, true, size_t> options;
int_vector base;
TRACE("str", tout
@ -9240,8 +9240,7 @@ namespace smt {
// ----------------------------------------------------------------------------------------
ptr_vector<expr> orList;
ptr_vector<expr> andList;
expr_ref_vector orList(m), andList(m);
for (long long i = l; i < h; i++) {
orList.push_back(m.mk_eq(val_indicator, mk_string(longlong_to_string(i).c_str()) ));
@ -9262,7 +9261,7 @@ namespace smt {
} else {
strAst = mk_string(aStr);
}
andList.push_back(m.mk_eq(orList[orList.size() - 1], m.mk_eq(freeVar, strAst)));
andList.push_back(m.mk_eq(orList[orList.size() - 1].get(), m.mk_eq(freeVar, strAst)));
}
if (!coverAll) {
orList.push_back(m.mk_eq(val_indicator, mk_string("more")));
@ -9273,21 +9272,8 @@ namespace smt {
}
}
expr ** or_items = alloc_svect(expr*, orList.size());
expr ** and_items = alloc_svect(expr*, andList.size() + 1);
for (int i = 0; i < (int) orList.size(); i++) {
or_items[i] = orList[i];
}
if (orList.size() > 1)
and_items[0] = m.mk_or(orList.size(), or_items);
else
and_items[0] = or_items[0];
for (int i = 0; i < (int) andList.size(); i++) {
and_items[i + 1] = andList[i];
}
expr * valTestAssert = m.mk_and(andList.size() + 1, and_items);
andList.push_back(mk_or(orList));
expr_ref valTestAssert = mk_and(andList);
// ---------------------------------------
// If the new value tester is $$_val_x_16_i
@ -9300,20 +9286,9 @@ namespace smt {
if (vTester != val_indicator)
andList.push_back(m.mk_eq(vTester, mk_string("more")));
}
expr * assertL = NULL;
if (andList.size() == 1) {
assertL = andList[0];
} else {
expr ** and_items = alloc_svect(expr*, andList.size());
for (int i = 0; i < (int) andList.size(); i++) {
and_items[i] = andList[i];
}
assertL = m.mk_and(andList.size(), and_items);
}
expr_ref assertL = mk_and(andList);
// (assertL => valTestAssert) <=> (!assertL OR valTestAssert)
valTestAssert = m.mk_or(m.mk_not(assertL), valTestAssert);
return valTestAssert;
return m.mk_or(m.mk_not(assertL), valTestAssert);
}
expr * theory_str::gen_free_var_options(expr * freeVar, expr * len_indicator,
@ -9378,7 +9353,7 @@ namespace smt {
<< " doesn't have an equivalence class value." << std::endl;);
refresh_theory_var(aTester);
expr * makeupAssert = gen_val_options(freeVar, len_indicator, aTester, len_valueStr, i);
expr_ref makeupAssert(gen_val_options(freeVar, len_indicator, aTester, len_valueStr, i), m);
TRACE("str", tout << "var: " << mk_ismt2_pp(freeVar, m) << std::endl
<< mk_ismt2_pp(makeupAssert, m) << std::endl;);
@ -9400,8 +9375,7 @@ namespace smt {
fvar_valueTester_map[freeVar][len].push_back(std::make_pair(sLevel, valTester));
print_value_tester_list(fvar_valueTester_map[freeVar][len]);
}
expr * nextAssert = gen_val_options(freeVar, len_indicator, valTester, len_valueStr, i + 1);
return nextAssert;
return gen_val_options(freeVar, len_indicator, valTester, len_valueStr, i + 1);
}
return NULL;

View file

@ -330,9 +330,9 @@ protected:
std::map<expr*, nfa> regex_nfa_cache; // Regex term --> NFA
char * char_set;
std::map<char, int> charSetLookupTable;
int charSetSize;
svector<char> char_set;
std::map<char, int> charSetLookupTable;
int charSetSize;
obj_pair_map<expr, expr, expr*> concat_astNode_map;
@ -553,7 +553,7 @@ protected:
expr * gen_len_test_options(expr * freeVar, expr * indicator, int tries);
expr * gen_free_var_options(expr * freeVar, expr * len_indicator,
zstring len_valueStr, expr * valTesterInCbEq, zstring valTesterValueStr);
expr * gen_val_options(expr * freeVar, expr * len_indicator, expr * val_indicator,
expr* gen_val_options(expr * freeVar, expr * len_indicator, expr * val_indicator,
zstring lenStr, int tries);
void print_value_tester_list(svector<std::pair<int, expr*> > & testerList);
bool get_next_val_encode(int_vector & base, int_vector & next);