This adds the concept of **functional induction** to lean.
Derived from the definition of a (possibly mutually) recursive function,
a **functional
induction principle** is tailored to proofs about that function. For
example from:
```
def ackermann : Nat → Nat → Nat
| 0, m => m + 1
| n+1, 0 => ackermann n 1
| n+1, m+1 => ackermann n (ackermann (n + 1) m)
derive_functional_induction ackermann
```
we get
```
ackermann.induct (motive : Nat → Nat → Prop) (case1 : ∀ (m : Nat), motive 0 m)
(case2 : ∀ (n : Nat), motive n 1 → motive (Nat.succ n) 0)
(case3 : ∀ (n m : Nat), motive (n + 1) m → motive n (ackermann (n + 1) m) → motive (Nat.succ n) (Nat.succ m))
(x x : Nat) : motive x x
```
At the moment, the user has to ask for the functional induction
principle explicitly using
```
derive_functional_induction ackermann
```
The module docstring of `Lean/Meta/Tactic/FunInd.lean` contains more
details on the
design and implementation of this command.
More convenience around this (e.g. a `functional induction` tactic) will
follow eventually.
This PR includes a bunch of `PSum`/`PSigma` related functions in the
`Lean.Tactic.FunInd`
namespace. I plan to move these to `PackArgs`/`PackMutual` afterwards,
and do some cleaning
up as I do that.
---------
Co-authored-by: David Thrane Christiansen <david@davidchristiansen.dk>
Co-authored-by: Leonardo de Moura <leomoura@amazon.com>
We want to be able to update `InfoState` at `AttrM` which is just an
alias for `CoreM`.
I considered defining `AttrM` as `StateRefT InfoState CoreM`, but this
is problematic because we also want to invoke `AttrM` monadic
actions from `MetaM`.
Closes#1350
This fix may impact performance. Note that we don't need to flush the
cache if we are "adding" stuff to the environment. We only need to
flush the caches if the change is not monotonic. BTW, most of the
changes are monotonic. I think this is why we did not hit this bug before.
We may also move all these caches to an environment extension. It is
an easy way to make sure we preserve the cache when extending the
environment.
I tried a few benchmarks and did not notice a significant difference.
cc @kha @gebner
fixes#1051
The new class specifies an interface for saving and restoring the
backtrackable part of the state.
This commit also fixes a few issues.
- `commitWhen` at `LevelDefEq` was defining a checkpoint for
the `isDefEq` methods, and it affects how postponed universe
constraints are handled. However, the name suggests it is
similar to `commitWhenSome?`, and consequently it was used
in other places that had nothing to do with `isDefEq`.
So, I renamed it, and provided the generic `commitWhen` at the new
`MonadBacktrack.lean` file.
- We were restoring more state then needed in a few places.
For example, we were discarding all caches.
- At `SyntheticMVars.lean`, we were using the `Meta.commitWhenSome?`
method which does not restore the `Term.State`.
@Kha I marked the corresponding methods as `protected`.
I currently can't stand `throw_error`, and I am optimistic about
server highlighting feature you are working on :)