Skip to content

Commit b143a95

Browse files
add notes and additional functions to sls-seq
Signed-off-by: Nikolaj Bjorner <[email protected]>
1 parent aed3279 commit b143a95

File tree

5 files changed

+122
-24
lines changed

5 files changed

+122
-24
lines changed

src/ast/sls/sls_arith_base.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1952,6 +1952,8 @@ namespace sls {
19521952
for (unsigned j = i + 1; j < args.get_num_args(); ++j) {
19531953
auto v1 = mk_term(args.get_arg(i));
19541954
auto v2 = mk_term(args.get_arg(j));
1955+
verbose_stream() << "repair " << v1 << " " << v2 << " "
1956+
<< value(v1) << " " << value(v2) << "\n";
19551957
if (value(v1) == value(v2)) {
19561958
auto new_value = value(v1) + num_t(1);
19571959
if (new_value == value(v2))

src/ast/sls/sls_seq_plugin.cpp

Lines changed: 102 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,19 @@ Alternate to lookahead strategy:
7272
Revert bias on long strings:
7373
- give preference to reset leaves that are assigned to long strings
7474
- bake in bias for shorter strings into equation solving?
75+
76+
Equality solving using stochastic Nelson.
77+
- Given equality where current assignment does not satisfy it:
78+
- Xw = v:
79+
- let X' range over prefixes of X that matches v.
80+
- non-deterministic set X <- strval0(X')
81+
- non-deterministic set X <- strval0(X') + 'a' where strval0(X') + 'a' matches prefix of strval0(v), and X' is longest prefix of X that matches v.
82+
- If X fully matches a prefix of v, then, in addition to the rules above:
83+
- consume constant character from strval0(X)w = v
84+
- reveal the next variable to solve for.
85+
86+
- What scores make sense to use for partial solutions?
87+
7588
--*/
7689

7790
#include "ast/sls/sls_seq_plugin.h"
@@ -411,23 +424,29 @@ namespace sls {
411424
if (m.is_bool(e))
412425
return;
413426

414-
if (seq.is_string(e->get_sort())) {
415-
if (is_value(e))
416-
return;
417-
strval0(e) = strval1(e);
418-
ctx.new_value_eh(e);
427+
if (seq.str.is_itos(e)) {
428+
repair_up_str_itos(e);
429+
return;
430+
}
431+
if (seq.str.is_stoi(e)) {
432+
repair_up_str_stoi(e);
419433
return;
420434
}
421-
422435
if (seq.str.is_length(e)) {
423436
repair_up_str_length(e);
424437
return;
425438
}
426-
427439
if (seq.str.is_index(e)) {
428440
repair_up_str_indexof(e);
429441
return;
430442
}
443+
if (seq.is_string(e->get_sort())) {
444+
if (is_value(e))
445+
return;
446+
strval0(e) = strval1(e);
447+
ctx.new_value_eh(e);
448+
return;
449+
}
431450

432451
verbose_stream() << "repair up nyi: " << mk_bounded_pp(e, m) << "\n";
433452
}
@@ -471,6 +490,35 @@ namespace sls {
471490
return apply_update();
472491
}
473492

493+
void seq_plugin::repair_up_str_stoi(app* e) {
494+
expr* x;
495+
VERIFY(seq.str.is_stoi(e, x));
496+
497+
rational val_e;
498+
rational val_x(strval0(x).encode().c_str());
499+
VERIFY(a.is_numeral(ctx.get_value(e), val_e));
500+
if (val_e.is_unsigned() && val_e == val_x)
501+
return;
502+
if (val_x < 0)
503+
update(e, rational(0));
504+
else
505+
update(e, val_x);
506+
}
507+
508+
void seq_plugin::repair_up_str_itos(app* e) {
509+
expr* x;
510+
VERIFY(seq.str.is_itos(e, x));
511+
rational val_x;
512+
VERIFY(a.is_numeral(ctx.get_value(x), val_x));
513+
rational val_e(strval0(e).encode().c_str());
514+
if (val_x.is_unsigned() && val_x == val_e)
515+
return;
516+
if (val_x < 0)
517+
update(e, zstring());
518+
else
519+
update(e, zstring(val_x.to_string()));
520+
}
521+
474522
void seq_plugin::repair_up_str_length(app* e) {
475523
expr* x;
476524
VERIFY(seq.str.is_length(e, x));
@@ -566,21 +614,33 @@ namespace sls {
566614
if (seq.is_string(to_app(e)->get_arg(0)->get_sort()))
567615
return repair_down_str_indexof(e);
568616
break;
617+
case OP_STRING_CONST:
618+
UNREACHABLE();
619+
break;
620+
case OP_STRING_ITOS:
621+
return repair_down_str_itos(e);
622+
case OP_STRING_STOI:
623+
return repair_down_str_stoi(e);
624+
case OP_STRING_UBVTOS:
625+
case OP_STRING_SBVTOS:
626+
case OP_STRING_TO_CODE:
627+
case OP_STRING_FROM_CODE:
569628
case OP_SEQ_UNIT:
570-
case OP_SEQ_REPLACE:
571629
case OP_SEQ_NTH:
572630
case OP_SEQ_NTH_I:
573631
case OP_SEQ_NTH_U:
574-
case OP_SEQ_LAST_INDEX:
575-
case OP_SEQ_TO_RE:
576-
case OP_SEQ_IN_RE:
632+
case OP_SEQ_REPLACE:
577633
case OP_SEQ_REPLACE_RE_ALL:
578634
case OP_SEQ_REPLACE_RE:
579635
case OP_SEQ_REPLACE_ALL:
580636
case OP_SEQ_MAP:
581637
case OP_SEQ_MAPI:
582638
case OP_SEQ_FOLDL:
583-
case OP_SEQ_FOLDLI:
639+
case OP_SEQ_FOLDLI:
640+
641+
case OP_SEQ_TO_RE:
642+
case OP_SEQ_IN_RE:
643+
584644
case OP_RE_PLUS:
585645
case OP_RE_STAR:
586646
case OP_RE_OPTION:
@@ -598,23 +658,43 @@ namespace sls {
598658
case OP_RE_OF_PRED:
599659
case OP_RE_REVERSE:
600660
case OP_RE_DERIVATIVE:
601-
case OP_STRING_CONST:
602-
case OP_STRING_ITOS:
603-
case OP_STRING_STOI:
604-
case OP_STRING_UBVTOS:
605-
case OP_STRING_SBVTOS:
606661
case OP_STRING_LT:
607662
case OP_STRING_LE:
608-
case OP_STRING_IS_DIGIT:
609-
case OP_STRING_TO_CODE:
610-
case OP_STRING_FROM_CODE:
611-
default:
612-
break;
663+
case OP_STRING_IS_DIGIT:
664+
break;
665+
default:
666+
verbose_stream() << "unexpected repair down " << mk_bounded_pp(e, m) << "\n";
667+
UNREACHABLE();
613668
}
614669
verbose_stream() << "nyi repair down " << mk_bounded_pp(e, m) << "\n";
615670
return false;
616671
}
617672

673+
bool seq_plugin::repair_down_str_itos(app* e) {
674+
expr* x;
675+
VERIFY(seq.str.is_itos(e, x));
676+
zstring se = strval0(e);
677+
rational r(se.encode().c_str());
678+
if (r.is_int())
679+
m_int_updates.push_back({ x, r, 1 });
680+
else
681+
m_int_updates.push_back({ x, rational(-1 - ctx.rand(10)), 1 });
682+
683+
return apply_update();
684+
}
685+
686+
bool seq_plugin::repair_down_str_stoi(app* e) {
687+
expr* x;
688+
rational r;
689+
VERIFY(seq.str.is_stoi(e, x));
690+
VERIFY(a.is_numeral(ctx.get_value(e), r) && r.is_int());
691+
if (r < 0)
692+
return false;
693+
zstring r_val(r.to_string());
694+
m_str_updates.push_back({ x, r_val, 1 });
695+
return apply_update();
696+
}
697+
618698
bool seq_plugin::repair_down_str_at(app* e) {
619699
expr* x, * y;
620700
VERIFY(seq.str.is_at(e, x, y));

src/ast/sls/sls_seq_plugin.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,13 @@ namespace sls {
7979
bool repair_down_str_replace(app* e);
8080
bool repair_down_str_prefixof(app* e);
8181
bool repair_down_str_suffixof(app* e);
82+
bool repair_down_str_itos(app* e);
83+
bool repair_down_str_stoi(app* e);
8284

8385
void repair_up_str_length(app* e);
8486
void repair_up_str_indexof(app* e);
87+
void repair_up_str_itos(app* e);
88+
void repair_up_str_stoi(app* e);
8589

8690

8791
bool is_seq_predicate(expr* e);

src/smt/theory_sls.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ namespace smt {
7676
return ctx.get_num_bool_vars();
7777
}
7878

79+
void theory_sls::init_search_eh() {
80+
m_init_search = true;
81+
}
82+
7983
void theory_sls::finalize() {
8084
if (!m_smt_plugin)
8185
return;
@@ -84,11 +88,14 @@ namespace smt {
8488
m_smt_plugin->finalize(m_model);
8589
m_model = nullptr;
8690
m_smt_plugin = nullptr;
91+
m_init_search = false;
8792
}
8893

8994
void theory_sls::propagate() {
90-
if (!m_smt_plugin)
95+
if (!m_init_search)
9196
return;
97+
if (!m_smt_plugin)
98+
m_smt_plugin = alloc(sls::smt_plugin, * this);
9299
if (!m_checking) {
93100
expr_ref_vector fmls(m);
94101
for (unsigned i = 0; i < ctx.get_num_asserted_formulas(); ++i)
@@ -104,6 +111,7 @@ namespace smt {
104111
m_smt_plugin->collect_statistics(m_st);
105112
m_smt_plugin->finalize(m_model);
106113
m_smt_plugin = nullptr;
114+
m_init_search = false;
107115
}
108116
}
109117

@@ -183,8 +191,9 @@ namespace smt {
183191
finalize();
184192
smt_params p(ctx.get_fparams());
185193
m_parallel_mode = p.m_sls_parallel;
186-
m_smt_plugin = alloc(sls::smt_plugin, *this);
194+
m_smt_plugin = nullptr;
187195
m_checking = false;
196+
m_init_search = false;
188197
}
189198

190199
void theory_sls::collect_statistics(::statistics& st) const {
@@ -216,6 +225,7 @@ namespace smt {
216225
m_smt_plugin->collect_statistics(m_st);
217226
m_smt_plugin->finalize(m_model);
218227
m_smt_plugin = nullptr;
228+
m_init_search = false;
219229
}
220230
}
221231

src/smt/theory_sls.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ namespace smt {
7272
unsigned m_after_resolve_decide_count = 0;
7373
unsigned m_resolve_count = 0;
7474
unsigned m_resolve_gap = 0;
75+
bool m_init_search = false;
7576
::statistics m_st;
7677
vector<sat::literal_vector> m_shared_clauses;
7778

@@ -125,6 +126,7 @@ namespace smt {
125126
void inc_activity(sat::bool_var v, double inc) override;
126127
bool parallel_mode() const override { return m_parallel_mode; }
127128
bool get_smt_value(expr* v, expr_ref& value) override;
129+
void init_search_eh() override;
128130

129131
};
130132

0 commit comments

Comments
 (0)