mirror of
https://github.com/Z3Prover/z3
synced 2025-04-24 09:35:32 +00:00
cave in to supporting proofs (partially) in simplifiers, updated doc
This commit is contained in:
parent
aaabbfb594
commit
80033e8744
36 changed files with 157 additions and 108 deletions
|
@ -5,19 +5,11 @@ Module Name:
|
|||
|
||||
injectivity_tactic.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
Injectivity tactics
|
||||
- Discover axioms of the form `forall x. (= (g (f x)) x`
|
||||
Mark `f` as injective
|
||||
- Rewrite (sub)terms of the form `(= (f x) (f y))` to `(= x y)` whenever `f` is injective.
|
||||
|
||||
Author:
|
||||
|
||||
Nicolas Braud-Santoni (t-nibrau) 2017-08-10
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
|
@ -164,8 +156,6 @@ class injectivity_tactic : public tactic {
|
|||
struct rewriter_eq_cfg : public default_rewriter_cfg {
|
||||
ast_manager & m_manager;
|
||||
InjHelper & inj_map;
|
||||
// expr_ref_vector m_out;
|
||||
// sort_ref_vector m_bindings;
|
||||
|
||||
ast_manager & m() const { return m_manager; }
|
||||
|
||||
|
@ -176,14 +166,13 @@ class injectivity_tactic : public tactic {
|
|||
}
|
||||
|
||||
void cleanup_buffers() {
|
||||
// m_out.finalize();
|
||||
}
|
||||
|
||||
void reset() {
|
||||
}
|
||||
|
||||
br_status reduce_app(func_decl * f, unsigned num, expr * const * args, expr_ref & result, proof_ref & result_pr) {
|
||||
if(num != 2)
|
||||
if (num != 2)
|
||||
return BR_FAILED;
|
||||
|
||||
if (!m().is_eq(f))
|
||||
|
@ -230,8 +219,6 @@ class injectivity_tactic : public tactic {
|
|||
finder * m_finder;
|
||||
rewriter_eq * m_eq;
|
||||
InjHelper * m_map;
|
||||
// rewriter_inverse * m_inverse;
|
||||
|
||||
params_ref m_params;
|
||||
ast_manager & m_manager;
|
||||
|
||||
|
|
|
@ -13,7 +13,33 @@ Author:
|
|||
|
||||
Nicolas Braud-Santoni (t-nibrau) 2017-08-10
|
||||
|
||||
Notes:
|
||||
|
||||
Tactic Documentation:
|
||||
|
||||
## Tactic injectivity
|
||||
|
||||
### Short Description:
|
||||
|
||||
- Discover axioms of the form `forall x. (= (g (f x)) x`
|
||||
Mark `f` as injective
|
||||
|
||||
- Rewrite (sub)terms of the form `(= (f x) (f y))` to `(= x y)` whenever `f` is injective.
|
||||
|
||||
### Example
|
||||
|
||||
```z3
|
||||
(declare-fun f (Int) Int)
|
||||
(declare-fun g (Int) Int)
|
||||
(declare-const x Int)
|
||||
(declare-const y Int)
|
||||
(assert (forall ((x Int)) (= (g (f x)) x)))
|
||||
(assert (not (= (f x) (f (f y)))))
|
||||
(apply injectivity)
|
||||
```
|
||||
|
||||
### Notes
|
||||
|
||||
* does not support cores nor proofs
|
||||
|
||||
--*/
|
||||
#pragma once
|
||||
|
|
|
@ -23,15 +23,15 @@ Reduce the number of arguments of function applications, when for all occurrence
|
|||
|
||||
### Long Description
|
||||
|
||||
Example, suppose we have a function `f` with `2` arguments.
|
||||
There are 1000 applications of this function, but the first argument is always "a", "b" or "c".
|
||||
Thus, we replace the `f(t1, t2)` with
|
||||
Example, suppose we have a function $f$ with 2 arguments.
|
||||
There are 1000 applications of this function, but the first argument is always $a$, $b$ or $c$.
|
||||
Thus, we replace the $f(t_1, t_2)$ with
|
||||
|
||||
* `f_a(t2)` if `t1 = a`
|
||||
* `f_b(t2)` if `t2 = b`
|
||||
* `f_c(t2)` if `t2 = c`
|
||||
* $f_a(t_2)$ if $t_1 = a$
|
||||
* $f_b(t_2)$ if $t_2 = b$
|
||||
* $f_c(t_2)$ if $t_2 = c$
|
||||
|
||||
Since `f_a`, `f_b`, `f_c` are new symbols, satisfiability is preserved.
|
||||
Since $f_a$, $f_b$, $f_c$ are new symbols, satisfiability is preserved.
|
||||
|
||||
This transformation is very similar in spirit to the Ackermman's reduction.
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ public:
|
|||
m(m),
|
||||
m_params(p),
|
||||
m_factory(f),
|
||||
m_dep(m, m.mk_true(), nullptr)
|
||||
m_dep(m, m.mk_true(), nullptr, nullptr)
|
||||
{}
|
||||
|
||||
/**
|
||||
|
@ -58,22 +58,22 @@ public:
|
|||
unsigned qtail() const override { return m_goal->size(); }
|
||||
|
||||
dependent_expr const& operator[](unsigned i) override {
|
||||
m_dep = dependent_expr(m, m_goal->form(i), m_goal->dep(i));
|
||||
m_dep = dependent_expr(m, m_goal->form(i), m_goal->pr(i), m_goal->dep(i));
|
||||
return m_dep;
|
||||
}
|
||||
|
||||
void update(unsigned i, dependent_expr const& j) override {
|
||||
if (inconsistent())
|
||||
return;
|
||||
auto [f, d] = j();
|
||||
m_goal->update(i, f, nullptr, d);
|
||||
auto [f, p, d] = j();
|
||||
m_goal->update(i, f, p, d);
|
||||
}
|
||||
|
||||
void add(dependent_expr const& j) override {
|
||||
if (inconsistent())
|
||||
return;
|
||||
auto [f, d] = j();
|
||||
m_goal->assert_expr(f, nullptr, d);
|
||||
auto [f, p, d] = j();
|
||||
m_goal->assert_expr(f, p, d);
|
||||
}
|
||||
|
||||
bool inconsistent() override {
|
||||
|
@ -108,7 +108,7 @@ public:
|
|||
tactic_report report(name(), *in);
|
||||
m_goal = in.get();
|
||||
try {
|
||||
if (!in->proofs_enabled())
|
||||
if (!in->proofs_enabled() || m_simp->supports_proofs())
|
||||
m_simp->reduce();
|
||||
if (m.inc())
|
||||
advance_qhead();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue