Skip to content

Commit d43f9b5

Browse files
committed
Added string_constraintt invariant checking
Updated the documentation to explicitly state the invariants (and turned on MathJax in Doxygen). Created a function to check the invariant and added a check in `string_refinementt::dec_solve`.
1 parent 9f4179f commit d43f9b5

File tree

5 files changed

+230
-46
lines changed

5 files changed

+230
-46
lines changed

src/doxyfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1473,7 +1473,7 @@ FORMULA_TRANSPARENT = YES
14731473
# The default value is: NO.
14741474
# This tag requires that the tag GENERATE_HTML is set to YES.
14751475

1476-
USE_MATHJAX = NO
1476+
USE_MATHJAX = YES
14771477

14781478
# When MathJax is enabled you can set the default output format to be used for
14791479
# the MathJax output. See the MathJax site (see:

src/solvers/refinement/string_constraint.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,30 @@ Author: Romain Brenguier, [email protected]
2424
#include <solvers/refinement/bv_refinement.h>
2525
#include <solvers/refinement/string_refinement_invariant.h>
2626
#include <util/refined_string_type.h>
27+
#include <langapi/language_util.h>
28+
29+
/*! \brief Universally quantified string constraint
30+
31+
This represents a universally quantified string constraint as laid out in
32+
DOI: 10.1007/978-3-319-03077-7. The paper seems to specify a universal
33+
constraint as follows.
34+
35+
A universal constraint is of the form \f$\forall n. L(n) \rightarrow
36+
P(n, s_0,\ldots, s_k)\f$ where
37+
38+
1. \f$L(n)\f$ does not contain string indices [possibly not required, but
39+
implied by examples]
40+
2. \f$\forall n. L(n) \rightarrow P'\left(s_0[f_0(n)],\ldots, s_k[f_k(n)]
41+
\right)\f$, i.e. when focusing on one specific string, all indices are
42+
the same [stated in a roundabout manner]
43+
3. Each \f$f\f$ is linear and therefore has an inverse [explicitly stated]
44+
4. \f$L(n)\f$ and \f$P(n, s_0,\ldots, s_k)\f$ may contain other (free)
45+
variables, but in \f$P\f$, \f$n\f$ can only occur as an argument to an
46+
\f$f\f$ [explicitly stated, implied]
47+
48+
We extend this slightly by restricting n to be in a specific range, but this
49+
is another implication which can be pushed in to \f$L(n)\f$.
50+
*/
2751

2852
class string_constraintt: public exprt
2953
{
@@ -114,6 +138,15 @@ extern inline string_constraintt &to_string_constraint(exprt &expr)
114138
return static_cast<string_constraintt &>(expr);
115139
}
116140

141+
inline static std::string from_expr(
142+
const namespacet &ns,
143+
const irep_idt &identifier,
144+
const string_constraintt &expr)
145+
{
146+
return from_expr(ns, identifier, expr.premise())+" => "+
147+
from_expr(ns, identifier, expr.body());
148+
}
149+
117150
class string_not_contains_constraintt: public exprt
118151
{
119152
public:

src/solvers/refinement/string_constraint_generator_transformation.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -293,8 +293,9 @@ string_exprt string_constraint_generatort::add_axioms_for_to_upper_case(
293293

294294
// We add axioms:
295295
// a1 : |res| = |str|
296-
// a2 : forall idx<str.length, 'a'<=str[idx]<='z' => res[idx]=str[idx]+'A'-'a'
297-
// a3 : forall idx<str.length, !('a'<=str[idx]<='z') => res[idx]=str[idx]
296+
// a2 : forall idx1<str.length, 'a'<=str[idx1]<='z' =>
297+
// res[idx1]=str[idx1]+'A'-'a'
298+
// a3 : forall idx2<str.length, !('a'<=str[idx2]<='z') => res[idx2]=str[idx2]
298299
// Note that index expressions are only allowed in the body of universal
299300
// axioms, so we use a trivial premise and push our premise into the body.
300301

0 commit comments

Comments
 (0)