@@ -233,7 +233,7 @@ static void display_index_set(
233233static 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