Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: rename automatically generated "unfold" theorems #3767

Merged
merged 1 commit into from
Mar 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Lean/Elab/PreDefinition/Eqns.lean
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/Lean/Elab/PreDefinition/Structural/Eqns.lean
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/Lean/Elab/PreDefinition/WF/Eqns.lean
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
27 changes: 17 additions & 10 deletions src/Lean/Meta/Eqns.lean
Original file line number Diff line number Diff line change
Expand Up @@ -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

def unfoldThmSuffix := "eq_def"

/-- Returns `true` if `s == "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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions tests/lean/run/1026.lean
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -20,4 +20,4 @@ info: foo.def (n : Nat) :
foo x
-/
#guard_msgs in
#check foo.def
#check foo.eq_def
2 changes: 1 addition & 1 deletion tests/lean/run/nestedWF.lean
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ theorem ex2 : g 0 = 0 := by
unfold g
simp

#check g.def
#check g.eq_def


end Ex2
38 changes: 27 additions & 11 deletions tests/lean/run/reserved.lean
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
-- `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

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
Expand All @@ -31,24 +31,24 @@ 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
| 0 => 1
| 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
Expand Down Expand Up @@ -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
Expand All @@ -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
2 changes: 1 addition & 1 deletion tests/lean/run/splitIssue.lean
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions tests/lean/run/splitList.lean
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions tests/lean/run/structEqns.lean
Original file line number Diff line number Diff line change
Expand Up @@ -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') =>
Expand All @@ -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 :=
Expand Down
12 changes: 6 additions & 6 deletions tests/lean/run/structuralEqns.lean
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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

Expand All @@ -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
Expand All @@ -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 +
Expand All @@ -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 <|
Expand All @@ -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
4 changes: 2 additions & 2 deletions tests/lean/run/structuralEqns2.lean
Original file line number Diff line number Diff line change
Expand Up @@ -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 :=
Expand All @@ -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
2 changes: 1 addition & 1 deletion tests/lean/run/structuralEqns3.lean
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion tests/lean/run/wfEqns1.lean
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ end
#eval tst ``isEven
#check @isEven.eq_1
#check @isEven.eq_2
#check @isEven.def
#check @isEven.eq_def
4 changes: 2 additions & 2 deletions tests/lean/run/wfEqns2.lean
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion tests/lean/run/wfEqns3.lean
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ decreasing_by

#eval tst ``f
#check f.eq_1
#check f.def
#check f.eq_def
4 changes: 2 additions & 2 deletions tests/lean/run/wfEqns4.lean
Original file line number Diff line number Diff line change
Expand Up @@ -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
Loading