mirror of
				https://github.com/Z3Prover/z3
				synced 2025-11-04 05:19:11 +00:00 
			
		
		
		
	theory_str frontend changes
This commit is contained in:
		
							parent
							
								
									a048d74bae
								
							
						
					
					
						commit
						46ac718790
					
				
					 5 changed files with 76 additions and 6 deletions
				
			
		| 
						 | 
					@ -17,6 +17,7 @@ Revision History:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
--*/
 | 
					--*/
 | 
				
			||||||
#include<sstream>
 | 
					#include<sstream>
 | 
				
			||||||
 | 
					#include<cstring>
 | 
				
			||||||
#include"ast.h"
 | 
					#include"ast.h"
 | 
				
			||||||
#include"ast_pp.h"
 | 
					#include"ast_pp.h"
 | 
				
			||||||
#include"ast_ll_pp.h"
 | 
					#include"ast_ll_pp.h"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -117,6 +117,9 @@ public:
 | 
				
			||||||
    explicit parameter(symbol const & s): m_kind(PARAM_SYMBOL) { new (m_symbol) symbol(s); }
 | 
					    explicit parameter(symbol const & s): m_kind(PARAM_SYMBOL) { new (m_symbol) symbol(s); }
 | 
				
			||||||
    explicit parameter(rational const & r): m_kind(PARAM_RATIONAL) { new (m_rational) rational(r); }
 | 
					    explicit parameter(rational const & r): m_kind(PARAM_RATIONAL) { new (m_rational) rational(r); }
 | 
				
			||||||
    explicit parameter(double d):m_kind(PARAM_DOUBLE), m_dval(d) {}
 | 
					    explicit parameter(double d):m_kind(PARAM_DOUBLE), m_dval(d) {}
 | 
				
			||||||
 | 
					    explicit parameter(const char *s):m_kind(PARAM_SYMBOL) {
 | 
				
			||||||
 | 
					        new (m_symbol) symbol(s);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    explicit parameter(unsigned ext_id, bool):m_kind(PARAM_EXTERNAL), m_ext_id(ext_id) {}
 | 
					    explicit parameter(unsigned ext_id, bool):m_kind(PARAM_EXTERNAL), m_ext_id(ext_id) {}
 | 
				
			||||||
    parameter(parameter const&);
 | 
					    parameter(parameter const&);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -329,7 +329,8 @@ br_status seq_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * con
 | 
				
			||||||
    switch(f->get_decl_kind()) {
 | 
					    switch(f->get_decl_kind()) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    case OP_SEQ_UNIT:
 | 
					    case OP_SEQ_UNIT:
 | 
				
			||||||
        return BR_FAILED;
 | 
					        SASSERT(num_args == 1);
 | 
				
			||||||
 | 
					        return mk_seq_unit(args[0], result);
 | 
				
			||||||
    case OP_SEQ_EMPTY:
 | 
					    case OP_SEQ_EMPTY:
 | 
				
			||||||
        return BR_FAILED;
 | 
					        return BR_FAILED;
 | 
				
			||||||
    case OP_RE_PLUS:
 | 
					    case OP_RE_PLUS:
 | 
				
			||||||
| 
						 | 
					@ -351,7 +352,8 @@ br_status seq_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * con
 | 
				
			||||||
        SASSERT(num_args == 2);
 | 
					        SASSERT(num_args == 2);
 | 
				
			||||||
        return mk_re_union(args[0], args[1], result);
 | 
					        return mk_re_union(args[0], args[1], result);
 | 
				
			||||||
    case OP_RE_RANGE:
 | 
					    case OP_RE_RANGE:
 | 
				
			||||||
        return BR_FAILED;    
 | 
					        SASSERT(num_args == 2);
 | 
				
			||||||
 | 
					        return mk_re_range(args[0], args[1], result);
 | 
				
			||||||
    case OP_RE_INTERSECT:
 | 
					    case OP_RE_INTERSECT:
 | 
				
			||||||
        SASSERT(num_args == 2);
 | 
					        SASSERT(num_args == 2);
 | 
				
			||||||
        return mk_re_inter(args[0], args[1], result);
 | 
					        return mk_re_inter(args[0], args[1], result);
 | 
				
			||||||
| 
						 | 
					@ -434,6 +436,33 @@ br_status seq_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * con
 | 
				
			||||||
    return BR_FAILED;
 | 
					    return BR_FAILED;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * (seq.unit (_ BitVector 8)) ==> String constant
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					br_status seq_rewriter::mk_seq_unit(expr* e, expr_ref& result) {
 | 
				
			||||||
 | 
					    sort * s = m().get_sort(e);
 | 
				
			||||||
 | 
					    bv_util bvu(m());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (is_sort_of(s, bvu.get_family_id(), BV_SORT)) {
 | 
				
			||||||
 | 
					        // specifically we want (_ BitVector 8)
 | 
				
			||||||
 | 
					        rational n_val;
 | 
				
			||||||
 | 
					        unsigned int n_size;
 | 
				
			||||||
 | 
					        if (bvu.is_numeral(e, n_val, n_size)) {
 | 
				
			||||||
 | 
					            if (n_size == 8) {
 | 
				
			||||||
 | 
					                // convert to string constant
 | 
				
			||||||
 | 
					                char ch = (char)n_val.get_int32();
 | 
				
			||||||
 | 
					                TRACE("seq", tout << "rewrite seq.unit of 8-bit value " << n_val.to_string() << " to string constant \"" << ch << "\"" << std::endl;);
 | 
				
			||||||
 | 
					                char s_tmp[2] = {ch, '\0'};
 | 
				
			||||||
 | 
					                symbol s(s_tmp);
 | 
				
			||||||
 | 
					                result = m_util.str.mk_string(s);
 | 
				
			||||||
 | 
					                return BR_DONE;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return BR_FAILED;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
   string + string = string
 | 
					   string + string = string
 | 
				
			||||||
   a + (b + c) = (a + b) + c
 | 
					   a + (b + c) = (a + b) + c
 | 
				
			||||||
| 
						 | 
					@ -1401,6 +1430,39 @@ br_status seq_rewriter::mk_re_star(expr* a, expr_ref& result) {
 | 
				
			||||||
    return BR_FAILED;
 | 
					    return BR_FAILED;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * (re.range c_1 c_n) = (re.union (str.to.re c1) (str.to.re c2) ... (str.to.re cn))
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					br_status seq_rewriter::mk_re_range(expr* lo, expr* hi, expr_ref& result) {
 | 
				
			||||||
 | 
					    TRACE("seq", tout << "rewrite re.range [" << mk_pp(lo, m()) << " " << mk_pp(hi, m()) << "]\n";);
 | 
				
			||||||
 | 
					    zstring str_lo, str_hi;
 | 
				
			||||||
 | 
					    if (m_util.str.is_string(lo, str_lo) && m_util.str.is_string(hi, str_hi)) {
 | 
				
			||||||
 | 
					        if (str_lo.length() == 1 && str_hi.length() == 1) {
 | 
				
			||||||
 | 
					            unsigned int c1 = str_lo[0];
 | 
				
			||||||
 | 
					            unsigned int c2 = str_hi[0];
 | 
				
			||||||
 | 
					            if (c1 > c2) {
 | 
				
			||||||
 | 
					                // exchange c1 and c2
 | 
				
			||||||
 | 
					                unsigned int tmp = c1;
 | 
				
			||||||
 | 
					                c2 = c1;
 | 
				
			||||||
 | 
					                c1 = tmp;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            zstring s(c1);
 | 
				
			||||||
 | 
					            expr_ref acc(m_util.re.mk_to_re(m_util.str.mk_string(s)), m());
 | 
				
			||||||
 | 
					            for (unsigned int ch = c1 + 1; ch <= c2; ++ch) {
 | 
				
			||||||
 | 
					                zstring s_ch(ch);
 | 
				
			||||||
 | 
					                expr_ref acc2(m_util.re.mk_to_re(m_util.str.mk_string(s_ch)), m());
 | 
				
			||||||
 | 
					                acc = m_util.re.mk_union(acc, acc2);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            result = acc;
 | 
				
			||||||
 | 
					            return BR_REWRITE2;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            m().raise_exception("string constants in re.range must have length 1");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return BR_FAILED;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
   emp+ = emp
 | 
					   emp+ = emp
 | 
				
			||||||
   all+ = all
 | 
					   all+ = all
 | 
				
			||||||
| 
						 | 
					@ -1430,9 +1492,9 @@ br_status seq_rewriter::mk_re_plus(expr* a, expr_ref& result) {
 | 
				
			||||||
        return BR_DONE;
 | 
					        return BR_DONE;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return BR_FAILED;
 | 
					    //return BR_FAILED;
 | 
				
			||||||
//  result = m_util.re.mk_concat(a, m_util.re.mk_star(a));
 | 
					    result = m_util.re.mk_concat(a, m_util.re.mk_star(a));
 | 
				
			||||||
//  return BR_REWRITE2;
 | 
					    return BR_REWRITE2;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
br_status seq_rewriter::mk_re_opt(expr* a, expr_ref& result) {
 | 
					br_status seq_rewriter::mk_re_opt(expr* a, expr_ref& result) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -98,6 +98,7 @@ class seq_rewriter {
 | 
				
			||||||
    re2automaton   m_re2aut;
 | 
					    re2automaton   m_re2aut;
 | 
				
			||||||
    expr_ref_vector m_es, m_lhs, m_rhs;
 | 
					    expr_ref_vector m_es, m_lhs, m_rhs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    br_status mk_seq_unit(expr* e, expr_ref& result);
 | 
				
			||||||
    br_status mk_seq_concat(expr* a, expr* b, expr_ref& result);
 | 
					    br_status mk_seq_concat(expr* a, expr* b, expr_ref& result);
 | 
				
			||||||
    br_status mk_seq_length(expr* a, expr_ref& result);
 | 
					    br_status mk_seq_length(expr* a, expr_ref& result);
 | 
				
			||||||
    br_status mk_seq_extract(expr* a, expr* b, expr* c, expr_ref& result);
 | 
					    br_status mk_seq_extract(expr* a, expr* b, expr* c, expr_ref& result);
 | 
				
			||||||
| 
						 | 
					@ -119,6 +120,7 @@ class seq_rewriter {
 | 
				
			||||||
    br_status mk_re_plus(expr* a, expr_ref& result);
 | 
					    br_status mk_re_plus(expr* a, expr_ref& result);
 | 
				
			||||||
    br_status mk_re_opt(expr* a, expr_ref& result);
 | 
					    br_status mk_re_opt(expr* a, expr_ref& result);
 | 
				
			||||||
    br_status mk_re_loop(unsigned num_args, expr* const* args, expr_ref& result);
 | 
					    br_status mk_re_loop(unsigned num_args, expr* const* args, expr_ref& result);
 | 
				
			||||||
 | 
					    br_status mk_re_range(expr* lo, expr* hi, expr_ref& result);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool set_empty(unsigned sz, expr* const* es, bool all, expr_ref_vector& lhs, expr_ref_vector& rhs);
 | 
					    bool set_empty(unsigned sz, expr* const* es, bool all, expr_ref_vector& lhs, expr_ref_vector& rhs);
 | 
				
			||||||
    bool is_subsequence(unsigned n, expr* const* l, unsigned m, expr* const* r, 
 | 
					    bool is_subsequence(unsigned n, expr* const* l, unsigned m, expr* const* r, 
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -573,7 +573,7 @@ void seq_decl_plugin::set_manager(ast_manager* m, family_id id) {
 | 
				
			||||||
    m_char = bv.mk_sort(8);
 | 
					    m_char = bv.mk_sort(8);
 | 
				
			||||||
    m->inc_ref(m_char);
 | 
					    m->inc_ref(m_char);
 | 
				
			||||||
    parameter param(m_char);
 | 
					    parameter param(m_char);
 | 
				
			||||||
    m_string = m->mk_sort(symbol("String"), sort_info(m_family_id, SEQ_SORT, 1, ¶m));
 | 
					    m_string = m->mk_sort(symbol("StringSequence"), sort_info(m_family_id, SEQ_SORT, 1, ¶m));
 | 
				
			||||||
    m->inc_ref(m_string);
 | 
					    m->inc_ref(m_string);
 | 
				
			||||||
    parameter paramS(m_string);
 | 
					    parameter paramS(m_string);
 | 
				
			||||||
    m_re = m->mk_sort(m_family_id, RE_SORT, 1, ¶mS);
 | 
					    m_re = m->mk_sort(m_family_id, RE_SORT, 1, ¶mS);
 | 
				
			||||||
| 
						 | 
					@ -831,7 +831,9 @@ void seq_decl_plugin::get_sort_names(svector<builtin_name> & sort_names, symbol
 | 
				
			||||||
    init();
 | 
					    init();
 | 
				
			||||||
    sort_names.push_back(builtin_name("Seq",   SEQ_SORT));
 | 
					    sort_names.push_back(builtin_name("Seq",   SEQ_SORT));
 | 
				
			||||||
    sort_names.push_back(builtin_name("RegEx", RE_SORT));
 | 
					    sort_names.push_back(builtin_name("RegEx", RE_SORT));
 | 
				
			||||||
 | 
					    // SMT-LIB 2.5 compatibility
 | 
				
			||||||
    sort_names.push_back(builtin_name("String", _STRING_SORT));
 | 
					    sort_names.push_back(builtin_name("String", _STRING_SORT));
 | 
				
			||||||
 | 
					    sort_names.push_back(builtin_name("StringSequence", _STRING_SORT));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
app* seq_decl_plugin::mk_string(symbol const& s) {
 | 
					app* seq_decl_plugin::mk_string(symbol const& s) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue