Skip to content

Handle more formulas than just equations in string solver #5016

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

romainbrenguier
Copy link
Contributor

Previously the string-solver was restricting builtin-functions to be the left-hand-side of an equations, so formulas like g1 => c = char_at(string, 10) would be forbidden.
This removes this restriction by replacing these function applications by symbols.
The array_to_length and pointer_to_array associations should still only appear on lhs of an equations. Char array equalities should also only appear as an equation.

The changes are tested with unit tests as the current symex is not producing the kind of formulas which were not handled.
The motivation for this feature is that I have seen this kind of equations appear while experimenting with BDD guards #4765

  • Each commit message has a non-empty body, explaining why the change was made.
  • Methods or procedures I have added are documented, following the guidelines provided in CODING_STANDARD.md.
  • The feature or user visible behaviour I have added or modified has been documented in the User Guide in doc/cprover-manual/
  • Regression or unit tests are included, or existing tests cover the modified code (in this case I have detailed which ones those are in the commit message).
  • [na] My commit message includes data points confirming performance improvements (if claimed).
  • My PR is restricted to a single feature or bugfix.
  • [na] White-space or formatting changes outside the feature-related changed lines are in commits of their own.

@codecov-io
Copy link

Codecov Report

Merging #5016 into develop will increase coverage by 0.04%.
The diff coverage is 100%.

Impacted file tree graph

@@             Coverage Diff             @@
##           develop    #5016      +/-   ##
===========================================
+ Coverage    69.48%   69.52%   +0.04%     
===========================================
  Files         1310     1311       +1     
  Lines       108813   108955     +142     
===========================================
+ Hits         75609    75755     +146     
+ Misses       33204    33200       -4
Impacted Files Coverage Δ
src/solvers/strings/string_dependencies.h 100% <ø> (ø) ⬆️
src/solvers/strings/string_refinement.h 100% <ø> (ø) ⬆️
src/solvers/strings/string_refinement.cpp 88.52% <100%> (+0.24%) ⬆️
...ers/strings/string_refinement/dependency_graph.cpp 100% <100%> (ø) ⬆️
src/solvers/strings/string_dependencies.cpp 82.75% <100%> (+0.14%) ⬆️
...rs/strings/string_refinement/string_refinement.cpp 100% <100%> (ø)
src/solvers/strings/string_refinement_util.cpp 94.66% <0%> (-4%) ⬇️
unit/catch/catch.hpp 41.35% <0%> (+0.08%) ⬆️
... and 1 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 744671a...10418f6. Read the comment docs.

Copy link
Contributor

@allredj allredj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✔️
Passed Diffblue compatibility checks (cbmc commit: 10418f6).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/123485329

Copy link
Contributor

@allredj allredj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A change requested in the documentation, otherwise looks good.

@@ -188,16 +188,20 @@ class string_dependenciest
/// If the string builtin_function is not a supported one, mark all the string
/// arguments as depending on an unknown builtin_function.
/// \param dependencies: graph to which we add the node
/// \param equation: an equation whose right hand side is possibly a call to a
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function description needs updating. It still mentions the rhs.

/// builtin functions
/// \return an expression in which function applications have been replaced
/// by symbols corresponding to the `return_value` field of the associated
/// builtin function.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚫 Missing: Document that the function returns empty when there is no substitution.

for(const auto &eq : equations)
{
if(auto equal_expr = expr_try_dynamic_cast<equal_exprt>(eq))
equalities.push_back(*equal_expr);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I understand. Why do equalities that don't appear as top-level equal_exprts not need to be added to the vector of equalities? 🐎

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If they don't appear at the top then we can't be sure they always hold, for instance if we have g1 => (s1 == s2), we cannot be sure s1 and s2 will be equal in the end and we have to keep them as separate symbols (instead of replacing occurences of s1 by s2).

equations.push_back(eq_expr);
}
if(!value)
equations.push_back(not_exprt{expr});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that to compensate for 🐎 ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not really, it's more like the opposite: because we introduce things that may not be equal_exprt in equations they need to be filtered out in the previous commit

Since the argument is a unique_ptr, it cannot be copied so having the
function take the argument by copy means that it has to be moved at the
function call, which makes clear from there that the argument is moved
and shouldn't be used afterwards.
The add_node function was only handling expressions of the form:
`lhs = builtin_function(args)`
We make it handle more general expressions and look recursively for
functions to replace, for instance
`(lhs == a) && (builtin_function(b) == builtin_function(c))`
 would be replaced by
 `(lhs == a) && (string_builtin_return1 == string_builtin_return2)`.
This makes the function more generic
This make it handle the cases where the function application is not
directly the right hand side of the equation but may be deeper inside
the expression.
EXplicit that it is not modified by the function.
Accept formulas that are not equations as input.
This is to make the solver more robust to different kind of formulas.
In particular, formulas of the form
`guard1 => result = some_string_builin_function(s)` should be accepted.
Even if they are not equations, they may contain formulas talking about
char arrays and other expressions which require special handling by the solver.
This tests the solver directly on a set of desired formula instead of
through symex as would a regression test.
This can be easier to debug when trying to track a bug or add an new
feature, as the correspondence with the string solver code would be
easier to see.
@romainbrenguier romainbrenguier force-pushed the enhance/solver-equations branch from 10418f6 to 462d355 Compare August 19, 2019 12:14
@romainbrenguier romainbrenguier removed their assignment Aug 19, 2019
Copy link
Contributor

@allredj allredj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✔️
Passed Diffblue compatibility checks (cbmc commit: 462d355).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/123848151

@romainbrenguier romainbrenguier merged commit 440ad9c into diffblue:develop Aug 20, 2019
@romainbrenguier romainbrenguier deleted the enhance/solver-equations branch August 20, 2019 09:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants