Zulip Chat Archive
Stream: mathlib4
Topic: Multiplicative doesn't play well with simp
Yongyi Chen (Nov 16 2023 at 00:25):
In particular, simp doesn't simplify defeqs. My MWE is a real world example, a group homomorphism :
import Mathlib
def α' (n : ℕ) : Multiplicative (ZMod 2) →* AddAut (ZMod n) where
toFun x := (AddEquiv.neg _) ^ x.val
map_one' := rfl
map_mul'
| (0 : ZMod 2), (0 : ZMod 2) => rfl
| (0 : ZMod 2), (1 : ZMod 2) => rfl
| (1 : ZMod 2), (0 : ZMod 2) => rfl
| (1 : ZMod 2), (1 : ZMod 2) => by
ext x
dsimp only
simp
-- Goal : ↑(AddEquiv.neg (ZMod n) ^ ZMod.val (1 * 1)) x = ↑(AddEquiv.neg (ZMod n) ^ ZMod.val 1) (↑(AddEquiv.neg (ZMod n) ^ ZMod.val 1) x)
sorry
This proof works but I shouldn't need to do manual defeq conversions with conv:
import Mathlib
def α' (n : ℕ) : Multiplicative (ZMod 2) →* AddAut (ZMod n) where
toFun x := (AddEquiv.neg _) ^ x.val
map_one' := rfl
map_mul'
| (0 : ZMod 2), (0 : ZMod 2) => rfl
| (0 : ZMod 2), (1 : ZMod 2) => rfl
| (1 : ZMod 2), (0 : ZMod 2) => rfl
| (1 : ZMod 2), (1 : ZMod 2) => by
ext x
dsimp only
conv in ZMod.val _ => change 0
conv in ZMod.val _ => change 1
conv in ZMod.val _ => change 1
simp only [pow_zero, AddAut.one_apply, pow_one, AddAut.mul_apply, AddEquiv.neg_apply, map_neg, neg_neg]
Eric Wieser (Nov 16 2023 at 01:22):
You're having this problem because you cheated and didn't use ofAdd
and toAdd
:
def α' (n : ℕ) : Multiplicative (ZMod 2) →* AddAut (ZMod n) where
toFun x := (AddEquiv.neg _) ^ x.toAdd.val
map_one' := rfl
map_mul'
| .ofAdd (0 : ZMod 2), .ofAdd (0 : ZMod 2) => rfl
| .ofAdd (0 : ZMod 2), .ofAdd (1 : ZMod 2) => rfl
| .ofAdd (1 : ZMod 2), .ofAdd (0 : ZMod 2) => rfl
| .ofAdd (1 : ZMod 2), .ofAdd (1 : ZMod 2) => by
ext x
dsimp only
simp
Eric Wieser (Nov 16 2023 at 01:22):
You were pretending that Multiplicative (ZMod 2)
and ZMod 2
were the same type, but simp
is not ok with you doing that
Yongyi Chen (Nov 16 2023 at 01:32):
Ohh actually | ofAdd (0 : ZMod 2)
was one of the things I tried, and Lean didn't accept that... because I was missing the dot!
Eric Wieser (Nov 16 2023 at 01:34):
Without the dot it thinks you're declaring a new variable called ofAdd
Eric Wieser (Nov 16 2023 at 01:35):
Note I also changed .toFun
Eric Wieser (Nov 16 2023 at 01:35):
As an aside, I think there's probably some overlap here with docs#instModuleZModOfNatNatInstOfNatNatAdditiveUnitsIntInstMonoidIntToSemiringToDivisionSemiringToSemifieldInstFieldZModFact_prime_twoAddCommMonoidToCommMonoidInstCommGroupUnitsInstCommMonoidInt
Yongyi Chen (Nov 16 2023 at 02:27):
Eric Wieser said:
You're having this problem because you cheated and didn't use
ofAdd
andtoAdd
:def α' (n : ℕ) : Multiplicative (ZMod 2) →* AddAut (ZMod n) where toFun x := (AddEquiv.neg _) ^ x.toAdd.val map_one' := rfl map_mul' | .ofAdd (0 : ZMod 2), .ofAdd (0 : ZMod 2) => rfl | .ofAdd (0 : ZMod 2), .ofAdd (1 : ZMod 2) => rfl | .ofAdd (1 : ZMod 2), .ofAdd (0 : ZMod 2) => rfl | .ofAdd (1 : ZMod 2), .ofAdd (1 : ZMod 2) => by ext x dsimp only simp
OK, I tried this code snippet. Before I got to my computer, I thought this was a valid proof, but actually there is still some stuff to do after the simp. How to finish?
The goal state is
x = ↑(AddEquiv.neg (ZMod n) ^ ZMod.val 1) (↑(AddEquiv.neg (ZMod n) ^ ZMod.val 1) x)
Obviously, for example, ZMod.val 1
is defeq to 1
, but simp refuses to touch that for some reason.
Eric Wieser (Nov 16 2023 at 02:30):
You should write a lemma that says the thing that is obvious to you
Eric Wieser (Nov 16 2023 at 02:30):
And then hand it to simp
Eric Wieser (Nov 16 2023 at 02:31):
Is the proof easier without ext
?
Yongyi Chen (Nov 16 2023 at 02:32):
ok this works:
def α' (n : ℕ) : Multiplicative (ZMod 2) →* AddAut (ZMod n) where
toFun x := (AddEquiv.neg _) ^ x.toAdd.val
map_one' := rfl
map_mul'
| .ofAdd (0 : ZMod 2), .ofAdd (0 : ZMod 2) => rfl
| .ofAdd (0 : ZMod 2), .ofAdd (1 : ZMod 2) => rfl
| .ofAdd (1 : ZMod 2), .ofAdd (0 : ZMod 2) => rfl
| .ofAdd (1 : ZMod 2), .ofAdd (1 : ZMod 2) => by
simp [ZMod.val]
ext
simp
Last updated: Dec 20 2023 at 11:08 UTC