mirror of
				https://github.com/Z3Prover/z3
				synced 2025-11-04 05:19:11 +00:00 
			
		
		
		
	more testing of fixplex
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
		
							parent
							
								
									dc879dc3fb
								
							
						
					
					
						commit
						5791b41133
					
				
					 2 changed files with 92 additions and 16 deletions
				
			
		| 
						 | 
				
			
			@ -230,8 +230,7 @@ namespace polysat {
 | 
			
		|||
       number of trailing zeros. 
 | 
			
		||||
    */
 | 
			
		||||
    template<typename Ext>
 | 
			
		||||
    var_t fixplex<Ext>::select_pivot_core(var_t x, 
 | 
			
		||||
                                    numeral const& new_value, numeral & out_b) {
 | 
			
		||||
    var_t fixplex<Ext>::select_pivot_core(var_t x, numeral const& new_value, numeral & out_b) {
 | 
			
		||||
        SASSERT(is_base(x));
 | 
			
		||||
        var_t max    = get_num_vars();
 | 
			
		||||
        var_t result = max;
 | 
			
		||||
| 
						 | 
				
			
			@ -275,7 +274,9 @@ namespace polysat {
 | 
			
		|||
                is_improvement = true;
 | 
			
		||||
            else if (best_in_bounds && _in_bounds && num == best_so_far && col_sz < best_col_sz)
 | 
			
		||||
                is_improvement = true;
 | 
			
		||||
            else if (best_in_bounds && !_in_bounds && delta_y == delta_best && best_so_far == num && col_sz == best_col_sz)
 | 
			
		||||
            else if (!best_in_bounds && !_in_bounds && delta_y == delta_best && best_so_far == num && col_sz == best_col_sz)
 | 
			
		||||
                is_plateau = true;
 | 
			
		||||
            else if (best_in_bounds && _in_bounds && best_so_far == num && col_sz == best_col_sz)
 | 
			
		||||
                is_plateau = true;
 | 
			
		||||
            
 | 
			
		||||
            if (is_improvement) {
 | 
			
		||||
| 
						 | 
				
			
			@ -295,13 +296,23 @@ namespace polysat {
 | 
			
		|||
                }
 | 
			
		||||
            }                              
 | 
			
		||||
        }
 | 
			
		||||
        return result < max ? result : null_var;
 | 
			
		||||
        if (result == max)
 | 
			
		||||
            return null_var;
 | 
			
		||||
        if (!best_in_bounds && delta_best >= value2delta(x, new_value))
 | 
			
		||||
            return null_var;
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Compute delta to add to the value, such that value + delta is either lo(v), or hi(v) - 1
 | 
			
		||||
     * A pre-condition is that value is not in the range [lo(v),hi(v)[, 
 | 
			
		||||
     * and therefore as a consequence lo(v) != hi(v).
 | 
			
		||||
     */
 | 
			
		||||
    template<typename Ext>
 | 
			
		||||
    typename fixplex<Ext>::numeral 
 | 
			
		||||
    fixplex<Ext>::value2delta(var_t v, numeral const& value) const {
 | 
			
		||||
        SASSERT(!in_bounds(v));
 | 
			
		||||
        SASSERT(lo(v) != hi(v));
 | 
			
		||||
        if (lo(v) - value < value - hi(v))
 | 
			
		||||
            return lo(v) - value;
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			@ -309,6 +320,13 @@ namespace polysat {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The the bounds of variable v.
 | 
			
		||||
     * If the current value of v, value(v), is in bounds, no further updates are made.
 | 
			
		||||
     * If value(v) is outside the the new bounds, then
 | 
			
		||||
     * - the tableau is updated if v is non-basic.
 | 
			
		||||
     * - the variable v is queued to patch if v is basic.
 | 
			
		||||
     */
 | 
			
		||||
    template<typename Ext>
 | 
			
		||||
    void fixplex<Ext>::set_bounds(var_t v, numeral const& lo, numeral const& hi) {         
 | 
			
		||||
        m_vars[v].m_lo = lo; 
 | 
			
		||||
| 
						 | 
				
			
			@ -321,6 +339,10 @@ namespace polysat {
 | 
			
		|||
            update_value(v, value2delta(v, value(v)));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check if the coefficient b of y has the minimal number of trailing zeros.
 | 
			
		||||
     * In other words, the coefficient b is a multiple of the smallest power of 2.
 | 
			
		||||
     */
 | 
			
		||||
    template<typename Ext>
 | 
			
		||||
    bool fixplex<Ext>::has_minimal_trailing_zeros(var_t y, numeral const& b) {
 | 
			
		||||
        unsigned tz1 = trailing_zeros(b);
 | 
			
		||||
| 
						 | 
				
			
			@ -335,6 +357,24 @@ namespace polysat {
 | 
			
		|||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Determine if row is linear infeasiable.
 | 
			
		||||
     * A row is linear infeasible if it can be established
 | 
			
		||||
     * that none of the available assignments within current
 | 
			
		||||
     * bounds let the row add up to 0.
 | 
			
		||||
     * 
 | 
			
		||||
     * Assume the row is of the form:
 | 
			
		||||
     *   ax + by + cz = 0
 | 
			
		||||
     * with bounds
 | 
			
		||||
     *   x : [lo_x, hi_x[, y : [lo_y, hi_y[, z : [lo_z : hi_z[
 | 
			
		||||
     * 
 | 
			
		||||
     * Claim. The row is infeasible if the following conditions are met:
 | 
			
		||||
     * 
 | 
			
		||||
     * - 0 < a*lo_x + b*lo_y + c*lo_z <= a*hi_x + b*hi_y + c*hi_z  mod 2^k
 | 
			
		||||
     * - a*(hi_x - lo_x) + b*(hi_y - lo_y) + c*(hi_z - lo_z) < 2^k
 | 
			
		||||
     * - lo_x != hi_x, lo_y != hi_y, lo_z != hi_z
 | 
			
		||||
     * 
 | 
			
		||||
     */
 | 
			
		||||
    template<typename Ext>
 | 
			
		||||
    bool fixplex<Ext>::is_infeasible_row(var_t x) {
 | 
			
		||||
        SASSERT(is_base(x));
 | 
			
		||||
| 
						 | 
				
			
			@ -577,11 +617,12 @@ namespace polysat {
 | 
			
		|||
        SASSERT(m_vars[s].m_base2row == r.id());
 | 
			
		||||
        SASSERT(m_vars[s].m_is_base);
 | 
			
		||||
        numeral sum = 0;
 | 
			
		||||
        numeral base_coeff = m_rows[r.id()].m_base_coeff;
 | 
			
		||||
        for (auto const& e : M.row_entries(r)) {
 | 
			
		||||
            sum += value(e.m_var) * e.m_coeff;
 | 
			
		||||
            SASSERT(s != e.m_var || m_rows[r.id()].m_base_coeff == e.m_coeff);
 | 
			
		||||
            SASSERT(s != e.m_var || base_coeff == e.m_coeff);
 | 
			
		||||
        }
 | 
			
		||||
        if (sum != 0) {
 | 
			
		||||
        if (sum >= base_coeff) {
 | 
			
		||||
            IF_VERBOSE(0, M.display_row(verbose_stream(), r););
 | 
			
		||||
            TRACE("polysat", display(tout << "non-well formed row\n"); M.display_row(tout << "row: ", r););
 | 
			
		||||
            throw default_exception("non-well formed row");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,24 +5,59 @@ namespace polysat {
 | 
			
		|||
 | 
			
		||||
    typedef uint64_ext::numeral numeral;
 | 
			
		||||
 | 
			
		||||
    static void test1() {
 | 
			
		||||
    struct solver_scope {
 | 
			
		||||
        reslimit lim;
 | 
			
		||||
        fixplex<uint64_ext> fp(lim);
 | 
			
		||||
        var_t x = 0, y = 1, z = 2;
 | 
			
		||||
        
 | 
			
		||||
    };
 | 
			
		||||
    struct scoped_fp : public solver_scope, public fixplex<uint64_ext> {
 | 
			
		||||
        scoped_fp(): fixplex<uint64_ext>(lim) {}
 | 
			
		||||
 | 
			
		||||
        void run() {
 | 
			
		||||
            std::cout << *this << "\n";
 | 
			
		||||
            std::cout << make_feasible() << "\n";
 | 
			
		||||
            std::cout << *this << "\n";
 | 
			
		||||
            statistics st;
 | 
			
		||||
            collect_statistics(st);
 | 
			
		||||
            std::cout << st << "\n";
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    static void test1() {
 | 
			
		||||
        scoped_fp fp;
 | 
			
		||||
        var_t x = 0, y = 1, z = 2;        
 | 
			
		||||
        var_t ys[3] = { x, y, z };
 | 
			
		||||
        numeral coeffs[3] = { 2, 1, 4 };        
 | 
			
		||||
        fp.add_row(x, 3, ys, coeffs);
 | 
			
		||||
        fp.set_bounds(x, 1, 2);
 | 
			
		||||
        std::cout << fp << "\n";
 | 
			
		||||
        fp.make_feasible();
 | 
			
		||||
        std::cout << fp << "\n";
 | 
			
		||||
        statistics st;
 | 
			
		||||
        fp.collect_statistics(st);
 | 
			
		||||
        std::cout << st << "\n";
 | 
			
		||||
        fp.run();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static void test2() {
 | 
			
		||||
        scoped_fp fp;
 | 
			
		||||
        var_t x = 0, y = 1, z = 2;        
 | 
			
		||||
        var_t ys[3] = { x, y, z };
 | 
			
		||||
        numeral coeffs[3] = { 1, 2, 4 };        
 | 
			
		||||
        fp.add_row(x, 3, ys, coeffs);
 | 
			
		||||
        fp.set_bounds(x, 3, 4);
 | 
			
		||||
        fp.run();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static void test3() {
 | 
			
		||||
        scoped_fp fp;
 | 
			
		||||
        var_t x = 0, y = 1, z = 2;        
 | 
			
		||||
        var_t ys[3] = { x, y, z };
 | 
			
		||||
        numeral coeffs[3] = { 1, 1, 1 };        
 | 
			
		||||
        fp.add_row(x, 3, ys, coeffs);
 | 
			
		||||
        fp.set_bounds(x, 3, 4);
 | 
			
		||||
        fp.set_bounds(y, 3, 4);
 | 
			
		||||
        fp.set_bounds(z, 3, 4);
 | 
			
		||||
        fp.run();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void tst_fixplex() {
 | 
			
		||||
    polysat::test1();
 | 
			
		||||
    polysat::test2();
 | 
			
		||||
    polysat::test3();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue