mirror of
				https://github.com/Z3Prover/z3
				synced 2025-10-31 03:32:28 +00:00 
			
		
		
		
	add handling of misc operations
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
		
							parent
							
								
									3da37f4fb5
								
							
						
					
					
						commit
						4405fa1156
					
				
					 2 changed files with 34 additions and 19 deletions
				
			
		|  | @ -364,6 +364,7 @@ public: | ||||||
|     MATCH_UNARY(is_bv_not); |     MATCH_UNARY(is_bv_not); | ||||||
| 
 | 
 | ||||||
|     MATCH_BINARY(is_bv_add); |     MATCH_BINARY(is_bv_add); | ||||||
|  |     MATCH_BINARY(is_bv_sub); | ||||||
|     MATCH_BINARY(is_bv_mul); |     MATCH_BINARY(is_bv_mul); | ||||||
|     MATCH_BINARY(is_bv_sle); |     MATCH_BINARY(is_bv_sle); | ||||||
|     MATCH_BINARY(is_bv_ule); |     MATCH_BINARY(is_bv_ule); | ||||||
|  |  | ||||||
|  | @ -727,33 +727,44 @@ namespace polysat { | ||||||
|             return *r; |             return *r; | ||||||
|         bv_util bv(m); |         bv_util bv(m); | ||||||
|         rational n; |         rational n; | ||||||
|         unsigned sz; |         unsigned sz = bv.get_bv_size(e); | ||||||
|         expr* a, *b; |         expr* a, *b; | ||||||
|         if (bv.is_bv_add(e, a, b)) { |         if (bv.is_bv_add(e, a, b)) { | ||||||
|             auto pa = to_pdd(m, s, expr2pdd, a); |             auto pa = to_pdd(m, s, expr2pdd, a); | ||||||
|             auto pb = to_pdd(m, s, expr2pdd, b); |             auto pb = to_pdd(m, s, expr2pdd, b); | ||||||
|             r = alloc(pdd, pa + pb); |             r = alloc(pdd, pa + pb); | ||||||
|         } |         } | ||||||
|  |         else if (bv.is_bv_sub(e, a, b)) { | ||||||
|  |             auto pa = to_pdd(m, s, expr2pdd, a); | ||||||
|  |             auto pb = to_pdd(m, s, expr2pdd, b); | ||||||
|  |             r = alloc(pdd, pa - pb); | ||||||
|  |         } | ||||||
|         else if (bv.is_bv_mul(e, a, b)) { |         else if (bv.is_bv_mul(e, a, b)) { | ||||||
|             auto pa = to_pdd(m, s, expr2pdd, a); |             auto pa = to_pdd(m, s, expr2pdd, a); | ||||||
|             auto pb = to_pdd(m, s, expr2pdd, b); |             auto pb = to_pdd(m, s, expr2pdd, b); | ||||||
|             r = alloc(pdd, pa * pb); |             r = alloc(pdd, pa * pb); | ||||||
|         } |         } | ||||||
|         else if (bv.is_bv_udiv(e, a, b)) { |         else if (bv.is_bv_udiv(e, a, b)) { | ||||||
|             std::cout << "TODO udiv\n"; |             // quot = udiv(a, b)
 | ||||||
|  |             // quot*b + rem == a
 | ||||||
|  |             // rem < b or b == 0
 | ||||||
|  |             // quot*b does not overflow
 | ||||||
|  |             auto quot = s.var(s.add_var(sz)); | ||||||
|  |             auto rem = s.var(s.add_var(sz)); | ||||||
|  |             auto pa = to_pdd(m, s, expr2pdd, a); | ||||||
|  |             auto pb = to_pdd(m, s, expr2pdd, b);             | ||||||
|  |             s.add_eq(quot*pb + rem - pa); | ||||||
|  |             s.add_ult(rem, pb); | ||||||
|  |             // TODO:
 | ||||||
|  |             // s.add_mul_noovfl(quot, pb);
 | ||||||
|  |             r = alloc(pdd, quot); | ||||||
|         } |         } | ||||||
|         else if (bv.is_numeral(e, n, sz)) { |         else if (bv.is_numeral(e, n, sz))  | ||||||
|             r = alloc(pdd, s.value(n, sz)); |             r = alloc(pdd, s.value(n, sz)); | ||||||
|         } |         else if (is_uninterp(e))  | ||||||
|         else if (is_uninterp(e)) { |  | ||||||
|             sz = bv.get_bv_size(e); |  | ||||||
|             r = alloc(pdd, s.var(s.add_var(sz))); |             r = alloc(pdd, s.var(s.add_var(sz))); | ||||||
|         } |         else { | ||||||
|         else  |             std::cout << "UNKNOWN " << mk_pp(e, m) << "\n"; | ||||||
|             std::cout << "unknown " << mk_pp(e, m) << "\n"; |  | ||||||
| 
 |  | ||||||
|         if (!r) { |  | ||||||
|             sz = bv.get_bv_size(e); |  | ||||||
|             r = alloc(pdd, s.var(s.add_var(sz))); |             r = alloc(pdd, s.var(s.add_var(sz))); | ||||||
|         } |         } | ||||||
|         expr2pdd.insert(e, r); |         expr2pdd.insert(e, r); | ||||||
|  | @ -793,15 +804,21 @@ namespace polysat { | ||||||
|             else if (bv.is_slt(fm, a, b) || bv.is_sgt(fm, b, a)) { |             else if (bv.is_slt(fm, a, b) || bv.is_sgt(fm, b, a)) { | ||||||
|                 auto pa = to_pdd(m, s, expr2pdd, a); |                 auto pa = to_pdd(m, s, expr2pdd, a); | ||||||
|                 auto pb = to_pdd(m, s, expr2pdd, b); |                 auto pb = to_pdd(m, s, expr2pdd, b); | ||||||
|                 std::cout << "slt\n"; |                 if (is_not) | ||||||
|  |                     s.add_sle(pb, pa); | ||||||
|  |                 else  | ||||||
|  |                     s.add_slt(pa, pb); | ||||||
|             } |             } | ||||||
|             else if (bv.is_sle(fm, a, b) || bv.is_sge(fm, b, a)) { |             else if (bv.is_sle(fm, a, b) || bv.is_sge(fm, b, a)) { | ||||||
|                 auto pa = to_pdd(m, s, expr2pdd, a); |                 auto pa = to_pdd(m, s, expr2pdd, a); | ||||||
|                 auto pb = to_pdd(m, s, expr2pdd, b); |                 auto pb = to_pdd(m, s, expr2pdd, b); | ||||||
|                 std::cout << "sle\n"; |                 if (is_not) | ||||||
|  |                     s.add_slt(pb, pa); | ||||||
|  |                 else  | ||||||
|  |                     s.add_sle(pa, pb); | ||||||
|             } |             } | ||||||
|             else { |             else { | ||||||
|                 std::cout << "formula: " << is_not << " " << mk_pp(fm, m) << "\n";             |                 std::cout << "SKIP: " << mk_pp(fm, m) << "\n";             | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         for (auto [k,v] : expr2pdd) |         for (auto [k,v] : expr2pdd) | ||||||
|  | @ -842,19 +859,15 @@ void tst_polysat() { | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // TBD also add test that loads from a file and runs the polysat engine.
 |  | ||||||
| // sketch follows below:
 |  | ||||||
| 
 | 
 | ||||||
| #include "ast/bv_decl_plugin.h" | #include "ast/bv_decl_plugin.h" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| void tst_polysat_argv(char** argv, int argc, int& i) { | void tst_polysat_argv(char** argv, int argc, int& i) { | ||||||
|     // set up SMT2 parser to extract assertions
 |     // set up SMT2 parser to extract assertions
 | ||||||
|     // assume they are simple bit-vector equations (and inequations)
 |     // assume they are simple bit-vector equations (and inequations)
 | ||||||
|     // convert to solver state.
 |     // convert to solver state.
 | ||||||
|      |      | ||||||
|     std::cout << "argc " << argc << "\n"; |  | ||||||
|     if (argc < 3) { |     if (argc < 3) { | ||||||
|         std::cerr << "Usage: " << argv[0] << " FILE\n"; |         std::cerr << "Usage: " << argv[0] << " FILE\n"; | ||||||
|         return; |         return; | ||||||
|  | @ -872,5 +885,6 @@ void tst_polysat_argv(char** argv, int argc, int& i) { | ||||||
|     auto fmls = ctx.assertions(); |     auto fmls = ctx.assertions(); | ||||||
|     polysat::scoped_solver s("polysat"); |     polysat::scoped_solver s("polysat"); | ||||||
|     polysat::internalize(m, s, fmls); |     polysat::internalize(m, s, fmls); | ||||||
|  |     std::cout << "checking\n"; | ||||||
|     s.check(); |     s.check(); | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue