3131
3232static exprt substitute_array_with_expr (const exprt &expr, const exprt &index);
3333
34- static exprt instantiate (
35- messaget::mstreamt &stream,
36- const string_constraintt &axiom,
37- const exprt &str,
38- const exprt &val);
3934static bool is_char_array (const namespacet &ns, const typet &type);
4035
4136static bool is_valid_string_constraint (
@@ -71,7 +66,14 @@ static void initial_index_set(
7166 std::map<exprt, std::set<exprt>> &index_set,
7267 std::map<exprt, std::set<exprt>> ¤t_index_set,
7368 const namespacet &ns,
74- const std::vector<string_constraintt> &string_axioms);
69+ const string_not_contains_constraintt &axiom);
70+
71+ static void initial_index_set (
72+ std::map<exprt, std::set<exprt>> &index_set,
73+ std::map<exprt, std::set<exprt>> ¤t_index_set,
74+ const namespacet &ns,
75+ const std::vector<string_constraintt> &string_axioms,
76+ const std::vector<string_not_contains_constraintt> &nc_axioms);
7577
7678exprt simplify_sum (const exprt &f);
7779
@@ -87,9 +89,13 @@ static void update_index_set(
8789 const namespacet &ns,
8890 const exprt &formula);
8991
90- static std::vector< exprt> instantiate_not_contains (
92+ static exprt instantiate (
9193 messaget::mstreamt &stream,
92- const namespacet &ns,
94+ const string_constraintt &axiom,
95+ const exprt &str,
96+ const exprt &val);
97+
98+ static std::vector<exprt> instantiate (
9399 const string_not_contains_constraintt &axiom,
94100 const std::map<exprt, std::set<exprt>> &index_set,
95101 const std::map<exprt, std::set<exprt>> ¤t_index_set,
@@ -259,18 +265,28 @@ static void display_current_index_set(
259265
260266static std::vector<exprt> generate_instantiations (
261267 messaget::mstreamt &stream,
268+ const namespacet &ns,
269+ string_constraint_generatort &generator,
270+ const std::map<exprt, std::set<exprt>> &index_set,
262271 const std::map<exprt, std::set<exprt>> ¤t_index_set,
263- const std::vector<string_constraintt> &universal_axioms)
272+ const std::vector<string_constraintt> &universal_axioms,
273+ const std::vector<string_not_contains_constraintt> ¬_contains_axioms)
264274{
265275 std::vector<exprt> lemmas;
266276 for (const auto &i : current_index_set)
267277 {
268- for (const auto &ua : universal_axioms)
278+ for (const auto &univ_axiom : universal_axioms)
269279 {
270280 for (const auto &j : i.second )
271- lemmas.push_back (instantiate (stream, ua , i.first , j));
281+ lemmas.push_back (instantiate (stream, univ_axiom , i.first , j));
272282 }
273283 }
284+ for (const auto &nc_axiom : not_contains_axioms)
285+ {
286+ for (const auto &instance :
287+ instantiate (nc_axiom, index_set, current_index_set, generator))
288+ lemmas.push_back (instance);
289+ }
274290 return lemmas;
275291}
276292
@@ -766,11 +782,23 @@ decision_proceduret::resultt string_refinementt::dec_solve()
766782 return res;
767783 }
768784
769- initial_index_set (index_set, current_index_set, ns, universal_axioms);
785+ initial_index_set (
786+ index_set,
787+ current_index_set,
788+ ns,
789+ universal_axioms,
790+ not_contains_axioms);
770791 update_index_set (index_set, current_index_set, ns, current_constraints);
771792 current_constraints.clear ();
772793 for (const auto &instance :
773- generate_instantiations (debug (), current_index_set, universal_axioms))
794+ generate_instantiations (
795+ debug (),
796+ ns,
797+ generator,
798+ index_set,
799+ current_index_set,
800+ universal_axioms,
801+ not_contains_axioms))
774802 add_lemma (instance);
775803 display_current_index_set (debug (), ns, current_index_set);
776804
@@ -824,29 +852,19 @@ decision_proceduret::resultt string_refinementt::dec_solve()
824852 return resultt::D_ERROR;
825853 }
826854
855+ display_current_index_set (debug (), ns, current_index_set);
827856 display_index_set (debug (), ns, current_index_set, index_set);
828857 current_constraints.clear ();
829858 for (const auto &instance :
830859 generate_instantiations (
831- debug (), current_index_set, universal_axioms))
860+ debug (),
861+ ns,
862+ generator,
863+ index_set,
864+ current_index_set,
865+ universal_axioms,
866+ not_contains_axioms))
832867 add_lemma (instance);
833- display_current_index_set (debug (), ns, current_index_set);
834-
835- debug () << " instantiating NOT_CONTAINS constraints" << ' \n ' ;
836- for (unsigned i=0 ; i<not_contains_axioms.size (); i++)
837- {
838- debug () << " constraint " << i << ' \n ' ;
839- const std::vector<exprt> instances=
840- instantiate_not_contains (
841- debug (),
842- ns,
843- not_contains_axioms[i],
844- index_set,
845- current_index_set,
846- generator);
847- for (const exprt &instance : instances)
848- add_lemma (instance);
849- }
850868 }
851869 else
852870 {
@@ -1463,17 +1481,34 @@ static std::pair<bool, std::vector<exprt>> check_axioms(
14631481
14641482 exprt negaxiom=negation_of_not_contains_constraint (
14651483 nc_axiom_in_model, univ_var);
1466- stream << " (string_refinementt::check_axioms) Adding negated constraint: "
1467- << from_expr (ns, " " , negaxiom) << eom;
1468- substitute_array_access (negaxiom);
14691484
1470- if (const auto &witness=find_counter_example (ns, ui, negaxiom, univ_var))
1485+ stream << " " << i << " .\n "
1486+ << " - axiom:\n "
1487+ << " " << from_expr (ns, " " , nc_axiom) << ' \n ' ;
1488+ stream << " - axiom_in_model:\n "
1489+ << " " << from_expr (ns, " " , nc_axiom_in_model) << ' \n ' ;
1490+ stream << " - negated_axiom:\n "
1491+ << " " << from_expr (ns, " " , negaxiom) << ' \n ' ;
1492+
1493+ exprt with_concretized_arrays=concretize_arrays_in_expression (
1494+ negaxiom, max_string_length);
1495+ stream << " - negated_axiom_with_concretized_array_access:\n "
1496+ << " " << from_expr (ns, " " , with_concretized_arrays) << ' \n ' ;
1497+
1498+ substitute_array_access (with_concretized_arrays);
1499+ stream << " - negated_axiom_without_array_access:\n "
1500+ << " " << from_expr (ns, " " , with_concretized_arrays) << ' \n ' ;
1501+
1502+ if (const auto &witness=
1503+ find_counter_example (ns, ui, with_concretized_arrays, univ_var))
14711504 {
1472- stream << " string constraint can be violated for "
1505+ stream << " - violated_for: "
14731506 << univ_var.get_identifier ()
1474- << " =" << from_expr (ns, " " , *witness) << eom ;
1507+ << " =" << from_expr (ns, " " , *witness) << ' \n ' ;
14751508 violated_not_contains[i]=*witness;
14761509 }
1510+ else
1511+ stream << " - correct" << ' \n ' ;
14771512 }
14781513
14791514 if (violated.empty () && violated_not_contains.empty ())
@@ -1724,10 +1759,13 @@ static void initial_index_set(
17241759 std::map<exprt, std::set<exprt>> &index_set,
17251760 std::map<exprt, std::set<exprt>> ¤t_index_set,
17261761 const namespacet &ns,
1727- const std::vector<string_constraintt> &string_axioms)
1762+ const std::vector<string_constraintt> &string_axioms,
1763+ const std::vector<string_not_contains_constraintt> &nc_axioms)
17281764{
17291765 for (const auto &axiom : string_axioms)
17301766 initial_index_set (index_set, current_index_set, ns, axiom);
1767+ for (const auto &axiom : nc_axioms)
1768+ initial_index_set (index_set, current_index_set, ns, axiom);
17311769}
17321770
17331771// / add to the index set all the indices that appear in the formulas
@@ -1829,6 +1867,41 @@ static void initial_index_set(
18291867 }
18301868}
18311869
1870+ static void initial_index_set (
1871+ std::map<exprt, std::set<exprt>> &index_set,
1872+ std::map<exprt, std::set<exprt>> ¤t_index_set,
1873+ const namespacet &ns,
1874+ const string_not_contains_constraintt &axiom)
1875+ {
1876+ auto it=axiom.premise ().depth_begin ();
1877+ const auto end=axiom.premise ().depth_end ();
1878+ while (it!=end)
1879+ {
1880+ if (it->id ()==ID_index)
1881+ {
1882+ const exprt &s=it->op0 ();
1883+ const exprt &i=it->op1 ();
1884+
1885+ // cur is of the form s[i] and no quantified variable appears in i
1886+ add_to_index_set (index_set, current_index_set, ns, s, i);
1887+
1888+ it.next_sibling_or_parent ();
1889+ }
1890+ else
1891+ ++it;
1892+ }
1893+
1894+ minus_exprt kminus1 (
1895+ axiom.exists_upper_bound (),
1896+ from_integer (1 , axiom.exists_upper_bound ().type ()));
1897+ add_to_index_set (
1898+ index_set,
1899+ current_index_set,
1900+ ns,
1901+ axiom.s1 ().content (),
1902+ kminus1);
1903+ }
1904+
18321905// / add to the index set all the indices that appear in the formula
18331906// / \par parameters: a string constraint
18341907static void update_index_set (
@@ -1938,9 +2011,7 @@ static exprt instantiate(
19382011// / substituting the quantifiers and generating axioms.
19392012// / \param [in] axiom: the axiom to instantiate
19402013// / \return the lemmas produced through instantiation
1941- static std::vector<exprt> instantiate_not_contains (
1942- messaget::mstreamt &stream,
1943- const namespacet &ns,
2014+ static std::vector<exprt> instantiate (
19442015 const string_not_contains_constraintt &axiom,
19452016 const std::map<exprt, std::set<exprt>> &index_set,
19462017 const std::map<exprt, std::set<exprt>> ¤t_index_set,
@@ -1949,9 +2020,6 @@ static std::vector<exprt> instantiate_not_contains(
19492020 const string_exprt &s0=axiom.s0 ();
19502021 const string_exprt &s1=axiom.s1 ();
19512022
1952- stream << " instantiate not contains " << from_expr (ns, " " , s0) << " : "
1953- << from_expr (ns, " " , s1) << messaget::eom;
1954-
19552023 const auto &index_set0=index_set.find (s0.content ());
19562024 const auto &index_set1=index_set.find (s1.content ());
19572025 const auto ¤t_index_set0=current_index_set.find (s0.content ());
0 commit comments