-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
QEL: Fast Approximated Quantifier Elimination #6820
Merged
Merged
Changes from 37 commits
Commits
Show all changes
45 commits
Select commit
Hold shift + click to select a range
7b241c0
qe_lite: cleanup and comment
hgvk94 e048b05
mbp_arrays: refactor out partial equality (peq)
hgvk94 7886d17
rewriter: new rewrite rules
hgvk94 7cd2e23
datatype_rw: new rewrite rule for ADTs
agurfinkel 163ae2a
array_rewriter rules for rewriting PEQs
agurfinkel f07a980
th_rewriter: wire PEQ simplifications
agurfinkel 3610355
spacer_iuc: avoid terms with default in IUC
hgvk94 9c7e1f8
mbp_term_graph: replace root with repr
hgvk94 822d9b4
mbp_term_graph: formatting
hgvk94 c250ad6
mbp_term_graph: class_props, getters, setters
igcontreras b1c022e
mbp_term_graph: auxiliary methods for qel
hgvk94 090b95e
mbp_term_graph: bug fix
hgvk94 4f7ade9
mbp_term_graph: pick, refine repr, compute cgrnd
hgvk94 bd80037
mbp_term_graph: internalize deq
igcontreras 7998376
mbp_term_graph: constructor
hgvk94 e2b3f72
mbp_term_graph: optionally internalize equalities
hgvk94 cab7225
qel
igcontreras 67e76ed
formatting
hgvk94 398783a
comments on term_lt
igcontreras c203724
get terms and other api for mbp_qel
hgvk94 53034f7
plugins for mbp_qel
hgvk94 0e55b84
mbp_qel_util: utilities for mbp_qel
hgvk94 4140eb3
qe_mbp: QEL-based mbp
hgvk94 9e5b0d5
qel: expose QEL API
hgvk94 0509ce5
spacer: replace qe_lite in qe_project_spacer by qel
hgvk94 e9782a9
cmd_context: debug commands for qel and mbp_qel
igcontreras 1a7be27
qe_mbp: model-based rewriters for arrays
agurfinkel 0115452
qe_mbp: QEL-based projection functions
hgvk94 6fc9db5
qsat: wire in QEL-based mbp
agurfinkel aa8588c
qsat: debug code
agurfinkel d0db81a
qsat: maybe a bug fix
agurfinkel 531c7d7
chore: use new api to create solver in qsat
agurfinkel 3fd957c
mbp_term_graph use all_of idiom
agurfinkel 9367122
feat: solver for integer multiplication
igcontreras 8f60527
array_peq: formatting, no change to code
agurfinkel eb6a93d
mbp_qel_util: block comment + format
agurfinkel 9c4c1d6
mbt_term_graph: clang-format
agurfinkel 0e78d24
bug fix. Move dt rewrite to qe_mbp
hgvk94 8f59ff0
array_peq: add header
hgvk94 939ef12
run clang format on mbp plugins
hgvk94 da034cc
clang format on mul solver
hgvk94 54a117d
format do-while
hgvk94 fbb9cdd
format
hgvk94 5ff449c
format do-while
hgvk94 e2649b9
update release notes
hgvk94 File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
#include "ast/array_peq.h" | ||
|
||
#define PARTIAL_EQ "!partial_eq" | ||
bool is_partial_eq(const func_decl *f) { | ||
SASSERT(f); | ||
return f->get_name() == PARTIAL_EQ; | ||
} | ||
|
||
bool is_partial_eq(const app *a) { | ||
SASSERT(a); | ||
return is_partial_eq(a->get_decl()); | ||
} | ||
|
||
app_ref mk_peq(expr *e0, expr *e1, vector<expr_ref_vector> const &indices, | ||
ast_manager &m) { | ||
peq p(e0, e1, indices, m); | ||
return p.mk_peq(); | ||
} | ||
|
||
agurfinkel marked this conversation as resolved.
Show resolved
Hide resolved
|
||
app_ref peq::mk_eq(app_ref_vector &aux_consts, bool stores_on_rhs) { | ||
if (!m_eq) { | ||
expr_ref lhs(m_lhs, m), rhs(m_rhs, m); | ||
if (!stores_on_rhs) { std::swap(lhs, rhs); } | ||
// lhs = (...(store (store rhs i0 v0) i1 v1)...) | ||
sort *val_sort = get_array_range(lhs->get_sort()); | ||
for (expr_ref_vector const &diff : m_diff_indices) { | ||
ptr_vector<expr> store_args; | ||
store_args.push_back(rhs); | ||
store_args.append(diff.size(), diff.data()); | ||
app_ref val(m.mk_fresh_const("diff", val_sort), m); | ||
store_args.push_back(val); | ||
aux_consts.push_back(val); | ||
rhs = m_arr_u.mk_store(store_args); | ||
} | ||
m_eq = m.mk_eq(lhs, rhs); | ||
} | ||
return m_eq; | ||
} | ||
|
||
app_ref peq::mk_peq() { | ||
if (!m_peq) { | ||
ptr_vector<expr> args; | ||
args.push_back(m_lhs); | ||
args.push_back(m_rhs); | ||
for (auto const &v : m_diff_indices) { | ||
args.append(v.size(), v.data()); | ||
} | ||
m_peq = m.mk_app(m_decl, args.size(), args.data()); | ||
} | ||
return m_peq; | ||
} | ||
|
||
peq::peq(expr *lhs, expr *rhs, vector<expr_ref_vector> const &diff_indices, | ||
ast_manager &m) | ||
: m(m), m_lhs(lhs, m), m_rhs(rhs, m), m_diff_indices(diff_indices), | ||
m_decl(m), m_peq(m), m_eq(m), m_arr_u(m) { | ||
SASSERT(m_arr_u.is_array(lhs)); | ||
SASSERT(m_arr_u.is_array(rhs)); | ||
SASSERT(lhs->get_sort() == rhs->get_sort()); | ||
ptr_vector<sort> sorts; | ||
sorts.push_back(m_lhs->get_sort()); | ||
sorts.push_back(m_rhs->get_sort()); | ||
|
||
for (auto const &v : diff_indices) { | ||
SASSERT(v.size() == get_array_arity(m_lhs->get_sort())); | ||
for (expr *e : v) sorts.push_back(e->get_sort()); | ||
} | ||
m_decl = m.mk_func_decl(symbol(PARTIAL_EQ), sorts.size(), sorts.data(), | ||
m.mk_bool_sort()); | ||
} | ||
|
||
peq::peq(app *p, ast_manager &m) | ||
: m(m), m_lhs(p->get_arg(0), m), m_rhs(p->get_arg(1), m), | ||
m_decl(p->get_decl(), m), m_peq(p, m), m_eq(m), m_arr_u(m), | ||
m_name(symbol(PARTIAL_EQ)) { | ||
SASSERT(is_partial_eq(p)); | ||
|
||
SASSERT(m_arr_u.is_array(m_lhs)); | ||
SASSERT(m_arr_u.is_array(m_rhs)); | ||
SASSERT(m_lhs->get_sort() == m_rhs->get_sort()); | ||
unsigned arity = get_array_arity(m_lhs->get_sort()); | ||
for (unsigned i = 2; i < p->get_num_args(); i += arity) { | ||
SASSERT(arity + i <= p->get_num_args()); | ||
expr_ref_vector vec(m); | ||
vec.append(arity, p->get_args() + i); | ||
m_diff_indices.push_back(std::move(vec)); | ||
} | ||
} |
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 |
---|---|---|
@@ -0,0 +1,91 @@ | ||
/*++ | ||
Copyright (c) 2023 Microsoft Corporation | ||
|
||
Module Name: | ||
|
||
array_peq.h | ||
|
||
Abstract: | ||
|
||
Partial equality for arrays | ||
|
||
Author: | ||
|
||
Nikolaj Bjorner (nbjorner) 2015-06-13 | ||
Hari Govind V K | ||
|
||
Revision History: | ||
|
||
--*/ | ||
#pragma once | ||
|
||
#include "ast/array_decl_plugin.h" | ||
#include "ast/ast.h" | ||
|
||
/** | ||
* \brief utility class for partial equalities | ||
* | ||
* A partial equality (a ==I b), for two arrays a, b and a finite set of indices | ||
* I holds iff (forall i :: i \not\in I => a[i] == b[i]). In other words, peq is | ||
* a restricted form of the extensionality axiom | ||
* | ||
* Using this class, we denote (a =I b) as f(a,b,i0,i1,...), | ||
* where f is an uninterpreted predicate with the name PARTIAL_EQ and | ||
* I = {i0,i1,...} | ||
*/ | ||
|
||
class peq { | ||
ast_manager &m; | ||
expr_ref m_lhs; | ||
expr_ref m_rhs; | ||
vector<expr_ref_vector> m_diff_indices; | ||
func_decl_ref m_decl; // the partial equality declaration | ||
app_ref m_peq; // partial equality application | ||
app_ref m_eq; // equivalent std equality using def. of partial eq | ||
array_util m_arr_u; | ||
symbol m_name; | ||
|
||
public: | ||
peq(app *p, ast_manager &m); | ||
|
||
peq(expr *lhs, expr *rhs, vector<expr_ref_vector> const &diff_indices, | ||
ast_manager &m); | ||
|
||
expr_ref lhs() { return m_lhs; } | ||
|
||
expr_ref rhs() { return m_rhs; } | ||
|
||
void get_diff_indices(vector<expr_ref_vector> &result) { | ||
result.append(m_diff_indices); | ||
} | ||
|
||
/** Convert peq into a peq expression */ | ||
app_ref mk_peq(); | ||
|
||
/** Convert peq into an equality | ||
|
||
For peq of the form (a =I b) returns (a = b[i0 := v0, i1 := v1, ...]) | ||
where i0, i1 \in I, and v0, v1 are fresh skolem constants | ||
|
||
Skolems are returned in aux_consts | ||
|
||
The left and right hand arguments are reversed when stores_on_rhs is | ||
false | ||
*/ | ||
app_ref mk_eq(app_ref_vector &aux_consts, bool stores_on_rhs = true); | ||
}; | ||
|
||
/** | ||
* mk (e0 ==indices e1) | ||
* | ||
* result has stores if either e0 or e1 or an index term has stores | ||
*/ | ||
app_ref mk_peq(expr *e0, expr *e1, vector<expr_ref_vector> const &indices, | ||
ast_manager &m); | ||
|
||
bool is_partial_eq(const func_decl *f); | ||
|
||
bool is_partial_eq(const app *a); | ||
|
||
inline bool is_peq(const func_decl *f) { return is_partial_eq(f); } | ||
inline bool is_peq(const app *a) { return is_partial_eq(a); } |
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
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.
header