mirror of
				https://github.com/Z3Prover/z3
				synced 2025-11-03 21:09:11 +00:00 
			
		
		
		
	add scoping for variable equivalences between new monomials
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
		
							parent
							
								
									919f687df6
								
							
						
					
					
						commit
						31e2a9b163
					
				
					 2 changed files with 4 additions and 13 deletions
				
			
		| 
						 | 
				
			
			@ -47,21 +47,10 @@ void emonics::push() {
 | 
			
		|||
    SASSERT(invariant());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// this assumes that all calls to m_ve.merge are after emonics::add within
 | 
			
		||||
// the same scope. Suppose that m_ve.merge is used before an emonics:add in the same scope
 | 
			
		||||
// then the unmerge on the variable applies to the monic during pop, which it shouldn't.
 | 
			
		||||
// To fix this, the undo-stack for m_ve and monics addition have to be coordinated
 | 
			
		||||
// this could be achieved in some ways, such as pushing a scope on m_ve whenever a monic is added.
 | 
			
		||||
// Before fixing this it is worth adding a unit test to exercise this scenario. 
 | 
			
		||||
// The scenario is difficult to trigger from the normal solving context because emonics::add
 | 
			
		||||
// is triggered by internalization, which typically happens before search (except for quantifier instantiation).
 | 
			
		||||
//
 | 
			
		||||
void emonics::pop(unsigned n) {
 | 
			
		||||
    TRACE("nla_solver_mons", tout << "pop: " << n << "\n";);
 | 
			
		||||
    SASSERT(invariant());
 | 
			
		||||
    for (unsigned j = 0; j < n; ++j) {
 | 
			
		||||
        m_ve.pop(1);
 | 
			
		||||
        unsigned old_sz = m_lim[m_lim.size() - 1];
 | 
			
		||||
        for (unsigned i = m_monics.size(); i-- > old_sz; ) {
 | 
			
		||||
            monic & m = m_monics[i];
 | 
			
		||||
| 
						 | 
				
			
			@ -71,12 +60,13 @@ void emonics::pop(unsigned n) {
 | 
			
		|||
            lpvar last_var = UINT_MAX;
 | 
			
		||||
            for (lpvar v : m.vars()) {
 | 
			
		||||
                if (v != last_var) {
 | 
			
		||||
                    TRACE("nla_solver_mons", tout << "remove cell " << v << ": " << i << " " << m_use_lists[v].m_head->m_index << "\n";);
 | 
			
		||||
                    remove_cell(m_use_lists[v]);
 | 
			
		||||
                    last_var = v;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            m_ve.pop(1);
 | 
			
		||||
        }
 | 
			
		||||
        m_ve.pop(1);
 | 
			
		||||
        m_monics.shrink(old_sz);
 | 
			
		||||
        m_region.pop_scope(1);
 | 
			
		||||
        m_lim.pop_back();
 | 
			
		||||
| 
						 | 
				
			
			@ -318,6 +308,7 @@ void emonics::add(lpvar v, unsigned sz, lpvar const* vs) {
 | 
			
		|||
    TRACE("nla_solver_mons", tout << "v = " << v << "\n";);
 | 
			
		||||
    SASSERT(m_ve.is_root(v));
 | 
			
		||||
    SASSERT(!is_monic_var(v));
 | 
			
		||||
    m_ve.push();
 | 
			
		||||
    unsigned idx = m_monics.size();
 | 
			
		||||
    bool sign = false; 
 | 
			
		||||
    m_vs.reset();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -437,7 +437,7 @@ class theory_lra::imp {
 | 
			
		|||
        return add_const(1, is_int ? m_one_var : m_rone_var, is_int);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
     lpvar get_zero(bool is_int) {
 | 
			
		||||
    lpvar get_zero(bool is_int) {
 | 
			
		||||
        return add_const(0, is_int ? m_zero_var : m_rzero_var, is_int);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue