mirror of
				https://github.com/Z3Prover/z3
				synced 2025-10-31 11:42:28 +00:00 
			
		
		
		
	Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
		
							parent
							
								
									1517ca907e
								
							
						
					
					
						commit
						8e2ad4e461
					
				
					 7 changed files with 68 additions and 25 deletions
				
			
		|  | @ -182,5 +182,8 @@ foreach (_build_type ${_build_types_as_upper}) | |||
|     # Indicate that the executable is compatible with DEP | ||||
|     # See https://msdn.microsoft.com/en-us/library/ms235442.aspx | ||||
|     string(APPEND CMAKE_EXE_LINKER_FLAGS_${_build_type} " /NXCOMPAT") | ||||
| 
 | ||||
|     # per GitHub issue #2380, enable checksum | ||||
|     string(APPEND CMAKE_EXE_LINKER_FLAGS_${_build_type} " /RELEASE") | ||||
|   endif() | ||||
| endforeach() | ||||
|  |  | |||
|  | @ -98,6 +98,7 @@ JS_ENABLED=False | |||
| PYTHON_INSTALL_ENABLED=False | ||||
| STATIC_LIB=False | ||||
| STATIC_BIN=False | ||||
| ADD_CHECKSUM=True | ||||
| VER_MAJOR=None | ||||
| VER_MINOR=None | ||||
| VER_BUILD=None | ||||
|  | @ -2441,6 +2442,8 @@ def mk_config(): | |||
|             static_opt = '/MT' | ||||
|         else: | ||||
|             static_opt = '/MD' | ||||
|         if ADD_CHECKSUM: | ||||
|             extra_opt = ' %s /RELEASE' % extra_opt | ||||
|         maybe_disable_dynamic_base = '/DYNAMICBASE' if ALWAYS_DYNAMIC_BASE else '/DYNAMICBASE:NO' | ||||
|         if DEBUG_MODE: | ||||
|             static_opt = static_opt + 'd' | ||||
|  |  | |||
|  | @ -344,9 +344,6 @@ private: | |||
|             expr_ref query_result(dlctx.get_answer_as_formula(), m); | ||||
|             sbuffer<symbol> var_names; | ||||
|             unsigned num_decls = 0; | ||||
|             if (is_quantifier(m_target)) { | ||||
|                 num_decls = to_quantifier(m_target)->get_num_decls(); | ||||
|             } | ||||
|             ctx.display(ctx.regular_stream(), query_result, 0, num_decls, "X", var_names); | ||||
|             ctx.regular_stream() << std::endl; | ||||
|         } | ||||
|  |  | |||
|  | @ -86,6 +86,7 @@ namespace qe { | |||
|         nlsat::literal_vector                m_assumptions; | ||||
|         u_map<expr*>                         m_asm2fml; | ||||
|         expr_ref_vector                      m_trail; | ||||
|         app_ref                              m_delta0, m_delta1; | ||||
|          | ||||
|         lbool check_sat() { | ||||
|             while (true) { | ||||
|  | @ -511,6 +512,20 @@ namespace qe { | |||
|             bool has_divs() const { return m_has_divs; } | ||||
|         }; | ||||
| 
 | ||||
|         /*
 | ||||
|           Ackermanize division | ||||
| 
 | ||||
|           For each p/q: | ||||
|              p = 0 & q = 0 => div = delta0 | ||||
|              p != 0 & q = 0 => div = p*delta1 | ||||
|              q != 0 => div*q = p | ||||
| 
 | ||||
|           delta0 stands for 0/0 | ||||
|           delta1 stands for 1/0 | ||||
|           assumption: p * 1/0 = p/0 for p != 0,  | ||||
|           so 2/0 != a * 1/0 & a = 2 is unsat by fiat. | ||||
|          */ | ||||
| 
 | ||||
|         void purify(expr_ref& fml, div_rewriter_star& rw, expr_ref_vector& paxioms) { | ||||
|             is_pure_proc  is_pure(*this); | ||||
|             { | ||||
|  | @ -520,14 +535,16 @@ namespace qe { | |||
|             if (is_pure.has_divs()) { | ||||
|                 arith_util arith(m); | ||||
|                 proof_ref pr(m); | ||||
|                 TRACE("qe", tout << fml << "\n";); | ||||
|                 rw(fml, fml, pr); | ||||
|                 TRACE("qe", tout << fml << "\n";); | ||||
|                 m_delta0 = m.mk_fresh_const("delta0", arith.mk_real()); | ||||
|                 m_delta1 = m.mk_fresh_const("delta1", arith.mk_real()); | ||||
|                 vector<div> const& divs = rw.divs(); | ||||
|                 for (unsigned i = 0; i < divs.size(); ++i) { | ||||
|                     paxioms.push_back( | ||||
|                         m.mk_or(m.mk_eq(divs[i].den, arith.mk_numeral(rational(0), false)),  | ||||
|                                 m.mk_eq(divs[i].num, arith.mk_mul(divs[i].den, divs[i].name))));                     | ||||
|                     expr_ref den_is0(m.mk_eq(divs[i].den, arith.mk_real(0)), m); | ||||
|                     expr_ref num_is0(m.mk_eq(divs[i].num, arith.mk_real(0)), m); | ||||
|                     paxioms.push_back(m.mk_or(den_is0, m.mk_eq(divs[i].num, arith.mk_mul(divs[i].den, divs[i].name)))); | ||||
|                     paxioms.push_back(m.mk_or(m.mk_not(den_is0), m.mk_not(num_is0), m.mk_eq(divs[i].name, m_delta0))); | ||||
|                     paxioms.push_back(m.mk_or(m.mk_not(den_is0), num_is0, m.mk_eq(divs[i].name, arith.mk_mul(divs[i].num, m_delta1)))); | ||||
|                     for (unsigned j = i + 1; j < divs.size(); ++j) { | ||||
|                         paxioms.push_back(m.mk_or(m.mk_not(m.mk_eq(divs[i].den, divs[j].den)), | ||||
|                                                   m.mk_not(m.mk_eq(divs[i].num, divs[j].num)),  | ||||
|  | @ -546,6 +563,8 @@ namespace qe { | |||
|                 return; | ||||
|             } | ||||
|             expr_ref ante = mk_and(paxioms); | ||||
|             qvars[0].push_back(m_delta0); | ||||
|             qvars[0].push_back(m_delta1); | ||||
|             for (div const& d : rw.divs()) { | ||||
|                 qvars[qvars.size()-2].push_back(d.name); | ||||
|             } | ||||
|  | @ -555,6 +574,7 @@ namespace qe { | |||
|             else { | ||||
|                 fml = m.mk_and(fml, ante); | ||||
|             } | ||||
|             TRACE("qe", tout << fml << "\n";); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -675,6 +695,7 @@ namespace qe { | |||
|                     if (m_a2b.is_var(v)) { | ||||
|                         SASSERT(m.is_bool(v)); | ||||
|                         nlsat::bool_var b = m_a2b.to_var(v); | ||||
|                         TRACE("qe", tout << mk_pp(v, m) << " |-> b" << b << "\n";); | ||||
|                         m_bound_bvars.back().push_back(b); | ||||
|                         set_level(b, lvl); | ||||
|                     } | ||||
|  | @ -703,14 +724,13 @@ namespace qe { | |||
|         } | ||||
| 
 | ||||
|         void init_expr2var(vector<app_ref_vector> const& qvars) { | ||||
|             for (unsigned i = 0; i < qvars.size(); ++i) { | ||||
|                 init_expr2var(qvars[i]); | ||||
|             for (app_ref_vector const& qvs : qvars) { | ||||
|                 init_expr2var(qvs); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         void init_expr2var(app_ref_vector const& qvars) { | ||||
|             for (unsigned i = 0; i < qvars.size(); ++i) { | ||||
|                 app* v = qvars[i]; | ||||
|             for (app* v : qvars) { | ||||
|                 if (m.is_bool(v)) { | ||||
|                     m_a2b.insert(v, m_solver.mk_bool_var()); | ||||
|                 } | ||||
|  | @ -784,7 +804,9 @@ namespace qe { | |||
|             m_cancel(false), | ||||
|             m_answer(m), | ||||
|             m_answer_simplify(m), | ||||
|             m_trail(m) | ||||
|             m_trail(m), | ||||
|             m_delta0(m), | ||||
|             m_delta1(m) | ||||
|         { | ||||
|             m_solver.get_explain().set_signed_project(true); | ||||
|             m_nftactic = mk_tseitin_cnf_tactic(m); | ||||
|  |  | |||
|  | @ -603,6 +603,7 @@ namespace smt { | |||
|         theory_var internalize_to_int(app * n); | ||||
|         void internalize_is_int(app * n); | ||||
|         theory_var internalize_numeral(app * n); | ||||
|         theory_var internalize_numeral(app * n, numeral const& val); | ||||
|         theory_var internalize_term_core(app * n); | ||||
|         void mk_axiom(expr * n1, expr * n2, bool simplify_conseq = true); | ||||
|         void mk_idiv_mod_axioms(expr * dividend, expr * divisor); | ||||
|  |  | |||
|  | @ -240,11 +240,22 @@ namespace smt { | |||
|                 return; | ||||
|             } | ||||
|         } | ||||
|         rational _val; | ||||
|         rational _val1, _val2; | ||||
|         expr* arg1, *arg2; | ||||
|         if (m_util.is_mul(m, arg1, arg2) && m_util.is_numeral(arg1, _val) && is_app(arg1) && is_app(arg2)) { | ||||
|         if (m_util.is_mul(m, arg1, arg2) && m_util.is_numeral(arg1, _val1) && is_app(arg1) && is_app(arg2)) { | ||||
|             SASSERT(m->get_num_args() == 2); | ||||
|             numeral val(_val); | ||||
|             if (m_util.is_numeral(arg2, _val2)) { | ||||
|                 numeral val(_val1 + _val2); | ||||
|                 theory_var v = internalize_numeral(m, val); | ||||
|                 if (reflection_enabled()) { | ||||
|                     internalize_term_core(to_app(arg1)); | ||||
|                     internalize_term_core(to_app(arg2)); | ||||
|                     mk_enode(m); | ||||
|                 } | ||||
|                 add_row_entry<true>(r_id, numeral::one(), v); | ||||
|                 return; | ||||
|             } | ||||
|             numeral val(_val1); | ||||
|             theory_var v = internalize_term_core(to_app(arg2));             | ||||
|             if (reflection_enabled()) { | ||||
|                 internalize_term_core(to_app(arg1)); | ||||
|  | @ -329,6 +340,7 @@ namespace smt { | |||
|     theory_var theory_arith<Ext>::internalize_mul(app * m) { | ||||
|         rational _val; | ||||
|         SASSERT(m_util.is_mul(m)); | ||||
|         SASSERT(!m_util.is_numeral(m->get_arg(1))); | ||||
|         if (m_util.is_numeral(m->get_arg(0), _val)) { | ||||
|             SASSERT(m->get_num_args() == 2); | ||||
|             numeral val(_val); | ||||
|  | @ -713,6 +725,11 @@ namespace smt { | |||
|         rational _val; | ||||
|         VERIFY(m_util.is_numeral(n, _val)); | ||||
|         numeral val(_val); | ||||
|         return internalize_numeral(n, val); | ||||
|     } | ||||
| 
 | ||||
|     template<typename Ext> | ||||
|     theory_var theory_arith<Ext>::internalize_numeral(app * n, numeral const& val) { | ||||
|         SASSERT(!get_context().e_internalized(n)); | ||||
|         enode * e    = mk_enode(n); | ||||
|         // internalizer is marking enodes as interpreted whenever the associated ast is a value and a constant.
 | ||||
|  |  | |||
|  | @ -5923,10 +5923,11 @@ void theory_seq::propagate_not_suffix(expr* e) { | |||
|    e1 < e2 => e1 = empty or e1 = xcy | ||||
|    e1 < e2 => e1 = empty or c < d | ||||
|    e1 < e2 => e2 = xdz | ||||
|    !(e1 < e2) => e1 = e2 or e2 = empty or e2 = xcy | ||||
|    !(e1 < e2) => e1 = e2 or e2 = empty or c < d | ||||
|    !(e1 < e2) => e1 = e2 or e1 = xdz | ||||
|    !(e1 < e2) => e1 = e2 or e2 = empty or e2 = xdz | ||||
|    !(e1 < e2) => e1 = e2 or e2 = empty or d < c | ||||
|    !(e1 < e2) => e1 = e2 or e1 = xcy | ||||
|     | ||||
| optional: | ||||
|    e1 < e2 or e1 = e2 or e2 < e1 | ||||
|    !(e1 = e2) or !(e1 < e2) | ||||
|    !(e1 = e2) or !(e2 < e1) | ||||
|  | @ -5952,15 +5953,14 @@ void theory_seq::add_lt_axiom(expr* n) { | |||
|     literal eq   = mk_eq(e1, e2, false); | ||||
|     literal e1xcy = mk_eq(e1, xcy, false); | ||||
|     literal e2xdz = mk_eq(e2, xdz, false); | ||||
|     literal e2xcy = mk_eq(e2, xcy, false); | ||||
|     literal e1xdz = mk_eq(e1, xdz, false); | ||||
|     literal ltcd = mk_literal(m_util.mk_lt(c, d)); | ||||
|     literal ltdc = mk_literal(m_util.mk_lt(d, c)); | ||||
|     add_axiom(~lt, e2xdz); | ||||
|     add_axiom(~lt, emp1, e1xcy); | ||||
|     add_axiom(~lt, emp1, ltcd); | ||||
|     add_axiom(lt, eq, e1xdz); | ||||
|     add_axiom(lt, eq, emp2, ltcd); | ||||
|     add_axiom(lt, eq, emp2, e2xcy); | ||||
|     add_axiom(lt, eq, e1xcy); | ||||
|     add_axiom(lt, eq, emp2, ltdc); | ||||
|     add_axiom(lt, eq, emp2, e2xdz); | ||||
|     if (e1->get_id() <= e2->get_id()) { | ||||
|         literal gt = mk_literal(m_util.str.mk_lex_lt(e2, e1)); | ||||
|         add_axiom(lt, eq, gt); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue