3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-06-27 08:28:44 +00:00
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2020-03-05 07:57:21 +01:00
parent 76d91f7d2b
commit 153d0661fe
3 changed files with 51 additions and 57 deletions

View file

@ -74,7 +74,7 @@ expr * array_factory::get_some_value(sort * s) {
bool array_factory::mk_two_diff_values_for(sort * s) { bool array_factory::mk_two_diff_values_for(sort * s) {
DEBUG_CODE({ DEBUG_CODE({
value_set * set = 0; value_set * set = 0;
SASSERT(!m_sort2value_set.find(s, set) || set->size() == 0); SASSERT(!m_sort2value_set.find(s, set) || set->size() <= 1);
}); });
expr_ref r1(m_manager); expr_ref r1(m_manager);
expr_ref r2(m_manager); expr_ref r2(m_manager);
@ -91,34 +91,28 @@ bool array_factory::mk_two_diff_values_for(sort * s) {
fi2->insert_entry(args.c_ptr(), r2); fi2->insert_entry(args.c_ptr(), r2);
DEBUG_CODE({ DEBUG_CODE({
value_set * set = 0; value_set * set = 0;
SASSERT(m_sort2value_set.find(s, set) && set->size() == 2); SASSERT(m_sort2value_set.find(s, set) && set->size() >= 2);
}); });
return true; return true;
} }
bool array_factory::get_some_values(sort * s, expr_ref & v1, expr_ref & v2) { bool array_factory::get_some_values(sort * s, expr_ref & v1, expr_ref & v2) {
value_set * set = nullptr; value_set * set = nullptr;
if (!m_sort2value_set.find(s, set) || set->empty()) { if (!m_sort2value_set.find(s, set) || set->size() < 2) {
if (!mk_two_diff_values_for(s)) if (!mk_two_diff_values_for(s)) {
TRACE("array_factory_bug", tout << "could not create diff values: " << mk_pp(s, m_manager) << "\n";);
return false; return false;
} }
}
m_sort2value_set.find(s, set); m_sort2value_set.find(s, set);
SASSERT(set != 0); SASSERT(set != 0);
SASSERT(set->size() > 0);
if (set->size() == 1) {
v1 = *(set->begin());
v2 = get_fresh_value(s);
return v2.get() != nullptr;
}
else {
SASSERT(set->size() >= 2); SASSERT(set->size() >= 2);
value_set::iterator it = set->begin(); value_set::iterator it = set->begin();
v1 = *it; v1 = *it;
++it; ++it;
v2 = *it; v2 = *it;
return true; return true;
}
} }
// //
@ -144,10 +138,9 @@ expr * array_factory::get_fresh_value(sort * s) {
fi->set_else(range_val); fi->set_else(range_val);
return val; return val;
} }
else {
TRACE("array_factory_bug", tout << "array fresh value: using fresh index, range: " << mk_pp(range, m_manager) << "\n";); TRACE("array_factory_bug", tout << "array fresh value: using fresh index, range: " << mk_pp(range, m_manager) << "\n";);
expr_ref v1(m_manager); expr_ref v1(m_manager), v2(m_manager), w1(m_manager), w2(m_manager);
expr_ref v2(m_manager);
if (m_model.get_some_values(range, v1, v2)) { if (m_model.get_some_values(range, v1, v2)) {
// Claim: A is fresh if A[i1] = v1 and A[i2] = v2 where i1 and i2 are fresh values, // Claim: A is fresh if A[i1] = v1 and A[i2] = v2 where i1 and i2 are fresh values,
// and v1 and v2 are distinct. // and v1 and v2 are distinct.
@ -185,7 +178,6 @@ expr * array_factory::get_fresh_value(sort * s) {
return val; return val;
} }
} }
}
// TODO: use more expensive procedures to create a fresh array value. // TODO: use more expensive procedures to create a fresh array value.
// Example: track the values used in the domain. // Example: track the values used in the domain.

View file

@ -318,7 +318,7 @@ namespace smt {
for (source const& curr : sources) { for (source const& curr : sources) {
if (curr.is_fresh_value()) { if (curr.is_fresh_value()) {
sort * s = curr.get_value()->get_sort(); sort * s = curr.get_value()->get_sort();
TRACE("model_fresh_bug", tout << curr << " : " << mk_pp(s, m) << "\n";); TRACE("model_fresh_bug", tout << curr << " : " << mk_pp(s, m) << " " << curr.get_value()->get_value() << "\n";);
expr * val = m_model->get_fresh_value(s); expr * val = m_model->get_fresh_value(s);
TRACE("model_fresh_bug", tout << curr << " := #" << (val == nullptr ? UINT_MAX : val->get_id()) << "\n";); TRACE("model_fresh_bug", tout << curr << " := #" << (val == nullptr ? UINT_MAX : val->get_id()) << "\n";);
m_asts.push_back(val); m_asts.push_back(val);

View file

@ -995,6 +995,8 @@ namespace smt {
// IMPORTANT: // IMPORTANT:
// The implementation should not assume a fresh value is created for // The implementation should not assume a fresh value is created for
// the else_val if the range is finite // the else_val if the range is finite
TRACE("array", tout << mk_pp(n->get_owner(), get_manager()) << " " << mk_pp(range, get_manager()) << " " << range->is_infinite() << "\n";);
if (range->is_infinite()) if (range->is_infinite())
else_val = TAG(void*, m.mk_extra_fresh_value(range), 1); else_val = TAG(void*, m.mk_extra_fresh_value(range), 1);
else else