Skip to content

Commit 45af45d

Browse files
committed
TG-672 Uniformity in algorithm for treatement of universal and not contains constraints
1 parent dd03003 commit 45af45d

File tree

1 file changed

+112
-44
lines changed

1 file changed

+112
-44
lines changed

src/solvers/refinement/string_refinement.cpp

+112-44
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,6 @@ Author: Alberto Griggio, [email protected]
3131

3232
static 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);
3934
static bool is_char_array(const namespacet &ns, const typet &type);
4035

4136
static 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>> &current_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>> &current_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

7678
exprt 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>> &current_index_set,
@@ -259,18 +265,28 @@ static void display_current_index_set(
259265

260266
static 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>> &current_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> &not_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>> &current_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>> &current_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
18341907
static 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>> &current_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 &current_index_set0=current_index_set.find(s0.content());

0 commit comments

Comments
 (0)