Zulip Chat Archive
Stream: Is there code for X?
Topic: Membership of substructure
Artie Khovanov (Sep 30 2024 at 21:05):
Is there a tactic, or even just a pattern, for proving membership in substructures?
e.g. if we have (S R : Type*) [CommRing R] [SetLike S R] [SubringClass S R] (A : S)
, and (x : R) (y : R) (hx : x ∈ A) (hy : y ∈ A)
, is there an easy way to prove x * y - (y + 1) + (y ^ 3) ∈ A
?
Right now the best I can do is just chain all the closure axioms together, but this becomes very tedious in practice when working with substructures.
Bjørn Kjos-Hanssen (Sep 30 2024 at 21:30):
by aesop
:smile:
import Mathlib
example (S R : Type*) [CommRing R] [SetLike S R] [SubringClass S R] (A : S) (x : R) (y : R) (hx : x ∈ A) (hy : y ∈ A) :
x * y - (y + 1) + (y ^ 3) ∈ A := by aesop
Artie Khovanov (Sep 30 2024 at 21:35):
Thanks! That makes sense.
How can I extend this to new structures I create? For instance, I have a structure which (among other things) is a semiring containing all squares. I need to prove membership of x₁ * x₂ + (a * a) * (y₁ * y₂)
, given that the xs and ys are in my structure.
Can I somehow register mysquare_mem
assumption with Aesop? Is there an easy way to see other lemmas already registed with Aesop, perhaps, so I can copy the pattern?
Bjørn Kjos-Hanssen (Sep 30 2024 at 22:59):
Not sure... Can you post a #mwe of the situation?
Artie Khovanov (Sep 30 2024 at 23:05):
import Mathlib
variable (S R : Type*) [CommRing R] [SetLike S R]
/-- `RingPreorderingClass S R` says that `S` is a type of (ring) preorderings on `R`. -/
class RingPreorderingClass extends SubsemiringClass S R : Prop where
square_mem (P : S) (x : R) : x * x ∈ P /- want to "register" this -/
minus_one_not_mem (P : S) : -1 ∉ P
variable [RingPreorderingClass S R] (P : S)
theorem closure_test (a x₁ x₂ y₁ y₂ : R)
(hx₁ : x₁ ∈ P) (hy₁ : y₁ ∈ P) (hx₂ : x₂ ∈ P) (hy₂ : y₂ ∈ P) :
x₁ * x₂ + a * a * (y₁ * y₂) ∈ P := by
aesop /- doesn't work -/
Bjørn Kjos-Hanssen (Oct 01 2024 at 00:17):
OK I found a solution by reminding Lean that P
contains all squares before invoking aesop
:
import Mathlib
variable (S R : Type*) [CommRing R] [SetLike S R]
/-- `RingPreorderingClass S R` says that `S` is a type of (ring) preorderings on `R`. -/
class RingPreorderingClass extends SubsemiringClass S R : Prop where
square_mem (P : S) (x : R) : x * x ∈ P /- want to "register" this -/
minus_one_not_mem (P : S) : -1 ∉ P
variable [RingPreorderingClass S R] (P : S)
theorem closure_test (a x₁ x₂ y₁ y₂ : R)
(hx₁ : x₁ ∈ P) (hy₁ : y₁ ∈ P) (hx₂ : x₂ ∈ P) (hy₂ : y₂ ∈ P) :
x₁ * x₂ + (a * a) * (y₁ * y₂) ∈ P := by
have := RingPreorderingClass.square_mem P
aesop
Artie Khovanov (Oct 01 2024 at 00:18):
that makes sense, thanks so much!
I guess I should look through the Aesop docs to try figure out how to register the rule permanently..
Artie Khovanov (Oct 01 2024 at 00:19):
and yeah the a * a
should be in brackets that's my bad
Bjørn Kjos-Hanssen (Oct 01 2024 at 00:22):
I guess in the meantime you can shorten things by writing
lemma aesop' : ∀ (x : R), x * x ∈ P := RingPreorderingClass.square_mem P
theorem closure_test (a x₁ x₂ y₁ y₂ : R)
(hx₁ : x₁ ∈ P) (hy₁ : y₁ ∈ P) (hx₂ : x₂ ∈ P) (hy₂ : y₂ ∈ P) :
x₁ * x₂ + (a * a) * (y₁ * y₂) ∈ P := by
have := aesop'; aesop
Artie Khovanov (Oct 01 2024 at 00:22):
true yeah
Artie Khovanov (Oct 01 2024 at 00:26):
(deleted)
Artie Khovanov (Oct 01 2024 at 00:28):
OK I found out how to register the rule -- but aesop
appplies the multiplicative rule first :( so it doesn't work
I guess there is probably some priority system...
Artie Khovanov (Oct 01 2024 at 00:32):
so there is!
import Mathlib
variable (S R : Type*) [CommRing R] [SetLike S R]
/-- `RingPreorderingClass S R` says that `S` is a type of (ring) preorderings on `R`. -/
class RingPreorderingClass extends SubsemiringClass S R : Prop where
square_mem (P : S) (x : R) : x * x ∈ P
minus_one_not_mem (P : S) : -1 ∉ P
export RingPreorderingClass (square_mem)
export RingPreorderingClass (minus_one_not_mem)
attribute [aesop safe 0 apply (rule_sets := [SetLike])] square_mem
variable [RingPreorderingClass S R] (P : S)
theorem closure_test (a x₁ x₂ y₁ y₂ : R)
(hx₁ : x₁ ∈ P) (hy₁ : y₁ ∈ P) (hx₂ : x₂ ∈ P) (hy₂ : y₂ ∈ P) :
x₁ * x₂ + (a * a) * (y₁ * y₂) ∈ P := by
aesop
thanks for your help @Bjørn Kjos-Hanssen ☀️ !
I think this code is idiomatic now (unless someone more experienced than me would like to weigh in?)
Bjørn Kjos-Hanssen (Oct 01 2024 at 01:08):
Nice! Doesn't look like you need more than attribute [aesop safe 0] square_mem
in that line by the way.
Artie Khovanov (Oct 01 2024 at 01:15):
Yeah, the last two attributes restrict the usage scope of the rule. So (since I aim to merge to Mathlib) I think they should stay, if only for performance reasons.
Last updated: May 02 2025 at 03:31 UTC