Skip to content

Commit 9fa9aa0

Browse files
fix #2468, adding assignment phase heuristic
Signed-off-by: Nikolaj Bjorner <[email protected]>
1 parent 42e2145 commit 9fa9aa0

19 files changed

+268
-79
lines changed

src/ast/array_decl_plugin.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,10 @@ class array_util : public array_recognizers {
210210
return r;
211211
}
212212

213+
app * mk_default(expr * a) {
214+
return m_manager.mk_app(m_fid, OP_ARRAY_DEFAULT, 0, nullptr, 1, &a);
215+
}
216+
213217
app * mk_const_array(sort * s, expr * v) {
214218
parameter param(s);
215219
return m_manager.mk_app(m_fid, OP_CONST_ARRAY, 1, &param, 1, &v);
@@ -251,6 +255,14 @@ class array_util : public array_recognizers {
251255
parameter param(f);
252256
return m_manager.mk_app(m_fid, OP_AS_ARRAY, 1, &param, 0, nullptr, nullptr);
253257
}
258+
259+
sort* get_array_range_rec(sort* s) {
260+
while (is_array(s)) {
261+
s = get_array_range(s);
262+
}
263+
return s;
264+
}
265+
254266
};
255267

256268

src/ast/datatype_decl_plugin.cpp

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,19 @@ namespace datatype {
450450
m_manager->raise_exception("datatype is not co-variant");
451451
}
452452

453+
array_util autil(m);
454+
for (sort* s : sorts) {
455+
for (constructor const* c : get_def(s)) {
456+
for (accessor const* a : *c) {
457+
if (autil.is_array(a->range())) {
458+
if (sorts.contains(get_array_range(a->range()))) {
459+
m_has_nested_arrays = true;
460+
}
461+
}
462+
}
463+
}
464+
}
465+
453466
u().compute_datatype_size_functions(m_def_block);
454467
for (symbol const& s : m_def_block) {
455468
sort_ref_vector ps(m);
@@ -892,10 +905,13 @@ namespace datatype {
892905
for (unsigned i = 0; i < n; ++i) {
893906
get_subsorts(get_array_domain(s, i), subsorts);
894907
}
908+
if (!is_datatype(get_array_range(s))) {
909+
get_subsorts(get_array_range(s), subsorts);
910+
}
895911
for (sort* r : subsorts) {
896912
if (mark.is_marked(r)) return false;
897913
}
898-
return is_covariant(mark, subsorts, get_array_range(s));
914+
return true;
899915
}
900916

901917
def const& util::get_def(sort* s) const {
@@ -1115,6 +1131,7 @@ namespace datatype {
11151131

11161132
ptr_vector<func_decl> const& constructors = *get_datatype_constructors(ty);
11171133
unsigned sz = constructors.size();
1134+
array_util autil(m);
11181135
TRACE("util_bug", tout << "get-non-rec constructor: " << sort_ref(ty, m) << "\n";
11191136
tout << "forbidden: ";
11201137
for (sort* s : forbidden_set) tout << sort_ref(s, m) << " ";
@@ -1129,7 +1146,7 @@ namespace datatype {
11291146
TRACE("util_bug", tout << "checking " << sort_ref(ty, m) << ": " << func_decl_ref(c, m) << "\n";);
11301147
unsigned num_args = c->get_arity();
11311148
unsigned i = 0;
1132-
for (; i < num_args && !is_datatype(c->get_domain(i)); i++);
1149+
for (; i < num_args && !is_datatype(autil.get_array_range_rec(c->get_domain(i))); i++);
11331150
if (i == num_args) {
11341151
TRACE("util_bug", tout << "found non-rec " << func_decl_ref(c, m) << "\n";);
11351152
return c;
@@ -1142,7 +1159,7 @@ namespace datatype {
11421159
unsigned num_args = c->get_arity();
11431160
unsigned i = 0;
11441161
for (; i < num_args; i++) {
1145-
sort * T_i = c->get_domain(i);
1162+
sort * T_i = autil.get_array_range_rec(c->get_domain(i));
11461163
TRACE("util_bug", tout << "c: " << i << " " << sort_ref(T_i, m) << "\n";);
11471164
if (!is_datatype(T_i)) {
11481165
TRACE("util_bug", tout << sort_ref(T_i, m) << " is not a datatype\n";);

src/ast/datatype_decl_plugin.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,13 +210,14 @@ namespace datatype {
210210
unsigned m_id_counter;
211211
svector<symbol> m_def_block;
212212
unsigned m_class_id;
213+
mutable bool m_has_nested_arrays;
213214

214215
void inherit(decl_plugin* other_p, ast_translation& tr) override;
215216

216217
void log_axiom_definitions(symbol const& s, sort * new_sort);
217218

218219
public:
219-
plugin(): m_id_counter(0), m_class_id(0) {}
220+
plugin(): m_id_counter(0), m_class_id(0), m_has_nested_arrays(false) {}
220221
~plugin() override;
221222

222223
void finalize() override;
@@ -254,6 +255,8 @@ namespace datatype {
254255
unsigned get_axiom_base_id(symbol const& s) { return m_axiom_bases[s]; }
255256
util & u() const;
256257

258+
bool has_nested_arrays() const { return m_has_nested_arrays; }
259+
257260
private:
258261
bool is_value_visit(expr * arg, ptr_buffer<app> & todo) const;
259262

@@ -353,6 +356,7 @@ namespace datatype {
353356
func_decl * get_accessor_constructor(func_decl * accessor);
354357
func_decl * get_recognizer_constructor(func_decl * recognizer) const;
355358
func_decl * get_update_accessor(func_decl * update) const;
359+
bool has_nested_arrays() const { return m_plugin->has_nested_arrays(); }
356360
family_id get_family_id() const { return m_family_id; }
357361
bool are_siblings(sort * s1, sort * s2);
358362
bool is_func_decl(op_kind k, unsigned num_params, parameter const* params, func_decl* f);

src/smt/params/smt_params.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ enum phase_selection {
3939
PS_CACHING_CONSERVATIVE,
4040
PS_CACHING_CONSERVATIVE2, // similar to the previous one, but alternated default config from time to time.
4141
PS_RANDOM,
42-
PS_OCCURRENCE
42+
PS_OCCURRENCE,
43+
PS_THEORY
4344
};
4445

4546
enum restart_strategy {

src/smt/params/smt_params_helper.pyg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ def_module_params(module_name='smt',
1010
('quasi_macros', BOOL, False, 'try to find universally quantified formulas that are quasi-macros'),
1111
('restricted_quasi_macros', BOOL, False, 'try to find universally quantified formulas that are restricted quasi-macros'),
1212
('ematching', BOOL, True, 'E-Matching based quantifier instantiation'),
13-
('phase_selection', UINT, 3, 'phase selection heuristic: 0 - always false, 1 - always true, 2 - phase caching, 3 - phase caching conservative, 4 - phase caching conservative 2, 5 - random, 6 - number of occurrences'),
13+
('phase_selection', UINT, 3, 'phase selection heuristic: 0 - always false, 1 - always true, 2 - phase caching, 3 - phase caching conservative, 4 - phase caching conservative 2, 5 - random, 6 - number of occurrences, 7 - theory'),
1414
('restart_strategy', UINT, 1, '0 - geometric, 1 - inner-outer-geometric, 2 - luby, 3 - fixed, 4 - arithmetic'),
1515
('restart_factor', DOUBLE, 1.1, 'when using geometric (or inner-outer-geometric) progression of restarts, it specifies the constant used to multiply the current restart threshold'),
1616
('case_split', UINT, 1, '0 - case split based on variable activity, 1 - similar to 0, but delay case splits created during the search, 2 - similar to 0, but cache the relevancy, 3 - case split based on relevancy (structural splitting), 4 - case split on relevancy and activity, 5 - case split on relevancy and current goal, 6 - activity-based case split with theory-aware branching activity'),

src/smt/smt_arith_value.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Revision History:
1717
1818
--*/
1919

20+
#include "ast/ast_pp.h"
2021
#include "smt/smt_arith_value.h"
2122

2223
namespace smt {
@@ -50,6 +51,7 @@ namespace smt {
5051
next = next->get_next();
5152
}
5253
while (n != next);
54+
CTRACE("arith_value", !found, tout << "value not found for " << mk_pp(e, m_ctx->get_manager()) << "\n";);
5355
return found;
5456
}
5557

@@ -69,6 +71,7 @@ namespace smt {
6971
next = next->get_next();
7072
}
7173
while (n != next);
74+
CTRACE("arith_value", !found, tout << "value not found for " << mk_pp(e, m_ctx->get_manager()) << "\n";);
7275
return found;
7376
}
7477

@@ -79,6 +82,7 @@ namespace smt {
7982
if (m_tha) return m_tha->get_upper(n, up, is_strict);
8083
if (m_thi) return m_thi->get_upper(n, up, is_strict);
8184
if (m_thr) return m_thr->get_upper(n, up, is_strict);
85+
TRACE("arith_value", tout << "value not found for " << mk_pp(e, m_ctx->get_manager()) << "\n";);
8286
return false;
8387
}
8488

@@ -89,6 +93,7 @@ namespace smt {
8993
if (m_tha) return m_tha->get_lower(n, up, is_strict);
9094
if (m_thi) return m_thi->get_lower(n, up, is_strict);
9195
if (m_thr) return m_thr->get_lower(n, up, is_strict);
96+
TRACE("arith_value", tout << "value not found for " << mk_pp(e, m_ctx->get_manager()) << "\n";);
9297
return false;
9398
}
9499

@@ -99,6 +104,7 @@ namespace smt {
99104
if (m_tha && m_tha->get_value(n, _val) && a.is_numeral(_val, val)) return true;
100105
if (m_thi && m_thi->get_value(n, _val) && a.is_numeral(_val, val)) return true;
101106
if (m_thr && m_thr->get_value(n, val)) return true;
107+
TRACE("arith_value", tout << "value not found for " << mk_pp(e, m_ctx->get_manager()) << "\n";);
102108
return false;
103109
}
104110

@@ -115,6 +121,7 @@ namespace smt {
115121
next = next->get_next();
116122
}
117123
while (next != n);
124+
TRACE("arith_value", tout << "value not found for " << mk_pp(e, m_ctx->get_manager()) << "\n";);
118125
return false;
119126
}
120127

src/smt/smt_context.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1849,6 +1849,16 @@ namespace smt {
18491849
}
18501850
else {
18511851
switch (m_fparams.m_phase_selection) {
1852+
case PS_THEORY:
1853+
if (d.is_theory_atom()) {
1854+
theory * th = m_theories.get_plugin(d.get_theory());
1855+
lbool ph = th->get_phase(var);
1856+
if (ph != l_undef) {
1857+
is_pos = ph == l_true;
1858+
break;
1859+
}
1860+
}
1861+
Z3_fallthrough;
18521862
case PS_CACHING:
18531863
case PS_CACHING_CONSERVATIVE:
18541864
case PS_CACHING_CONSERVATIVE2:

0 commit comments

Comments
 (0)