mirror of
				https://github.com/Z3Prover/z3
				synced 2025-11-04 05:19:11 +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);
 | 
					        unsigned sz = bv.get_bv_size(b);
 | 
				
			||||||
        expr_ref_vector es(m);
 | 
					        expr_ref_vector es(m);
 | 
				
			||||||
        expr_ref bb(b, m), ten(bv.mk_numeral(10, sz), 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))));
 | 
					            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();
 | 
					        es.reverse();
 | 
				
			||||||
        eq = m.mk_eq(seq.str.mk_ubv2s(b), seq.str.mk_concat(es, seq.str.mk_string_sort()));
 | 
					        eq = m.mk_eq(seq.str.mk_ubv2s(b), seq.str.mk_concat(es, seq.str.mk_string_sort()));
 | 
				
			||||||
        add_clause(~ge10k, ge10k1, eq);
 | 
					        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) {
 | 
					    void axioms::ubv2ch_axiom(sort* bv_sort) {
 | 
				
			||||||
        bv_util bv(m);
 | 
					        bv_util bv(m);
 | 
				
			||||||
        expr_ref eq(m);
 | 
					        expr_ref eq(m);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -95,6 +95,7 @@ namespace seq {
 | 
				
			||||||
        void stoi_axiom(expr* e, unsigned k);
 | 
					        void stoi_axiom(expr* e, unsigned k);
 | 
				
			||||||
        void itos_axiom(expr* s, unsigned k);
 | 
					        void itos_axiom(expr* s, unsigned k);
 | 
				
			||||||
        void ubv2s_axiom(expr* b, unsigned k);
 | 
					        void ubv2s_axiom(expr* b, unsigned k);
 | 
				
			||||||
 | 
					        void ubv2s_len_axiom(expr* b, unsigned k);
 | 
				
			||||||
        void ubv2ch_axiom(sort* bv_sort);
 | 
					        void ubv2ch_axiom(sort* bv_sort);
 | 
				
			||||||
        void lt_axiom(expr* n);
 | 
					        void lt_axiom(expr* n);
 | 
				
			||||||
        void le_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_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_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_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_ubv2ch_axioms(sort* s) { m_ax.ubv2ch_axiom(s); }
 | 
				
			||||||
        void add_lt_axiom(expr* n) { m_ax.lt_axiom(n); }
 | 
					        void add_lt_axiom(expr* n) { m_ax.lt_axiom(n); }
 | 
				
			||||||
        void add_le_axiom(expr* n) { m_ax.le_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) {
 | 
					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_ubv_string.push_back(e);
 | 
				
			||||||
    m_trail_stack.push(push_back_vector<expr_ref_vector>(m_ubv_string));
 | 
					    m_trail_stack.push(push_back_vector<expr_ref_vector>(m_ubv_string));
 | 
				
			||||||
 | 
					    add_length_to_eqc(e);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool theory_seq::check_ubv_string() {
 | 
					bool theory_seq::check_ubv_string() {
 | 
				
			||||||
| 
						 | 
					@ -1554,6 +1565,11 @@ bool theory_seq::check_ubv_string(expr* e) {
 | 
				
			||||||
    expr* b = nullptr;
 | 
					    expr* b = nullptr;
 | 
				
			||||||
    bv_util bv(m);
 | 
					    bv_util bv(m);
 | 
				
			||||||
    VERIFY(m_util.str.is_ubv2s(e, b));
 | 
					    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);
 | 
					    unsigned sz = bv.get_bv_size(b);
 | 
				
			||||||
    rational value(0);
 | 
					    rational value(0);
 | 
				
			||||||
    bool all_bits_assigned = true;
 | 
					    bool all_bits_assigned = true;
 | 
				
			||||||
| 
						 | 
					@ -1579,14 +1595,7 @@ bool theory_seq::check_ubv_string(expr* e) {
 | 
				
			||||||
        k++;
 | 
					        k++;
 | 
				
			||||||
        value = div(value, rational(10));
 | 
					        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_has_ubv_axiom.insert(e);
 | 
				
			||||||
    m_trail_stack.push(insert_obj_trail<expr>(m_has_ubv_axiom, e));
 | 
					    m_trail_stack.push(insert_obj_trail<expr>(m_has_ubv_axiom, e));
 | 
				
			||||||
    m_ax.add_ubv2s_axiom(b, k);
 | 
					    m_ax.add_ubv2s_axiom(b, k);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue