Better support for simplifying class projections.
This commit is contained in:
Leonardo de Moura 2022-11-24 11:55:45 -08:00
parent 71b7562c2f
commit 9d8b324f8d
2 changed files with 47 additions and 10 deletions

View file

@ -82,21 +82,38 @@ private def reduceProjFn? (e : Expr) : SimpM (Option Expr) := do
match (← getProjectionFnInfo? cinfo.name) with
| none => return none
| some projInfo =>
if projInfo.fromClass then
if (← read).isDeclToUnfold cinfo.name then
-- We only unfold class projections when the user explicitly requested them to be unfolded.
-- Recall that `unfoldDefinition?` has support for unfolding this kind of projection.
withReducibleAndInstances <| unfoldDefinition? e
else
return none
else
-- `structure` projection
match (← unfoldDefinition? e) with
/- Helper function for applying `reduceProj?` to the result of `unfoldDefinition?` -/
let reduceProjCont? (e? : Option Expr) : SimpM (Option Expr) := do
match e? with
| none => pure none
| some e =>
match (← reduceProj? e.getAppFn) with
| some f => return some (mkAppN f e.getAppArgs)
| none => return none
if projInfo.fromClass then
-- `class` projection
if (← read).isDeclToUnfold cinfo.name then
/-
If user requested `class` projection to be unfolded, we set transparency mode to `.instances`,
and invoke `unfoldDefinition?`.
Recall that `unfoldDefinition?` has support for unfolding this kind of projection when transparency mode is `.instances`.
-/
withReducibleAndInstances <| unfoldDefinition? e
else
/-
Recall that class projections are **not** marked with `[reducible]` because we want them to be
in "reducible canonical form". However, if we have a class projection of the form `Class.projFn (Class.mk ...)`,
we want to reduce it. See issue #1869 for an example where this is important.
-/
unless e.getAppNumArgs > projInfo.numParams do
return none
let major := e.getArg! projInfo.numParams
unless major.isConstructorApp (← getEnv) do
return none
reduceProjCont? (← withDefault <| unfoldDefinition? e)
else
-- `structure` projections
reduceProjCont? (← unfoldDefinition? e)
private def reduceFVar (cfg : Config) (e : Expr) : MetaM Expr := do
if cfg.zeta then

20
tests/lean/run/1869.lean Normal file
View file

@ -0,0 +1,20 @@
universe v u u'
class CategoryStruct (C : Type u) :=
(Hom : C → C → Type v)
(id : ∀ X, Hom X X)
(comp : ∀ {X Y Z : C}, Hom X Y → Hom Y Z → Hom X Z)
class Category (C : Type u) extends CategoryStruct.{v} C :=
(comp_id : ∀ {X Y : C} (f : Hom X Y), comp f (id Y) = f)
open CategoryStruct
open Category
attribute [simp] comp_id
instance (C : Type u) [Category.{v} C] : Category.{v} (ULift.{u'} C) where
Hom := λ X Y => Hom X.down Y.down
id := λ X => id X.down
comp := λ f g => comp f g
comp_id := λ f => by simp