mirror of
				https://github.com/Z3Prover/z3
				synced 2025-10-31 11:42:28 +00:00 
			
		
		
		
	
						commit
						a5f4980c92
					
				
					 7 changed files with 910 additions and 590 deletions
				
			
		|  | @ -33,7 +33,7 @@ public: | ||||||
|     bool is_h_marked(proof* p) {return m_h_mark.is_marked(p);} |     bool is_h_marked(proof* p) {return m_h_mark.is_marked(p);} | ||||||
| 
 | 
 | ||||||
|     bool is_b_pure (proof *p) { |     bool is_b_pure (proof *p) { | ||||||
|         return !is_h_marked (p) && is_core_pure(m.get_fact (p)); |         return !is_h_marked(p) && !this->is_a_marked(p) && is_core_pure(m.get_fact(p)); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     void display_dot(std::ostream &out); |     void display_dot(std::ostream &out); | ||||||
|  |  | ||||||
|  | @ -322,6 +322,24 @@ void iuc_solver::get_iuc(expr_ref_vector &core) | ||||||
|         // -- new hypothesis reducer
 |         // -- new hypothesis reducer
 | ||||||
|         else |         else | ||||||
|         { |         { | ||||||
|  | #if 0 | ||||||
|  |             static unsigned bcnt = 0; | ||||||
|  |             { | ||||||
|  |                 bcnt++; | ||||||
|  |                 TRACE("spacer", tout << "Dumping pf bcnt: " << bcnt << "\n";); | ||||||
|  |                 if (bcnt == 123) { | ||||||
|  |                     std::ofstream ofs; | ||||||
|  |                     ofs.open("/tmp/bpf_" + std::to_string(bcnt) + ".dot"); | ||||||
|  |                     iuc_proof iuc_pf_before(m, res.get(), core_lits); | ||||||
|  |                     iuc_pf_before.display_dot(ofs); | ||||||
|  |                     ofs.close(); | ||||||
|  | 
 | ||||||
|  |                     proof_checker pc(m); | ||||||
|  |                     expr_ref_vector side(m); | ||||||
|  |                     ENSURE(pc.check(res, side)); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | #endif | ||||||
|             scoped_watch _t_ (m_hyp_reduce2_sw); |             scoped_watch _t_ (m_hyp_reduce2_sw); | ||||||
| 
 | 
 | ||||||
|             // pre-process proof for better iuc extraction
 |             // pre-process proof for better iuc extraction
 | ||||||
|  | @ -356,6 +374,22 @@ void iuc_solver::get_iuc(expr_ref_vector &core) | ||||||
| 
 | 
 | ||||||
|         iuc_proof iuc_pf(m, res, core_lits); |         iuc_proof iuc_pf(m, res, core_lits); | ||||||
| 
 | 
 | ||||||
|  | #if 0 | ||||||
|  |         static unsigned cnt = 0; | ||||||
|  |         { | ||||||
|  |             cnt++; | ||||||
|  |             TRACE("spacer", tout << "Dumping pf cnt: " << cnt << "\n";); | ||||||
|  |             if (cnt == 123) { | ||||||
|  |                 std::ofstream ofs; | ||||||
|  |                 ofs.open("/tmp/pf_" + std::to_string(cnt) + ".dot"); | ||||||
|  |                 iuc_pf.display_dot(ofs); | ||||||
|  |                 ofs.close(); | ||||||
|  |                 proof_checker pc(m); | ||||||
|  |                 expr_ref_vector side(m); | ||||||
|  |                 ENSURE(pc.check(res, side)); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | #endif | ||||||
|         unsat_core_learner learner(m, iuc_pf); |         unsat_core_learner learner(m, iuc_pf); | ||||||
| 
 | 
 | ||||||
|         unsat_core_plugin* plugin; |         unsat_core_plugin* plugin; | ||||||
|  |  | ||||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -36,28 +36,27 @@ void unsat_core_learner::register_plugin(unsat_core_plugin* plugin) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void unsat_core_learner::compute_unsat_core(expr_ref_vector& unsat_core) { | void unsat_core_learner::compute_unsat_core(expr_ref_vector& unsat_core) { | ||||||
|     // traverse proof
 |  | ||||||
|     proof_post_order it(m_pr.get(), m); |     proof_post_order it(m_pr.get(), m); | ||||||
|     while (it.hasNext()) { |     while (it.hasNext()) { | ||||||
|         proof* currentNode = it.next(); |         proof* curr = it.next(); | ||||||
| 
 | 
 | ||||||
|         if (m.get_num_parents(currentNode) > 0) { |         bool done = is_closed(curr); | ||||||
|             bool need_to_mark_closed = true; |         if (done) continue; | ||||||
| 
 | 
 | ||||||
|             for (proof* premise : m.get_parents(currentNode)) { |         if (m.get_num_parents(curr) > 0) { | ||||||
|                 need_to_mark_closed &= (!m_pr.is_b_marked(premise) || m_closed.is_marked(premise)); |             done = true; | ||||||
|             } |             for (proof* p : m.get_parents(curr)) done &= !is_b_open(p); | ||||||
| 
 |             set_closed(curr, done); | ||||||
|             // save result
 |  | ||||||
|             m_closed.mark(currentNode, need_to_mark_closed); |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // we have now collected all necessary information, so we can visit the node
 |         // we have now collected all necessary information,
 | ||||||
|         // if the node mixes A-reasoning and B-reasoning and contains non-closed premises
 |         // so we can visit the node
 | ||||||
|         if (m_pr.is_a_marked(currentNode) &&  |         // if the node mixes A-reasoning and B-reasoning
 | ||||||
|             m_pr.is_b_marked(currentNode) &&  |         // and contains non-closed premises
 | ||||||
|             !m_closed.is_marked(currentNode)) { |         if (!done) { | ||||||
|             compute_partial_core(currentNode); // then we need to compute a partial core
 |             if (is_a(curr) && is_b(curr)) { | ||||||
|  |                 compute_partial_core(curr); | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -74,7 +73,7 @@ void unsat_core_learner::compute_unsat_core(expr_ref_vector& unsat_core) { | ||||||
| 
 | 
 | ||||||
| void unsat_core_learner::compute_partial_core(proof* step) { | void unsat_core_learner::compute_partial_core(proof* step) { | ||||||
|     for (unsat_core_plugin* plugin : m_plugins) { |     for (unsat_core_plugin* plugin : m_plugins) { | ||||||
|         if (m_closed.is_marked(step)) break; |         if (is_closed(step)) break; | ||||||
|         plugin->compute_partial_core(step); |         plugin->compute_partial_core(step); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | @ -93,9 +92,6 @@ void unsat_core_learner::set_closed(proof* p, bool value) { | ||||||
|     m_closed.mark(p, value); |     m_closed.mark(p, value); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool unsat_core_learner::is_b_open(proof *p) { |  | ||||||
|     return m_pr.is_b_marked(p) && !is_closed (p); |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| void unsat_core_learner::add_lemma_to_core(expr* lemma) { | void unsat_core_learner::add_lemma_to_core(expr* lemma) { | ||||||
|     m_unsat_core.push_back(lemma); |     m_unsat_core.push_back(lemma); | ||||||
|  |  | ||||||
|  | @ -22,6 +22,7 @@ Revision History: | ||||||
| #include "ast/ast.h" | #include "ast/ast.h" | ||||||
| #include "muz/spacer/spacer_util.h" | #include "muz/spacer/spacer_util.h" | ||||||
| #include "muz/spacer/spacer_proof_utils.h" | #include "muz/spacer/spacer_proof_utils.h" | ||||||
|  | #include "muz/spacer/spacer_iuc_proof.h" | ||||||
| 
 | 
 | ||||||
| namespace spacer { | namespace spacer { | ||||||
| 
 | 
 | ||||||
|  | @ -31,13 +32,32 @@ namespace spacer { | ||||||
|     class unsat_core_learner { |     class unsat_core_learner { | ||||||
|         typedef obj_hashtable<expr> expr_set; |         typedef obj_hashtable<expr> expr_set; | ||||||
| 
 | 
 | ||||||
|  |         ast_manager& m; | ||||||
|  |         iuc_proof&   m_pr; | ||||||
|  | 
 | ||||||
|  |         ptr_vector<unsat_core_plugin> m_plugins; | ||||||
|  |         ast_mark m_closed; | ||||||
|  | 
 | ||||||
|  |         expr_ref_vector m_unsat_core; | ||||||
|  | 
 | ||||||
|     public: |     public: | ||||||
|         unsat_core_learner(ast_manager& m, iuc_proof& pr) : |         unsat_core_learner(ast_manager& m, iuc_proof& pr) : | ||||||
|             m(m), m_pr(pr), m_unsat_core(m) {}; |             m(m), m_pr(pr), m_unsat_core(m) {}; | ||||||
|         virtual ~unsat_core_learner(); |         virtual ~unsat_core_learner(); | ||||||
| 
 | 
 | ||||||
|         ast_manager& m; |         ast_manager& get_manager() {return m;} | ||||||
|         iuc_proof&   m_pr; | 
 | ||||||
|  | 
 | ||||||
|  |         bool is_a(proof *pr) { | ||||||
|  |             // AG: treat hypotheses as A
 | ||||||
|  |             // AG: assume that all B-hyp have been eliminated
 | ||||||
|  |             // AG: this is not yet true in case of arithmetic eq_prop
 | ||||||
|  |             return m_pr.is_a_marked(pr) || is_h(pr); | ||||||
|  |         } | ||||||
|  |         bool is_b(proof *pr) {return m_pr.is_b_marked(pr);} | ||||||
|  |         bool is_h(proof *pr) {return m_pr.is_h_marked(pr);} | ||||||
|  |         bool is_b_pure(proof *pr) { return m_pr.is_b_pure(pr);} | ||||||
|  |         bool is_b_open(proof *p) {return m_pr.is_b_marked(p) && !is_closed (p);} | ||||||
| 
 | 
 | ||||||
|         /*
 |         /*
 | ||||||
|          * register a plugin for computation of partial unsat cores |          * register a plugin for computation of partial unsat cores | ||||||
|  | @ -59,7 +79,6 @@ namespace spacer { | ||||||
|         bool is_closed(proof* p); |         bool is_closed(proof* p); | ||||||
|         void set_closed(proof* p, bool value); |         void set_closed(proof* p, bool value); | ||||||
| 
 | 
 | ||||||
|         bool is_b_open (proof *p); |  | ||||||
| 
 | 
 | ||||||
|         /*
 |         /*
 | ||||||
|          * adds a lemma to the unsat core |          * adds a lemma to the unsat core | ||||||
|  | @ -67,14 +86,6 @@ namespace spacer { | ||||||
|         void add_lemma_to_core(expr* lemma); |         void add_lemma_to_core(expr* lemma); | ||||||
| 
 | 
 | ||||||
|     private: |     private: | ||||||
|         ptr_vector<unsat_core_plugin> m_plugins; |  | ||||||
|         ast_mark m_closed; |  | ||||||
| 
 |  | ||||||
|         /*
 |  | ||||||
|          * collects the lemmas of the unsat-core |  | ||||||
|          * will at the end be inserted into unsat_core. |  | ||||||
|          */ |  | ||||||
|         expr_ref_vector m_unsat_core; |  | ||||||
| 
 | 
 | ||||||
|         /*
 |         /*
 | ||||||
|          * computes partial core for step by delegating computation to plugins |          * computes partial core for step by delegating computation to plugins | ||||||
|  |  | ||||||
|  | @ -34,27 +34,25 @@ Revision History: | ||||||
| 
 | 
 | ||||||
| namespace spacer { | namespace spacer { | ||||||
| 
 | 
 | ||||||
|     unsat_core_plugin::unsat_core_plugin(unsat_core_learner& learner):  |     unsat_core_plugin::unsat_core_plugin(unsat_core_learner& ctx): | ||||||
|         m(learner.m), m_learner(learner) {}; |         m(ctx.get_manager()), m_ctx(ctx) {}; | ||||||
| 
 | 
 | ||||||
|     void unsat_core_plugin_lemma::compute_partial_core(proof* step) { |     void unsat_core_plugin_lemma::compute_partial_core(proof* step) { | ||||||
|         SASSERT(m_learner.m_pr.is_a_marked(step)); |         SASSERT(m_ctx.is_a(step)); | ||||||
|         SASSERT(m_learner.m_pr.is_b_marked(step)); |         SASSERT(m_ctx.is_b(step)); | ||||||
| 
 | 
 | ||||||
|         for (proof* premise : m.get_parents(step)) { |         for (auto* p : m.get_parents(step)) { | ||||||
|              |             if (m_ctx.is_b_open (p))  { | ||||||
|             if (m_learner.is_b_open (premise))  { |  | ||||||
|                 // by IH, premises that are AB marked are already closed
 |                 // by IH, premises that are AB marked are already closed
 | ||||||
|                 SASSERT(!m_learner.m_pr.is_a_marked(premise)); |                 SASSERT(!m_ctx.is_a(p)); | ||||||
|                 add_lowest_split_to_core(premise); |                 add_lowest_split_to_core(p); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         m_learner.set_closed(step, true); |         m_ctx.set_closed(step, true); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     void unsat_core_plugin_lemma::add_lowest_split_to_core(proof* step) const |     void unsat_core_plugin_lemma::add_lowest_split_to_core(proof* step) const { | ||||||
|     { |         SASSERT(m_ctx.is_b_open(step)); | ||||||
|         SASSERT(m_learner.is_b_open(step)); |  | ||||||
| 
 | 
 | ||||||
|         ptr_buffer<proof> todo; |         ptr_buffer<proof> todo; | ||||||
|         todo.push_back(step); |         todo.push_back(step); | ||||||
|  | @ -64,45 +62,46 @@ namespace spacer { | ||||||
|             todo.pop_back(); |             todo.pop_back(); | ||||||
| 
 | 
 | ||||||
|             // if current step hasn't been processed,
 |             // if current step hasn't been processed,
 | ||||||
|             if (!m_learner.is_closed(pf)) { |             if (!m_ctx.is_closed(pf)) { | ||||||
|                 m_learner.set_closed(pf, true); |                 m_ctx.set_closed(pf, true); | ||||||
|                 // the step is b-marked and not closed.
 |                 // the step is b-marked and not closed.
 | ||||||
|                 // by I.H. the step must be already visited
 |                 // by I.H. the step must be already visited
 | ||||||
|                 // so if it is also a-marked, it must be closed
 |                 // so if it is also a-marked, it must be closed
 | ||||||
|                 SASSERT(m_learner.m_pr.is_b_marked(pf)); |                 SASSERT(m_ctx.is_b(pf)); | ||||||
|                 SASSERT(!m_learner.m_pr.is_a_marked(pf)); |                 SASSERT(!m_ctx.is_a(pf)); | ||||||
| 
 | 
 | ||||||
|                 // the current step needs to be interpolated:
 |                 // the current step needs to be interpolated:
 | ||||||
|                 expr* fact = m.get_fact(pf); |                 expr* fact = m.get_fact(pf); | ||||||
|                 // if we trust the current step and we are able to use it
 |                 // if we trust the current step and we are able to use it
 | ||||||
|                 if (m_learner.m_pr.is_b_pure (pf) && |                 if (m_ctx.is_b_pure (pf) && (m.is_asserted(pf) || is_literal(m, fact))) { | ||||||
|                     (m.is_asserted(pf) || is_literal(m, fact))) { |  | ||||||
|                     // just add it to the core
 |                     // just add it to the core
 | ||||||
|                     m_learner.add_lemma_to_core(fact); |                     m_ctx.add_lemma_to_core(fact); | ||||||
|                 } |                 } | ||||||
|                 // otherwise recurse on premises
 |                 // otherwise recurse on premises
 | ||||||
|                 else { |                 else { | ||||||
|                     for (proof* premise : m.get_parents(pf)) |                     for (proof* premise : m.get_parents(pf)) | ||||||
|                         if (m_learner.is_b_open(premise))  |                         if (m_ctx.is_b_open(premise)) | ||||||
|                             todo.push_back(premise); |                             todo.push_back(premise); | ||||||
|                 } |                 } | ||||||
|                  |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     void unsat_core_plugin_farkas_lemma::compute_partial_core(proof* step) |     /***
 | ||||||
|     { |      * FARKAS | ||||||
|         SASSERT(m_learner.m_pr.is_a_marked(step)); |      */ | ||||||
|         SASSERT(m_learner.m_pr.is_b_marked(step)); |     void unsat_core_plugin_farkas_lemma::compute_partial_core(proof* step) { | ||||||
|  |         SASSERT(m_ctx.is_a(step)); | ||||||
|  |         SASSERT(m_ctx.is_b(step)); | ||||||
|         // XXX this assertion should be true so there is no need to check for it
 |         // XXX this assertion should be true so there is no need to check for it
 | ||||||
|         SASSERT (!m_learner.is_closed (step)); |         SASSERT (!m_ctx.is_closed (step)); | ||||||
|         func_decl* d = step->get_decl(); |         func_decl* d = step->get_decl(); | ||||||
|         symbol sym; |         symbol sym; | ||||||
|         if (!m_learner.is_closed(step) && // if step is not already interpolated
 |         TRACE("spacer.farkas", | ||||||
|             is_farkas_lemma(m, step)) {  |               tout << "looking at: " << mk_pp(step, m) << "\n";); | ||||||
|             // weaker check: d->get_num_parameters() >= m.get_num_parents(step) + 2 
 |         if (!m_ctx.is_closed(step) && is_farkas_lemma(m, step)) { | ||||||
|  |             // weaker check : d->get_num_parameters() >= m.get_num_parents(step) + 2
 | ||||||
| 
 | 
 | ||||||
|             SASSERT(d->get_num_parameters() == m.get_num_parents(step) + 2); |             SASSERT(d->get_num_parameters() == m.get_num_parents(step) + 2); | ||||||
|             SASSERT(m.has_fact(step)); |             SASSERT(m.has_fact(step)); | ||||||
|  | @ -135,32 +134,33 @@ namespace spacer { | ||||||
|              */ |              */ | ||||||
|             parameter const* params = d->get_parameters() + 2; // point to the first Farkas coefficient
 |             parameter const* params = d->get_parameters() + 2; // point to the first Farkas coefficient
 | ||||||
| 
 | 
 | ||||||
|             STRACE("spacer.farkas", |             TRACE("spacer.farkas", | ||||||
|                    verbose_stream() << "Farkas input: "<< "\n"; |                   tout << "Farkas input: "<< "\n"; | ||||||
|                    for (unsigned i = 0; i < m.get_num_parents(step); ++i) { |                   for (unsigned i = 0; i < m.get_num_parents(step); ++i) { | ||||||
|                        proof * prem = m.get_parent(step, i);                        |                       proof * prem = m.get_parent(step, i); | ||||||
|                        rational coef = params[i].get_rational();                        |                       rational coef = params[i].get_rational(); | ||||||
|                        bool b_pure = m_learner.m_pr.is_b_pure (prem); |                       bool b_pure = m_ctx.is_b_pure (prem); | ||||||
|                        verbose_stream() << (b_pure?"B":"A") << " " << coef << " " << mk_pp(m.get_fact(prem), m) << "\n"; |                       tout << (b_pure?"B":"A") << " " << coef << " " << mk_pp(m.get_fact(prem), m) << "\n"; | ||||||
|                    } |                   } | ||||||
|                    ); |                 ); | ||||||
| 
 | 
 | ||||||
|             bool can_be_closed = true; |             bool done = true; | ||||||
| 
 | 
 | ||||||
|             for (unsigned i = 0; i < m.get_num_parents(step); ++i) { |             for (unsigned i = 0; i < m.get_num_parents(step); ++i) { | ||||||
|                 proof * premise = m.get_parent(step, i); |                 proof * premise = m.get_parent(step, i); | ||||||
| 
 | 
 | ||||||
|                 if (m_learner.is_b_open (premise)) { |                 if (m_ctx.is_b_open (premise)) { | ||||||
|                     SASSERT(!m_learner.m_pr.is_a_marked(premise)); |                     SASSERT(!m_ctx.is_a(premise)); | ||||||
| 
 | 
 | ||||||
|                     if (m_learner.m_pr.is_b_pure (step)) { |                     if (m_ctx.is_b_pure (premise)) { | ||||||
|                         if (!m_use_constant_from_a) { |                         if (!m_use_constant_from_a) { | ||||||
|                             rational coefficient = params[i].get_rational(); |                             rational coefficient = params[i].get_rational(); | ||||||
|                             coeff_lits.push_back(std::make_pair(abs(coefficient), (app*)m.get_fact(premise))); |                             coeff_lits.push_back(std::make_pair(abs(coefficient), (app*)m.get_fact(premise))); | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|                     else { |                     else { | ||||||
|                         can_be_closed = false; |                         // -- mixed premise, won't be able to close this proof step
 | ||||||
|  |                         done = false; | ||||||
| 
 | 
 | ||||||
|                         if (m_use_constant_from_a) { |                         if (m_use_constant_from_a) { | ||||||
|                             rational coefficient = params[i].get_rational(); |                             rational coefficient = params[i].get_rational(); | ||||||
|  | @ -176,6 +176,7 @@ namespace spacer { | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  |             // TBD: factor into another method
 | ||||||
|             if (m_use_constant_from_a) { |             if (m_use_constant_from_a) { | ||||||
|                 params += m.get_num_parents(step); // point to the first Farkas coefficient, which corresponds to a formula in the conclusion
 |                 params += m.get_num_parents(step); // point to the first Farkas coefficient, which corresponds to a formula in the conclusion
 | ||||||
| 
 | 
 | ||||||
|  | @ -205,13 +206,12 @@ namespace spacer { | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             // only if all b-premises can be used directly, add the farkas core and close the step
 |             // only if all b-premises can be used directly, add the farkas core and close the step
 | ||||||
|             if (can_be_closed) { |             // AG: this decision needs to be re-evaluated. If the proof cannot be closed, literals above
 | ||||||
|                 m_learner.set_closed(step, true); |             // AG: it will go into the core. However, it does not mean that this literal should/could not be added.
 | ||||||
|                  |             m_ctx.set_closed(step, done); | ||||||
|                 expr_ref res = compute_linear_combination(coeff_lits); |             expr_ref res = compute_linear_combination(coeff_lits); | ||||||
|                  |             TRACE("spacer.farkas", tout << "Farkas core: " << res << "\n";); | ||||||
|                 m_learner.add_lemma_to_core(res); |             m_ctx.add_lemma_to_core(res); | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -235,12 +235,12 @@ namespace spacer { | ||||||
| 
 | 
 | ||||||
|     void unsat_core_plugin_farkas_lemma_optimized::compute_partial_core(proof* step) |     void unsat_core_plugin_farkas_lemma_optimized::compute_partial_core(proof* step) | ||||||
|     { |     { | ||||||
|         SASSERT(m_learner.m_pr.is_a_marked(step)); |         SASSERT(m_ctx.is_a(step)); | ||||||
|         SASSERT(m_learner.m_pr.is_b_marked(step)); |         SASSERT(m_ctx.is_b(step)); | ||||||
| 
 | 
 | ||||||
|         func_decl* d = step->get_decl(); |         func_decl* d = step->get_decl(); | ||||||
|         symbol sym; |         symbol sym; | ||||||
|         if (!m_learner.is_closed(step) && // if step is not already interpolated
 |         if (!m_ctx.is_closed(step) && // if step is not already interpolated
 | ||||||
|            is_farkas_lemma(m, step)) { |            is_farkas_lemma(m, step)) { | ||||||
|             SASSERT(d->get_num_parameters() == m.get_num_parents(step) + 2); |             SASSERT(d->get_num_parameters() == m.get_num_parents(step) + 2); | ||||||
|             SASSERT(m.has_fact(step)); |             SASSERT(m.has_fact(step)); | ||||||
|  | @ -249,25 +249,25 @@ namespace spacer { | ||||||
| 
 | 
 | ||||||
|             parameter const* params = d->get_parameters() + 2; // point to the first Farkas coefficient
 |             parameter const* params = d->get_parameters() + 2; // point to the first Farkas coefficient
 | ||||||
| 
 | 
 | ||||||
|             STRACE("spacer.farkas", |             TRACE("spacer.farkas", | ||||||
|                    verbose_stream() << "Farkas input: "<< "\n"; |                   tout << "Farkas input: "<< "\n"; | ||||||
|                    for (unsigned i = 0; i < m.get_num_parents(step); ++i) { |                   for (unsigned i = 0; i < m.get_num_parents(step); ++i) { | ||||||
|                        proof * prem = m.get_parent(step, i); |                       proof * prem = m.get_parent(step, i); | ||||||
|                        rational coef = params[i].get_rational();                        |                       rational coef = params[i].get_rational(); | ||||||
|                        bool b_pure = m_learner.m_pr.is_b_pure (prem); |                       bool b_pure = m_ctx.is_b_pure (prem); | ||||||
|                        verbose_stream() << (b_pure?"B":"A") << " " << coef << " " << mk_pp(m.get_fact(prem), m_learner.m) << "\n"; |                       tout << (b_pure?"B":"A") << " " << coef << " " << mk_pp(m.get_fact(prem), m) << "\n"; | ||||||
|                    } |                   } | ||||||
|                    ); |                 ); | ||||||
| 
 | 
 | ||||||
|             bool can_be_closed = true; |             bool can_be_closed = true; | ||||||
|             for (unsigned i = 0; i < m.get_num_parents(step); ++i) { |             for (unsigned i = 0; i < m.get_num_parents(step); ++i) { | ||||||
|                 proof * premise = m.get_parent(step, i); |                 proof * premise = m.get_parent(step, i); | ||||||
| 
 | 
 | ||||||
|                 if (m_learner.m_pr.is_b_marked(premise) && !m_learner.is_closed(premise)) |                 if (m_ctx.is_b(premise) && !m_ctx.is_closed(premise)) | ||||||
|                 { |                 { | ||||||
|                     SASSERT(!m_learner.m_pr.is_a_marked(premise)); |                     SASSERT(!m_ctx.is_a(premise)); | ||||||
| 
 | 
 | ||||||
|                     if (m_learner.m_pr.is_b_pure(premise)) |                     if (m_ctx.is_b_pure(premise)) | ||||||
|                     { |                     { | ||||||
|                         rational coefficient = params[i].get_rational(); |                         rational coefficient = params[i].get_rational(); | ||||||
|                         linear_combination.push_back |                         linear_combination.push_back | ||||||
|  | @ -283,7 +283,7 @@ namespace spacer { | ||||||
|             // only if all b-premises can be used directly, close the step and add linear combinations for later processing
 |             // only if all b-premises can be used directly, close the step and add linear combinations for later processing
 | ||||||
|             if (can_be_closed) |             if (can_be_closed) | ||||||
|             { |             { | ||||||
|                 m_learner.set_closed(step, true); |                 m_ctx.set_closed(step, true); | ||||||
|                 if (!linear_combination.empty()) |                 if (!linear_combination.empty()) | ||||||
|                 { |                 { | ||||||
|                     m_linear_combinations.push_back(linear_combination); |                     m_linear_combinations.push_back(linear_combination); | ||||||
|  | @ -349,7 +349,7 @@ namespace spacer { | ||||||
|             SASSERT(!coeff_lits.empty()); |             SASSERT(!coeff_lits.empty()); | ||||||
|             expr_ref linear_combination = compute_linear_combination(coeff_lits); |             expr_ref linear_combination = compute_linear_combination(coeff_lits); | ||||||
| 
 | 
 | ||||||
|             m_learner.add_lemma_to_core(linear_combination); |             m_ctx.add_lemma_to_core(linear_combination); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|     } |     } | ||||||
|  | @ -480,7 +480,7 @@ namespace spacer { | ||||||
|                     SASSERT(!coeff_lits.empty()); // since then previous outer loop would have found solution already
 |                     SASSERT(!coeff_lits.empty()); // since then previous outer loop would have found solution already
 | ||||||
|                     expr_ref linear_combination = compute_linear_combination(coeff_lits); |                     expr_ref linear_combination = compute_linear_combination(coeff_lits); | ||||||
| 
 | 
 | ||||||
|                     m_learner.add_lemma_to_core(linear_combination); |                     m_ctx.add_lemma_to_core(linear_combination); | ||||||
|                 } |                 } | ||||||
|                 return; |                 return; | ||||||
|             } |             } | ||||||
|  | @ -504,10 +504,10 @@ namespace spacer { | ||||||
|     { |     { | ||||||
|         ptr_vector<proof> todo; |         ptr_vector<proof> todo; | ||||||
| 
 | 
 | ||||||
|         SASSERT(m_learner.m_pr.is_a_marked(step)); |         SASSERT(m_ctx.is_a(step)); | ||||||
|         SASSERT(m_learner.m_pr.is_b_marked(step)); |         SASSERT(m_ctx.is_b(step)); | ||||||
|         SASSERT(m.get_num_parents(step) > 0); |         SASSERT(m.get_num_parents(step) > 0); | ||||||
|         SASSERT(!m_learner.is_closed(step)); |         SASSERT(!m_ctx.is_closed(step)); | ||||||
|         todo.push_back(step); |         todo.push_back(step); | ||||||
| 
 | 
 | ||||||
|         while (!todo.empty()) |         while (!todo.empty()) | ||||||
|  | @ -516,7 +516,7 @@ namespace spacer { | ||||||
|             todo.pop_back(); |             todo.pop_back(); | ||||||
| 
 | 
 | ||||||
|             // if we need to deal with the node and if we haven't added the corresponding edges so far
 |             // if we need to deal with the node and if we haven't added the corresponding edges so far
 | ||||||
|             if (!m_learner.is_closed(current) && !m_visited.is_marked(current)) |             if (!m_ctx.is_closed(current) && !m_visited.is_marked(current)) | ||||||
|             { |             { | ||||||
|                 // compute smallest subproof rooted in current, which has only good edges
 |                 // compute smallest subproof rooted in current, which has only good edges
 | ||||||
|                 // add an edge from current to each leaf of that subproof
 |                 // add an edge from current to each leaf of that subproof
 | ||||||
|  | @ -527,7 +527,7 @@ namespace spacer { | ||||||
| 
 | 
 | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         m_learner.set_closed(step, true); |         m_ctx.set_closed(step, true); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -538,7 +538,7 @@ namespace spacer { | ||||||
|         ptr_buffer<proof> todo_subproof; |         ptr_buffer<proof> todo_subproof; | ||||||
| 
 | 
 | ||||||
|         for (proof* premise : m.get_parents(step)) { |         for (proof* premise : m.get_parents(step)) { | ||||||
|             if (m_learner.m_pr.is_b_marked(premise)) { |             if (m_ctx.is_b(premise)) { | ||||||
|                 todo_subproof.push_back(premise); |                 todo_subproof.push_back(premise); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  | @ -548,21 +548,21 @@ namespace spacer { | ||||||
|             todo_subproof.pop_back(); |             todo_subproof.pop_back(); | ||||||
| 
 | 
 | ||||||
|             // if we need to deal with the node
 |             // if we need to deal with the node
 | ||||||
|             if (!m_learner.is_closed(current)) |             if (!m_ctx.is_closed(current)) | ||||||
|             { |             { | ||||||
|                 SASSERT(!m_learner.m_pr.is_a_marked(current)); // by I.H. the step must be already visited
 |                 SASSERT(!m_ctx.is_a(current)); // by I.H. the step must be already visited
 | ||||||
| 
 | 
 | ||||||
|                 // and the current step needs to be interpolated:
 |                 // and the current step needs to be interpolated:
 | ||||||
|                 if (m_learner.m_pr.is_b_marked(current)) |                 if (m_ctx.is_b(current)) | ||||||
|                 { |                 { | ||||||
|                     // if we trust the current step and we are able to use it
 |                     // if we trust the current step and we are able to use it
 | ||||||
|                     if (m_learner.m_pr.is_b_pure (current) && |                     if (m_ctx.is_b_pure (current) && | ||||||
|                         (m.is_asserted(current) || |                         (m.is_asserted(current) || | ||||||
|                          is_literal(m, m.get_fact(current)))) |                          is_literal(m, m.get_fact(current)))) | ||||||
|                     { |                     { | ||||||
|                         // we found a leaf of the subproof, so
 |                         // we found a leaf of the subproof, so
 | ||||||
|                         // 1) we add corresponding edges
 |                         // 1) we add corresponding edges
 | ||||||
|                         if (m_learner.m_pr.is_a_marked(step)) |                         if (m_ctx.is_a(step)) | ||||||
|                         { |                         { | ||||||
|                             add_edge(nullptr, current); // current is sink
 |                             add_edge(nullptr, current); // current is sink
 | ||||||
|                         } |                         } | ||||||
|  | @ -684,7 +684,7 @@ namespace spacer { | ||||||
|         m_min_cut.compute_min_cut(cut_nodes); |         m_min_cut.compute_min_cut(cut_nodes); | ||||||
| 
 | 
 | ||||||
|         for (unsigned cut_node : cut_nodes)   { |         for (unsigned cut_node : cut_nodes)   { | ||||||
|             m_learner.add_lemma_to_core(m_node_to_formula[cut_node]); |             m_ctx.add_lemma_to_core(m_node_to_formula[cut_node]); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -36,7 +36,7 @@ namespace spacer { | ||||||
|         virtual void compute_partial_core(proof* step) = 0; |         virtual void compute_partial_core(proof* step) = 0; | ||||||
|         virtual void finalize(){}; |         virtual void finalize(){}; | ||||||
| 
 | 
 | ||||||
|         unsat_core_learner& m_learner; |         unsat_core_learner& m_ctx; | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     class unsat_core_plugin_lemma : public unsat_core_plugin { |     class unsat_core_plugin_lemma : public unsat_core_plugin { | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue