Zulip Chat Archive
Stream: new members
Topic: Distributing ↑ over (v + 0)
Martin C. Martin (Nov 06 2023 at 18:49):
As an exercise, I'm defining vector spaces in Lean. However, I'm having trouble proving v + 0 = v in a subspace.
intro v; ext
reduces the goal to ↑(v + 0) = ↑v, and next I'm hoping for something to distribute the ↑ on the left hand side. In Lean 3, simp
would do that, but in Lean 4, simp
just undoes the ext
. I want to get to where I can use rw [AddCommGroup.add_zero]
to finish the proof.
Here's my #mwe, sorry it's so long:
import Mathlib.Algebra.Field.Basic
import Mathlib.Data.SetLike.Basic
namespace LADR
@[ext]
class AddCommGroup (V : Type _) extends Add V, Zero V, Neg V where
add_comm : ∀ u v : V, u + v = v + u
add_assoc : ∀ u v w : V, u + v + w = u + (v + w)
add_zero : ∀ v : V, v + 0 = v
add_right_inv : ∀ v : V, v + -v = 0
@[ext]
class VectorSpace (F : Type _) (V : Type _) [Field F] [AddCommGroup V] extends SMul F V where
smul_assoc : ∀ a b : F, ∀ v : V, (a * b) • v = a • b • v
mul_ident : ∀ v : V, (1 : F) • v = v
left_distrib : ∀ a : F, ∀ u v : V, a • (u + v) = a • u + a • v
right_distrib : ∀ a b : F, ∀ v : V, (a + b) • v = a • v + b • v
variable {F : Type _} [field_f: Field F]
namespace VectorSpace
variable {V : Type _} [AddCommGroup V] [VectorSpace F V]
theorem neg_one_smul_is_neg {v : V} : (-1 : F) • v = -v := sorry
end VectorSpace
structure AddCommSubgroup (V : Type _) [AddCommGroup V] where
carrier : Set V
add_mem' : ∀ {u v : V}, u ∈ carrier → v ∈ carrier → u + v ∈ carrier
zero_mem' : (0 : V) ∈ carrier
namespace AddCommSubgroup
variable {V : Type _} [AddCommGroup V] {v : V}
instance : SetLike (AddCommSubgroup V) V :=
⟨AddCommSubgroup.carrier, fun p q h => by cases p ; cases q ; congr⟩
@[simp]
theorem mem_carrier {p : AddCommSubgroup V} : v ∈ p.carrier ↔ v ∈ (p : Set V) :=
Iff.rfl
@[ext]
theorem ext {p q : AddCommSubgroup V} (h : ∀ v, v ∈ p ↔ v ∈ q) : p = q :=
SetLike.ext h
end AddCommSubgroup
-- Because this is a structure rather than a class, it's ok to extend add_comm_subgroup
structure Subspace (F : Type _) (V : Type _) [Field F] [AddCommGroup V] [VectorSpace F V] extends
AddCommSubgroup V where
smul_mem' : ∀ (c : F) {v : V}, v ∈ carrier → c • v ∈ carrier
namespace Subspace
variable {F : Type _} {V : Type _} [Field F] [AddCommGroup V] [VectorSpace F V]
variable {v : V}
instance : SetLike (Subspace F V) V where
coe s := s.carrier
coe_injective' p q h := by cases p; cases q; congr; exact SetLike.coe_injective' h
@[simp]
theorem mem_carrier {p : Subspace F V} : v ∈ p.carrier ↔ v ∈ (p : Set V) :=
Iff.rfl
@[ext]
theorem ext {p q : Subspace F V} (h : ∀ v, v ∈ p ↔ v ∈ q) : p = q :=
SetLike.ext h
variable (p : Subspace F V)
instance foo : AddCommGroup p
where
add u v := ⟨u.1 + v.1, by apply p.add_mem'; simp; simp⟩
zero := ⟨0, p.zero_mem'⟩
neg v := ⟨-v.1, by rw [← @VectorSpace.neg_one_smul_is_neg F _ V]; apply p.smul_mem'; simp⟩
add_comm := by intros; ext; apply AddCommGroup.add_comm
add_assoc := by intros; ext; apply AddCommGroup.add_assoc
add_zero := by intro v; ext; rw [AddCommGroup.add_zero] -- <-- This fails.
add_right_inv := by intros; ext; rw [AddCommGroup.add_right_inv] -- <-- This also fails.
end Subspace
end LADR
Eric Wieser (Nov 06 2023 at 18:51):
(note that Lean comments are --
not #
)
Jireh Loreaux (Nov 06 2023 at 18:52):
Note:
add_zero := by intro v; ext; exact AddCommGroup.add_zero _ -- This works.
Jireh Loreaux (Nov 06 2023 at 18:53):
The issue is that you are defining addition on the subspace at the same time as you are proving properties about it. If you define the addition first, then you can have a coe_add
lemma (proved by rfl
) which you can then rewrite with when you create the AddCommGroup
instance for subspaces.
Eric Wieser (Nov 06 2023 at 18:55):
Which would look like:
instance : Add p where
add u v := ⟨u.1 + v.1, by apply p.add_mem'; simp; simp⟩
@[simp] theorem val_add (a b : p) : (a + b).val = a.val + b.val := rfl
instance foo : AddCommGroup p where
add_zero := by intro v; ext; rw [val_add] -- this makes more progress
-- other fields,except `add`, as before
Martin C. Martin (Nov 06 2023 at 19:35):
Thanks to both of you! It's odd that exact
works but apply
and rw
did not. Is this related to using an underscore with exact
, but not with apply
or rw
?
Eric Wieser (Nov 06 2023 at 19:39):
I'm surprised it didn't work with apply
, but it wouldn't work with rw
because rw
refuses to unfold definitions
Martin C. Martin (Nov 06 2023 at 19:40):
In general, I do struggle to understand when to use simp
vs dsimp
vs rw
vs apply
vs exact
. I always thought anything that works with exact
would also work with apply
, that apply
is a kind of recursive exact
, but I guess that's not right.
Martin C. Martin (Nov 06 2023 at 19:42):
Actually, it does work with apply
. I swore I tried that a few weeks ago and it didn't work. You can see I used it on the earlier ones. Maybe I still had the simp
in there? Definitely doesn't work if you use simp
before the apply
.
Martin C. Martin (Nov 06 2023 at 19:43):
It seems odd that simp
is undoing ext
, but there's certainly a sense in which that's simpler. Still, I expect simp
to unfold definitions, rather than the opposite.
Jireh Loreaux (Nov 06 2023 at 21:27):
I would not expect simp
to unfold definitions in general (unless you pass them explicitly to the simp
call). Often that would defeat the purpose of having the definition, which is to hide some object behind the default semireducible transparency.
Last updated: Dec 20 2023 at 11:08 UTC