3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-24 09:35:32 +00:00
This commit is contained in:
Nikolaj Bjorner 2022-12-06 15:44:21 -08:00
parent 7df4e04a2c
commit 1e06c7414a
3 changed files with 130 additions and 2 deletions

View file

@ -13,7 +13,47 @@ Author:
Leonardo de Moura (leonardo) 2011-12-28.
Revision History:
Note:
tactic documentation below co-created using gptchat (with some corrections) :-)
Tactic Documentation:
## Tactic nnf
### Short Description:
The tactic converts formulas to negation normal form (NNF)
### Long Description
In NNF, negations only appear in front of atomic formulas.
Standard rules for conversion into negation normal form are:
- `(not (and p q))` is converted to `(or (not p) (not q))`
- `(not (or p q))` is converted to `(and (not p) (not q))`
- `(not (not p))` is converted to `p`
- `(not (exists x. p))` is converted to `(forall x. (not p))`
- `(not (forall x. p))` is converted to `(exists x. (not p))`
Once all negations are pushed inside, the resulting formula is in NNF.
### Example
```z3
(declare-const x Int)
(assert (not (or (> x 0) (< x 0))))
(apply nnf)
```
This would convert the formula (not (or (> x 0) (< x 0))) to (and (<= x 0) (>= x 0)), which is in NNF.
### Notes
* supports unsat cores, proof terms
--*/
#pragma once

View file

@ -13,7 +13,72 @@ Author:
Leonardo (leonardo) 2012-02-19
Notes:
Tactic Documentation:
## Tactic reduce-args
### Short Description:
Reduce the number of arguments of function applications, when for all occurrences of a function f the i-th is a value.
### 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
* `f_a(t2)` if `t1 = a`
* `f_b(t2)` if `t2 = b`
* `f_c(t2)` if `t2 = c`
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.
This transformation should work in the following way:
```
1- Create a mapping decl2arg_map from declarations to tuples of booleans, an entry [f -> (true, false, true)]
means that f is a declaration with 3 arguments where the first and third arguments are always values.
2- Traverse the formula and populate the mapping.
For each function application f(t1, ..., tn) do
a) Create a boolean tuple (is_value(t1), ..., is_value(tn)) and do
the logical-and with the tuple that is already in the mapping. If there is no such tuple
in the mapping, we just add a new entry.
If all entries are false-tuples, then there is nothing to be done. The transformation is not applicable.
Now, we create a mapping decl2new_decl from (decl, val_1, ..., val_n) to decls. Note that, n may be different for each entry,
but it is the same for the same declaration.
For example, suppose we have [f -> (true, false, true)] in decl2arg_map,
and applications f(1, a, 2), f(1, b, 2), f(1, b, 3), f(2, b, 3), f(2, c, 3) in the formula.
Then, decl2arg_map would contain
(f, 1, 2) -> f_1_2
(f, 1, 3) -> f_1_3
(f, 2, 3) -> f_2_3
where f_1_2, f_1_3 and f_2_3 are new function symbols.
Using the new map, we can replace the occurrences of f.
```
### Example
```z3
(declare-fun f (Int Int) Bool)
(declare-const x Int)
(assert (f 1 2))
(assert (f 1 3))
(assert (f 2 4))
(assert (f 2 5))
(assert (f 1 6))
(assert (f 1 7))
(assert (f 1 x))
(apply reduce-args)
```
### Notes
* supports unsat cores
* does not support proof terms
--*/
#pragma once