Compare commits

...

1 Commits

Author SHA1 Message Date
Leonardo de Moura
40b8e0bc12 chore: rename automatically generated "unfold" theorems
Given a definition `foo`, they were previously called `foo._unfold`
until 4.7.0. We tried to rename them to `foo.def`, but it created too
many issues in the Mathlib repo. We decided to rename it again to
`foo.eq_def`. The new name is also consistent with the `eq_<idx>`
theorems generated for different "cases". That is, `foo.eq_def` is the
equality theorem for the whole definition, and `foo.eq_<idx>` is the
equality theorem for case `<idx>`.
2024-03-25 13:47:36 -07:00
17 changed files with 70 additions and 47 deletions

View File

@@ -371,7 +371,7 @@ def mkUnfoldEq (declName : Name) (info : EqnInfoCore) : MetaM Name := withLCtx {
mkUnfoldProof declName goal.mvarId!
let type mkForallFVars xs type
let value mkLambdaFVars xs ( instantiateMVars goal)
let name := baseName ++ `def
let name := Name.str baseName unfoldThmSuffix
addDecl <| Declaration.thmDecl {
name, type, value
levelParams := info.levelParams

View File

@@ -68,7 +68,7 @@ def mkEqns (info : EqnInfo) : MetaM (Array Name) :=
for i in [: eqnTypes.size] do
let type := eqnTypes[i]!
trace[Elab.definition.structural.eqns] "{eqnTypes[i]!}"
let name := baseName ++ (`eq).appendIndexAfter (i+1)
let name := (Name.str baseName eqnThmSuffixBase).appendIndexAfter (i+1)
thmNames := thmNames.push name
let value mkProof info.declName type
let (type, value) removeUnusedEqnHypotheses type value

View File

