mirror of
				https://github.com/Z3Prover/z3
				synced 2025-11-03 21:09:11 +00:00 
			
		
		
		
	add rewrites for #2575
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
		
							parent
							
								
									78ed71b8de
								
							
						
					
					
						commit
						12034df11a
					
				
					 3 changed files with 70 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -1673,6 +1673,37 @@ br_status seq_rewriter::mk_re_concat(expr* a, expr* b, expr_ref& result) {
 | 
			
		|||
        result = a;
 | 
			
		||||
        return BR_DONE;
 | 
			
		||||
    }
 | 
			
		||||
    expr* a1 = nullptr, *b1 = nullptr;
 | 
			
		||||
    if (m_util.re.is_star(a, a1) && m_util.re.is_star(b, b1) && a1 == b1) {
 | 
			
		||||
        result = a;
 | 
			
		||||
        return BR_DONE;
 | 
			
		||||
    }
 | 
			
		||||
    if (m_util.re.is_star(a, a1) && a1 == b) {
 | 
			
		||||
        result = m_util.re.mk_concat(b, a);
 | 
			
		||||
        return BR_DONE;
 | 
			
		||||
    }
 | 
			
		||||
    {
 | 
			
		||||
        unsigned lo1, hi1, lo2, hi2;
 | 
			
		||||
        if (m_util.re.is_loop(a, a1, lo1, hi1) && m_util.re.is_loop(b, b1, lo2, hi2) && a1 == b1) {
 | 
			
		||||
            result = m_util.re.mk_loop(a1, lo1 + lo2, hi1 + hi2);
 | 
			
		||||
            return BR_DONE;
 | 
			
		||||
        }
 | 
			
		||||
        if (m_util.re.is_loop(a, a1, lo1) && m_util.re.is_loop(b, b1, lo2) && a1 == b1) {
 | 
			
		||||
            result = m_util.re.mk_loop(a1, lo1 + lo2);
 | 
			
		||||
            return BR_DONE;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    {
 | 
			
		||||
        expr* lo1, *hi1, *lo2, *hi2;
 | 
			
		||||
        if (m_util.re.is_loop(a, a1, lo1, hi1) && m_util.re.is_loop(b, b1, lo2, hi2) && a1 == b1) {
 | 
			
		||||
            result = m_util.re.mk_loop(a1, m_autil.mk_add(lo1, lo2), m_autil.mk_add(hi1, hi2));
 | 
			
		||||
            return BR_DONE;
 | 
			
		||||
        }
 | 
			
		||||
        if (m_util.re.is_loop(a, a1, lo1) && m_util.re.is_loop(b, b1, lo2) && a1 == b1) {
 | 
			
		||||
            result = m_util.re.mk_loop(a1, m_autil.mk_add(lo1, lo2));
 | 
			
		||||
            return BR_DONE;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return BR_FAILED;
 | 
			
		||||
}
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1093,6 +1093,16 @@ app* seq_util::re::mk_loop(expr* r, unsigned lo, unsigned hi) {
 | 
			
		|||
    return m.mk_app(m_fid, OP_RE_LOOP, 2, params, 1, &r);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
app* seq_util::re::mk_loop(expr* r, expr* lo) {
 | 
			
		||||
    expr* rs[2] = { r, lo };
 | 
			
		||||
    return m.mk_app(m_fid, OP_RE_LOOP, 0, nullptr, 2, rs);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
app* seq_util::re::mk_loop(expr* r, expr* lo, expr* hi) {
 | 
			
		||||
    expr* rs[3] = { r, lo, hi };
 | 
			
		||||
    return m.mk_app(m_fid, OP_RE_LOOP, 0, nullptr, 3, rs);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
app* seq_util::re::mk_full_char(sort* s) {
 | 
			
		||||
    return m.mk_app(m_fid, OP_RE_FULL_CHAR_SET, 0, nullptr, 0, nullptr, s);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1129,3 +1139,28 @@ bool seq_util::re::is_loop(expr const* n, expr*& body, unsigned& lo)  {
 | 
			
		|||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool seq_util::re::is_loop(expr const* n, expr*& body, expr*& lo, expr*& hi)  {
 | 
			
		||||
    if (is_loop(n)) {
 | 
			
		||||
        app const* a = to_app(n);
 | 
			
		||||
        if (a->get_num_args() == 3) {
 | 
			
		||||
            body = a->get_arg(0);
 | 
			
		||||
            lo = a->get_arg(1);
 | 
			
		||||
            hi = a->get_arg(2);
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool seq_util::re::is_loop(expr const* n, expr*& body, expr*& lo)  {
 | 
			
		||||
    if (is_loop(n)) {
 | 
			
		||||
        app const* a = to_app(n);
 | 
			
		||||
        if (a->get_num_args() == 2) {
 | 
			
		||||
            body = a->get_arg(0);
 | 
			
		||||
            lo = a->get_arg(1);
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -366,6 +366,8 @@ public:
 | 
			
		|||
        app* mk_opt(expr* r) { return m.mk_app(m_fid, OP_RE_OPTION, r); }
 | 
			
		||||
        app* mk_loop(expr* r, unsigned lo);
 | 
			
		||||
        app* mk_loop(expr* r, unsigned lo, unsigned hi);
 | 
			
		||||
        app* mk_loop(expr* r, expr* lo);
 | 
			
		||||
        app* mk_loop(expr* r, expr* lo, expr* hi);
 | 
			
		||||
        app* mk_full_char(sort* s);
 | 
			
		||||
        app* mk_full_seq(sort* s);
 | 
			
		||||
        app* mk_empty(sort* s);
 | 
			
		||||
| 
						 | 
				
			
			@ -394,6 +396,8 @@ public:
 | 
			
		|||
        MATCH_UNARY(is_opt);
 | 
			
		||||
        bool is_loop(expr const* n, expr*& body, unsigned& lo, unsigned& hi);
 | 
			
		||||
        bool is_loop(expr const* n, expr*& body, unsigned& lo);
 | 
			
		||||
        bool is_loop(expr const* n, expr*& body, expr*& lo, expr*& hi);
 | 
			
		||||
        bool is_loop(expr const* n, expr*& body, expr*& lo);
 | 
			
		||||
        bool is_unroll(expr const* n) const { return is_app_of(n, m_fid, _OP_RE_UNROLL); }
 | 
			
		||||
    };
 | 
			
		||||
    str str;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue