mirror of
https://github.com/Z3Prover/z3
synced 2025-04-07 09:55:19 +00:00
Merge branch 'master' of https://github.com/z3prover/z3
This commit is contained in:
commit
f961300036
|
@ -53,13 +53,21 @@ def extract_tactic_doc(ous, f):
|
||||||
if is_doc.search(line):
|
if is_doc.search(line):
|
||||||
generate_tactic_doc(ous, f, ins)
|
generate_tactic_doc(ous, f, ins)
|
||||||
|
|
||||||
|
def find_tactic_name(path):
|
||||||
|
with open(path) as ins:
|
||||||
|
for line in ins:
|
||||||
|
m = is_tac_name.search(line)
|
||||||
|
if m:
|
||||||
|
return m.group(1)
|
||||||
|
return ""
|
||||||
|
|
||||||
def presort_files():
|
def presort_files():
|
||||||
tac_files = []
|
tac_files = []
|
||||||
for root, dirs, files in os.walk(doc_path("../src")):
|
for root, dirs, files in os.walk(doc_path("../src")):
|
||||||
for f in files:
|
for f in files:
|
||||||
if f.endswith("tactic.h"):
|
if f.endswith("tactic.h"):
|
||||||
tac_files += [(f, os.path.join(root, f))]
|
tac_files += [(f, os.path.join(root, f))]
|
||||||
tac_files = sorted(tac_files, key = lambda x: x[0])
|
tac_files = sorted(tac_files, key = lambda x: find_tactic_name(x[1]))
|
||||||
return tac_files
|
return tac_files
|
||||||
|
|
||||||
def help(ous):
|
def help(ous):
|
||||||
|
|
|
@ -144,10 +144,12 @@ public:
|
||||||
|
|
||||||
bool get_subst(expr * s, expr * & t, proof * & t_pr)
|
bool get_subst(expr * s, expr * & t, proof * & t_pr)
|
||||||
{
|
{
|
||||||
if (!is_app(s)) { return false; }
|
if (!is_app(s))
|
||||||
|
return false;
|
||||||
app * a = to_app(s);
|
app * a = to_app(s);
|
||||||
func_decl * sym = a->get_decl();
|
func_decl * sym = a->get_decl();
|
||||||
if (!m_parent.has_index(sym, m_from_idx)) {
|
if (!m_parent.has_index(sym, m_from_idx)) {
|
||||||
|
CTRACE("spacer", m_homogenous && m_parent.is_muxed(sym), tout << "not found " << mk_pp(a, m) << "\n");
|
||||||
SASSERT(!m_homogenous || !m_parent.is_muxed(sym));
|
SASSERT(!m_homogenous || !m_parent.is_muxed(sym));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -442,9 +442,9 @@ public:
|
||||||
|
|
||||||
void collect_param_descrs(param_descrs & r) override {
|
void collect_param_descrs(param_descrs & r) override {
|
||||||
r.insert("nla2bv_max_bv_size", CPK_UINT, "(default: inf) maximum bit-vector size used by nla2bv tactic");
|
r.insert("nla2bv_max_bv_size", CPK_UINT, "(default: inf) maximum bit-vector size used by nla2bv tactic");
|
||||||
r.insert("nla2bv_bv_size", CPK_UINT, "(default: 4) default bit-vector size used by nla2bv tactic.");
|
r.insert("nla2bv_bv_size", CPK_UINT, "default bit-vector size used by nla2bv tactic.", "4");
|
||||||
r.insert("nla2bv_root", CPK_UINT, "(default: 2) nla2bv tactic encodes reals into bit-vectors using expressions of the form a+b*sqrt(c), this parameter sets the value of c used in the encoding.");
|
r.insert("nla2bv_root", CPK_UINT, "nla2bv tactic encodes reals into bit-vectors using expressions of the form a+b*sqrt(c), this parameter sets the value of c used in the encoding.", "2");
|
||||||
r.insert("nla2bv_divisor", CPK_UINT, "(default: 2) nla2bv tactic parameter.");
|
r.insert("nla2bv_divisor", CPK_UINT, "nla2bv tactic parameter.", "2");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -161,7 +161,7 @@ public:
|
||||||
|
|
||||||
void collect_param_descrs(param_descrs & r) override {
|
void collect_param_descrs(param_descrs & r) override {
|
||||||
insert_produce_models(r);
|
insert_produce_models(r);
|
||||||
r.insert("norm_int_only", CPK_BOOL, "(default: true) normalize only the bounds of integer constants.");
|
r.insert("norm_int_only", CPK_BOOL, "normalize only the bounds of integer constants.", "true");
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()(goal_ref const & in,
|
void operator()(goal_ref const & in,
|
||||||
|
|
|
@ -13,7 +13,32 @@ Author:
|
||||||
|
|
||||||
Christoph (cwinter) 2012-02-15
|
Christoph (cwinter) 2012-02-15
|
||||||
|
|
||||||
Notes:
|
Tactic Documentation:
|
||||||
|
|
||||||
|
## Tactic pb2bv
|
||||||
|
|
||||||
|
### Short Description
|
||||||
|
|
||||||
|
Convert pseudo-boolean constraints to bit-vectors
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
```z3
|
||||||
|
(declare-const x Int)
|
||||||
|
(declare-const y Int)
|
||||||
|
(declare-const z Int)
|
||||||
|
(declare-const u Int)
|
||||||
|
(assert (<= 0 x))
|
||||||
|
(assert (<= 0 y))
|
||||||
|
(assert (<= 0 z))
|
||||||
|
(assert (<= 0 u))
|
||||||
|
(assert (<= x 1))
|
||||||
|
(assert (<= y 1))
|
||||||
|
(assert (<= z 1))
|
||||||
|
(assert (<= u 1))
|
||||||
|
(assert (>= (+ (* 3 x) (* 2 y) (* 2 z) (* 2 u)) 4))
|
||||||
|
(apply pb2bv)
|
||||||
|
```
|
||||||
|
|
||||||
--*/
|
--*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
|
@ -4,30 +4,49 @@ Copyright (c) 2012 Microsoft Corporation
|
||||||
Module Name:
|
Module Name:
|
||||||
|
|
||||||
propagate_ineqs_tactic.h
|
propagate_ineqs_tactic.h
|
||||||
|
|
||||||
Abstract:
|
|
||||||
|
|
||||||
This tactic performs the following tasks:
|
|
||||||
|
|
||||||
- Propagate bounds using the bound_propagator.
|
|
||||||
- Eliminate subsumed inequalities.
|
|
||||||
For example:
|
|
||||||
x - y >= 3
|
|
||||||
can be replaced with true if we know that
|
|
||||||
x >= 3 and y <= 0
|
|
||||||
|
|
||||||
- Convert inequalities of the form p <= k and p >= k into p = k,
|
|
||||||
where p is a polynomial and k is a constant.
|
|
||||||
|
|
||||||
This strategy assumes the input is in arith LHS mode.
|
|
||||||
This can be achieved by using option :arith-lhs true in the
|
|
||||||
simplifier.
|
|
||||||
|
|
||||||
Author:
|
Author:
|
||||||
|
|
||||||
Leonardo (leonardo) 2012-02-19
|
Leonardo (leonardo) 2012-02-19
|
||||||
|
|
||||||
Notes:
|
Tactic Documentation:
|
||||||
|
|
||||||
|
## Tactic propagate-ineqs
|
||||||
|
|
||||||
|
### Short Description
|
||||||
|
|
||||||
|
Propagate ineqs/bounds, remove subsumed inequalities
|
||||||
|
|
||||||
|
### Long Description
|
||||||
|
|
||||||
|
This tactic performs the following tasks:
|
||||||
|
|
||||||
|
- Propagate bounds using the bound_propagator.
|
||||||
|
- Eliminate subsumed inequalities.
|
||||||
|
- For example:
|
||||||
|
`x - y >= 3` can be replaced with true if we know that `x >= 3` and `y <= 0`
|
||||||
|
|
||||||
|
- Convert inequalities of the form `p <= k` and `p >= k` into `p = k`,
|
||||||
|
where `p` is a polynomial and `k` is a constant.
|
||||||
|
|
||||||
|
This strategy assumes the input is in arith LHS mode.
|
||||||
|
This can be achieved by using option :arith-lhs true in the simplifier.
|
||||||
|
|
||||||
|
### Example
|
||||||
|
```z3
|
||||||
|
(declare-const x Int)
|
||||||
|
(declare-const y Int)
|
||||||
|
(declare-const z Int)
|
||||||
|
(declare-const u Int)
|
||||||
|
(declare-const v Int)
|
||||||
|
(declare-const w Int)
|
||||||
|
(assert (>= x 3))
|
||||||
|
(assert (<= y 0))
|
||||||
|
(assert (>= (- x y) 3))
|
||||||
|
(assert (>= (* u v w) 2))
|
||||||
|
(assert (<= (* v u w) 2))
|
||||||
|
(apply (and-then simplify propagate-ineqs))
|
||||||
|
```
|
||||||
|
|
||||||
--*/
|
--*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
|
@ -911,11 +911,11 @@ public:
|
||||||
|
|
||||||
void collect_param_descrs(param_descrs & r) override {
|
void collect_param_descrs(param_descrs & r) override {
|
||||||
r.insert("complete", CPK_BOOL,
|
r.insert("complete", CPK_BOOL,
|
||||||
"(default: true) add constraints to make sure that any interpretation of a underspecified arithmetic operators is a function. The result will include additional uninterpreted functions/constants: /0, div0, mod0, 0^0, neg-root");
|
"add constraints to make sure that any interpretation of a underspecified arithmetic operators is a function. The result will include additional uninterpreted functions/constants: /0, div0, mod0, 0^0, neg-root", "true");
|
||||||
r.insert("elim_root_objects", CPK_BOOL,
|
r.insert("elim_root_objects", CPK_BOOL,
|
||||||
"(default: true) eliminate root objects.");
|
"eliminate root objects.", "true");
|
||||||
r.insert("elim_inverses", CPK_BOOL,
|
r.insert("elim_inverses", CPK_BOOL,
|
||||||
"(default: true) eliminate inverse trigonometric functions (asin, acos, atan).");
|
"eliminate inverse trigonometric functions (asin, acos, atan).", "true");
|
||||||
th_rewriter::get_param_descrs(r);
|
th_rewriter::get_param_descrs(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,28 @@ Author:
|
||||||
|
|
||||||
Leonardo de Moura (leonardo) 2011-12-30.
|
Leonardo de Moura (leonardo) 2011-12-30.
|
||||||
|
|
||||||
Revision History:
|
Tactic Documentation:
|
||||||
|
|
||||||
|
## Tactic purify-arith
|
||||||
|
|
||||||
|
### Short Description
|
||||||
|
|
||||||
|
Eliminate unnecessary operators: -, /, div, mod, rem, is-int, to-int, ^, root-objects.
|
||||||
|
These operators can be replaced by introcing fresh variables and using multiplication and addition.
|
||||||
|
|
||||||
|
### Example
|
||||||
|
```z3
|
||||||
|
(declare-const x Int)
|
||||||
|
(declare-const y Int)
|
||||||
|
(declare-const z Int)
|
||||||
|
(declare-const u Int)
|
||||||
|
(declare-const v Int)
|
||||||
|
(declare-const w Int)
|
||||||
|
(assert (= (div x 3) y))
|
||||||
|
(assert (= (mod z 4) u))
|
||||||
|
(assert (> (mod v w) u))
|
||||||
|
(apply purify-arith)
|
||||||
|
```
|
||||||
|
|
||||||
--*/
|
--*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
|
@ -407,7 +407,7 @@ public:
|
||||||
|
|
||||||
void collect_param_descrs(param_descrs & r) override {
|
void collect_param_descrs(param_descrs & r) override {
|
||||||
th_rewriter::get_param_descrs(r);
|
th_rewriter::get_param_descrs(r);
|
||||||
r.insert("recover_01_max_bits", CPK_UINT, "(default: 10) maximum number of bits to consider in a clause.");
|
r.insert("recover_01_max_bits", CPK_UINT, "maximum number of bits to consider in a clause.", "10");
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()(goal_ref const & g,
|
void operator()(goal_ref const & g,
|
||||||
|
|
|
@ -129,10 +129,10 @@ public:
|
||||||
void collect_param_descrs(param_descrs & r) override {
|
void collect_param_descrs(param_descrs & r) override {
|
||||||
insert_max_memory(r);
|
insert_max_memory(r);
|
||||||
insert_max_steps(r);
|
insert_max_steps(r);
|
||||||
r.insert("blast_mul", CPK_BOOL, "(default: true) bit-blast multipliers (and dividers, remainders).");
|
r.insert("blast_mul", CPK_BOOL, "bit-blast multipliers (and dividers, remainders).", "true");
|
||||||
r.insert("blast_add", CPK_BOOL, "(default: true) bit-blast adders.");
|
r.insert("blast_add", CPK_BOOL, "bit-blast adders.", "true");
|
||||||
r.insert("blast_quant", CPK_BOOL, "(default: false) bit-blast quantified variables.");
|
r.insert("blast_quant", CPK_BOOL, "bit-blast quantified variables.", "false");
|
||||||
r.insert("blast_full", CPK_BOOL, "(default: false) bit-blast any term with bit-vector sort, this option will make E-matching ineffective in any pattern containing bit-vector terms.");
|
r.insert("blast_full", CPK_BOOL, "bit-blast any term with bit-vector sort, this option will make E-matching ineffective in any pattern containing bit-vector terms.", "false");
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()(goal_ref const & g,
|
void operator()(goal_ref const & g,
|
||||||
|
|
|
@ -1,21 +1,33 @@
|
||||||
/*++
|
/*++
|
||||||
Copyright (c) 2011 Microsoft Corporation
|
Copyright (c) 2011 Microsoft Corporation
|
||||||
|
|
||||||
Module Name:
|
Module Name:
|
||||||
|
|
||||||
bit_blaster_tactic.h
|
bit_blaster_tactic.h
|
||||||
|
|
||||||
Abstract:
|
Author:
|
||||||
|
|
||||||
Apply bit-blasting to a given goal.
|
Leonardo (leonardo) 2011-10-25
|
||||||
|
|
||||||
Author:
|
|
||||||
|
|
||||||
Leonardo (leonardo) 2011-10-25
|
|
||||||
|
|
||||||
Notes:
|
|
||||||
|
|
||||||
|
Tactic Documentation:
|
||||||
|
|
||||||
|
## Tactic bit-blast
|
||||||
|
|
||||||
|
### Short Description
|
||||||
|
|
||||||
|
Apply bit-blasting to a given goal.
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
```z3
|
||||||
|
(declare-const x (_ BitVec 8))
|
||||||
|
(declare-const y (_ BitVec 8))
|
||||||
|
(assert (bvule x y))
|
||||||
|
(apply bit-blast)
|
||||||
|
```
|
||||||
|
|
||||||
--*/
|
--*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "util/params.h"
|
#include "util/params.h"
|
||||||
|
|
|
@ -5,21 +5,37 @@ Module Name:
|
||||||
|
|
||||||
bv1_blaster_tactic.h
|
bv1_blaster_tactic.h
|
||||||
|
|
||||||
Abstract:
|
|
||||||
|
|
||||||
Rewriter for "blasting" bit-vectors of size n into bit-vectors of size 1.
|
|
||||||
This rewriter only supports concat and extract operators.
|
|
||||||
This transformation is useful for handling benchmarks that contain
|
|
||||||
many BV equalities.
|
|
||||||
|
|
||||||
Remark: other operators can be mapped into concat/extract by using
|
|
||||||
the simplifiers.
|
|
||||||
|
|
||||||
Author:
|
Author:
|
||||||
|
|
||||||
Leonardo (leonardo) 2011-10-25
|
Leonardo (leonardo) 2011-10-25
|
||||||
|
|
||||||
Notes:
|
Tactic Documentation:
|
||||||
|
|
||||||
|
## Tactic bv1-blast
|
||||||
|
|
||||||
|
### Short Description
|
||||||
|
|
||||||
|
Reduce bit-vector expressions into bit-vectors of size 1 (notes: only equality, extract and concat are supported).
|
||||||
|
|
||||||
|
### Long Description
|
||||||
|
|
||||||
|
Rewriter for "blasting" bit-vectors of size n into bit-vectors of size 1.
|
||||||
|
This rewriter only supports concat and extract operators.
|
||||||
|
This transformation is useful for handling benchmarks that contain
|
||||||
|
many BV equalities.
|
||||||
|
|
||||||
|
_Remark_: other operators can be mapped into concat/extract by using
|
||||||
|
the simplifiers.
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
```z3
|
||||||
|
(declare-const x (_ BitVec 8))
|
||||||
|
(declare-const y (_ BitVec 4))
|
||||||
|
(declare-const z (_ BitVec 4))
|
||||||
|
(assert (= (concat y z) x))
|
||||||
|
(apply bv1-blast)
|
||||||
|
```
|
||||||
|
|
||||||
--*/
|
--*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
|
@ -48,7 +48,6 @@ struct bv_bound_chk_rewriter_cfg : public default_rewriter_cfg {
|
||||||
m_bv_ineq_consistency_test_max = p.bv_ineq_consistency_test_max();
|
m_bv_ineq_consistency_test_max = p.bv_ineq_consistency_test_max();
|
||||||
m_max_memory = p.max_memory();
|
m_max_memory = p.max_memory();
|
||||||
m_max_steps = p.max_steps();
|
m_max_steps = p.max_steps();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ast_manager & m() const { return m_m; }
|
ast_manager & m() const { return m_m; }
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
/*++
|
/*++
|
||||||
Copyright (c) 2016 Microsoft Corporation
|
Copyright (c) 2016 Microsoft Corporation
|
||||||
|
|
||||||
Module Name:
|
Module Name:
|
||||||
|
|
||||||
bv_bound_chk_tactic.h
|
bv_bound_chk_tactic.h
|
||||||
|
|
||||||
Abstract:
|
Author:
|
||||||
|
|
||||||
|
Mikolas Janota
|
||||||
|
|
||||||
Author:
|
### Notes
|
||||||
|
|
||||||
Mikolas Janota
|
* does not support proofs, does not support cores
|
||||||
|
|
||||||
Revision History:
|
|
||||||
--*/
|
--*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
|
|
@ -35,11 +35,12 @@ namespace {
|
||||||
struct interval {
|
struct interval {
|
||||||
// l < h: [l, h]
|
// l < h: [l, h]
|
||||||
// l > h: [0, h] U [l, UMAX_INT]
|
// l > h: [0, h] U [l, UMAX_INT]
|
||||||
uint64_t l, h;
|
uint64_t l = 0, h = 0;
|
||||||
unsigned sz;
|
unsigned sz = 0;
|
||||||
bool tight;
|
bool tight = true;
|
||||||
|
|
||||||
interval() {}
|
interval() {}
|
||||||
|
|
||||||
interval(uint64_t l, uint64_t h, unsigned sz, bool tight = false) : l(l), h(h), sz(sz), tight(tight) {
|
interval(uint64_t l, uint64_t h, unsigned sz, bool tight = false) : l(l), h(h), sz(sz), tight(tight) {
|
||||||
// canonicalize full set
|
// canonicalize full set
|
||||||
if (is_wrapped() && l == h + 1) {
|
if (is_wrapped() && l == h + 1) {
|
||||||
|
@ -50,8 +51,7 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool invariant() const {
|
bool invariant() const {
|
||||||
return l <= uMaxInt(sz) && h <= uMaxInt(sz) &&
|
return l <= uMaxInt(sz) && h <= uMaxInt(sz) && (!is_wrapped() || l != h+1);
|
||||||
(!is_wrapped() || l != h+1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_full() const { return l == 0 && h == uMaxInt(sz); }
|
bool is_full() const { return l == 0 && h == uMaxInt(sz); }
|
||||||
|
@ -67,22 +67,17 @@ namespace {
|
||||||
bool implies(const interval& b) const {
|
bool implies(const interval& b) const {
|
||||||
if (b.is_full())
|
if (b.is_full())
|
||||||
return true;
|
return true;
|
||||||
if (is_full())
|
else if (is_full())
|
||||||
return false;
|
return false;
|
||||||
|
else if (is_wrapped())
|
||||||
if (is_wrapped()) {
|
|
||||||
// l >= b.l >= b.h >= h
|
// l >= b.l >= b.h >= h
|
||||||
return b.is_wrapped() && h <= b.h && l >= b.l;
|
return b.is_wrapped() && h <= b.h && l >= b.l;
|
||||||
}
|
else if (b.is_wrapped())
|
||||||
else if (b.is_wrapped()) {
|
|
||||||
// b.l > b.h >= h >= l
|
// b.l > b.h >= h >= l
|
||||||
// h >= l >= b.l > b.h
|
// h >= l >= b.l > b.h
|
||||||
return h <= b.h || l >= b.l;
|
return h <= b.h || l >= b.l;
|
||||||
}
|
else
|
||||||
else {
|
return l >= b.l && h <= b.h;
|
||||||
//
|
|
||||||
return l >= b.l && h <= b.h;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// return false if intersection is unsat
|
/// return false if intersection is unsat
|
||||||
|
@ -98,28 +93,26 @@ namespace {
|
||||||
|
|
||||||
if (is_wrapped()) {
|
if (is_wrapped()) {
|
||||||
if (b.is_wrapped()) {
|
if (b.is_wrapped()) {
|
||||||
if (h >= b.l) {
|
if (h >= b.l)
|
||||||
result = b;
|
result = b;
|
||||||
} else if (b.h >= l) {
|
else if (b.h >= l)
|
||||||
result = *this;
|
result = *this;
|
||||||
} else {
|
else
|
||||||
result = interval(std::max(l, b.l), std::min(h, b.h), sz);
|
result = interval(std::max(l, b.l), std::min(h, b.h), sz);
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return b.intersect(*this, result);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
return b.intersect(*this, result);
|
||||||
}
|
}
|
||||||
else if (b.is_wrapped()) {
|
else if (b.is_wrapped()) {
|
||||||
// ... b.h ... l ... h ... b.l ..
|
// ... b.h ... l ... h ... b.l ..
|
||||||
if (h < b.l && l > b.h) {
|
if (h < b.l && l > b.h)
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
// ... l ... b.l ... h ...
|
// ... l ... b.l ... h ...
|
||||||
if (h >= b.l && l <= b.h) {
|
if (h >= b.l && l <= b.h)
|
||||||
result = b;
|
result = b;
|
||||||
} else if (h >= b.l) {
|
else if (h >= b.l)
|
||||||
result = interval(b.l, h, sz);
|
result = interval(b.l, h, sz);
|
||||||
} else {
|
else {
|
||||||
// ... l .. b.h .. h .. b.l ...
|
// ... l .. b.h .. h .. b.l ...
|
||||||
SASSERT(l <= b.h);
|
SASSERT(l <= b.h);
|
||||||
result = interval(l, std::min(h, b.h), sz);
|
result = interval(l, std::min(h, b.h), sz);
|
||||||
|
@ -136,20 +129,16 @@ namespace {
|
||||||
|
|
||||||
/// return false if negation is empty
|
/// return false if negation is empty
|
||||||
bool negate(interval& result) const {
|
bool negate(interval& result) const {
|
||||||
if (!tight) {
|
if (!tight)
|
||||||
result = interval(0, uMaxInt(sz), true);
|
result = interval(0, uMaxInt(sz), true);
|
||||||
return true;
|
else if (is_full())
|
||||||
}
|
|
||||||
|
|
||||||
if (is_full())
|
|
||||||
return false;
|
return false;
|
||||||
if (l == 0) {
|
else if (l == 0)
|
||||||
result = interval(h + 1, uMaxInt(sz), sz);
|
result = interval(h + 1, uMaxInt(sz), sz);
|
||||||
} else if (uMaxInt(sz) == h) {
|
else if (uMaxInt(sz) == h)
|
||||||
result = interval(0, l - 1, sz);
|
result = interval(0, l - 1, sz);
|
||||||
} else {
|
else
|
||||||
result = interval(h + 1, l - 1, sz);
|
result = interval(h + 1, l - 1, sz);
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -163,9 +152,9 @@ namespace {
|
||||||
|
|
||||||
|
|
||||||
struct undo_bound {
|
struct undo_bound {
|
||||||
expr* e { nullptr };
|
expr* e = nullptr;
|
||||||
interval b;
|
interval b;
|
||||||
bool fresh { false };
|
bool fresh = false;
|
||||||
undo_bound(expr* e, const interval& b, bool fresh) : e(e), b(b), fresh(fresh) {}
|
undo_bound(expr* e, const interval& b, bool fresh) : e(e), b(b), fresh(fresh) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -176,7 +165,7 @@ namespace {
|
||||||
|
|
||||||
ast_manager& m;
|
ast_manager& m;
|
||||||
params_ref m_params;
|
params_ref m_params;
|
||||||
bool m_propagate_eq;
|
bool m_propagate_eq = false;
|
||||||
bv_util m_bv;
|
bv_util m_bv;
|
||||||
vector<undo_bound> m_scopes;
|
vector<undo_bound> m_scopes;
|
||||||
map m_bound;
|
map m_bound;
|
||||||
|
@ -224,7 +213,8 @@ namespace {
|
||||||
v = lhs;
|
v = lhs;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if (m.is_eq(e, lhs, rhs)) {
|
}
|
||||||
|
else if (m.is_eq(e, lhs, rhs)) {
|
||||||
if (is_number(lhs, n, sz)) {
|
if (is_number(lhs, n, sz)) {
|
||||||
if (m_bv.is_numeral(rhs))
|
if (m_bv.is_numeral(rhs))
|
||||||
return false;
|
return false;
|
||||||
|
@ -252,7 +242,7 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_param_descrs(param_descrs& r) {
|
static void get_param_descrs(param_descrs& r) {
|
||||||
r.insert("propagate-eq", CPK_BOOL, "(default: false) propagate equalities from inequalities");
|
r.insert("propagate-eq", CPK_BOOL, "propagate equalities from inequalities", "false");
|
||||||
}
|
}
|
||||||
|
|
||||||
~bv_bounds_simplifier() override {
|
~bv_bounds_simplifier() override {
|
||||||
|
@ -546,22 +536,19 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_param_descrs(param_descrs& r) {
|
static void get_param_descrs(param_descrs& r) {
|
||||||
r.insert("propagate-eq", CPK_BOOL, "(default: false) propagate equalities from inequalities");
|
r.insert("propagate-eq", CPK_BOOL, "propagate equalities from inequalities", "false");
|
||||||
}
|
}
|
||||||
|
|
||||||
~dom_bv_bounds_simplifier() override {
|
~dom_bv_bounds_simplifier() override {
|
||||||
for (unsigned i = 0, e = m_expr_vars.size(); i < e; ++i) {
|
for (auto* e : m_expr_vars)
|
||||||
dealloc(m_expr_vars[i]);
|
dealloc(e);
|
||||||
}
|
for (auto* b : m_bound_exprs)
|
||||||
for (unsigned i = 0, e = m_bound_exprs.size(); i < e; ++i) {
|
dealloc(b);
|
||||||
dealloc(m_bound_exprs[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool assert_expr(expr * t, bool sign) override {
|
bool assert_expr(expr * t, bool sign) override {
|
||||||
while (m.is_not(t, t)) {
|
while (m.is_not(t, t))
|
||||||
sign = !sign;
|
sign = !sign;
|
||||||
}
|
|
||||||
|
|
||||||
interval b;
|
interval b;
|
||||||
expr* t1;
|
expr* t1;
|
||||||
|
@ -581,7 +568,8 @@ namespace {
|
||||||
return true;
|
return true;
|
||||||
m_scopes.push_back(undo_bound(t1, old, false));
|
m_scopes.push_back(undo_bound(t1, old, false));
|
||||||
old = intr;
|
old = intr;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
m_bound.insert(t1, b);
|
m_bound.insert(t1, b);
|
||||||
m_scopes.push_back(undo_bound(t1, interval(), true));
|
m_scopes.push_back(undo_bound(t1, interval(), true));
|
||||||
}
|
}
|
||||||
|
@ -602,9 +590,8 @@ namespace {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool sign = false;
|
bool sign = false;
|
||||||
while (m.is_not(t, t)) {
|
while (m.is_not(t, t))
|
||||||
sign = !sign;
|
sign = !sign;
|
||||||
}
|
|
||||||
|
|
||||||
if (!is_bound(t, t1, b))
|
if (!is_bound(t, t1, b))
|
||||||
return;
|
return;
|
||||||
|
@ -619,27 +606,21 @@ namespace {
|
||||||
|
|
||||||
interval ctx, intr;
|
interval ctx, intr;
|
||||||
bool was_updated = true;
|
bool was_updated = true;
|
||||||
if (b.is_full() && b.tight) {
|
if (b.is_full() && b.tight)
|
||||||
r = m.mk_true();
|
r = m.mk_true();
|
||||||
}
|
|
||||||
else if (m_bound.find(t1, ctx)) {
|
else if (m_bound.find(t1, ctx)) {
|
||||||
if (ctx.implies(b)) {
|
if (ctx.implies(b))
|
||||||
r = m.mk_true();
|
r = m.mk_true();
|
||||||
}
|
else if (!b.intersect(ctx, intr))
|
||||||
else if (!b.intersect(ctx, intr)) {
|
r = m.mk_false();
|
||||||
r = m.mk_false();
|
else if (m_propagate_eq && intr.is_singleton())
|
||||||
}
|
|
||||||
else if (m_propagate_eq && intr.is_singleton()) {
|
|
||||||
r = m.mk_eq(t1, m_bv.mk_numeral(rational(intr.l, rational::ui64()),
|
r = m.mk_eq(t1, m_bv.mk_numeral(rational(intr.l, rational::ui64()),
|
||||||
t1->get_sort()));
|
t1->get_sort()));
|
||||||
}
|
else
|
||||||
else {
|
was_updated = false;
|
||||||
was_updated = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
was_updated = false;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
was_updated = false;
|
||||||
|
|
||||||
TRACE("bv", tout << mk_pp(t, m) << " " << b << " (ctx: " << ctx << ") (intr: " << intr << "): " << r << "\n";);
|
TRACE("bv", tout << mk_pp(t, m) << " " << b << " (ctx: " << ctx << ") (intr: " << intr << "): " << r << "\n";);
|
||||||
if (sign && was_updated)
|
if (sign && was_updated)
|
||||||
|
@ -654,18 +635,16 @@ namespace {
|
||||||
while (!todo.empty()) {
|
while (!todo.empty()) {
|
||||||
t = todo.back();
|
t = todo.back();
|
||||||
todo.pop_back();
|
todo.pop_back();
|
||||||
if (mark.is_marked(t)) {
|
if (mark.is_marked(t))
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
if (t == v) {
|
if (t == v) {
|
||||||
todo.reset();
|
todo.reset();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
mark.mark(t);
|
mark.mark(t);
|
||||||
|
|
||||||
if (!is_app(t)) {
|
if (!is_app(t))
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
app* a = to_app(t);
|
app* a = to_app(t);
|
||||||
todo.append(a->get_num_args(), a->get_args());
|
todo.append(a->get_num_args(), a->get_args());
|
||||||
}
|
}
|
||||||
|
@ -680,14 +659,11 @@ namespace {
|
||||||
while (!todo.empty()) {
|
while (!todo.empty()) {
|
||||||
t = todo.back();
|
t = todo.back();
|
||||||
todo.pop_back();
|
todo.pop_back();
|
||||||
if (mark1.is_marked(t)) {
|
if (mark1.is_marked(t))
|
||||||
continue;
|
continue;
|
||||||
}
|
mark1.mark(t);
|
||||||
mark1.mark(t);
|
if (!is_app(t))
|
||||||
|
continue;
|
||||||
if (!is_app(t)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
interval b;
|
interval b;
|
||||||
expr* e;
|
expr* e;
|
||||||
if (is_bound(t, e, b)) {
|
if (is_bound(t, e, b)) {
|
||||||
|
@ -718,14 +694,13 @@ namespace {
|
||||||
m_scopes.reset();
|
m_scopes.reset();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (unsigned i = m_scopes.size()-1; i >= target; --i) {
|
for (unsigned i = m_scopes.size(); i-- > target; ) {
|
||||||
undo_bound& undo = m_scopes[i];
|
undo_bound& undo = m_scopes[i];
|
||||||
SASSERT(m_bound.contains(undo.e));
|
SASSERT(m_bound.contains(undo.e));
|
||||||
if (undo.fresh) {
|
if (undo.fresh)
|
||||||
m_bound.erase(undo.e);
|
m_bound.erase(undo.e);
|
||||||
} else {
|
else
|
||||||
m_bound.insert(undo.e, undo.b);
|
m_bound.insert(undo.e, undo.b);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
m_scopes.shrink(target);
|
m_scopes.shrink(target);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,15 +5,34 @@ Module Name:
|
||||||
|
|
||||||
bv_bounds_tactic.h
|
bv_bounds_tactic.h
|
||||||
|
|
||||||
Abstract:
|
|
||||||
|
|
||||||
Contextual bounds simplification tactic.
|
|
||||||
|
|
||||||
Author:
|
Author:
|
||||||
|
|
||||||
Nuno Lopes (nlopes) 2016-2-12
|
Nuno Lopes (nlopes) 2016-2-12
|
||||||
Nikolaj Bjorner (nbjorner)
|
Nikolaj Bjorner (nbjorner)
|
||||||
|
|
||||||
|
Tactic Documentation:
|
||||||
|
|
||||||
|
## Tactic propagate-bv-bounds
|
||||||
|
|
||||||
|
### Short Description
|
||||||
|
|
||||||
|
Contextual bounds simplification tactic.
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
```z3
|
||||||
|
(declare-const x (_ BitVec 32))
|
||||||
|
(declare-const y (_ BitVec 32))
|
||||||
|
(declare-const z (_ BitVec 32))
|
||||||
|
(assert (bvule (_ bv4 32) x))
|
||||||
|
(assert (bvule x (_ bv24 32)))
|
||||||
|
(assert (or (bvule x (_ bv100 32)) (bvule (_ bv32 32) x)))
|
||||||
|
(apply propagate-bv-bounds)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Notes
|
||||||
|
|
||||||
|
* assumes that bit-vector inequalities have been simplified to use bvule/bvsle
|
||||||
|
|
||||||
--*/
|
--*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
|
@ -7,12 +7,6 @@ Module Name:
|
||||||
|
|
||||||
Abstract:
|
Abstract:
|
||||||
|
|
||||||
Reduce the number of bits used to encode constants, by using signed bounds.
|
|
||||||
Example: suppose x is a bit-vector of size 8, and we have
|
|
||||||
signed bounds for x such that:
|
|
||||||
-2 <= x <= 2
|
|
||||||
Then, x can be replaced by ((sign-extend 5) k)
|
|
||||||
where k is a fresh bit-vector constant of size 3.
|
|
||||||
|
|
||||||
Author:
|
Author:
|
||||||
|
|
||||||
|
@ -20,6 +14,41 @@ Author:
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
|
|
||||||
|
Tactic Documentation:
|
||||||
|
|
||||||
|
## Tactic reduce-bv-size
|
||||||
|
|
||||||
|
### Short Description
|
||||||
|
|
||||||
|
Rry to reduce bit-vector sizes using inequalities.
|
||||||
|
|
||||||
|
### Long Description
|
||||||
|
|
||||||
|
Reduce the number of bits used to encode constants, by using signed bounds.
|
||||||
|
Example: suppose $x$ is a bit-vector of size 8, and we have
|
||||||
|
signed bounds for $x$ such that:
|
||||||
|
|
||||||
|
```
|
||||||
|
-2 <= x <= 2
|
||||||
|
```
|
||||||
|
|
||||||
|
Then, $x$ can be replaced by `((sign-extend 5) k)`
|
||||||
|
where `k` is a fresh bit-vector constant of size 3.
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
```z3
|
||||||
|
(declare-const x (_ BitVec 32))
|
||||||
|
(assert (bvsle (bvneg (_ bv2 32)) x))
|
||||||
|
(assert (bvsle x (_ bv2 32)))
|
||||||
|
(assert (= (bvmul x x) (_ bv9 32)))
|
||||||
|
(apply (and-then simplify reduce-bv-size))
|
||||||
|
```
|
||||||
|
|
||||||
|
### Notes
|
||||||
|
|
||||||
|
* does not support proofs, nor unsat cores
|
||||||
|
|
||||||
--*/
|
--*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
|
|
@ -3,18 +3,30 @@ Copyright (c) 2015 Microsoft Corporation
|
||||||
|
|
||||||
Module Name:
|
Module Name:
|
||||||
|
|
||||||
bvarray2ufbvarray2uf_tactic.h
|
bvarray2uf_tactic.h
|
||||||
|
|
||||||
Abstract:
|
|
||||||
|
|
||||||
Tactic that rewrites bit-vector arrays into bit-vector
|
|
||||||
(uninterpreted) functions.
|
|
||||||
|
|
||||||
Author:
|
Author:
|
||||||
|
|
||||||
Christoph (cwinter) 2015-11-04
|
Christoph (cwinter) 2015-11-04
|
||||||
|
|
||||||
Notes:
|
Tactic Documentation:
|
||||||
|
|
||||||
|
## Tactic bvarray2uf
|
||||||
|
|
||||||
|
### Short Description
|
||||||
|
|
||||||
|
Tactic that rewrites bit-vector arrays into bit-vector
|
||||||
|
(uninterpreted) functions.
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
```z3
|
||||||
|
(declare-const a (Array (_ BitVec 32) (_ BitVec 32)))
|
||||||
|
(declare-const b (_ BitVec 32))
|
||||||
|
(declare-const c (_ BitVec 32))
|
||||||
|
(assert (= (select a b) c))
|
||||||
|
(apply bvarray2uf)
|
||||||
|
```
|
||||||
|
|
||||||
--*/
|
--*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
|
@ -5,15 +5,28 @@ Module Name:
|
||||||
|
|
||||||
dt2bv_tactic.h
|
dt2bv_tactic.h
|
||||||
|
|
||||||
Abstract:
|
|
||||||
|
|
||||||
Tactic that eliminates finite domain data-types.
|
|
||||||
|
|
||||||
Author:
|
Author:
|
||||||
|
|
||||||
nbjorner 2016-07-22
|
nbjorner 2016-07-22
|
||||||
|
|
||||||
Revision History:
|
Tactic Documentation
|
||||||
|
|
||||||
|
## Tactic dt2bv
|
||||||
|
|
||||||
|
### Short Description
|
||||||
|
|
||||||
|
Tactic that eliminates finite domain data-types.
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
```z3
|
||||||
|
(declare-datatypes ((Color 0)) (((Red) (Blue) (Green) (DarkBlue) (MetallicBlack) (MetallicSilver) (Silver) (Black))))
|
||||||
|
(declare-const x Color)
|
||||||
|
(declare-const y Color)
|
||||||
|
(assert (not (= x y)))
|
||||||
|
(assert (not (= x Red)))
|
||||||
|
(apply dt2bv)
|
||||||
|
```
|
||||||
|
|
||||||
--*/
|
--*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
|
@ -15,6 +15,22 @@ Author:
|
||||||
|
|
||||||
Revision History:
|
Revision History:
|
||||||
|
|
||||||
|
Tactic Documentation
|
||||||
|
|
||||||
|
## Tactic elim-small-bv
|
||||||
|
|
||||||
|
### Short Description
|
||||||
|
|
||||||
|
Eliminate small, quantified bit-vectors by expansion
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
```z3
|
||||||
|
(declare-fun p ((_ BitVec 2)) Bool)
|
||||||
|
(assert (forall ((x (_ BitVec 2))) (p x)))
|
||||||
|
(apply elim-small-bv)
|
||||||
|
```
|
||||||
|
|
||||||
--*/
|
--*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
|
|
@ -7,16 +7,26 @@ Module Name:
|
||||||
|
|
||||||
Abstract:
|
Abstract:
|
||||||
|
|
||||||
Rewriter for "maximing" the number of shared terms.
|
|
||||||
The idea is to rewrite AC terms to maximize sharing.
|
|
||||||
This rewriter is particularly useful for reducing
|
|
||||||
the number of Adders and Multipliers before "bit-blasting".
|
|
||||||
|
|
||||||
Author:
|
Author:
|
||||||
|
|
||||||
Leonardo de Moura (leonardo) 2011-12-29.
|
Leonardo de Moura (leonardo) 2011-12-29.
|
||||||
|
|
||||||
Revision History:
|
Tactic Documentation
|
||||||
|
|
||||||
|
## Tactic max-bv-sharing
|
||||||
|
|
||||||
|
### Short Description
|
||||||
|
|
||||||
|
Use heuristics to maximize the sharing of bit-vector expressions such as adders and multipliers
|
||||||
|
|
||||||
|
### Long Description
|
||||||
|
|
||||||
|
Rewriter for "maximing" the number of shared terms.
|
||||||
|
The idea is to rewrite AC terms to maximize sharing.
|
||||||
|
This rewriter is particularly useful for reducing
|
||||||
|
the number of Adders and Multipliers before "bit-blasting".
|
||||||
|
|
||||||
--*/
|
--*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
Loading…
Reference in a new issue