You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: posts/simp-made-simple.md
+13-16Lines changed: 13 additions & 16 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -97,8 +97,8 @@ as we shall see in the coming subsection.
97
97
98
98
[`Step`](https://leanprover-community.github.io/mathlib4_docs/find/?pattern=Lean.Meta.Simp.Step#doc) is the type that represents a single step in the simplification loop. In `simp`'s algorithm, a step intuitively corresponds to two pieces of information:
99
99
100
-
101
100
1) The **result** of simplifying an expression `e`,
101
+
102
102
2) The **location** of what should be simplified next, and in which **direction** (pre or post).
103
103
104
104
The result of simplifying `e` is encoded as an expression `e'` and a proof that `e = e'`.
@@ -170,25 +170,24 @@ previous blog post.
170
170
171
171
The constructors do the following:
172
172
173
-
-`continue` indicates that the simproc is done with this expression.
173
+
1)`continue` indicates that the simproc is done with this expression.
174
174
As a result, simp will not attempt to simplify the expression again using the same simproc to prevent the simplification procedure from looping.
175
175
This is often used as the "default" output if a simproc was unable to find a simplification in a given expression.
176
176
For example:
177
177
178
178
-`Nat.reduceDvd` uses this when the expression is *not* of the form `a | b` where `a`, `b` are explicit natural numbers.
179
-
180
179
-`reduceIte` use this when the expression is *not* of the form `if h then a else b` where `h` is an expression that can be simplified to `True` or `False`
181
180
(note that the simplification of `h` is handled by a different `simp` call).
182
181
183
182
This only applies for the expression at hand: if this is a pre-procedure then the simproc may still end up being called on subexpressions.
184
183
For example, when calling `simp` on `if RiemannHypothesis then 0 else if 1 + 1 = 2 then 0 else 0`, the simproc `reduceIte` runs twice: once on the outer `if ... then ... else`, where it uses `continue`, and once on the inner `if ... then ... else`, which gets simplified to `0`.
185
184
186
-
-`done` indicates that `simp` is done with a given expression.
185
+
2)`done` indicates that `simp` is done with a given expression.
187
186
When `Nat.reduceDvd` is called on an expression of the form `a | b` where `a`, `b` are explicit natural numbers, it simplifies it to `True` or `False`.
188
187
Either way, the output is in simp normal form and there is no need to simplify it further.
189
188
Thus `Nat.reduceDvd` uses `done` in such a case.
190
189
191
-
-`visit` indicates (for a pre-procedure) that a simplification has been done but that pre-procedures should be tried again on the simplified expression.
190
+
3)`visit` indicates (for a pre-procedure) that a simplification has been done but that pre-procedures should be tried again on the simplified expression.
192
191
When `reduceIte` is called on a expressions of the form `if p then a else b` where `p` can simplified to `True` (resp. `False`), it outputs `a` (resp. `b`).
193
192
Since `a` and `b` could be arbitrarily complicated expressions, it makes sense to try and simplify them further.
194
193
Thus `reduceIte` uses `visit` in such a case.
@@ -197,8 +196,6 @@ The constructors do the following:
197
196
198
197
In this section, we take a look at another key component of the internals of simp, namely the `SimpM` monad.
199
198
200
-
### `SimpM`
201
-
202
199
[`SimpM`](https://leanprover-community.github.io/mathlib4_docs/find/?pattern=Lean.Meta.Simp.SimpM#doc) is the monad that tracks the current context `simp` is running in (what `simp` theorems are available, etc) and what has been done so far (e.g. number of steps taken, theorems used).
203
200
In particular it also captures the `MetaM` context.
204
201
@@ -224,15 +221,15 @@ Let's go through these steps one by one.
224
221
(i.e. what's happening, as the program runs), we need to capture more information than what `MetaM` gives us.
225
222
Specifically, we want a monad that can track what's happening via the following structure:
226
223
227
-
```lean
228
-
structure Simp.State where
229
-
cache : Cache
230
-
congrCache : CongrCache
231
-
dsimpCache : ExprStructMap Expr
232
-
usedTheorems : UsedSimps
233
-
numSteps : Nat
234
-
diag : Diagnostics
235
-
```
224
+
```lean
225
+
structure Simp.State where
226
+
cache : Cache
227
+
congrCache : CongrCache
228
+
dsimpCache : ExprStructMap Expr
229
+
usedTheorems : UsedSimps
230
+
numSteps : Nat
231
+
diag : Diagnostics
232
+
```
236
233
237
234
This is something we can achieve using the `StateRefT` monad transformer, which takes as input a state type (`Simp.State` in our case) and a monad, and creates a new monad that can read _and write_ this state.
238
235
In other words, `StateRefT Simp.State MetaM` is a souped up version of `MetaM` that can now track extra information by storing (and updating) a term of type `Simp.State`.
0 commit comments