Zulip Chat Archive
Stream: new members
Topic: Using rw at QuotientGroup
张守信(Shouxin Zhang) (Apr 20 2025 at 06:33):
In the example
open Subgroup in
example {G : Type*} [Group G] [IsCyclic G] (g : G):
letI := IsCyclic.commGroup (α := G)
letI : Normal (zpowers (g ^ 0)) := by
exact normal_of_comm _
G ⧸ (zpowers (g ^ 0)) ≃* G ⧸ (⊥ : Subgroup G) := by
rw [pow_zero, zpowers_one_eq_bot]
Tactic rw works well, but in the following case
instance {G : Type*} [Group G] [IsCyclic G] (g : G) :
Subgroup.Normal (Subgroup.zpowers (g ^ 0)) := by
letI := IsCyclic.commGroup (α := G)
exact Subgroup.normal_of_comm _
open Subgroup in
example {G : Type*} [Group G] [IsCyclic G] (g : G):
G ⧸ (zpowers (g ^ 0)) ≃* G ⧸ (⊥ : Subgroup G) := by
rw [pow_zero, zpowers_one_eq_bot]
Lean will return error : "tactic 'rewrite' failed, motive is not type correct: instNormalZpowersHPowOfNat_exercise g
has type
(zpowers (g ^ 0)).Normal : Prop
but is expected to have type
(zpowers _a).Normal : Prop"
How can I deal with this strange question?
Robin Arnez (Apr 20 2025 at 07:29):
In new versions, it gives a detailed explanation:
tactic 'rewrite' failed, motive is not type correct:
fun _a => G ⧸ zpowers _a ≃* G ⧸ ⊥
Error: application type mismatch
@QuotientGroup.Quotient.group G inst✝¹ (zpowers _a) ⋯
argument
«instNormalZpowersHPowOfNat_mathlib-demo» g
has type
(zpowers (g ^ 0)).Normal : Prop
but is expected to have type
(zpowers _a).Normal : Prop
Explanation: The rewrite tactic rewrites an expression 'e' using an equality 'a = b' by the following process. First, it looks for all 'a' in 'e'. Second, it tries to abstract these occurrences of 'a' to create a function 'm := fun _a => ...', called the *motive*, with the property that 'm a' is definitionally equal to 'e'. Third, we observe that 'congrArg' implies that 'm a = m b', which can be used with lemmas such as 'Eq.mpr' to change the goal. However, if 'e' depends on specific properties of 'a', then the motive 'm' might not typecheck.
Possible solutions: use rewrite's 'occs' configuration option to limit which occurrences are rewritten, or use 'simp' or 'conv' mode, which have strategies for certain kinds of dependencies (these tactics can handle proofs and 'Decidable' instances whose types depend on the rewritten term, and 'simp' can apply user-defined '@[congr]' theorems as well).
tl;dr: rw just does a naive substitution and doesn't for example touch the instance you defined above, because it doesn't take g ^ 0 as a parameter. So it still uses the same instance but now with type zpowers 1, giving a type error. In the version above, it was parameterized because normal_of_comm can take anything, so rw will also substitute that. Whether that works or not very much depends on the situation but if you want to avoid this, usually simp and conv are options; in this case you're probably better off using special functions:
import Mathlib.GroupTheory.SpecificGroups.Cyclic
instance {G : Type*} [Group G] [IsCyclic G] (g : G) :
Subgroup.Normal (Subgroup.zpowers (g ^ 0)) := by
letI := IsCyclic.commGroup (α := G)
exact Subgroup.normal_of_comm _
open Subgroup in
example {G : Type*} [Group G] [IsCyclic G] (g : G):
G ⧸ (zpowers (g ^ 0)) ≃* G ⧸ (⊥ : Subgroup G) := by
apply QuotientGroup.quotientMulEquivOfEq
rw [pow_zero, zpowers_one_eq_bot]
张守信(Shouxin Zhang) (Apr 20 2025 at 11:25):
Robin Arnez said:
In new versions, it gives a detailed explanation:
tactic 'rewrite' failed, motive is not type correct: fun _a => G ⧸ zpowers _a ≃* G ⧸ ⊥ Error: application type mismatch @QuotientGroup.Quotient.group G inst✝¹ (zpowers _a) ⋯ argument «instNormalZpowersHPowOfNat_mathlib-demo» g has type (zpowers (g ^ 0)).Normal : Prop but is expected to have type (zpowers _a).Normal : Prop Explanation: The rewrite tactic rewrites an expression 'e' using an equality 'a = b' by the following process. First, it looks for all 'a' in 'e'. Second, it tries to abstract these occurrences of 'a' to create a function 'm := fun _a => ...', called the *motive*, with the property that 'm a' is definitionally equal to 'e'. Third, we observe that 'congrArg' implies that 'm a = m b', which can be used with lemmas such as 'Eq.mpr' to change the goal. However, if 'e' depends on specific properties of 'a', then the motive 'm' might not typecheck. Possible solutions: use rewrite's 'occs' configuration option to limit which occurrences are rewritten, or use 'simp' or 'conv' mode, which have strategies for certain kinds of dependencies (these tactics can handle proofs and 'Decidable' instances whose types depend on the rewritten term, and 'simp' can apply user-defined '@[congr]' theorems as well).tl;dr:
rwjust does a naive substitution and doesn't for example touch the instance you defined above, because it doesn't takeg ^ 0as a parameter. So it still uses the same instance but now with typezpowers 1, giving a type error. In the version above, it was parameterized becausenormal_of_commcan take anything, sorwwill also substitute that. Whether that works or not very much depends on the situation but if you want to avoid this, usuallysimpandconvare options; in this case you're probably better off using special functions:import Mathlib.GroupTheory.SpecificGroups.Cyclic instance {G : Type*} [Group G] [IsCyclic G] (g : G) : Subgroup.Normal (Subgroup.zpowers (g ^ 0)) := by letI := IsCyclic.commGroup (α := G) exact Subgroup.normal_of_comm _ open Subgroup in example {G : Type*} [Group G] [IsCyclic G] (g : G): G ⧸ (zpowers (g ^ 0)) ≃* G ⧸ (⊥ : Subgroup G) := by apply QuotientGroup.quotientMulEquivOfEq rw [pow_zero, zpowers_one_eq_bot]
I know this answer, but this answer really seems strange, because we must using a theorem to congr , instead of rw directly. simp and conv also failed.
Is there really no simple way to fix this? Or is there something wrong with the way I write instance that prevents Lean from automatically finding motive?
Robin Arnez (Apr 20 2025 at 13:03):
you probably aren't supposed to use rw, simp or conv here, a MulEquiv is in principle data and rw and stuff is discouraged there because it removes defeq and blocks reduction. That's probably also the reason why QuotientGroup.quotientMulEquivOfEq exists in the first place.
Last updated: May 02 2025 at 03:31 UTC