mirror of
				https://github.com/Z3Prover/z3
				synced 2025-10-31 03:32:28 +00:00 
			
		
		
		
	adding factory for model initialization
This commit is contained in:
		
							parent
							
								
									9e79fe0a51
								
							
						
					
					
						commit
						981c7d27ea
					
				
					 3 changed files with 96 additions and 12 deletions
				
			
		|  | @ -36,6 +36,16 @@ namespace smt { | |||
|         m_axioms.set_add_clause(add_clause_fn); | ||||
|     } | ||||
| 
 | ||||
|     theory_finite_set::~theory_finite_set() { | ||||
|         reset_set_members(); | ||||
|     } | ||||
| 
 | ||||
|     void theory_finite_set::reset_set_members() { | ||||
|         for (auto [k, s] : m_set_members) | ||||
|             dealloc(s); | ||||
|         m_set_members.reset(); | ||||
|     } | ||||
| 
 | ||||
|     /**
 | ||||
|     * Boolean atomic formulas for finite sets are one of: | ||||
|     * (set.in x S) | ||||
|  | @ -108,6 +118,12 @@ namespace smt { | |||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     void theory_finite_set::apply_sort_cnstr(enode* n, sort* s) { | ||||
|         SASSERT(u.is_finite_set(s)); | ||||
|         if (!is_attached_to_var(n)) | ||||
|             ctx.attach_th_var(n, this, mk_var(n)); | ||||
|     } | ||||
| 
 | ||||
|     void theory_finite_set::new_eq_eh(theory_var v1, theory_var v2) { | ||||
|         TRACE(finite_set, tout << "new_eq_eh: v" << v1 << " = v" << v2 << "\n";); | ||||
|         // When two sets are equal, propagate membership constraints
 | ||||
|  | @ -275,15 +291,78 @@ namespace smt { | |||
|         TRACE(finite_set, tout << "init_model\n";); | ||||
|         // Model generation will use default interpretation for sets
 | ||||
|         // The model will be constructed based on the membership literals that are true
 | ||||
|         m_factory = alloc(finite_set_value_factory, m, u.get_family_id(), mg.get_model()); | ||||
|         mg.register_factory(m_factory); | ||||
|         collect_members(); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|     void theory_finite_set::collect_members() { | ||||
|         // This method can be used to collect all elements that are members of sets
 | ||||
|         // and ensure that the model factory has values for them.
 | ||||
|         // For now, we rely on the default model construction.
 | ||||
|         reset_set_members(); | ||||
|         for (auto x : m_elements) { | ||||
|             if (!ctx.is_relevant(x)) | ||||
|                 continue; | ||||
|             x = x->get_root(); | ||||
|             // TODO: use marking of x to avoid duplicate work
 | ||||
|             for (auto p : enode::parents(x)) { | ||||
|                 if (!ctx.is_relevant(p)) | ||||
|                     continue; | ||||
|                 if (!u.is_in(p->get_expr())) | ||||
|                     continue; | ||||
|                 if (ctx.get_assignment(p->get_expr()) != l_true) | ||||
|                     continue; | ||||
|                 enode *elem = nullptr, *set = nullptr; | ||||
|                 set = p->get_arg(1)->get_root(); | ||||
|                 elem = p->get_arg(0)->get_root(); | ||||
|                 if (elem != x) | ||||
|                     continue;  | ||||
|                 if (!m_set_members.contains(set))  | ||||
|                     m_set_members.insert(set, alloc(obj_hashtable<enode>));                 | ||||
|                 m_set_members.find(set)->insert(x); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     struct finite_set_value_proc : model_value_proc {     | ||||
|         finite_set_util& u; | ||||
|         sort *s = nullptr; | ||||
|         obj_hashtable<enode>* m_elements = nullptr; | ||||
| 
 | ||||
|         finite_set_value_proc(finite_set_util& u, sort* s, obj_hashtable<enode>* elements) :  | ||||
|             u(u), s(s), | ||||
|             m_elements(elements) {} | ||||
| 
 | ||||
|         void get_dependencies(buffer<model_value_dependency> &result) override { | ||||
|             if (!m_elements) | ||||
|                 return; | ||||
|             for (auto v : *m_elements) | ||||
|                 result.push_back(model_value_dependency(v)); | ||||
|         } | ||||
| 
 | ||||
|         app *mk_value(model_generator &mg, expr_ref_vector const &values) override {             | ||||
|             SASSERT(values.size() == m_elements->size()); | ||||
|             if (values.empty())  | ||||
|                 return u.mk_empty(s); | ||||
|             SASSERT(m_elements); | ||||
|             app *r = nullptr; | ||||
|             for (auto v : values) { | ||||
|                 app *e = u.mk_singleton(v); | ||||
|                 r = r ? u.mk_union(r, e) : e; | ||||
|             } | ||||
|             return r; | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     model_value_proc * theory_finite_set::mk_value(enode * n, model_generator & mg) { | ||||
|         TRACE(finite_set, tout << "mk_value: " << mk_pp(n->get_expr(), m) << "\n";); | ||||
|          | ||||
|         // For now, return nullptr to use default model construction
 | ||||
|         // A complete implementation would construct explicit set values
 | ||||
|         // based on true membership literals
 | ||||
|         return nullptr; | ||||
|         TRACE(finite_set, tout << "mk_value: " << mk_pp(n->get_expr(), m) << "\n";);        | ||||
|         obj_hashtable<enode>*elements = nullptr; | ||||
|         sort *s = n->get_expr()->get_sort(); | ||||
|         m_set_members.find(n->get_root(), elements);  | ||||
|         return alloc(finite_set_value_proc, u, s, elements); | ||||
|     } | ||||
| 
 | ||||
|     /**
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue