31
31
32
32
static exprt substitute_array_with_expr (const exprt &expr, const exprt &index);
33
33
34
- static exprt instantiate (
35
- messaget::mstreamt &stream,
36
- const string_constraintt &axiom,
37
- const exprt &str,
38
- const exprt &val);
39
34
static bool is_char_array (const namespacet &ns, const typet &type);
40
35
41
36
static bool is_valid_string_constraint (
@@ -71,7 +66,14 @@ static void initial_index_set(
71
66
std::map<exprt, std::set<exprt>> &index_set,
72
67
std::map<exprt, std::set<exprt>> ¤t_index_set,
73
68
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);
75
77
76
78
exprt simplify_sum (const exprt &f);
77
79
@@ -87,9 +89,13 @@ static void update_index_set(
87
89
const namespacet &ns,
88
90
const exprt &formula);
89
91
90
- static std::vector< exprt> instantiate_not_contains (
92
+ static exprt instantiate (
91
93
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 (
93
99
const string_not_contains_constraintt &axiom,
94
100
const std::map<exprt, std::set<exprt>> &index_set,
95
101
const std::map<exprt, std::set<exprt>> ¤t_index_set,
@@ -259,18 +265,28 @@ static void display_current_index_set(
259
265
260
266
static std::vector<exprt> generate_instantiations (
261
267
messaget::mstreamt &stream,
268
+ const namespacet &ns,
269
+ string_constraint_generatort &generator,
270
+ const std::map<exprt, std::set<exprt>> &index_set,
262
271
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)
264
274
{
265
275
std::vector<exprt> lemmas;
266
276
for (const auto &i : current_index_set)
267
277
{
268
- for (const auto &ua : universal_axioms)
278
+ for (const auto &univ_axiom : universal_axioms)
269
279
{
270
280
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));
272
282
}
273
283
}
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
+ }
274
290
return lemmas;
275
291
}
276
292
@@ -766,11 +782,23 @@ decision_proceduret::resultt string_refinementt::dec_solve()
766
782
return res;
767
783
}
768
784
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);
770
791
update_index_set (index_set, current_index_set, ns, current_constraints);
771
792
current_constraints.clear ();
772
793
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))
774
802
add_lemma (instance);
775
803
display_current_index_set (debug (), ns, current_index_set);
776
804
@@ -824,29 +852,19 @@ decision_proceduret::resultt string_refinementt::dec_solve()
824
852
return resultt::D_ERROR;
825
853
}
826
854
855
+ display_current_index_set (debug (), ns, current_index_set);
827
856
display_index_set (debug (), ns, current_index_set, index_set);
828
857
current_constraints.clear ();
829
858
for (const auto &instance :
830
859
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))
832
867
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
- }
850
868
}
851
869
else
852
870
{
@@ -1463,17 +1481,34 @@ static std::pair<bool, std::vector<exprt>> check_axioms(
1463
1481
1464
1482
exprt negaxiom=negation_of_not_contains_constraint (
1465
1483
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);
1469
1484
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))
1471
1504
{
1472
- stream << " string constraint can be violated for "
1505
+ stream << " - violated_for: "
1473
1506
<< univ_var.get_identifier ()
1474
- << " =" << from_expr (ns, " " , *witness) << eom ;
1507
+ << " =" << from_expr (ns, " " , *witness) << ' \n ' ;
1475
1508
violated_not_contains[i]=*witness;
1476
1509
}
1510
+ else
1511
+ stream << " - correct" << ' \n ' ;
1477
1512
}
1478
1513
1479
1514
if (violated.empty () && violated_not_contains.empty ())
@@ -1724,10 +1759,13 @@ static void initial_index_set(
1724
1759
std::map<exprt, std::set<exprt>> &index_set,
1725
1760
std::map<exprt, std::set<exprt>> ¤t_index_set,
1726
1761
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)
1728
1764
{
1729
1765
for (const auto &axiom : string_axioms)
1730
1766
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);
1731
1769
}
1732
1770
1733
1771
// / add to the index set all the indices that appear in the formulas
@@ -1829,6 +1867,41 @@ static void initial_index_set(
1829
1867
}
1830
1868
}
1831
1869
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
+
1832
1905
// / add to the index set all the indices that appear in the formula
1833
1906
// / \par parameters: a string constraint
1834
1907
static void update_index_set (
@@ -1938,9 +2011,7 @@ static exprt instantiate(
1938
2011
// / substituting the quantifiers and generating axioms.
1939
2012
// / \param [in] axiom: the axiom to instantiate
1940
2013
// / \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 (
1944
2015
const string_not_contains_constraintt &axiom,
1945
2016
const std::map<exprt, std::set<exprt>> &index_set,
1946
2017
const std::map<exprt, std::set<exprt>> ¤t_index_set,
@@ -1949,9 +2020,6 @@ static std::vector<exprt> instantiate_not_contains(
1949
2020
const string_exprt &s0=axiom.s0 ();
1950
2021
const string_exprt &s1=axiom.s1 ();
1951
2022
1952
- stream << " instantiate not contains " << from_expr (ns, " " , s0) << " : "
1953
- << from_expr (ns, " " , s1) << messaget::eom;
1954
-
1955
2023
const auto &index_set0=index_set.find (s0.content ());
1956
2024
const auto &index_set1=index_set.find (s1.content ());
1957
2025
const auto ¤t_index_set0=current_index_set.find (s0.content ());
0 commit comments