Skip to content

Commit e67f326

Browse files
committed
TG-672 Added universal constraint counter-examples, assumed fix-point with no not contains constraints is equi-SAT
1 parent 72a537a commit e67f326

File tree

1 file changed

+40
-10
lines changed

1 file changed

+40
-10
lines changed

src/solvers/refinement/string_refinement.cpp

+40-10
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ static void display_index_set(
233233
static std::vector<exprt> generate_instantiations(
234234
messaget::mstreamt &stream,
235235
const namespacet &ns,
236-
string_constraint_generatort &generator,
236+
const string_constraint_generatort &generator,
237237
const index_set_pairt &index_set,
238238
const string_axiomst &axioms)
239239
{
@@ -638,10 +638,7 @@ decision_proceduret::resultt string_refinementt::dec_solve()
638638
return res;
639639
}
640640

641-
initial_index_set(
642-
index_sets,
643-
ns,
644-
axioms);
641+
initial_index_set(index_sets, ns, axioms);
645642
update_index_set(index_sets, ns, current_constraints);
646643
display_index_set(debug(), ns, index_sets);
647644
current_constraints.clear();
@@ -700,7 +697,21 @@ decision_proceduret::resultt string_refinementt::dec_solve()
700697
if(index_sets.current.empty())
701698
{
702699
debug() << "current index set is empty" << eom;
703-
return resultt::D_ERROR;
700+
if(axioms.not_contains.empty())
701+
{
702+
debug() << "no not_contains axioms, hence SAT" << eom;
703+
concretize_lengths(
704+
found_length,
705+
get,
706+
symbol_resolve,
707+
generator.get_created_strings());
708+
return resultt::D_SATISFIABLE;
709+
}
710+
else
711+
{
712+
debug() << "not_contains axioms exist, hence ERROR" << eom;
713+
return resultt::D_ERROR;
714+
}
704715
}
705716

706717
display_index_set(debug(), ns, index_sets);
@@ -1373,9 +1384,28 @@ static std::pair<bool, std::vector<exprt>> check_axioms(
13731384
if(use_counter_example)
13741385
{
13751386
stream << "Adding counter-examples: " << eom;
1376-
// TODO: add counter-examples for universal constraints?
13771387

13781388
std::vector<exprt> lemmas;
1389+
1390+
for(const auto &v : violated)
1391+
{
1392+
const exprt &val=v.second;
1393+
const string_constraintt &axiom=axioms.universal[v.first];
1394+
1395+
implies_exprt instance(axiom.premise(), axiom.body());
1396+
replace_expr(axiom.univ_var(), val, instance);
1397+
// We are not sure the index set contains only positive numbers
1398+
exprt bounds=and_exprt(
1399+
axiom.univ_within_bounds(),
1400+
binary_relation_exprt(
1401+
from_integer(0, val.type()), ID_le, val));
1402+
replace_expr(axiom.univ_var(), val, bounds);
1403+
const implies_exprt counter(bounds, instance);
1404+
1405+
stream << " - " << from_expr(ns, "", counter) << eom;
1406+
lemmas.push_back(counter);
1407+
}
1408+
13791409
for(const auto &v : violated_not_contains)
13801410
{
13811411
const exprt &val=v.second;
@@ -1390,7 +1420,7 @@ static std::pair<bool, std::vector<exprt>> check_axioms(
13901420
const exprt counter=::instantiate_not_contains(
13911421
axiom, indices, generator)[0];
13921422

1393-
stream << " - " << from_expr(ns, "", counter) << eom;
1423+
stream << " - " << from_expr(ns, "", counter) << eom;
13941424
lemmas.push_back(counter);
13951425
}
13961426
return { false, lemmas };
@@ -1696,7 +1726,7 @@ static void initial_index_set(
16961726
{
16971727
// otherwise we add k-1
16981728
exprt e(i);
1699-
minus_exprt kminus1(
1729+
const minus_exprt kminus1(
17001730
axiom.upper_bound(),
17011731
from_integer(1, axiom.upper_bound().type()));
17021732
replace_expr(qvar, kminus1, e);
@@ -1732,7 +1762,7 @@ static void initial_index_set(
17321762
++it;
17331763
}
17341764

1735-
minus_exprt kminus1(
1765+
const minus_exprt kminus1(
17361766
axiom.exists_upper_bound(),
17371767
from_integer(1, axiom.exists_upper_bound().type()));
17381768
add_to_index_set(index_set, ns, axiom.s1().content(), kminus1);

0 commit comments

Comments
 (0)