forked from Z3Prover/z3
-
Notifications
You must be signed in to change notification settings - Fork 6
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
First step towards replace_all
operations
#209
Open
vhavlena
wants to merge
12
commits into
devel
Choose a base branch
from
transducers
base: devel
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
564678d
formula: basic transducer and replace_alls support
vhavlena 3955d3b
formula: remove replace_alls; operations with transducer predicate
vhavlena ee2c3d0
inclusion graph: transducer constraints support
vhavlena 17e2a18
preprocess: transducer constraint support
vhavlena 6cacc38
integration: sketch of handling replace_all
vhavlena 4f5d74c
replace_all: construct transducer constraint
vhavlena 13c0fe1
replace_re_all: predicate handling
vhavlena 58a5b2d
README: version of mata
vhavlena 8bf9274
Update src/test/noodler/inclusion-graph-node.cc
vhavlena d4fab84
Update src/test/noodler/formula.cpp
vhavlena 74d8ca3
rename get_word_formula_from_relevant to get_formula_from_relevant
vhavlena 997b54d
update STRACE logging in string_theory_propagation
vhavlena 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
There are no files selected for viewing
This file contains 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 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 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 |
---|---|---|
|
@@ -24,6 +24,7 @@ | |
#include <map> | ||
#include <unordered_set> | ||
#include <iostream> | ||
#include <mata/nft/nft.hh> | ||
|
||
#include "util/zstring.h" | ||
#include "ast/ast.h" | ||
|
@@ -35,6 +36,7 @@ namespace smt::noodler { | |
Equation, | ||
Inequation, | ||
NotContains, | ||
Transducer, | ||
}; | ||
|
||
[[nodiscard]] static std::string to_string(PredicateType predicate_type) { | ||
|
@@ -45,6 +47,8 @@ namespace smt::noodler { | |
return "Inequation"; | ||
case PredicateType::NotContains: | ||
return "Notcontains"; | ||
case PredicateType::Transducer: | ||
return "Transducer"; | ||
} | ||
|
||
throw std::runtime_error("Unhandled predicate type passed to to_string()."); | ||
|
@@ -290,7 +294,7 @@ namespace smt::noodler { | |
}; | ||
|
||
Predicate() : type(PredicateType::Equation) {} | ||
explicit Predicate(const PredicateType type): type(type) { | ||
explicit Predicate(const PredicateType type): type(type), params(), transducer() { | ||
if (is_equation() || is_inequation()) { | ||
params.resize(2); | ||
params.emplace_back(); | ||
|
@@ -300,15 +304,25 @@ namespace smt::noodler { | |
|
||
explicit Predicate(const PredicateType type, std::vector<std::vector<BasicTerm>> par): | ||
type(type), | ||
params(par) | ||
params(par), | ||
transducer() | ||
{ } | ||
|
||
explicit Predicate(const PredicateType type, std::vector<std::vector<BasicTerm>> par, std::shared_ptr<mata::nft::Nft> trans) : | ||
type(type), | ||
params(par), | ||
transducer(trans) { | ||
assert(type == PredicateType::Transducer); | ||
assert(trans->num_of_levels == 2); | ||
} | ||
|
||
[[nodiscard]] PredicateType get_type() const { return type; } | ||
[[nodiscard]] bool is_equation() const { return type == PredicateType::Equation; } | ||
[[nodiscard]] bool is_inequation() const { return type == PredicateType::Inequation; } | ||
[[nodiscard]] bool is_not_cont() const { return type == PredicateType::NotContains; } | ||
[[nodiscard]] bool is_eq_or_ineq() const { return is_equation() || is_inequation(); } | ||
[[nodiscard]] bool is_two_sided() const { return is_equation() || is_inequation() || is_not_cont(); } | ||
[[nodiscard]] bool is_transducer() const { return is(PredicateType::Transducer); } | ||
[[nodiscard]] bool is_two_sided() const { return is_equation() || is_inequation() || is_not_cont() || is_transducer(); } | ||
[[nodiscard]] bool is_predicate() const { return !is_eq_or_ineq(); } | ||
[[nodiscard]] bool is(const PredicateType predicate_type) const { return predicate_type == this->type; } | ||
|
||
|
@@ -364,15 +378,15 @@ namespace smt::noodler { | |
} | ||
|
||
std::set<BasicTerm> get_left_set() const { | ||
assert(is_eq_or_ineq()); | ||
assert(is_two_sided()); | ||
std::set<BasicTerm> ret; | ||
for(const BasicTerm& t : this->params[0]) | ||
ret.insert(t); | ||
return ret; | ||
} | ||
|
||
std::set<BasicTerm> get_right_set() const { | ||
assert(is_eq_or_ineq()); | ||
assert(is_two_sided()); | ||
std::set<BasicTerm> ret; | ||
for(const BasicTerm& t : this->params[1]) | ||
ret.insert(t); | ||
|
@@ -413,6 +427,7 @@ namespace smt::noodler { | |
return LenNode(LenFormulaType::PLUS, ops); | ||
}; | ||
|
||
assert(is_eq_or_ineq()); | ||
LenNode left = plus_chain(this->params[0]); | ||
LenNode right = plus_chain(this->params[1]); | ||
LenNode eq = LenNode(LenFormulaType::EQ, {left, right}); | ||
|
@@ -429,7 +444,12 @@ namespace smt::noodler { | |
[[nodiscard]] const std::vector<BasicTerm>& get_side(EquationSideType side) const; | ||
|
||
[[nodiscard]] Predicate get_switched_sides_predicate() const { | ||
assert(is_eq_or_ineq()); | ||
assert(is_two_sided()); | ||
// for transducers we need to invert tapes, i.e., T(x,y) iff T^{-1}(y,x) | ||
if(is_transducer()) { | ||
auto nft_inverse = std::make_shared<mata::nft::Nft>(mata::nft::invert_levels(*transducer)); | ||
return Predicate{ PredicateType::Transducer, { get_right_side(), get_left_side() }, nft_inverse }; | ||
} | ||
return Predicate{ type, { get_right_side(), get_left_side() } }; | ||
} | ||
|
||
|
@@ -479,6 +499,7 @@ namespace smt::noodler { | |
modif = modif || r; | ||
} | ||
res = Predicate(this->type, new_params); | ||
res.transducer = this->transducer; | ||
return modif; | ||
} | ||
|
||
|
@@ -536,23 +557,30 @@ namespace smt::noodler { | |
size_t operator()(const Predicate& predicate) const { | ||
size_t res{}; | ||
size_t row_hash = std::hash<PredicateType>()(predicate.type); | ||
for (const auto& term: predicate.get_left_side()) { | ||
size_t col_hash = BasicTerm::HashFunction()(term) << 1; | ||
res ^= col_hash; | ||
} | ||
for (const auto& term: predicate.get_right_side()) { | ||
size_t col_hash = BasicTerm::HashFunction()(term) << 1; | ||
res ^= col_hash; | ||
for(const auto& pr : predicate.get_params()) { | ||
for(const BasicTerm& term : pr) { | ||
size_t col_hash = BasicTerm::HashFunction()(term) << 1; | ||
res ^= col_hash; | ||
} | ||
} | ||
return row_hash ^ res; | ||
} | ||
}; | ||
|
||
// TODO: Additional operations. | ||
/** | ||
* @brief Get the transducer shared pointer (for the transducer predicates only). | ||
* | ||
* @return std::shared_ptr<mata::nft::Nft> Transducer | ||
*/ | ||
const std::shared_ptr<mata::nft::Nft>& get_transducer() const { | ||
assert(is_transducer()); | ||
return transducer; | ||
} | ||
|
||
private: | ||
PredicateType type; | ||
std::vector<std::vector<BasicTerm>> params; | ||
std::shared_ptr<mata::nft::Nft> transducer; // transducer for the case of PredicateType::Transducer | ||
|
||
// TODO: Add additional attributes such as cost, etc. | ||
}; // Class Predicate. | ||
|
@@ -578,9 +606,18 @@ namespace smt::noodler { | |
if (lhs.get_params() < rhs.get_params()) { | ||
return true; | ||
} | ||
// For transducer predicates we compare pointers (assuming linear memory model) | ||
if (lhs.is_transducer()) { | ||
// if we have the same object stored on two different places | ||
if (lhs.get_transducer()->is_identical(*rhs.get_transducer())) { | ||
return false; | ||
} | ||
// compare pointers | ||
return lhs.get_transducer() < rhs.get_transducer(); | ||
Comment on lines
+612
to
+616
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similarly here, we should probably be checking only |
||
} | ||
return false; | ||
} | ||
static bool operator>(const Predicate& lhs, const Predicate& rhs) { return !(lhs < rhs); } | ||
static bool operator>(const Predicate& lhs, const Predicate& rhs) { return !(lhs < rhs) && lhs != rhs; } | ||
|
||
//---------------------------------------------------------------------------------------------------------------------------------- | ||
|
||
|
This file contains 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 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
Oops, something went wrong.
Oops, something went wrong.
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.
This might be dangerous, we will forget that a cheap test is done here. Maybe some other function called
cheap_equals
?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.
Hmm, now that I think about it, it is equivalence of predicates and not the language equivalence, so checking if they are identical here makes sense. I would maybe go even step further and compare the pointers and not the transducers, I think equality is used for hashing, right?