mirror of
				https://github.com/Z3Prover/z3
				synced 2025-10-31 19:52:29 +00:00 
			
		
		
		
	add length axioms
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
		
							parent
							
								
									a49a5b3a0b
								
							
						
					
					
						commit
						0752b1385c
					
				
					 4 changed files with 43 additions and 10 deletions
				
			
		|  | @ -786,15 +786,37 @@ namespace seq { | |||
|         unsigned sz = bv.get_bv_size(b); | ||||
|         expr_ref_vector es(m); | ||||
|         expr_ref bb(b, m), ten(bv.mk_numeral(10, sz), m); | ||||
|         for (unsigned i = 0; i < k; ++i) { | ||||
|         pow = 1; | ||||
|         for (unsigned i = 0; i <= k; ++i) { | ||||
|             if (pow > 1) | ||||
|                 bb = bv.mk_bv_udiv(b, bv.mk_numeral(pow, bv_sort)); | ||||
|             es.push_back(seq.str.mk_unit(m_sk.mk_ubv2ch(bv.mk_bv_urem(bb, ten)))); | ||||
|             bb = bv.mk_bv_udiv(bb, ten); | ||||
|             pow *= 10; | ||||
|         } | ||||
|         es.reverse(); | ||||
|         eq = m.mk_eq(seq.str.mk_ubv2s(b), seq.str.mk_concat(es, seq.str.mk_string_sort())); | ||||
|         add_clause(~ge10k, ge10k1, eq); | ||||
|     } | ||||
| 
 | ||||
|     /*
 | ||||
|     *   len(ubv2s(b)) = k => 10^k-1 <= b < 10^{k}   k > 1 | ||||
|     *   len(ubv2s(b)) = 1 =>  b < 10^{1}   k = 1 | ||||
|     */ | ||||
|     void axioms::ubv2s_len_axiom(expr* b, unsigned k) { | ||||
|         expr_ref ge10k(m), ge10k1(m), eq(m); | ||||
|         bv_util bv(m); | ||||
|         sort* bv_sort = b->get_sort(); | ||||
|         rational pow(1); | ||||
|         for (unsigned i = 1; i < k; ++i) | ||||
|             pow *= 10; | ||||
|         ge10k = bv.mk_ule(bv.mk_numeral(pow, bv_sort), b);         | ||||
|         ge10k1 = bv.mk_ule(bv.mk_numeral(pow * 10, bv_sort), b); | ||||
|         eq = m.mk_eq(seq.str.mk_length(seq.str.mk_ubv2s(b)), a.mk_int(k)); | ||||
|         add_clause(~eq, ~ge10k1); | ||||
|         if (k > 1) | ||||
|             add_clause(~eq, ge10k); | ||||
|     } | ||||
| 
 | ||||
|     void axioms::ubv2ch_axiom(sort* bv_sort) { | ||||
|         bv_util bv(m); | ||||
|         expr_ref eq(m); | ||||
|  |  | |||
|  | @ -95,6 +95,7 @@ namespace seq { | |||
|         void stoi_axiom(expr* e, unsigned k); | ||||
|         void itos_axiom(expr* s, unsigned k); | ||||
|         void ubv2s_axiom(expr* b, unsigned k); | ||||
|         void ubv2s_len_axiom(expr* b, unsigned k); | ||||
|         void ubv2ch_axiom(sort* bv_sort); | ||||
|         void lt_axiom(expr* n); | ||||
|         void le_axiom(expr* n); | ||||
|  |  | |||
|  | @ -80,6 +80,7 @@ namespace smt { | |||
|         void add_stoi_axiom(expr* e, unsigned k) { m_ax.stoi_axiom(e, k); } | ||||
|         void add_itos_axiom(expr* s, unsigned k) { m_ax.itos_axiom(s, k); } | ||||
|         void add_ubv2s_axiom(expr* b, unsigned k) { m_ax.ubv2s_axiom(b, k); } | ||||
|         void add_ubv2s_len_axiom(expr* b, unsigned k) { m_ax.ubv2s_len_axiom(b, k); } | ||||
|         void add_ubv2ch_axioms(sort* s) { m_ax.ubv2ch_axiom(s); } | ||||
|         void add_lt_axiom(expr* n) { m_ax.lt_axiom(n); } | ||||
|         void add_le_axiom(expr* n) { m_ax.le_axiom(n); } | ||||
|  |  | |||
|  | @ -1532,8 +1532,19 @@ bool theory_seq::add_length_to_eqc(expr* e) { | |||
| } | ||||
| 
 | ||||
| void theory_seq::add_ubv_string(expr* e) { | ||||
|     bool has_sort = false; | ||||
|     expr* b = nullptr; | ||||
|     VERIFY(m_util.str.is_ubv2s(e, b)); | ||||
|     for (auto* e2 : m_ubv_string) { | ||||
|         expr* b2 = nullptr; | ||||
|         VERIFY(m_util.str.is_ubv2s(e2, b2)); | ||||
|         has_sort |= b2->get_sort() == b->get_sort(); | ||||
|     } | ||||
|     if (!has_sort) | ||||
|         m_ax.add_ubv2ch_axioms(b->get_sort()); | ||||
|     m_ubv_string.push_back(e); | ||||
|     m_trail_stack.push(push_back_vector<expr_ref_vector>(m_ubv_string)); | ||||
|     add_length_to_eqc(e); | ||||
| } | ||||
| 
 | ||||
| bool theory_seq::check_ubv_string() { | ||||
|  | @ -1554,6 +1565,11 @@ bool theory_seq::check_ubv_string(expr* e) { | |||
|     expr* b = nullptr; | ||||
|     bv_util bv(m); | ||||
|     VERIFY(m_util.str.is_ubv2s(e, b)); | ||||
|     rational len; | ||||
|     if (get_length(e, len) && len.is_unsigned())  | ||||
|         m_ax.add_ubv2s_len_axiom(b, len.get_unsigned()); | ||||
|      | ||||
| 
 | ||||
|     unsigned sz = bv.get_bv_size(b); | ||||
|     rational value(0); | ||||
|     bool all_bits_assigned = true; | ||||
|  | @ -1579,14 +1595,7 @@ bool theory_seq::check_ubv_string(expr* e) { | |||
|         k++; | ||||
|         value = div(value, rational(10)); | ||||
|     } | ||||
|     bool has_sort = false; | ||||
|     for (auto* e2 : m_has_ubv_axiom) { | ||||
|         expr* b2 = nullptr; | ||||
|         VERIFY(m_util.str.is_ubv2s(e2, b2)); | ||||
|         has_sort |= b2->get_sort() == b->get_sort(); | ||||
|     } | ||||
|     if (!has_sort) | ||||
|         m_ax.add_ubv2ch_axioms(b->get_sort()); | ||||
| 
 | ||||
|     m_has_ubv_axiom.insert(e); | ||||
|     m_trail_stack.push(insert_obj_trail<expr>(m_has_ubv_axiom, e)); | ||||
|     m_ax.add_ubv2s_axiom(b, k); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue