Zulip Chat Archive
Stream: general
Topic: simps and match and destruction of a subtype with a metavar
Yakov Pechersky (Jul 11 2025 at 13:09):
In #26941, I proposed changing the construction of docs#WithZero.lift' to use recZeroCoe directly. I ran into this while working with a more complex construction mapping a valuation's value group with zero to a different type. This construction is via composition with WithZero.withZeroUnitsEquiv, which is simps tagged.
Somehow, when using simp in a downstream proof where I am constructing a Units on the fly with a deferred proof obligation metavariable, there is a match match ↑⟨y, ⋯⟩ with that doesn't get simplified. This happens when lift' is defined via an explicit match. If, instead, lift' used recZeroCoe, then the match does get simplified.
This seems to be some complex interaction with simps, because any simpler goals of the same nature don't seem to have this issue. The "MWE" is below, showing the different goal states for the existing and proposed new definition.
Do any simp and simps experts understand what's going on?
import Mathlib.Algebra.GroupWithZero.WithZero
import Mathlib.Algebra.GroupWithZero.Range
import Mathlib.Algebra.Order.GroupWithZero.WithZero
variable {G H : Type*} [CommGroupWithZero G] [LinearOrderedCommGroupWithZero H] (f : G →*₀ H)
open MonoidWithZeroHom
@[simps!]
def foo : WithZero (valueGroup f) →*₀ WithZero Hˣ :=
WithZero.map' (valueGroup f).subtype
/--
info: theorem _example.extracted_1.{u_2, u_1} {G : Type u_1} {H : Type u_2} [inst : CommGroupWithZero G]
[inst_1 : LinearOrderedCommGroupWithZero H] (f : G →*₀ H) (x : H) (y : Hˣ) :
WithZero.recZeroCoe 0 Units.val
(match ↑⟨y, ⋯⟩ with
| none => 0
| some a => ↑↑a) =
x := sorry
-/
#guard_msgs (info) in
example {G : Type*} [Group G] (s : Subgroup G) (x : H) (y : Hˣ) :
∃ y : WithZero (valueGroup f),
(WithZero.withZeroUnitsEquiv.toMonoidHom.comp (foo f).toMonoidHom) y = x := by
refine ⟨WithZero.coe ⟨y, ?_⟩, ?_⟩
· sorry
· simp
extract_goal
sorry
@[simps! symm_apply_apply]
nonrec def lift'' {α β : Type*} [MulOneClass α] [MulZeroOneClass β] :
(α →* β) ≃ (WithZero α →*₀ β) where
toFun f :=
{ toFun := WithZero.recZeroCoe 0 f
map_zero' := rfl
map_one' := by simp
map_mul' := fun
| 0, _ => (zero_mul _).symm
| (_ : α), 0 => (mul_zero _).symm
| (_ : α), (_ : α) => map_mul f _ _ }
invFun F := F.toMonoidHom.comp WithZero.coeMonoidHom
def map'' {α β : Type*} [MulOneClass α] [MulOneClass β] (f : α →* β) :
WithZero α →*₀ WithZero β :=
lift'' (WithZero.coeMonoidHom.comp f)
@[simps!]
def fooAgain : WithZero (valueGroup f) →*₀ WithZero Hˣ :=
map'' (valueGroup f).subtype
/--
info: theorem _example.extracted_1.{u_2, u_1} {G : Type u_1} {H : Type u_2} [inst : CommGroupWithZero G]
[inst_1 : LinearOrderedCommGroupWithZero H] (f : G →*₀ H) (x : H) (y : Hˣ) : ↑y = x := sorry
-/
#guard_msgs (info) in
example {G : Type*} [Group G] (s : Subgroup G) (x : H) (y : Hˣ) :
∃ y : WithZero (valueGroup f),
(WithZero.withZeroUnitsEquiv.toMonoidHom.comp (fooAgain f).toMonoidHom) y = x := by
refine ⟨WithZero.coe ⟨y, ?_⟩, ?_⟩
· sorry
· simp
extract_goal
sorry
Last updated: Dec 20 2025 at 21:32 UTC