mirror of
				https://github.com/Z3Prover/z3
				synced 2025-10-31 19:52:29 +00:00 
			
		
		
		
	regression fix, fix unicode mode
This commit is contained in:
		
							parent
							
								
									64ba44d2ac
								
							
						
					
					
						commit
						4e8ba8b160
					
				
					 4 changed files with 63 additions and 63 deletions
				
			
		|  | @ -1049,18 +1049,23 @@ bool seq_decl_plugin::is_considered_uninterpreted(func_decl * f) { | |||
|     return util.str.is_nth_u(f); | ||||
| } | ||||
| 
 | ||||
| bool seq_decl_plugin::is_unique_value(app* e) const { | ||||
|     if (is_app_of(e, m_family_id, OP_CHAR_CONST)) | ||||
|         return true; | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| bool seq_decl_plugin::is_value(app* e) const { | ||||
|     while (true) { | ||||
|         if (is_app_of(e, m_family_id, OP_SEQ_EMPTY)) { | ||||
|         if (is_app_of(e, m_family_id, OP_SEQ_EMPTY))  | ||||
|             return true; | ||||
|         } | ||||
|         if (is_app_of(e, m_family_id, OP_STRING_CONST)) { | ||||
|         if (is_app_of(e, m_family_id, OP_STRING_CONST))  | ||||
|             return true; | ||||
|         if (is_app_of(e, m_family_id, OP_CHAR_CONST)) | ||||
|             return true; | ||||
|         } | ||||
|         if (is_app_of(e, m_family_id, OP_SEQ_UNIT) && | ||||
|             m_manager->is_value(e->get_arg(0))) { | ||||
|             m_manager->is_value(e->get_arg(0)))  | ||||
|             return true; | ||||
|         } | ||||
|         if (is_app_of(e, m_family_id, OP_SEQ_CONCAT)) { | ||||
|             bool first = true; | ||||
|             for (expr* arg : *e) { | ||||
|  | @ -1086,29 +1091,23 @@ bool seq_decl_plugin::are_equal(app* a, app* b) const { | |||
| } | ||||
| 
 | ||||
| bool seq_decl_plugin::are_distinct(app* a, app* b) const { | ||||
|     if (a == b) { | ||||
|     if (a == b)  | ||||
|         return false; | ||||
|     } | ||||
|     if (is_app_of(a, m_family_id, OP_STRING_CONST) && | ||||
|         is_app_of(b, m_family_id, OP_STRING_CONST)) { | ||||
|         is_app_of(b, m_family_id, OP_STRING_CONST))  | ||||
|         return true; | ||||
|     if (is_app_of(a, m_family_id, OP_CHAR_CONST) &&  | ||||
|         is_app_of(b, m_family_id, OP_CHAR_CONST))  | ||||
|         return true; | ||||
|     } | ||||
|     if (is_app_of(a, m_family_id, OP_SEQ_UNIT) &&  | ||||
|         is_app_of(b, m_family_id, OP_SEQ_UNIT)) { | ||||
|         is_app_of(b, m_family_id, OP_SEQ_UNIT))  | ||||
|         return m_manager->are_distinct(a->get_arg(0), b->get_arg(0)); | ||||
|     } | ||||
|     if (is_app_of(a, m_family_id, OP_SEQ_EMPTY) &&  | ||||
|         is_app_of(b, m_family_id, OP_SEQ_UNIT)) { | ||||
|         is_app_of(b, m_family_id, OP_SEQ_UNIT))  | ||||
|         return true; | ||||
|     } | ||||
|     if (is_app_of(b, m_family_id, OP_SEQ_EMPTY) &&  | ||||
|         is_app_of(a, m_family_id, OP_SEQ_UNIT)) { | ||||
|         is_app_of(a, m_family_id, OP_SEQ_UNIT))  | ||||
|         return true; | ||||
|     }         | ||||
|     if (unicode() && is_app_of(a, m_family_id, OP_CHAR_CONST) &&  | ||||
|         is_app_of(b, m_family_id, OP_CHAR_CONST)) { | ||||
|         return true; | ||||
|     } | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -215,7 +215,7 @@ public: | |||
| 
 | ||||
|     bool is_value(app * e) const override; | ||||
| 
 | ||||
|     bool is_unique_value(app * e) const override { return false; } | ||||
|     bool is_unique_value(app * e) const override; | ||||
| 
 | ||||
|     bool are_equal(app* a, app* b) const override; | ||||
| 
 | ||||
|  |  | |||
|  | @ -67,6 +67,8 @@ namespace smt { | |||
|         ctx().internalize(ebits.c_ptr(), ebits.size(), true); | ||||
|         for (expr* arg : ebits) | ||||
|             bits.push_back(literal(ctx().get_bool_var(arg)));             | ||||
|         for (literal bit : bits) | ||||
|             ctx().mark_as_relevant(bit); | ||||
|     } | ||||
| 
 | ||||
|     void seq_unicode::internalize_le(literal lit, app* term) { | ||||
|  | @ -102,7 +104,7 @@ namespace smt { | |||
|             literal _eq = null_literal; | ||||
|             auto eq = [&]() { | ||||
|                 if (_eq == null_literal)  | ||||
|                     _eq = th.mk_eq(th.get_expr(v), th.get_expr(w), false); | ||||
|                     _eq = th.mk_literal(m.mk_eq(th.get_expr(v), th.get_expr(w))); | ||||
|                 return _eq; | ||||
|             }; | ||||
|             for (; i-- > 0; ) { | ||||
|  | @ -158,7 +160,7 @@ namespace smt { | |||
|      */ | ||||
|     bool seq_unicode::final_check() {    | ||||
|         m_var2value.reset(); | ||||
|         m_var2value.resize(th.get_num_vars(), 0); | ||||
|         m_var2value.resize(th.get_num_vars(), UINT_MAX); | ||||
|         m_value2var.reset(); | ||||
| 
 | ||||
|         // extract the initial set of constants.
 | ||||
|  | @ -167,61 +169,58 @@ namespace smt { | |||
|         bool requires_fix = false; | ||||
|         for (unsigned v = th.get_num_vars(); v-- > 0; ) { | ||||
|             expr* e = th.get_expr(v); | ||||
|             if (seq.is_char(e) && th.get_enode(v)->is_root() && get_value(v, c)) { | ||||
|             if (seq.is_char(e) && m_var2value[v] == UINT_MAX && get_value(v, c)) { | ||||
|                 CTRACE("seq", seq.is_char(e), tout << mk_pp(e, m) << " root: " << th.get_enode(v)->is_root() << " is_value: " << get_value(v, c) << "\n";); | ||||
|                 enode* r = th.get_enode(v)->get_root(); | ||||
|                 m_value2var.reserve(c + 1, null_theory_var); | ||||
|                 theory_var u = m_value2var[c]; | ||||
|                 if (u != null_theory_var && r != th.get_enode(u)->get_root()) { | ||||
|                     enforce_ackerman(u, v); | ||||
|                     requires_fix = true; | ||||
|                     continue; | ||||
|                 } | ||||
|                 if (c >= zstring::max_char()) { | ||||
|                     enforce_value_bound(v); | ||||
|                     requires_fix = true; | ||||
|                     continue; | ||||
|                 } | ||||
|                 values.insert(c); | ||||
|                 m_var2value[v] = c; | ||||
|                 m_value2var.reserve(c + 1, null_theory_var); | ||||
|                 theory_var w = m_value2var[c]; | ||||
|                 if (w != null_theory_var && th.get_enode(v)->get_root() != th.get_enode(w)->get_root()) { | ||||
|                     enforce_ackerman(v, w); | ||||
|                     requires_fix = true; | ||||
|                 } | ||||
|                 else { | ||||
|                     m_value2var[c] = v; | ||||
|                 } | ||||
|                 for (enode* n : *th.get_enode(v)) { | ||||
|                     theory_var w = n->get_th_var(th.get_id()); | ||||
|                     if (v != w && get_value(w, d) && d != c) { | ||||
|                         enforce_ackerman(v, w); | ||||
| 
 | ||||
|                 for (enode* n : *r) { | ||||
|                     u = n->get_th_var(th.get_id()); | ||||
|                     if (get_value(u, d) && d != c) { | ||||
|                         enforce_ackerman(u, v); | ||||
|                         requires_fix = true; | ||||
|                         break; | ||||
|                     } | ||||
|                     m_var2value[u] = c; | ||||
|                 } | ||||
|                 values.insert(c); | ||||
|                 m_value2var[c] = v; | ||||
|             } | ||||
|         } | ||||
|         if (requires_fix) | ||||
|             return false; | ||||
|          | ||||
|         // assign values to roots
 | ||||
|         // assign values to other unassigned nodes
 | ||||
|         c = 'a'; | ||||
|         for (unsigned v = th.get_num_vars(); v-- > 0; ) { | ||||
|             expr* e = th.get_expr(v); | ||||
|             if (!seq.is_char(e) || !th.get_enode(v)->is_root() || get_value(v, d)) | ||||
|                 continue; | ||||
|                         | ||||
|             d = c; | ||||
|             while (values.contains(c)) { | ||||
|                 c = (c + 1) % zstring::max_char(); | ||||
|                 if (d == c) { | ||||
|                     enforce_bits(); | ||||
|                     return false; | ||||
|                 }                     | ||||
|             } | ||||
|             m_var2value[v] = c; | ||||
|             values.insert(c); | ||||
|         } | ||||
|         for (unsigned v = th.get_num_vars(); v-- > 0; ) { | ||||
|             expr* e = th.get_expr(v); | ||||
|             if (seq.is_char(e) && !th.get_enode(v)->is_root() && !get_value(v, d)) { | ||||
|                 theory_var w = th.get_enode(v)->get_root()->get_th_var(th.get_id()); | ||||
|                 SASSERT(w != v && w != null_theory_var); | ||||
|                 m_var2value[v] = m_var2value[w]; | ||||
|             }      | ||||
|             if (seq.is_char(e) && m_var2value[v] == UINT_MAX) { | ||||
|                 d = c; | ||||
|                 while (values.contains(c)) { | ||||
|                     c = (c + 1) % zstring::max_char(); | ||||
|                     if (d == c) { | ||||
|                         enforce_bits(); | ||||
|                         return false; | ||||
|                     }                     | ||||
|                 } | ||||
|                 TRACE("seq", tout << "fresh: " << mk_pp(e, m) << " := " << c << "\n";); | ||||
|                 for (enode* n : *th.get_enode(v))  | ||||
|                     m_var2value[n->get_th_var(th.get_id())] = c; | ||||
|                 m_value2var.reserve(c + 1, null_theory_var); | ||||
|                 m_value2var[c] = v; | ||||
|                 values.insert(c); | ||||
|             }                        | ||||
|         } | ||||
|         return true; | ||||
|     } | ||||
|  | @ -249,12 +248,14 @@ namespace smt { | |||
| 
 | ||||
|     void seq_unicode::enforce_ackerman(theory_var v, theory_var w) { | ||||
|         TRACE("seq", tout << "enforce ackerman " << v << " " << w << "\n";); | ||||
|         literal eq = th.mk_eq(th.get_expr(v), th.get_expr(w), false); | ||||
|         literal eq = th.mk_literal(m.mk_eq(th.get_expr(v), th.get_expr(w))); | ||||
|         ctx().mark_as_relevant(eq); | ||||
|         literal_vector lits; | ||||
|         auto& a = get_ebits(v); | ||||
|         auto& b = get_ebits(w); | ||||
|         for (unsigned i = a.size(); i-- > 0; ) { | ||||
|             literal beq = th.mk_eq(a[i], b[i], false); | ||||
|             ctx().mark_as_relevant(beq); | ||||
|             lits.push_back(~beq); | ||||
|             // eq => a = b
 | ||||
|             ctx().mk_th_axiom(th.get_id(), ~eq, beq); | ||||
|  |  | |||
|  | @ -3192,7 +3192,7 @@ bool theory_seq::should_research(expr_ref_vector & unsat_core) { | |||
|         IF_VERBOSE(1, verbose_stream() << "(smt.seq :increase-depth " << m_max_unfolding_depth << ")\n"); | ||||
|         return true; | ||||
|     } | ||||
|     else if (k_min >= UINT_MAX/4) { | ||||
|     else if (k_min != UINT_MAX && k_min >= UINT_MAX/4) { | ||||
|         throw default_exception("reached max unfolding"); | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue