mirror of
				https://github.com/Z3Prover/z3
				synced 2025-10-31 03:32:28 +00:00 
			
		
		
		
	
							parent
							
								
									7bc3b4e381
								
							
						
					
					
						commit
						f591e0948a
					
				
					 8 changed files with 209 additions and 210 deletions
				
			
		|  | @ -738,7 +738,6 @@ br_status seq_rewriter::mk_seq_contains(expr* a, expr* b, expr_ref& result) { | |||
|         return BR_REWRITE2; | ||||
|     }     | ||||
| 
 | ||||
| 
 | ||||
|     std::function<bool(expr*)> is_unit = [&](expr *e) { return m_util.str.is_unit(e); }; | ||||
| 
 | ||||
|     if (bs.forall(is_unit) && as.forall(is_unit)) { | ||||
|  | @ -754,6 +753,16 @@ br_status seq_rewriter::mk_seq_contains(expr* a, expr* b, expr_ref& result) { | |||
|         return BR_REWRITE_FULL; | ||||
|     } | ||||
| 
 | ||||
|     if (bs.size() == 1 && bs.forall(is_unit) && as.size() > 1) { | ||||
|         expr_ref_vector ors(m());         | ||||
|         for (expr* ai : as) { | ||||
|             ors.push_back(m_util.str.mk_contains(ai, bs.get(0))); | ||||
|         } | ||||
|         result = ::mk_or(ors); | ||||
|         return BR_REWRITE_FULL; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     return BR_FAILED; | ||||
| } | ||||
| 
 | ||||
|  | @ -1575,6 +1584,34 @@ br_status seq_rewriter::mk_eq_core(expr * l, expr * r, expr_ref & result) { | |||
|     return BR_REWRITE3; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * t = (concat (unit (nth t 0)) (unit (nth t 1)) (unit (nth t 2)) .. (unit (nth t k-1))) | ||||
|  * -> | ||||
|  * (length t) = k | ||||
|  */ | ||||
| bool seq_rewriter::reduce_nth_eq(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_vector& lhs, expr_ref_vector& rhs) { | ||||
|     if (ls.size() == 1 && !rs.empty()) { | ||||
|         expr* l = ls.get(0); | ||||
|         for (unsigned i = 0; i < rs.size(); ++i) { | ||||
|             unsigned k = 0; | ||||
|             expr* ru = nullptr, *r = nullptr; | ||||
|             if (m_util.str.is_unit(rs.get(i), ru) && m_util.str.is_nth(ru, r, k) && k == i && r == l) { | ||||
|                 continue; | ||||
|             } | ||||
|             return false; | ||||
|         } | ||||
|         arith_util a(m()); | ||||
|         lhs.push_back(m_util.str.mk_length(l)); | ||||
|         rhs.push_back(a.mk_int(rs.size())); | ||||
|         ls.reset(); | ||||
|         rs.reset(); | ||||
|         return true; | ||||
|     } | ||||
|     else if (rs.size() == 1 && !ls.empty()) { | ||||
|         return reduce_nth_eq(rs, ls, rhs, lhs); | ||||
|     } | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| bool seq_rewriter::reduce_eq(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_vector& lhs, expr_ref_vector& rhs, bool& change) { | ||||
|     expr* a, *b; | ||||
|  | @ -1582,6 +1619,10 @@ bool seq_rewriter::reduce_eq(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_ | |||
|     bool lchange = false; | ||||
|     SASSERT(lhs.empty()); | ||||
|     TRACE("seq", tout << ls << "\n"; tout << rs << "\n";); | ||||
|     if (reduce_nth_eq(ls, rs, lhs, rhs)) { | ||||
|         change = true; | ||||
|         return true; | ||||
|     } | ||||
|     // solve from back
 | ||||
|     while (true) { | ||||
|         while (!rs.empty() && m_util.str.is_empty(rs.back())) { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue