mirror of
				https://github.com/Z3Prover/z3
				synced 2025-10-31 03:32:28 +00:00 
			
		
		
		
	Bugfixes
This commit is contained in:
		
							parent
							
								
									d976251390
								
							
						
					
					
						commit
						a6fbd71c6b
					
				
					 2 changed files with 39 additions and 29 deletions
				
			
		|  | @ -80,8 +80,8 @@ namespace polysat { | |||
|         auto* e = m_alloc.back(); | ||||
|         e->src.reset(); | ||||
|         e->side_cond.reset(); | ||||
|         e->refined.reset(); | ||||
|         e->coeff = 1; | ||||
|         e->refined = nullptr; | ||||
|         m_alloc.pop_back(); | ||||
|         return e; | ||||
|     } | ||||
|  | @ -239,6 +239,7 @@ namespace polysat { | |||
| 
 | ||||
|     bool viable::intersect(pvar v, entry* ne) { | ||||
|         SASSERT(!s.is_assigned(v)); | ||||
|         SASSERT(!ne->src.empty()); | ||||
|         entry* e = m_units[v]; | ||||
|         if (e && e->interval.is_full()) { | ||||
|             m_alloc.push_back(ne); | ||||
|  | @ -493,8 +494,6 @@ namespace { | |||
|         rational y_max = compute_y_max(y0, a, lo, hi, M); | ||||
|         while (y_max < y_max_max && is_valid(y_max + 1)) { | ||||
|             y_max = compute_y_max(y_max + 1, a, lo, hi, M); | ||||
|             if (i >= 95) | ||||
|                 verbose_stream() << "refined y_max: " << y_max << "\n"; | ||||
|             if (++i == max_refinements) | ||||
|                 break; | ||||
|         } | ||||
|  | @ -504,8 +503,6 @@ namespace { | |||
|         rational y_min = y0; | ||||
|         while (y_min > y_min_min && is_valid(y_min - 1)) { | ||||
|             y_min = compute_y_min(y_min - 1, a, lo, hi, M); | ||||
|             if (i >= 95) | ||||
|                 verbose_stream() << "refined y_min: " << y_min << "\n"; | ||||
|             if (++i == max_refinements) | ||||
|                 break; | ||||
|         } | ||||
|  | @ -527,7 +524,7 @@ namespace { | |||
| 
 | ||||
|         // TODO: We might also extend simultaneously up and downwards if we want the actual interval (however, this might make use of more fixed bits and is weaker - worse - therefore)
 | ||||
|         entry* ne = alloc_entry(); | ||||
|         rational new_val = extend_by_bits<FORWARD>(v_pdd, val, fixed, justifications, ne->src, ne->side_cond); | ||||
|         rational new_val = extend_by_bits<FORWARD>(v_pdd, val, fixed, justifications, ne->src, ne->side_cond, ne->refined); | ||||
| 
 | ||||
|         if (new_val == val) { | ||||
|             m_alloc.push_back(ne); | ||||
|  | @ -594,7 +591,7 @@ namespace { | |||
|                         // No solution
 | ||||
|                         LOG("refined: no solution due to parity"); | ||||
|                         entry* ne = alloc_entry(); | ||||
|                         ne->refined = e; | ||||
|                         ne->refined.push_back(e); | ||||
|                         ne->src = e->src; | ||||
|                         ne->side_cond = e->side_cond; | ||||
|                         ne->coeff = 1; | ||||
|  | @ -611,7 +608,7 @@ namespace { | |||
|                         LOG("refined to [" << num_pp(s, v, lo) << ", " << num_pp(s, v, hi) << "["); | ||||
|                         SASSERT_EQ(mod(a * hi, mod_value), b);  // hi is the solution
 | ||||
|                         entry* ne = alloc_entry(); | ||||
|                         ne->refined = e; | ||||
|                         ne->refined.push_back(e); | ||||
|                         ne->src = e->src; | ||||
|                         ne->side_cond = e->side_cond; | ||||
|                         ne->coeff = 1; | ||||
|  | @ -643,7 +640,7 @@ namespace { | |||
|                     SASSERT_EQ(mod(a * (lo - 1), mod_value), b);  // lo-1 is a solution
 | ||||
|                     SASSERT_EQ(mod(a * hi, mod_value), b);  // hi is a solution
 | ||||
|                     entry* ne = alloc_entry(); | ||||
|                     ne->refined = e; | ||||
|                     ne->refined.push_back(e); | ||||
|                     ne->src = e->src; | ||||
|                     ne->side_cond = e->side_cond; | ||||
|                     ne->coeff = 1; | ||||
|  | @ -671,7 +668,7 @@ namespace { | |||
|                 if (hi == mod_value) | ||||
|                     hi = 0; | ||||
|                 entry* ne = alloc_entry(); | ||||
|                 ne->refined = e; | ||||
|                 ne->refined.push_back(e); | ||||
|                 ne->src = e->src; | ||||
|                 ne->side_cond = e->side_cond; | ||||
|                 ne->coeff = 1; | ||||
|  | @ -768,7 +765,7 @@ namespace { | |||
|                 pdd lop = s.var2pdd(v).mk_val(lo); | ||||
|                 pdd hip = s.var2pdd(v).mk_val(hi); | ||||
|                 entry* ne = alloc_entry(); | ||||
|                 ne->refined = e; | ||||
|                 ne->refined.push_back(e); | ||||
|                 ne->src = e->src; | ||||
|                 ne->side_cond = e->side_cond; | ||||
|                 ne->coeff = 1; | ||||
|  | @ -784,7 +781,7 @@ namespace { | |||
| 
 | ||||
|     // Skips all values that are not feasible w.r.t. fixed bits
 | ||||
|     template<bool FORWARD> | ||||
|     rational viable::extend_by_bits(const pdd& var, const rational& bound, const svector<lbool>& fixed, const vector<ptr_vector<entry>>& justifications, vector<signed_constraint>& src, vector<signed_constraint>& side_cond) const { | ||||
|     rational viable::extend_by_bits(const pdd& var, const rational& bound, const svector<lbool>& fixed, const vector<ptr_vector<entry>>& justifications, vector<signed_constraint>& src, vector<signed_constraint>& side_cond, ptr_vector<entry const>& refined) const { | ||||
|         unsigned k = var.power_of_2(); | ||||
|         if (fixed.empty()) | ||||
|             return bound; | ||||
|  | @ -800,6 +797,7 @@ namespace { | |||
|                     side_cond.push_back(sc); | ||||
|                 for (auto& c : add->src) | ||||
|                     src.push_back(c); | ||||
|                 refined.push_back(add); | ||||
|             } | ||||
|         }; | ||||
| 
 | ||||
|  | @ -820,7 +818,7 @@ namespace { | |||
|             if (fixed[i] != l_undef) { | ||||
|                 SASSERT(fixed[i] == l_true || fixed[i] == l_false); | ||||
|                 new_bound[i] = fixed[i]; | ||||
|                 if (FORWARD != (fixed[i] == l_false)) | ||||
|                 if (i == firstFail - 1 || FORWARD != (fixed[i] == l_false)) | ||||
|                     add_justification(i); // Minimize number of responsible fixed bits; we only add those justifications we need for sure
 | ||||
|             } | ||||
|             else | ||||
|  | @ -859,6 +857,7 @@ namespace { | |||
|                     add_justification(i); // Again, we need this justification; if carry is false we don't need it
 | ||||
|             } | ||||
|         } | ||||
|         SASSERT(!src.empty()); | ||||
|         if (carry) { | ||||
|             // We covered everything
 | ||||
|             /*if (FORWARD)
 | ||||
|  | @ -1145,7 +1144,7 @@ namespace { | |||
|         do { | ||||
|             found = false; | ||||
|             do { | ||||
|                 if (!e->refined) { | ||||
|                 if (e->refined.empty()) { | ||||
|                     auto const& lo = e->interval.lo(); | ||||
|                     auto const& hi = e->interval.hi(); | ||||
|                     if (lo.is_val() && hi.is_val()) { | ||||
|  | @ -1181,7 +1180,7 @@ namespace { | |||
|         do { | ||||
|             found = false; | ||||
|             do { | ||||
|                 if (!e->refined) { | ||||
|                 if (e->refined.empty()) { | ||||
|                     auto const& lo = e->interval.lo(); | ||||
|                     auto const& hi = e->interval.hi(); | ||||
|                     if (lo.is_val() && hi.is_val()) { | ||||
|  | @ -1317,6 +1316,9 @@ namespace { | |||
|                 UNREACHABLE(); | ||||
|             } | ||||
| 
 | ||||
|             if (refinements % 50 == 0) | ||||
|                 verbose_stream() << "Refinements " << refinements << "\n"; | ||||
| 
 | ||||
|             if (res != l_undef) | ||||
|                 return res; | ||||
|         } | ||||
|  | @ -1457,17 +1459,25 @@ namespace { | |||
|         entry const* first = m_units[v]; | ||||
|         entry const* e = first; | ||||
|         do { | ||||
|             entry const* origin = e; | ||||
|             while (origin->refined) | ||||
|                 origin = origin->refined; | ||||
|             for (const auto& src : origin->src) { | ||||
|                 sat::literal const lit = src.blit(); | ||||
|                 if (!added.contains(lit)) { | ||||
|                     added.insert(lit); | ||||
|                     LOG("Adding " << lit_pp(s, lit)); | ||||
|                     IF_VERBOSE(10, verbose_stream() << ";; " << lit_pp(s, lit) << "\n"); | ||||
|                     verbose_stream() << ";; " << lit_pp(s, lit) << "\n"; | ||||
|                     src.add_to_univariate_solver(v, s, *us, lit.to_uint()); | ||||
|             ptr_vector<entry const> to_process = e->refined; | ||||
|             while (!to_process.empty()) { | ||||
|                 auto current = to_process.back(); | ||||
|                 to_process.pop_back(); | ||||
|                 if (!current->refined.empty()) { | ||||
|                     for (auto& ref : current->refined) | ||||
|                         to_process.push_back(ref); | ||||
|                     continue; | ||||
|                 } | ||||
|                 const entry* origin = current; | ||||
|                 for (const auto& src : origin->src) { | ||||
|                     sat::literal const lit = src.blit(); | ||||
|                     if (!added.contains(lit)) { | ||||
|                         added.insert(lit); | ||||
|                         LOG("Adding " << lit_pp(s, lit)); | ||||
|                         IF_VERBOSE(10, verbose_stream() << ";; " << lit_pp(s, lit) << "\n"); | ||||
|                         verbose_stream() << ";; " << lit_pp(s, lit) << "\n"; | ||||
|                         src.add_to_univariate_solver(v, s, *us, lit.to_uint()); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             e = e->next(); | ||||
|  |  | |||
|  | @ -78,7 +78,7 @@ namespace polysat { | |||
|         forbidden_intervals      m_forbidden_intervals; | ||||
| 
 | ||||
|         struct entry final : public dll_base<entry>, public fi_record { | ||||
|             entry const* refined = nullptr; | ||||
|             ptr_vector<entry const> refined; | ||||
|         }; | ||||
|         enum class entry_kind { unit_e, equal_e, diseq_e }; | ||||
| 
 | ||||
|  | @ -105,7 +105,7 @@ namespace polysat { | |||
|         bool refine_disequal_lin(pvar v, rational const& val); | ||||
| 
 | ||||
|         template<bool FORWARD> | ||||
|         rational extend_by_bits(const pdd& var, const rational& bounds, const svector<lbool>& fixed, const vector<ptr_vector<entry>>& justifications, vector<signed_constraint>& src, vector<signed_constraint>& side_cond) const; | ||||
|         rational extend_by_bits(const pdd& var, const rational& bounds, const svector<lbool>& fixed, const vector<ptr_vector<entry>>& justifications, vector<signed_constraint>& src, vector<signed_constraint>& side_cond, ptr_vector<entry const>& refined) const; | ||||
| 
 | ||||
|         bool collect_bit_information(pvar v, bool add_conflict, svector<lbool>& fixed, vector<ptr_vector<entry>>& justifications); | ||||
| 
 | ||||
|  | @ -257,7 +257,7 @@ namespace polysat { | |||
|                 curr(curr), visited(visited || !curr) {} | ||||
| 
 | ||||
|             iterator& operator++() { | ||||
|                 if (idx < curr->side_cond.size()) | ||||
|                 if (idx < curr->side_cond.size() + curr->src.size() - 1) | ||||
|                     ++idx; | ||||
|                 else { | ||||
|                     idx = 0; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue