mirror of
				https://github.com/Z3Prover/z3
				synced 2025-10-31 11:42:28 +00:00 
			
		
		
		
	add an option to register callback on quantifier instantiation
Suppose a user propagator encodes axioms using quantifiers and uses E-matching for instantiation. If it wants to implement a custom priority scheme or drop some instances based on internal checks it can register a callback with quantifier instantiation
This commit is contained in:
		
							parent
							
								
									d4a4dd6cc7
								
							
						
					
					
						commit
						b33f444545
					
				
					 24 changed files with 126 additions and 3 deletions
				
			
		|  | @ -263,6 +263,11 @@ namespace smt { | |||
|         if (stat->get_num_instances() % m_params.m_qi_profile_freq == 0) { | ||||
|             m_qm.display_stats(verbose_stream(), q); | ||||
|         } | ||||
| 
 | ||||
|         if (m_on_binding && !m_on_binding(q, instance)) { | ||||
|             verbose_stream() << "qi_queue: on_binding returned false, skipping instance.\n"; | ||||
|             return; | ||||
|         } | ||||
|         expr_ref lemma(m); | ||||
|         if (m.is_or(s_instance)) { | ||||
|             ptr_vector<expr> args; | ||||
|  |  | |||
|  | @ -28,6 +28,7 @@ Revision History: | |||
| #include "params/qi_params.h" | ||||
| #include "ast/cost_evaluator.h" | ||||
| #include "util/statistics.h" | ||||
| #include "tactic/user_propagator_base.h" | ||||
| 
 | ||||
| namespace smt { | ||||
|     class context; | ||||
|  | @ -52,6 +53,7 @@ namespace smt { | |||
|         cached_var_subst              m_subst; | ||||
|         svector<float>                m_vals; | ||||
|         double                        m_eager_cost_threshold = 0; | ||||
|         std::function<bool(quantifier*,expr*)> m_on_binding; | ||||
|         struct entry { | ||||
|             fingerprint * m_qb; | ||||
|             float         m_cost; | ||||
|  | @ -95,6 +97,9 @@ namespace smt { | |||
|         void reset(); | ||||
|         void display_delayed_instances_stats(std::ostream & out) const; | ||||
|         void collect_statistics(::statistics & st) const; | ||||
|         void register_on_binding(std::function<bool(quantifier* q, expr* e)> & on_binding) { | ||||
|             m_on_binding = on_binding; | ||||
|         } | ||||
|     }; | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -1814,6 +1814,14 @@ namespace smt { | |||
|             m_user_propagator->register_decide(r); | ||||
|         } | ||||
| 
 | ||||
|         void user_propagate_register_on_binding(user_propagator::binding_eh_t& t) { | ||||
|             m_user_propagator->register_on_binding(t); | ||||
|         } | ||||
| 
 | ||||
|         void register_on_binding(std::function<bool(quantifier* q, expr* inst)>& f) { | ||||
|             m_qmanager->register_on_binding(f); | ||||
|         } | ||||
| 
 | ||||
|         void user_propagate_initialize_value(expr* var, expr* value); | ||||
| 
 | ||||
|         bool watches_fixed(enode* n) const; | ||||
|  |  | |||
|  | @ -307,6 +307,10 @@ namespace smt { | |||
|     void kernel::user_propagate_register_fixed(user_propagator::fixed_eh_t& fixed_eh) { | ||||
|         m_imp->m_kernel.user_propagate_register_fixed(fixed_eh); | ||||
|     } | ||||
| 
 | ||||
|     void kernel::user_propagate_register_on_binding(user_propagator::binding_eh_t& on_binding) { | ||||
|         m_imp->m_kernel.user_propagate_register_on_binding(on_binding); | ||||
|     } | ||||
|      | ||||
|     void kernel::user_propagate_register_final(user_propagator::final_eh_t& final_eh) { | ||||
|         m_imp->m_kernel.user_propagate_register_final(final_eh); | ||||
|  |  | |||
|  | @ -319,6 +319,8 @@ namespace smt { | |||
|          | ||||
|         void user_propagate_register_diseq(user_propagator::eq_eh_t& diseq_eh); | ||||
| 
 | ||||
|         void user_propagate_register_on_binding(user_propagator::binding_eh_t& binding_eh); | ||||
| 
 | ||||
|         void user_propagate_register_expr(expr* e); | ||||
|          | ||||
|         void user_propagate_register_created(user_propagator::created_eh_t& r); | ||||
|  |  | |||
|  | @ -339,6 +339,10 @@ namespace smt { | |||
|             m_plugin->add_eq_eh(n1, n2); | ||||
|         } | ||||
| 
 | ||||
|         void register_on_binding(std::function<bool(quantifier*, expr*)>& on_binding) { | ||||
|             m_qi_queue.register_on_binding(on_binding); | ||||
|         } | ||||
| 
 | ||||
|         void relevant_eh(enode * n) { | ||||
|             m_plugin->relevant_eh(n); | ||||
|         } | ||||
|  | @ -493,6 +497,10 @@ namespace smt { | |||
|         m_imp->add_eq_eh(n1, n2); | ||||
|     } | ||||
| 
 | ||||
|     void quantifier_manager::register_on_binding(std::function<bool(quantifier*, expr*)>& on_binding) { | ||||
|         m_imp->register_on_binding(on_binding); | ||||
|     } | ||||
| 
 | ||||
|     void quantifier_manager::relevant_eh(enode * n) { | ||||
|         m_imp->relevant_eh(n); | ||||
|     } | ||||
|  |  | |||
|  | @ -23,6 +23,7 @@ Revision History: | |||
| #include "util/statistics.h" | ||||
| #include "util/params.h" | ||||
| #include "smt/smt_types.h" | ||||
| #include "tactic/user_propagator_base.h" | ||||
| #include <tuple> | ||||
| 
 | ||||
| class proto_model; | ||||
|  | @ -96,6 +97,8 @@ namespace smt { | |||
|         void collect_statistics(::statistics & st) const; | ||||
|         void reset_statistics(); | ||||
| 
 | ||||
|         void register_on_binding(std::function<bool(quantifier*, expr*)> & f); | ||||
| 
 | ||||
|         ptr_vector<quantifier>::const_iterator begin_quantifiers() const; | ||||
|         ptr_vector<quantifier>::const_iterator end_quantifiers() const; | ||||
|         ptr_vector<quantifier>::const_iterator begin() const { return begin_quantifiers(); } | ||||
|  |  | |||
|  | @ -244,6 +244,10 @@ namespace { | |||
|             m_context.user_propagate_register_expr(e); | ||||
|         } | ||||
| 
 | ||||
|         void user_propagate_register_on_binding(user_propagator::binding_eh_t& binding_eh) override { | ||||
|             m_context.user_propagate_register_on_binding(binding_eh); | ||||
|         } | ||||
| 
 | ||||
|         void user_propagate_register_created(user_propagator::created_eh_t& c) override { | ||||
|             m_context.user_propagate_register_created(c); | ||||
|         } | ||||
|  |  | |||
|  | @ -402,6 +402,10 @@ public: | |||
|         m_diseq_eh = diseq_eh; | ||||
|     } | ||||
| 
 | ||||
|     void user_propagate_register_on_binding(user_propagator::binding_eh_t& binding_eh) override { | ||||
|         m_ctx.load()->user_propagate_register_on_binding(binding_eh); | ||||
|     } | ||||
| 
 | ||||
|     void user_propagate_register_expr(expr* e) override { | ||||
|         m_vars.push_back(e); | ||||
|     } | ||||
|  |  | |||
|  | @ -110,6 +110,15 @@ void theory_user_propagator::register_cb(expr* e) { | |||
|         add_expr(e, true); | ||||
| } | ||||
| 
 | ||||
| void theory_user_propagator::register_on_binding(user_propagator::binding_eh_t& binding_eh) { | ||||
|     std::function<bool(quantifier* q, expr* inst)> on_binding =  | ||||
|         [this, binding_eh](quantifier* q, expr* inst) { | ||||
|             return binding_eh(m_user_context, this, q, inst); | ||||
|         };     | ||||
|     ctx.register_on_binding(on_binding); | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| bool theory_user_propagator::next_split_cb(expr* e, unsigned idx, lbool phase) { | ||||
|     if (e == nullptr) { // clear
 | ||||
|         m_next_split_var = nullptr; | ||||
|  |  | |||
|  | @ -132,6 +132,7 @@ namespace smt { | |||
|         void register_diseq(user_propagator::eq_eh_t& diseq_eh) { m_diseq_eh = diseq_eh; } | ||||
|         void register_created(user_propagator::created_eh_t& created_eh) { m_created_eh = created_eh; } | ||||
|         void register_decide(user_propagator::decide_eh_t& decide_eh) { m_decide_eh = decide_eh; } | ||||
|         void register_on_binding(user_propagator::binding_eh_t& binding_eh); | ||||
| 
 | ||||
|         bool has_fixed() const { return (bool)m_fixed_eh; } | ||||
|          | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue