1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/*++
Copyright (c) 2022 Microsoft Corporation
Module Name:
elim_unconstr2_tactic.h
Abstract:
Tactic for eliminating unconstrained terms.
Author:
Nikolaj Bjorner (nbjorner) 2022-10-30
Tactic Documentation:
## Tactic elim-uncnstr
### Short Description
Eliminate Unconstrained uninterpreted constants
### Long Description
The tactic eliminates uninterpreted constants that occur only once in a goal and such that the immediate context
where they occur can be replaced by a fresh constant. We call these occurrences invertible.
It relies on a series of theory specific invertibility transformations.
In the following assume `x` and `x'` occur in a unique subterm and `y` is a fresh uninterpreted constant.
#### Boolean Connectives
| Original Context | New Term | Updated solution |
|------------------|----------|------------------------ |
`(if c x x')` | `y` | `x = x' = y` |
`(if x x' e)` | `y` | `x = true, x' = y` |
`(if x t x')` | `y` | `x = false, x' = y` |
`(not x)` | `y` | `x = (not y)` |
`(and x x')` | `y` | `x = y, x' = true` |
`(or x x')` | `y` | `x = y, x' = false` |
`(= x t)` | `y` | `x = (if y t (diff t))` |
where diff is a diagnonalization function available in domains of size `>` 1.
#### Arithmetic
| Original Context | New Term | Updated solution |
|------------------|----------|------------------------ |
`(+ x t)` | `y` | `x = y - t` |
`(* x x')` | `y` | `x = y, x' = 1` |
`(* -1 x)` | `y` | `x = -y` |
`(<= x t)` | `y` | `x = (if y t (+ t 1))` |
`(<= t x)` | `y` | `x = (if y t (- t 1))` |
#### Bit-vectors
| Original Context | New Term | Updated solution |
|------------------|----------|--------------------------|
`(bvadd x t)` | `y` | `x = y - t` |
`(bvmul x x')` | `y` | `x = y, x' = 1` |
`(bvmul odd x)` | `y` | `x = inv(odd)*y` |
`((extract sz-1 0) x)` | `y` | `x = y` |
`((extract hi lo) x)` | `y` | `x = (concat y1 y y2)` |
`(udiv x x')` | `y` | `x = y, x' = 1` |
`(concat x x')` | `y` | `x = (extract hi1 lo1 y)` |
`(bvule x t)` | `(or y (= t MAX))` | `x = (if y t (bvadd t 1))` |
`(bvule t x)` | `(or y (= t MIN))` | `x = (if y t (bvsub t 1))` |
`(bvnot x)` | `y` | `x = (bvnot y)` |
`(bvand x x')` | `y` | `x = y, x' = MAX` |
In addition there are conversions for shift and bit-wise or and signed comparison.
#### Arrays
| Original Context | New Term | Updated solution |
|------------------|----------|--------------------------|
`(select x t)` | `y` | `x = (const y)` |
`(store x x1 x2)` | `y` | `x2 = (select x x1), x = y, x1 = arb` |
#### Algebraic Datatypes
| Original Context | New Term | Updated solution |
|------------------|----------|--------------------------|
`(head x)` | `y` | `x = (cons y arb)` |
### Example
```z3
(declare-const x Int)
(declare-const y Int)
(declare-fun p (Int) Bool)
(assert (>= (+ y (+ x y)) y))
(assert (p y))
(apply elim-uncnstr)
(assert (p (+ x y)))
(apply elim-uncnstr)
```
### Notes
* supports unsat cores
* does not support fine-grained proofs
--*/
inline tactic *
;
;