feat: equation theorem manager

This commit is contained in:
Leonardo de Moura 2021-09-17 13:45:28 -07:00
parent 42eba87325
commit 793d493df0
2 changed files with 91 additions and 0 deletions

View file

@ -38,3 +38,4 @@ import Lean.Meta.Injective
import Lean.Meta.Structure
import Lean.Meta.Constructions
import Lean.Meta.CongrTheorems
import Lean.Meta.Eqns

90
src/Lean/Meta/Eqns.lean Normal file
View file

@ -0,0 +1,90 @@
/-
Copyright (c) 2021 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Leonardo de Moura
-/
import Lean.Meta.Basic
namespace Lean.Meta
def GetEqnsFn := Name → MetaM (Option (Array Name))
private builtin_initialize getEqnsFnsRef : IO.Ref (List GetEqnsFn) ← IO.mkRef []
/--
Register a new function for retrieving equation theorems.
We generate equations theorems on demand, and they are generated by more than one module.
For example, the structural and well-founded recursion modules generate them.
Most recent getters are tried first.
A getter returns an `Option (Array Name)`. The result is `none` if the getter failed.
Otherwise, it is a sequence of theorem names where each one of them corresponds to
an alternative. Example: the definition
```
def f (xs : List Nat) : List Nat :=
match xs with
| [] => []
| x::xs => (x+1)::f xs
```
should have two equational theorems associated with it
```
f [] = []
```
and
```
(x : Nat) → (xs : List Nat) → f (x :: xs) = (x+1) :: f xs
```
-/
def registerGetEqnsFn (f : GetEqnsFn) : IO Unit := do
unless (← initializing) do
throw (IO.userError "failed to register equation getter, this kind of extension can only be registered during initialization")
getEqnsFnsRef.modify (f :: ·)
def getEqnsFor? (declName : Name) : MetaM (Option (Array Name)) := do
for f in (← getEqnsFnsRef.get) do
if let some r ← f declName then
return some r
return none
def GetUnfoldEqnFn := Name → MetaM (Option Name)
private builtin_initialize getUnfoldEqnFnsRef : IO.Ref (List GetUnfoldEqnFn) ← IO.mkRef []
/--
Register a new function for retrieving a "unfold" equation theorem.
We generate this kind of equation theorem on demand, and it is generated by more than one module.
For example, the structural and well-founded recursion modules generate it.
Most recent getters are tried first.
A getter returns an `Option Name`. The result is `none` if the getter failed.
Otherwise, it is a theorem name. Example: the definition
```
def f (xs : List Nat) : List Nat :=
match xs with
| [] => []
| x::xs => (x+1)::f xs
```
should have the theorem
```
(xs : Nat) →
f xs =
match xs with
| [] => []
| x::xs => (x+1)::f xs
```
-/
def registerGetUnfoldEqnFn (f : GetUnfoldEqnFn) : IO Unit := do
unless (← initializing) do
throw (IO.userError "failed to register equation getter, this kind of extension can only be registered during initialization")
getUnfoldEqnFnsRef.modify (f :: ·)
def getUnfoldEqnFor? (declName : Name) : MetaM (Option Name) := do
for f in (← getUnfoldEqnFnsRef.get) do
if let some r ← f declName then
return some r
return none
end Lean.Meta