refactor: Split Constructions module (#4656)
for better build paralleization and less rebuilding when editing one of these files.
This commit is contained in:
parent
5ad5c2cf04
commit
5ce886cf96
5 changed files with 153 additions and 132 deletions
|
|
@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Authors: Gabriel Ebner
|
||||
-/
|
||||
prelude
|
||||
import Lean.Meta.Constructions
|
||||
import Lean.Meta.Constructions.CasesOn
|
||||
import Lean.Compiler.ImplementedByAttr
|
||||
import Lean.Elab.PreDefinition.WF.Eqns
|
||||
|
||||
|
|
|
|||
|
|
@ -4,135 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Authors: Leonardo de Moura
|
||||
-/
|
||||
prelude
|
||||
import Lean.AuxRecursor
|
||||
import Lean.AddDecl
|
||||
import Lean.Meta.AppBuilder
|
||||
import Lean.Meta.CompletionName
|
||||
import Lean.Meta.Constructions.CasesOn
|
||||
import Lean.Meta.Constructions.NoConfusion
|
||||
import Lean.Meta.Constructions.RecOn
|
||||
import Lean.Meta.Constructions.BRecOn
|
||||
|
||||
namespace Lean
|
||||
|
||||
@[extern "lean_mk_cases_on"] opaque mkCasesOnImp (env : Environment) (declName : @& Name) : Except KernelException Declaration
|
||||
@[extern "lean_mk_no_confusion_type"] opaque mkNoConfusionTypeCoreImp (env : Environment) (declName : @& Name) : Except KernelException Declaration
|
||||
@[extern "lean_mk_no_confusion"] opaque mkNoConfusionCoreImp (env : Environment) (declName : @& Name) : Except KernelException Declaration
|
||||
|
||||
open Meta
|
||||
|
||||
def mkCasesOn (declName : Name) : MetaM Unit := do
|
||||
let name := mkCasesOnName declName
|
||||
let decl ← ofExceptKernelException (mkCasesOnImp (← getEnv) declName)
|
||||
addDecl decl
|
||||
setReducibleAttribute name
|
||||
modifyEnv fun env => markAuxRecursor env name
|
||||
modifyEnv fun env => addProtected env name
|
||||
|
||||
def mkNoConfusionCore (declName : Name) : MetaM Unit := do
|
||||
-- Do not do anything unless can_elim_to_type. TODO: Extract to util
|
||||
let .inductInfo indVal ← getConstInfo declName | return
|
||||
let recInfo ← getConstInfo (mkRecName declName)
|
||||
unless recInfo.levelParams.length > indVal.levelParams.length do return
|
||||
|
||||
let name := Name.mkStr declName "noConfusionType"
|
||||
let decl ← ofExceptKernelException (mkNoConfusionTypeCoreImp (← getEnv) declName)
|
||||
addDecl decl
|
||||
setReducibleAttribute name
|
||||
modifyEnv fun env => addToCompletionBlackList env name
|
||||
modifyEnv fun env => addProtected env name
|
||||
|
||||
let name := Name.mkStr declName "noConfusion"
|
||||
let decl ← ofExceptKernelException (mkNoConfusionCoreImp (← getEnv) declName)
|
||||
addDecl decl
|
||||
setReducibleAttribute name
|
||||
modifyEnv fun env => markNoConfusion env name
|
||||
modifyEnv fun env => addProtected env name
|
||||
|
||||
def mkNoConfusionEnum (enumName : Name) : MetaM Unit := do
|
||||
if (← getEnv).contains ``noConfusionEnum then
|
||||
mkToCtorIdx
|
||||
mkNoConfusionType
|
||||
mkNoConfusion
|
||||
else
|
||||
-- `noConfusionEnum` was not defined yet, so we use `mkNoConfusionCore`
|
||||
mkNoConfusionCore enumName
|
||||
where
|
||||
mkToCtorIdx : MetaM Unit := do
|
||||
let ConstantInfo.inductInfo info ← getConstInfo enumName | unreachable!
|
||||
let us := info.levelParams.map mkLevelParam
|
||||
let numCtors := info.ctors.length
|
||||
let declName := Name.mkStr enumName "toCtorIdx"
|
||||
let enumType := mkConst enumName us
|
||||
let natType := mkConst ``Nat
|
||||
let declType ← mkArrow enumType natType
|
||||
let mut minors := #[]
|
||||
for i in [:numCtors] do
|
||||
minors := minors.push <| mkNatLit i
|
||||
withLocalDeclD `x enumType fun x => do
|
||||
let motive ← mkLambdaFVars #[x] natType
|
||||
let declValue ← mkLambdaFVars #[x] <| mkAppN (mkApp2 (mkConst (mkCasesOnName enumName) (levelOne::us)) motive x) minors
|
||||
addAndCompile <| Declaration.defnDecl {
|
||||
name := declName
|
||||
levelParams := info.levelParams
|
||||
type := declType
|
||||
value := declValue
|
||||
safety := DefinitionSafety.safe
|
||||
hints := ReducibilityHints.abbrev
|
||||
}
|
||||
setReducibleAttribute declName
|
||||
|
||||
mkNoConfusionType : MetaM Unit := do
|
||||
let ConstantInfo.inductInfo info ← getConstInfo enumName | unreachable!
|
||||
let us := info.levelParams.map mkLevelParam
|
||||
let v ← mkFreshUserName `v
|
||||
let enumType := mkConst enumName us
|
||||
let sortV := mkSort (mkLevelParam v)
|
||||
let toCtorIdx := mkConst (Name.mkStr enumName "toCtorIdx") us
|
||||
withLocalDeclD `P sortV fun P =>
|
||||
withLocalDeclD `x enumType fun x =>
|
||||
withLocalDeclD `y enumType fun y => do
|
||||
let declType ← mkForallFVars #[P, x, y] sortV
|
||||
let declValue ← mkLambdaFVars #[P, x, y] (← mkAppM ``noConfusionTypeEnum #[toCtorIdx, P, x, y])
|
||||
let declName := Name.mkStr enumName "noConfusionType"
|
||||
addAndCompile <| Declaration.defnDecl {
|
||||
name := declName
|
||||
levelParams := v :: info.levelParams
|
||||
type := declType
|
||||
value := declValue
|
||||
safety := DefinitionSafety.safe
|
||||
hints := ReducibilityHints.abbrev
|
||||
}
|
||||
setReducibleAttribute declName
|
||||
|
||||
mkNoConfusion : MetaM Unit := do
|
||||
let ConstantInfo.inductInfo info ← getConstInfo enumName | unreachable!
|
||||
let us := info.levelParams.map mkLevelParam
|
||||
let v ← mkFreshUserName `v
|
||||
let enumType := mkConst enumName us
|
||||
let sortV := mkSort (mkLevelParam v)
|
||||
let toCtorIdx := mkConst (Name.mkStr enumName "toCtorIdx") us
|
||||
let noConfusionType := mkConst (Name.mkStr enumName "noConfusionType") (mkLevelParam v :: us)
|
||||
withLocalDecl `P BinderInfo.implicit sortV fun P =>
|
||||
withLocalDecl `x BinderInfo.implicit enumType fun x =>
|
||||
withLocalDecl `y BinderInfo.implicit enumType fun y => do
|
||||
withLocalDeclD `h (← mkEq x y) fun h => do
|
||||
let declType ← mkForallFVars #[P, x, y, h] (mkApp3 noConfusionType P x y)
|
||||
let declValue ← mkLambdaFVars #[P, x, y, h] (← mkAppOptM ``noConfusionEnum #[none, none, none, toCtorIdx, P, x, y, h])
|
||||
let declName := Name.mkStr enumName "noConfusion"
|
||||
addAndCompile <| Declaration.defnDecl {
|
||||
name := declName
|
||||
levelParams := v :: info.levelParams
|
||||
type := declType
|
||||
value := declValue
|
||||
safety := DefinitionSafety.safe
|
||||
hints := ReducibilityHints.abbrev
|
||||
}
|
||||
setReducibleAttribute declName
|
||||
modifyEnv fun env => markNoConfusion env declName
|
||||
|
||||
def mkNoConfusion (declName : Name) : MetaM Unit := do
|
||||
if (← isEnumType declName) then
|
||||
mkNoConfusionEnum declName
|
||||
else
|
||||
mkNoConfusionCore declName
|
||||
|
||||
end Lean
|
||||
|
|
|
|||
23
src/Lean/Meta/Constructions/CasesOn.lean
Normal file
23
src/Lean/Meta/Constructions/CasesOn.lean
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/-
|
||||
Copyright (c) 2020 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Leonardo de Moura
|
||||
-/
|
||||
prelude
|
||||
import Lean.AddDecl
|
||||
import Lean.Meta.Basic
|
||||
|
||||
namespace Lean
|
||||
|
||||
@[extern "lean_mk_cases_on"] opaque mkCasesOnImp (env : Environment) (declName : @& Name) : Except KernelException Declaration
|
||||
|
||||
open Meta
|
||||
|
||||
def mkCasesOn (declName : Name) : MetaM Unit := do
|
||||
let name := mkCasesOnName declName
|
||||
let decl ← ofExceptKernelException (mkCasesOnImp (← getEnv) declName)
|
||||
addDecl decl
|
||||
setReducibleAttribute name
|
||||
modifyEnv fun env => markAuxRecursor env name
|
||||
|
||||
end Lean
|
||||
126
src/Lean/Meta/Constructions/NoConfusion.lean
Normal file
126
src/Lean/Meta/Constructions/NoConfusion.lean
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
/-
|
||||
Copyright (c) 2020 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Leonardo de Moura
|
||||
-/
|
||||
prelude
|
||||
import Lean.AddDecl
|
||||
import Lean.Meta.AppBuilder
|
||||
import Lean.Meta.CompletionName
|
||||
|
||||
namespace Lean
|
||||
|
||||
@[extern "lean_mk_no_confusion_type"] opaque mkNoConfusionTypeCoreImp (env : Environment) (declName : @& Name) : Except KernelException Declaration
|
||||
@[extern "lean_mk_no_confusion"] opaque mkNoConfusionCoreImp (env : Environment) (declName : @& Name) : Except KernelException Declaration
|
||||
|
||||
open Meta
|
||||
|
||||
def mkNoConfusionCore (declName : Name) : MetaM Unit := do
|
||||
-- Do not do anything unless can_elim_to_type. TODO: Extract to util
|
||||
let .inductInfo indVal ← getConstInfo declName | return
|
||||
let recInfo ← getConstInfo (mkRecName declName)
|
||||
unless recInfo.levelParams.length > indVal.levelParams.length do return
|
||||
|
||||
let name := Name.mkStr declName "noConfusionType"
|
||||
let decl ← ofExceptKernelException (mkNoConfusionTypeCoreImp (← getEnv) declName)
|
||||
addDecl decl
|
||||
setReducibleAttribute name
|
||||
modifyEnv fun env => addToCompletionBlackList env name
|
||||
modifyEnv fun env => addProtected env name
|
||||
|
||||
let name := Name.mkStr declName "noConfusion"
|
||||
let decl ← ofExceptKernelException (mkNoConfusionCoreImp (← getEnv) declName)
|
||||
addDecl decl
|
||||
setReducibleAttribute name
|
||||
modifyEnv fun env => markNoConfusion env name
|
||||
modifyEnv fun env => addProtected env name
|
||||
|
||||
def mkNoConfusionEnum (enumName : Name) : MetaM Unit := do
|
||||
if (← getEnv).contains ``noConfusionEnum then
|
||||
mkToCtorIdx
|
||||
mkNoConfusionType
|
||||
mkNoConfusion
|
||||
else
|
||||
-- `noConfusionEnum` was not defined yet, so we use `mkNoConfusionCore`
|
||||
mkNoConfusionCore enumName
|
||||
where
|
||||
mkToCtorIdx : MetaM Unit := do
|
||||
let ConstantInfo.inductInfo info ← getConstInfo enumName | unreachable!
|
||||
let us := info.levelParams.map mkLevelParam
|
||||
let numCtors := info.ctors.length
|
||||
let declName := Name.mkStr enumName "toCtorIdx"
|
||||
let enumType := mkConst enumName us
|
||||
let natType := mkConst ``Nat
|
||||
let declType ← mkArrow enumType natType
|
||||
let mut minors := #[]
|
||||
for i in [:numCtors] do
|
||||
minors := minors.push <| mkNatLit i
|
||||
withLocalDeclD `x enumType fun x => do
|
||||
let motive ← mkLambdaFVars #[x] natType
|
||||
let declValue ← mkLambdaFVars #[x] <| mkAppN (mkApp2 (mkConst (mkCasesOnName enumName) (levelOne::us)) motive x) minors
|
||||
addAndCompile <| Declaration.defnDecl {
|
||||
name := declName
|
||||
levelParams := info.levelParams
|
||||
type := declType
|
||||
value := declValue
|
||||
safety := DefinitionSafety.safe
|
||||
hints := ReducibilityHints.abbrev
|
||||
}
|
||||
setReducibleAttribute declName
|
||||
|
||||
mkNoConfusionType : MetaM Unit := do
|
||||
let ConstantInfo.inductInfo info ← getConstInfo enumName | unreachable!
|
||||
let us := info.levelParams.map mkLevelParam
|
||||
let v ← mkFreshUserName `v
|
||||
let enumType := mkConst enumName us
|
||||
let sortV := mkSort (mkLevelParam v)
|
||||
let toCtorIdx := mkConst (Name.mkStr enumName "toCtorIdx") us
|
||||
withLocalDeclD `P sortV fun P =>
|
||||
withLocalDeclD `x enumType fun x =>
|
||||
withLocalDeclD `y enumType fun y => do
|
||||
let declType ← mkForallFVars #[P, x, y] sortV
|
||||
let declValue ← mkLambdaFVars #[P, x, y] (← mkAppM ``noConfusionTypeEnum #[toCtorIdx, P, x, y])
|
||||
let declName := Name.mkStr enumName "noConfusionType"
|
||||
addAndCompile <| Declaration.defnDecl {
|
||||
name := declName
|
||||
levelParams := v :: info.levelParams
|
||||
type := declType
|
||||
value := declValue
|
||||
safety := DefinitionSafety.safe
|
||||
hints := ReducibilityHints.abbrev
|
||||
}
|
||||
setReducibleAttribute declName
|
||||
|
||||
mkNoConfusion : MetaM Unit := do
|
||||
let ConstantInfo.inductInfo info ← getConstInfo enumName | unreachable!
|
||||
let us := info.levelParams.map mkLevelParam
|
||||
let v ← mkFreshUserName `v
|
||||
let enumType := mkConst enumName us
|
||||
let sortV := mkSort (mkLevelParam v)
|
||||
let toCtorIdx := mkConst (Name.mkStr enumName "toCtorIdx") us
|
||||
let noConfusionType := mkConst (Name.mkStr enumName "noConfusionType") (mkLevelParam v :: us)
|
||||
withLocalDecl `P BinderInfo.implicit sortV fun P =>
|
||||
withLocalDecl `x BinderInfo.implicit enumType fun x =>
|
||||
withLocalDecl `y BinderInfo.implicit enumType fun y => do
|
||||
withLocalDeclD `h (← mkEq x y) fun h => do
|
||||
let declType ← mkForallFVars #[P, x, y, h] (mkApp3 noConfusionType P x y)
|
||||
let declValue ← mkLambdaFVars #[P, x, y, h] (← mkAppOptM ``noConfusionEnum #[none, none, none, toCtorIdx, P, x, y, h])
|
||||
let declName := Name.mkStr enumName "noConfusion"
|
||||
addAndCompile <| Declaration.defnDecl {
|
||||
name := declName
|
||||
levelParams := v :: info.levelParams
|
||||
type := declType
|
||||
value := declValue
|
||||
safety := DefinitionSafety.safe
|
||||
hints := ReducibilityHints.abbrev
|
||||
}
|
||||
setReducibleAttribute declName
|
||||
modifyEnv fun env => markNoConfusion env declName
|
||||
|
||||
def mkNoConfusion (declName : Name) : MetaM Unit := do
|
||||
if (← isEnumType declName) then
|
||||
mkNoConfusionEnum declName
|
||||
else
|
||||
mkNoConfusionCore declName
|
||||
|
||||
end Lean
|
||||
|
|
@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Authors: Dany Fabian
|
||||
-/
|
||||
prelude
|
||||
import Lean.Meta.Constructions
|
||||
import Lean.Meta.Constructions.CasesOn
|
||||
import Lean.Meta.Match.Match
|
||||
|
||||
namespace Lean.Meta.IndPredBelow
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue