mirror of
				https://github.com/Z3Prover/z3
				synced 2025-10-31 11:42:28 +00:00 
			
		
		
		
	integrate aig further
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
		
							parent
							
								
									ca243428f8
								
							
						
					
					
						commit
						20618ff3b3
					
				
					 3 changed files with 80 additions and 44 deletions
				
			
		|  | @ -38,29 +38,43 @@ namespace sat { | |||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     aig_simplifier::aig_simplifier(solver& s):s(s), m_aig_cuts(m_config.m_max_cut_size, m_config.m_max_cutset_size) {         | ||||
|     aig_simplifier::aig_simplifier(solver& s): | ||||
|         s(s),  | ||||
|         m_aig_cuts(m_config.m_max_cut_size, m_config.m_max_cutset_size), | ||||
|         m_trail_size(0) {         | ||||
|     } | ||||
| 
 | ||||
|     void aig_simplifier::add_and(literal head, unsigned sz, literal const* lits) { | ||||
|         m_aig_cuts.add_node(head, and_op, sz, lits); | ||||
|         m_stats.m_num_ands++; | ||||
|     } | ||||
| 
 | ||||
|     //      head == l1 or l2 or l3 
 | ||||
|     // <=> 
 | ||||
|     //     ~head == ~l1 and ~l2 and ~l3
 | ||||
|     void aig_simplifier::add_or(literal head, unsigned sz, literal const* lits) { | ||||
|         m_aig_cuts.add_node(head, and_op, sz, lits); | ||||
|         m_lits.reset(); | ||||
|         m_lits.append(sz, lits); | ||||
|         for (unsigned i = 0; i < sz; ++i) m_lits[i].neg(); | ||||
|         m_aig_cuts.add_node(~head, and_op, sz, m_lits.c_ptr()); | ||||
|         m_stats.m_num_ands++; | ||||
|     } | ||||
| 
 | ||||
|     void aig_simplifier::add_xor(literal head, unsigned sz, literal const* lits) { | ||||
|         m_aig_cuts.add_node(head, xor_op, sz, lits); | ||||
|         m_stats.m_num_xors++; | ||||
|     } | ||||
| 
 | ||||
|     void aig_simplifier::add_ite(literal head, literal c, literal t, literal e) { | ||||
|         literal lits[3] = { c, t, e }; | ||||
|         m_aig_cuts.add_node(head, ite_op, 3, lits); | ||||
|         m_stats.m_num_ites++; | ||||
|     } | ||||
| 
 | ||||
|     void aig_simplifier::add_iff(literal head, literal l1, literal l2) { | ||||
|         literal lits[2] = { l1, ~l2 }; | ||||
|         m_aig_cuts.add_node(head, xor_op, 2, lits); | ||||
|         m_stats.m_num_xors++; | ||||
|     } | ||||
| 
 | ||||
|     void aig_simplifier::operator()() { | ||||
|  | @ -75,7 +89,14 @@ namespace sat { | |||
|        Ensure that they are sorted and variables have unique definitions. | ||||
|      */ | ||||
|     void aig_simplifier::clauses2aig() { | ||||
|         literal_vector literals; | ||||
| 
 | ||||
|         // update units
 | ||||
|         for (; m_trail_size < s.init_trail_size(); ++m_trail_size) { | ||||
|             literal lit = s.trail_literal(m_trail_size); | ||||
|             m_aig_cuts.add_node(lit, and_op, 0, 0); | ||||
|         } | ||||
|          | ||||
|          | ||||
|         std::function<void (literal head, literal_vector const& ands)> on_and =  | ||||
|             [&,this](literal head, literal_vector const& ands) { | ||||
|             m_aig_cuts.add_node(head, and_op, ands.size(), ands.c_ptr()); | ||||
|  | @ -112,10 +133,10 @@ namespace sat { | |||
|             unsigned sz = xors.size() - 1; | ||||
|             for (unsigned i = xors.size(); i-- > 0; ) { | ||||
|                 if (i != index)  | ||||
|                     literals.push_back(xors[i]); | ||||
|                     m_lits.push_back(xors[i]); | ||||
|             } | ||||
|             m_aig_cuts.add_node(head, xor_op, sz, literals.c_ptr()); | ||||
|             literals.reset(); | ||||
|             m_aig_cuts.add_node(head, xor_op, sz, m_lits.c_ptr()); | ||||
|             m_lits.reset(); | ||||
|             m_stats.m_num_xors++;             | ||||
|         }; | ||||
|         xor_finder xf(s); | ||||
|  | @ -134,7 +155,7 @@ namespace sat { | |||
|             uf.merge(l1.index(), l2.index()); | ||||
|             uf.merge((~l1).index(), (~l2).index()); | ||||
|         }; | ||||
|         unsigned old_num_eqs = m_stats.m_num_eqs; | ||||
|         bool new_eq = false; | ||||
|         for (unsigned i = cuts.size(); i-- > 0; ) { | ||||
|             m_stats.m_num_cuts += cuts[i].size(); | ||||
|             for (auto& cut : cuts[i]) { | ||||
|  | @ -145,7 +166,7 @@ namespace sat { | |||
|                     literal w(j, false); | ||||
|                     add_eq(v, w); | ||||
|                     TRACE("aig_simplifier", tout << v << " == " << ~w << "\n";); | ||||
|                     ++m_stats.m_num_eqs; | ||||
|                     new_eq = true; | ||||
|                     break; | ||||
|                 } | ||||
|                 cut.negate(); | ||||
|  | @ -154,40 +175,44 @@ namespace sat { | |||
|                     literal w(j, true); | ||||
|                     add_eq(v, w); | ||||
|                     TRACE("aig_simplifier", tout << v << " == " << w << "\n";); | ||||
|                     ++m_stats.m_num_eqs; | ||||
|                     new_eq = true; | ||||
|                     break; | ||||
|                 } | ||||
|                 cut.negate(); | ||||
|                 cut2id.insert(&cut, i);                 | ||||
|             } | ||||
|         }         | ||||
|         if (old_num_eqs < m_stats.m_num_eqs) { | ||||
|             // extract equivalences over non-eliminated literals.
 | ||||
|             bool new_eq = false; | ||||
|             for (unsigned idx = 0; idx < uf.get_num_vars(); ++idx) { | ||||
|                 if (!uf.is_root(idx) || 1 == uf.size(idx)) continue; | ||||
|                 literal root = null_literal; | ||||
|                 unsigned first = idx; | ||||
|                 do { | ||||
|                     literal lit = to_literal(idx); | ||||
|                     if (!s.was_eliminated(lit)) { | ||||
|                         if (root == null_literal) { | ||||
|                             root = lit; | ||||
|                         } | ||||
|                         else { | ||||
|                             uf2.merge(lit.index(), root.index()); | ||||
|                             new_eq = true; | ||||
|                         } | ||||
|                     } | ||||
|                     idx = uf.next(idx); | ||||
|                 } | ||||
|                 while (first != idx); | ||||
|             } | ||||
|             if (new_eq) { | ||||
|                 elim_eqs elim(s); | ||||
|                 elim(uf2); | ||||
|             } | ||||
|         if (!new_eq) { | ||||
|             return; | ||||
|         } | ||||
|         new_eq = false; | ||||
|         for (unsigned i = 2*s.num_vars(); i--> 0; ) uf2.mk_var(); | ||||
|         // extract equivalences over non-eliminated literals.
 | ||||
|         for (unsigned idx = 0; idx < uf.get_num_vars(); ++idx) { | ||||
|             if (!uf.is_root(idx) || 1 == uf.size(idx)) continue; | ||||
|             literal root = null_literal; | ||||
|             unsigned first = idx; | ||||
|             do { | ||||
|                 literal lit = to_literal(idx); | ||||
|                 if (!s.was_eliminated(lit)) { | ||||
|                     if (root == null_literal) { | ||||
|                         root = lit; | ||||
|                     } | ||||
|                     else { | ||||
|                         uf2.merge(lit.index(), root.index()); | ||||
|                         new_eq = true; | ||||
|                         ++m_stats.m_num_eqs; | ||||
|                     } | ||||
|                 } | ||||
|                 idx = uf.next(idx); | ||||
|             } | ||||
|             while (first != idx); | ||||
|         } | ||||
|         if (!new_eq) { | ||||
|             return; | ||||
|         } | ||||
|         elim_eqs elim(s); | ||||
|         elim(uf2);         | ||||
|     } | ||||
| 
 | ||||
|     void aig_simplifier::collect_statistics(statistics& st) const { | ||||
|  | @ -270,10 +295,13 @@ namespace sat { | |||
| 
 | ||||
|     void aig_cuts::augment_aig0(node const& n, cut_set& cs, vector<cut_set>& cuts) { | ||||
|         SASSERT(n.is_and()); | ||||
|         cut c; | ||||
|         cut c;           | ||||
|         cs.reset(); | ||||
|         if (!n.sign()) { | ||||
|             c.m_table = 3; | ||||
|         if (n.sign()) { | ||||
|             c.m_table = 0;   // constant false
 | ||||
|         } | ||||
|         else { | ||||
|             c.m_table = 0x3; // constant true
 | ||||
|         } | ||||
|         cs.insert(c); | ||||
|     } | ||||
|  | @ -374,7 +402,7 @@ namespace sat { | |||
|                 add_var(args[i].var()); | ||||
|             } | ||||
|         } | ||||
|         if (!m_aig[v].is_valid() || m_aig[v].is_var()) { | ||||
|         if (!m_aig[v].is_valid() || m_aig[v].is_var() || (sz == 0)) { | ||||
|             m_aig[v] = n; | ||||
|             init_cut_set(v); | ||||
|         } | ||||
|  | @ -389,7 +417,10 @@ namespace sat { | |||
|         SASSERT(n.is_valid()); | ||||
|         auto& cut_set = m_cuts[id]; | ||||
|         cut_set.init(m_region, m_max_cutset_size + 1); | ||||
|         cut_set.push_back(cut(id));         | ||||
|         cut_set.push_back(cut(id));    // TBD: if entry is a constant?
 | ||||
|         if (m_aux_aig.size() < id) { | ||||
|             m_aux_aig[id].reset(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     void aig_cuts::insert_aux(unsigned v, node const& n) { | ||||
|  |  | |||
|  | @ -100,6 +100,8 @@ namespace sat { | |||
|         stats   m_stats; | ||||
|         config  m_config; | ||||
|         aig_cuts m_aig_cuts; | ||||
|         unsigned m_trail_size; | ||||
|         literal_vector m_lits; | ||||
| 
 | ||||
|         struct report; | ||||
|         void clauses2aig(); | ||||
|  |  | |||
|  | @ -1937,10 +1937,9 @@ namespace sat { | |||
|             // TBD: throttle anf_delay based on yield
 | ||||
|         } | ||||
| 
 | ||||
|         if (m_config.m_aig_simplify && m_simplifications > m_config.m_aig_delay && !inconsistent()) { | ||||
|             aig_simplifier aig(*this); | ||||
|             aig(); | ||||
|             aig.collect_statistics(m_aux_stats); | ||||
|         if (m_aig_simplifier && m_simplifications > m_config.m_aig_delay && !inconsistent()) { | ||||
|             (*m_aig_simplifier)(); | ||||
|             m_aig_simplifier->collect_statistics(m_aux_stats); | ||||
|             // TBD: throttle aig_delay based on yield
 | ||||
|         } | ||||
|     } | ||||
|  | @ -3922,6 +3921,10 @@ namespace sat { | |||
|         m_fast_glue_backup.set_alpha(m_config.m_fast_glue_avg); | ||||
|         m_slow_glue_backup.set_alpha(m_config.m_slow_glue_avg); | ||||
|         m_trail_avg.set_alpha(m_config.m_slow_glue_avg); | ||||
| 
 | ||||
|         if (m_config.m_aig_simplify && !m_aig_simplifier) { | ||||
|             m_aig_simplifier = alloc(aig_simplifier, *this); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     void solver::collect_param_descrs(param_descrs & d) { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue