-
Notifications
You must be signed in to change notification settings - Fork 278
Computation of dependency graph for strings [TG-2605] #1895
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
romainbrenguier
merged 13 commits into
diffblue:develop
from
romainbrenguier:dependency-graph#TG-2582
Mar 12, 2018
Merged
Changes from 1 commit
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
f5adb47
Pull symbol generation out of constraint generator
romainbrenguier 42971da
Remove default axiom in associate array to pointer
romainbrenguier e72eacf
Pull array_pool class out of constraint generator
romainbrenguier 3e688e0
Create string_refinement_util for utility function
romainbrenguier 68ecd9e
Make interface of equation_symbol_mappingt clearer
romainbrenguier 0b58e31
Move utility functions to string_refinement_util
romainbrenguier bd8ee51
Define function template for output_dot
romainbrenguier 859d74c
Class for string builtin functions and dependences
romainbrenguier a556d3d
Pull out a get_function_name function
romainbrenguier a599003
Define function for array_pointer_association
romainbrenguier c4ba7b4
Separate pointer/function substitutions in solver
romainbrenguier 411e654
Unit tests for dependency graph
romainbrenguier 123541f
Correct string-max-input-length tests
romainbrenguier File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Create string_refinement_util for utility function
string_refinement.cpp file is becoming too large. This groups utility classes used by string_refinement in new files to reduce string_refinement.cpp a bit.
- Loading branch information
commit 3e688e05987bf604036aa5552adaf3f63f9cb405
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
/*******************************************************************\ | ||
|
||
Module: String solver | ||
|
||
Author: DiffBlue Limited. All rights reserved. | ||
|
||
\*******************************************************************/ | ||
|
||
#include <algorithm> | ||
#include <numeric> | ||
#include <util/arith_tools.h> | ||
#include <util/std_expr.h> | ||
#include "string_refinement_util.h" | ||
|
||
sparse_arrayt::sparse_arrayt(const with_exprt &expr) | ||
{ | ||
auto ref = std::ref(static_cast<const exprt &>(expr)); | ||
while(can_cast_expr<with_exprt>(ref.get())) | ||
{ | ||
const auto &with_expr = expr_dynamic_cast<with_exprt>(ref.get()); | ||
const auto current_index = numeric_cast_v<std::size_t>(with_expr.where()); | ||
entries.emplace_back(current_index, with_expr.new_value()); | ||
ref = with_expr.old(); | ||
} | ||
|
||
// This function only handles 'with' and 'array_of' expressions | ||
PRECONDITION(ref.get().id() == ID_array_of); | ||
default_value = expr_dynamic_cast<array_of_exprt>(ref.get()).what(); | ||
} | ||
|
||
exprt sparse_arrayt::to_if_expression(const exprt &index) const | ||
{ | ||
return std::accumulate( | ||
entries.begin(), | ||
entries.end(), | ||
default_value, | ||
[&]( | ||
const exprt if_expr, | ||
const std::pair<std::size_t, exprt> &entry) { // NOLINT | ||
const exprt entry_index = from_integer(entry.first, index.type()); | ||
const exprt &then_expr = entry.second; | ||
CHECK_RETURN(then_expr.type() == if_expr.type()); | ||
const equal_exprt index_equal(index, entry_index); | ||
return if_exprt(index_equal, then_expr, if_expr, if_expr.type()); | ||
}); | ||
} | ||
|
||
interval_sparse_arrayt::interval_sparse_arrayt(const with_exprt &expr) | ||
: sparse_arrayt(expr) | ||
{ | ||
// Entries are sorted so that successive entries correspond to intervals | ||
std::sort( | ||
entries.begin(), | ||
entries.end(), | ||
[]( | ||
const std::pair<std::size_t, exprt> &a, | ||
const std::pair<std::size_t, exprt> &b) { return a.first < b.first; }); | ||
} | ||
|
||
exprt interval_sparse_arrayt::to_if_expression(const exprt &index) const | ||
{ | ||
return std::accumulate( | ||
entries.rbegin(), | ||
entries.rend(), | ||
default_value, | ||
[&]( | ||
const exprt if_expr, | ||
const std::pair<std::size_t, exprt> &entry) { // NOLINT | ||
const exprt entry_index = from_integer(entry.first, index.type()); | ||
const exprt &then_expr = entry.second; | ||
CHECK_RETURN(then_expr.type() == if_expr.type()); | ||
const binary_relation_exprt index_small_eq(index, ID_le, entry_index); | ||
return if_exprt(index_small_eq, then_expr, if_expr, if_expr.type()); | ||
}); | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
/*******************************************************************\ | ||
|
||
Module: String solver | ||
|
||
Author: DiffBlue Limited. All rights reserved. | ||
|
||
\*******************************************************************/ | ||
|
||
#ifndef CPROVER_SOLVERS_REFINEMENT_STRING_REFINEMENT_UTIL_H | ||
#define CPROVER_SOLVERS_REFINEMENT_STRING_REFINEMENT_UTIL_H | ||
|
||
#include "string_constraint.h" | ||
|
||
struct index_set_pairt | ||
{ | ||
std::map<exprt, std::set<exprt>> cumulative; | ||
std::map<exprt, std::set<exprt>> current; | ||
}; | ||
|
||
struct string_axiomst | ||
{ | ||
std::vector<string_constraintt> universal; | ||
std::vector<string_not_contains_constraintt> not_contains; | ||
}; | ||
|
||
/// Represents arrays of the form `array_of(x) with {i:=a} with {j:=b} ...` | ||
/// by a default value `x` and a list of entries `(i,a)`, `(j,b)` etc. | ||
class sparse_arrayt | ||
{ | ||
public: | ||
/// Initialize a sparse array from an expression of the form | ||
/// `array_of(x) with {i:=a} with {j:=b} ...` | ||
/// This is the form in which array valuations coming from the underlying | ||
/// solver are given. | ||
explicit sparse_arrayt(const with_exprt &expr); | ||
|
||
/// Creates an if_expr corresponding to the result of accessing the array | ||
/// at the given index | ||
virtual exprt to_if_expression(const exprt &index) const; | ||
|
||
protected: | ||
exprt default_value; | ||
std::vector<std::pair<std::size_t, exprt>> entries; | ||
}; | ||
|
||
/// Represents arrays by the indexes up to which the value remains the same. | ||
/// For instance `{'a', 'a', 'a', 'b', 'b', 'c'}` would be represented by | ||
/// by ('a', 2) ; ('b', 4), ('c', 5). | ||
/// This is particularly useful when the array is constant on intervals. | ||
class interval_sparse_arrayt final : public sparse_arrayt | ||
{ | ||
public: | ||
/// An expression of the form `array_of(x) with {i:=a} with {j:=b}` is | ||
/// converted to an array `arr` where for all index `k` smaller than `i`, | ||
/// `arr[k]` is `a`, for all index between `i` (exclusive) and `j` it is `b` | ||
/// and for the others it is `x`. | ||
explicit interval_sparse_arrayt(const with_exprt &expr); | ||
exprt to_if_expression(const exprt &index) const override; | ||
}; | ||
|
||
/// Maps equation to expressions contained in them and conversely expressions to | ||
/// equations that contain them. This can be used on a subset of expressions | ||
/// which interests us, in particular strings. Equations are identified by an | ||
/// index of type `std::size_t` for more efficient insertion and lookup. | ||
class equation_symbol_mappingt | ||
{ | ||
public: | ||
// Record index of the equations that contain a given expression | ||
std::map<exprt, std::vector<std::size_t>> equations_containing; | ||
// Record expressions that are contained in the equation with the given index | ||
std::unordered_map<std::size_t, std::vector<exprt>> strings_in_equation; | ||
|
||
void add(const std::size_t i, const exprt &expr) | ||
{ | ||
equations_containing[expr].push_back(i); | ||
strings_in_equation[i].push_back(expr); | ||
} | ||
|
||
std::vector<exprt> find_expressions(const std::size_t i) | ||
{ | ||
return strings_in_equation[i]; | ||
} | ||
|
||
std::vector<std::size_t> find_equations(const exprt &expr) | ||
{ | ||
return equations_containing[expr]; | ||
} | ||
}; | ||
|
||
#endif // CPROVER_SOLVERS_REFINEMENT_STRING_REFINEMENT_UTIL_H |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you actually need this in the header file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not easy to avoid because some fields have type defined there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it's unavoidable then that's what it is, but if forward declarations would do the trick (as may be the case with the other includes) then it would help reducing dependencies during compilation. Just something to keep in mind.