@@ -29,57 +29,88 @@ namespace mbp {
2929 bool euf_project_plugin::operator ()(model& model, app_ref_vector& vars, expr_ref_vector& lits) {
3030 return false ;
3131 }
32-
33- bool euf_project_plugin::project (model& model, app_ref_vector& vars, expr_ref_vector& lits, vector<def>& defs) {
34- if (vars.empty ())
35- return false ;
32+
33+ void euf_project_plugin::solve_eqs (model& model, app_ref_vector& vars, expr_ref_vector& lits, vector<def>& defs) {
3634 flatten_and (lits);
3735 expr_mark var_set;
3836 auto is_pure = [&](expr_mark& var_set, expr* v) {
3937 return all_of (subterms::all (expr_ref (v, m)), [&](expr* w) { return !var_set.is_marked (w); });
4038 };
4139 for (auto v : vars)
4240 var_set.mark (v, true );
43- unsigned has_def = false ;
44- #if 1
4541 // solve trivial equations
4642 for (auto e : lits) {
4743 expr* x = nullptr , *y = nullptr ;
4844 if (m.is_eq (e, x, y) && var_set.is_marked (x) && is_pure (var_set, y)) {
4945 vars.erase (to_app (x));
5046 defs.push_back ({ expr_ref (x, m), expr_ref (y, m) });
51- has_def = true ;
5247 }
5348 else if (m.is_eq (e, y, x) && var_set.is_marked (x) && is_pure (var_set, y)) {
5449 vars.erase (to_app (x));
5550 defs.push_back ({ expr_ref (x, m), expr_ref (y, m) });
56- has_def = true ;
5751 }
5852 }
59- if (has_def)
60- return true ;
61- #endif
53+ }
54+
55+ bool euf_project_plugin::project (model& model, app_ref_vector& vars, expr_ref_vector& lits, vector<def>& defs) {
56+ if (vars.empty ())
57+ return false ;
58+ unsigned sz = defs.size ();
59+ while (true ) {
60+ unsigned sz1 = defs.size ();
61+ solve_eqs (model, vars, lits, defs);
62+ if (sz1 == defs.size ())
63+ break ;
64+ }
6265
66+ if (sz < defs.size ())
67+ return true ;
68+
6369 // check if there is a variable of uninterp sort
6470 if (all_of (vars, [&](expr* v) { return !m.is_uninterp (v->get_sort ()); }))
65- return has_def ;
71+ return false ;
6672
6773 term_graph tg (m);
6874 tg.add_lits (lits);
6975 for (auto v : vars)
7076 if (m.is_uninterp (v->get_sort ()))
7177 tg.add_var (v);
7278
73- //
74- // now what:
75- // / walk all subterms of lits.
76- // push in partitions by value.
77- // add equations from model
78- // compute repr from tg.
79- //
79+ expr_ref_vector terms (m);
80+ for (expr* f : subterms::all (lits))
81+ if (!m.is_bool (f))
82+ terms.push_back (f);
8083
84+
85+ // try to project on representatives:
86+ tg.add_model_based_terms (model, terms);
87+ unsigned j = 0 ;
88+ for (unsigned i = 0 ; i < vars.size (); ++i) {
89+ app* v = vars.get (i);
90+ if (m.is_uninterp (v->get_sort ())) {
91+ expr* r = tg.rep_of (v);
92+ if (r)
93+ defs.push_back ({ expr_ref (v, m), expr_ref (r, m) });
94+ else
95+ vars[j++] = v;
96+ }
97+ else
98+ vars[j++] = v;
99+ }
100+ vars.shrink (j);
101+
102+ if (sz < defs.size ())
103+ return true ;
81104
82- return has_def;
105+
106+ // walk equivalence classes.
107+ // try to unify with pure classes.
108+
109+
110+ // try to build a fresh term using available signature
111+
112+
113+ return false ;
83114 }
84115
85116}
0 commit comments