@@ -119,7 +119,7 @@ def mkEqns (declName : Name) (info : EqnInfo) : MetaM (Array Name) :=
for i in [: eqnTypes.size] do
let type := eqnTypes[i]!
trace[Elab.definition.wf.eqns] "{eqnTypes[i]!}"
let name := baseName ++ (`eq).appendIndexAfter (i+1)
let name := (Name.str baseName eqnThmSuffixBase).appendIndexAfter (i+1)
thmNames := thmNames.push name
let value mkProof declName type
let (type, value) removeUnusedEqnHypotheses type value

View File

@@ -9,25 +9,32 @@ import Lean.Meta.Basic
import Lean.Meta.AppBuilder
namespace Lean.Meta
def eqnThmSuffixBase := "eq"
def eqnThmSuffixBasePrefix := eqnThmSuffixBase ++ "_"
def eqn1ThmSuffix := eqnThmSuffixBasePrefix ++ "1"
example : eqn1ThmSuffix = "eq_1" := rfl
/-- Returns `true` if `s` is of the form `eq_<idx>` -/
def isEqnReservedNameSuffix (s : String) : Bool :=
"eq_".isPrefixOf s && (s.drop 3).isNat
eqnThmSuffixBasePrefix.isPrefixOf s && (s.drop 3).isNat
/-- Returns `true` if `s == "def"` -/
def unfoldThmSuffix := "eq_def"
/-- Returns `true` if `s == "eq_def"` -/
def isUnfoldReservedNameSuffix (s : String) : Bool :=
s == "def"
s == unfoldThmSuffix
/--
Throw an error if names for equation theorems for `declName` are not available.
-/
def ensureEqnReservedNamesAvailable (declName : Name) : CoreM Unit := do
ensureReservedNameAvailable declName "def"
ensureReservedNameAvailable declName "eq_1"
ensureReservedNameAvailable declName unfoldThmSuffix
ensureReservedNameAvailable declName eqn1ThmSuffix
-- TODO: `declName` may need to reserve multiple `eq_<idx>` names, but we check only the first one.
-- Possible improvement: try to efficiently compute the number of equation theorems at declaration time, and check all of them.
/--
Ensures that `f.def` and `f.eq_<idx>` are reserved names if `f` is a safe definition.
Ensures that `f.eq_def` and `f.eq_<idx>` are reserved names if `f` is a safe definition.
-/
builtin_initialize registerReservedNamePredicate fun env n =>
match n with
@@ -87,7 +94,7 @@ builtin_initialize eqnsExt : EnvExtension EqnsExtState ←
/--
Simple equation theorem for nonrecursive definitions.
-/
private def mkSimpleEqThm (declName : Name) (suffix := `def) : MetaM (Option Name) := do
private def mkSimpleEqThm (declName : Name) (suffix := Name.mkSimple unfoldThmSuffix) : MetaM (Option Name) := do
if let some (.defnInfo info) := ( getEnv).find? declName then
lambdaTelescope (cleanupAnnotations := true) info.value fun xs body => do
let lhs := mkAppN (mkConst info.name <| info.levelParams.map mkLevelParam) xs
@@ -122,7 +129,7 @@ Equation theorems are generated on demand, check whether they were generated in
-/
private partial def alreadyGenerated? (declName : Name) : MetaM (Option (Array Name)) := do
let env getEnv
let eq1 := declName ++ `eq_1
let eq1 := Name.str declName eqn1ThmSuffix
if env.contains eq1 then
let rec loop (idx : Nat) (eqs : Array Name) : MetaM (Array Name) := do
let nextEq := declName ++ (`eq).appendIndexAfter idx
@@ -152,7 +159,7 @@ def getEqnsFor? (declName : Name) (nonRec := false) : MetaM (Option (Array Name)
registerEqnThms declName r
return some r
if nonRec then
let some eqThm mkSimpleEqThm declName (suffix := `eq_1) | return none
let some eqThm mkSimpleEqThm declName (suffix := Name.mkSimple eqn1ThmSuffix) | return none
let r := #[eqThm]
registerEqnThms declName r
return some r
@@ -199,7 +206,7 @@ You can use `nonRec := true` to override this behavior.
-/
def getUnfoldEqnFor? (declName : Name) (nonRec := false) : MetaM (Option Name) := withLCtx {} {} do
let env getEnv
let unfoldName := declName ++ `def
let unfoldName := Name.str declName unfoldThmSuffix
if env.contains unfoldName then
return some unfoldName
if ( shouldGenerateEqnThms declName) then

View File

@@ -11,7 +11,7 @@ theorem ex : foo 0 = 0 := by
sorry
/--
info: foo.def (n : Nat) :
info: foo.eq_def (n : Nat) :
foo n =
if n = 0 then 0
else
@@ -20,4 +20,4 @@ info: foo.def (n : Nat) :
foo x
-/
#guard_msgs in
#check foo.def
#check foo.eq_def

View File

@@ -58,7 +58,7 @@ theorem ex2 : g 0 = 0 := by
unfold g
simp
#check g.def
#check g.eq_def
end Ex2

View File

@@ -1,8 +1,8 @@
-- `g.def` is not reserved yet
theorem g.def : 1 + x = x + 1 := Nat.add_comm ..
-- `g.eq_def` is not reserved yet
theorem g.eq_def : 1 + x = x + 1 := Nat.add_comm ..
/--
error: failed to declare `g` because `g.def` has already been declared
error: failed to declare `g` because `g.eq_def` has already been declared
-/
#guard_msgs (error) in
def g (x : Nat) := x + 1
@@ -10,10 +10,10 @@ def g (x : Nat) := x + 1
def f (x : Nat) := x + 1
/--
error: 'f.def' is a reserved name
error: 'f.eq_def' is a reserved name
-/
#guard_msgs (error) in
theorem f.def : f x = x + 1 := rfl
theorem f.eq_def : f x = x + 1 := rfl
/--
error: 'f.eq_1' is a reserved name
@@ -31,16 +31,16 @@ def f.eq_2_ := 10 -- Should be ok
#guard_msgs (error) in
#check f.eq_2
/-- info: f.def (x : Nat) : f x = x + 1 -/
/-- info: f.eq_def (x : Nat) : f x = x + 1 -/
#guard_msgs in
#check f.def
#check f.eq_def
def fact : Nat Nat
| 0 => 1
| n+1 => (n+1) * fact n
/--
info: fact.def :
info: fact.eq_def :
∀ (x : Nat),
fact x =
match x with
@@ -48,7 +48,7 @@ info: fact.def :
| n.succ => (n + 1) * fact n
-/
#guard_msgs in
#check fact.def
#check fact.eq_def
/-- info: fact.eq_1 : fact 0 = 1 -/
#guard_msgs in
@@ -77,9 +77,9 @@ example : fact' 0 + fact' 1 = 2 := by
rw [fact'.eq_1]
example : fact' 0 + fact' 1 = 2 := by
rw [fact'.def, fact'.def]; simp
rw [fact'.eq_def, fact'.eq_def]; simp
guard_target = 1 + fact' 0 = 2
rw [fact'.def]
rw [fact'.eq_def]
guard_target =
(1 + fact.match_1 (fun _ => Nat) 0 (fun _ => 1) fun n => (n + 1) * fact' n) = 2
simp
@@ -88,3 +88,19 @@ theorem bla : 0 = 0 := rfl
def bla.def := 1 -- should work since `bla` is a theorem
def bla.eq_1 := 2 -- should work since `bla` is a theorem
def find (as : Array Int) (i : Nat) (v : Int) : Nat :=
if _ : i < as.size then
if as[i] = v then
i
else
find as (i+1) v
else
i
/--
info: find.eq_def (as : Array Int) (i : Nat) (v : Int) :
find as i v = if x : i < as.size then if as[i] = v then i else find as (i + 1) v else i
-/
#guard_msgs in
#check find.eq_def

View File

@@ -30,7 +30,7 @@ theorem len_2 (a b : α) (bs : List α) : len (a::b::bs) = 1 + len (b::bs) := by
conv => lhs; unfold len
-- The `unfold` tactic above generated the following theorem
#check @len.def
#check @len.eq_def
theorem len_cons (a : α) (as : List α) : len (a::as) = 1 + len as := by
cases as with

View File

@@ -49,7 +49,7 @@ theorem len_2 (a b : α) (bs : List α) : len (a::b::bs) = 1 + len (b::bs) := by
conv => lhs; unfold len
-- The `unfold` tactic above generated the following theorem
#check @len.def
#check @len.eq_def
theorem len_cons (a : α) (as : List α) : len (a::as) = 1 + len as := by
cases as with
@@ -99,7 +99,7 @@ theorem len_2 (a b : α) (bs : List α) : len (a::b::bs) = 1 + len (b::bs) := by
conv => lhs; unfold len
-- The `unfold` tactic above generated the following theorem
#check @len.def
#check @len.eq_def
theorem len_cons (a : α) (as : List α) : len (a::as) = 1 + len as := by
cases as with

View File

@@ -17,7 +17,7 @@ def foo (xs ys zs : List Nat) : List Nat :=
#eval tst ``foo
/--
info: foo.def (xs ys zs : List Nat) :
info: foo.eq_def (xs ys zs : List Nat) :
foo xs ys zs =
match (xs, ys) with
| (xs', ys') =>
@@ -29,7 +29,7 @@ info: foo.def (xs ys zs : List Nat) :
| x => [2]
-/
#guard_msgs in
#check foo.def
#check foo.eq_def
def bar (xs ys : List Nat) : List Nat :=

View File

@@ -8,7 +8,7 @@ def tst (declName : Name) : MetaM Unit := do
#eval tst ``List.map
#check @List.map.eq_1
#check @List.map.eq_2
#check @List.map.def
#check @List.map.eq_def
def foo (xs ys zs : List Nat) : List Nat :=
match (xs, ys) with
@@ -23,7 +23,7 @@ def foo (xs ys zs : List Nat) : List Nat :=
#check foo.eq_1
#check foo.eq_2
#check foo.def
#check foo.eq_def
#eval tst ``foo
@@ -40,7 +40,7 @@ def g : List Nat → List Nat → Nat
#check g.eq_3
#check g.eq_4
#check g.eq_5
#check g.def
#check g.eq_def
def h (xs : List Nat) (y : Nat) : Nat :=
match xs with
@@ -53,7 +53,7 @@ def h (xs : List Nat) (y : Nat) : Nat :=
#eval tst ``h
#check h.eq_1
#check h.eq_2
#check h.def
#check h.eq_def
def r (i j : Nat) : Nat :=
i +
@@ -68,7 +68,7 @@ def r (i j : Nat) : Nat :=
#check r.eq_1
#check r.eq_2
#check r.eq_3
#check r.def
#check r.eq_def
def bla (f g : α α α) (a : α) (i : α) (j : Nat) : α :=
f i <|
@@ -83,4 +83,4 @@ def bla (f g : ααα) (a : α) (i : α) (j : Nat) : α :=
#check @bla.eq_1
#check @bla.eq_2
#check @bla.eq_3
#check @bla.def
#check @bla.eq_def

View File

@@ -14,7 +14,7 @@ def g (i j : Nat) : Nat :=
#eval tst ``g
#check g.eq_1
#check g.eq_2
#check g.def
#check g.eq_def
def h (i j : Nat) : Nat :=
let z :=
@@ -26,4 +26,4 @@ def h (i j : Nat) : Nat :=
#eval tst ``h
#check h.eq_1
#check h.eq_2
#check h.def
#check h.eq_def

View File

@@ -17,4 +17,4 @@ def wk_comp : Wk n m → Wk m l → Wk n l
#check @wk_comp.eq_1
#check @wk_comp.eq_2
#check @wk_comp.def
#check @wk_comp.eq_def

View File

@@ -24,4 +24,4 @@ end
#eval tst ``isEven
#check @isEven.eq_1
#check @isEven.eq_2
#check @isEven.def
#check @isEven.eq_def

View File

@@ -33,8 +33,8 @@ end
#eval tst ``g
#check g.eq_1
#check g.eq_2
#check g.def
#check g.eq_def
#eval tst ``h
#check h.eq_1
#check h.eq_2
#check h.def
#check h.eq_def

View File

@@ -16,4 +16,4 @@ decreasing_by
#eval tst ``f
#check f.eq_1
#check f.def
#check f.eq_def

View File

@@ -39,10 +39,10 @@ end
#eval tst ``f
#check @f.eq_1
#check @f.eq_2
#check @f.def
#check @f.eq_def
#eval tst ``h
#check @h.eq_1
#check @h.eq_2
#check @h.def
#check @h.eq_def