mirror of
https://github.com/Z3Prover/z3
synced 2025-08-10 21:20:52 +00:00
move files for build script
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
6e27ad42c8
commit
b6c43f6143
9 changed files with 8 additions and 7 deletions
145
src/ast/rewriter/factor_equivs.cpp
Normal file
145
src/ast/rewriter/factor_equivs.cpp
Normal file
|
@ -0,0 +1,145 @@
|
|||
/*++
|
||||
Copyright (c) 2017 Arie Gurfinkel
|
||||
|
||||
Module Name:
|
||||
|
||||
factor_equivs.cpp
|
||||
|
||||
Abstract:
|
||||
Factor equivalence classes out of an expression.
|
||||
|
||||
"Equivalence class structure" for objs. Uses a union_find structure internally.
|
||||
Operations are :
|
||||
-Declare a new equivalence class with a single element
|
||||
-Merge two equivalence classes
|
||||
-Retrieve whether two elements are in the same equivalence class
|
||||
-Iterate on all the elements of the equivalence class of a given element
|
||||
-Iterate on all equivalence classes (and then within them)
|
||||
|
||||
Author:
|
||||
|
||||
Julien Braine
|
||||
Arie Gurfinkel
|
||||
|
||||
Revision History:
|
||||
|
||||
*/
|
||||
|
||||
#include "ast/arith_decl_plugin.h"
|
||||
#include "ast/for_each_expr.h"
|
||||
#include "ast/ast_pp.h"
|
||||
#include "ast/rewriter/expr_safe_replace.h"
|
||||
#include "ast/rewriter/factor_equivs.h"
|
||||
|
||||
/**
|
||||
Factors input vector v into equivalence classes and the rest
|
||||
*/
|
||||
void factor_eqs(expr_ref_vector &v, expr_equiv_class &equiv) {
|
||||
ast_manager &m = v.get_manager();
|
||||
arith_util arith(m);
|
||||
expr *e1 = nullptr, *e2 = nullptr;
|
||||
|
||||
flatten_and(v);
|
||||
unsigned j = 0;
|
||||
for (unsigned i = 0; i < v.size(); ++i) {
|
||||
if (m.is_eq(v.get(i), e1, e2)) {
|
||||
if (arith.is_zero(e1)) {
|
||||
std::swap(e1, e2);
|
||||
}
|
||||
|
||||
// y + -1*x == 0
|
||||
expr* a0 = nullptr, *a1 = nullptr, *x = nullptr;
|
||||
if (arith.is_zero(e2) && arith.is_add(e1, a0, a1)) {
|
||||
if (arith.is_times_minus_one(a1, x)) {
|
||||
e1 = a0;
|
||||
e2 = x;
|
||||
}
|
||||
else if (arith.is_times_minus_one(a0, x)) {
|
||||
e1 = a1;
|
||||
e2 = x;
|
||||
}
|
||||
}
|
||||
equiv.merge(e1, e2);
|
||||
}
|
||||
else {
|
||||
if (j < i) {
|
||||
v[j] = v.get(i);
|
||||
}
|
||||
j++;
|
||||
}
|
||||
}
|
||||
v.shrink(j);
|
||||
}
|
||||
|
||||
/**
|
||||
* Chooses a representative of an equivalence class
|
||||
*/
|
||||
expr *choose_rep(expr_equiv_class::eq_class &clazz, ast_manager &m) {
|
||||
expr *rep = nullptr;
|
||||
unsigned rep_sz, elem_sz;
|
||||
for (expr *elem : clazz) {
|
||||
if (!m.is_value(elem)) {
|
||||
elem_sz = get_num_exprs(elem);
|
||||
if (!rep || (rep && rep_sz > elem_sz)) {
|
||||
rep = elem;
|
||||
rep_sz = elem_sz;
|
||||
}
|
||||
}
|
||||
}
|
||||
TRACE("equiv",
|
||||
tout << "Rep: " << mk_pp(rep, m) << "\n";
|
||||
for (expr *el : clazz)
|
||||
tout << mk_pp(el, m) << "\n";
|
||||
tout << "RepEnd\n";);
|
||||
|
||||
return rep;
|
||||
}
|
||||
|
||||
void rewrite_eqs (expr_ref_vector &v, expr_equiv_class &equiv) {
|
||||
ast_manager &m = v.m();
|
||||
expr_safe_replace sub(m);
|
||||
for (auto eq_class : equiv) {
|
||||
expr *rep = choose_rep(eq_class, m);
|
||||
for (expr *el : eq_class) {
|
||||
if (el != rep) {
|
||||
sub.insert (el, rep);
|
||||
}
|
||||
}
|
||||
}
|
||||
sub(v);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* converts equivalence classes to equalities
|
||||
*/
|
||||
void equiv_to_expr(expr_equiv_class &equiv, expr_ref_vector &out) {
|
||||
ast_manager &m = out.get_manager();
|
||||
for (auto eq_class : equiv) {
|
||||
expr *rep = choose_rep(eq_class, m);
|
||||
SASSERT(rep);
|
||||
for (expr *elem : eq_class) {
|
||||
if (rep != elem) {
|
||||
out.push_back (m.mk_eq (rep, elem));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* expands equivalence classes to all derivable equalities
|
||||
*/
|
||||
bool equiv_to_expr_full(expr_equiv_class &equiv, expr_ref_vector &out) {
|
||||
ast_manager &m = out.get_manager();
|
||||
bool dirty = false;
|
||||
for (auto eq_class : equiv) {
|
||||
for (auto a = eq_class.begin(), end = eq_class.end(); a != end; ++a) {
|
||||
expr_equiv_class::iterator b(a);
|
||||
for (++b; b != end; ++b) {
|
||||
out.push_back(m.mk_eq(*a, *b));
|
||||
dirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return dirty;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue