Zulip Chat Archive
Stream: lean4
Topic: Using `aesop` to perform cases on a non-inductive type
Anand Rao (Jan 14 2023 at 15:03):
As I understand it, aesop
uses the cases
rule builder to perform proofs by cases on inductive types, which can be further calibrated using the patterns
option. Is there currently a way to perform cases on type that is not an inductive type, or will there be support for this in the future?
For context, I am currently dealing with the type Fin 2 × Fin 2
, which I would like aesop
to learn to split into the four cases (0, 0)
, (0, 1)
, (1, 0)
and (1, 1)
.
Jannis Limperg (Jan 14 2023 at 15:55):
Maybe something roughly like this will work:
@[aesop safe forward]
theorem fin2_split : (x : Fin 2 x Fin 2) -> x = (0, 0) \or x = (0, 1) \or x = (1, 0) \or x = (1, 1)
Then Aesop should split the new hyp into the four cases and substitute the equations.
If this doesn't work, I may need to implement general elimination rules after all...
Anand Rao (Jan 14 2023 at 16:53):
Thanks a lot for the suggestion! It seems to work perfectly on the test example below. It is failing for the use case that I have in mind, but I think that is only because of my overall configuration of parameters - the error message suggests that the case splitting has already occurred and the error is elsewhere downstream. I do not need this feature crucially in my code, it is just to trim a couple of lines of case matching and delegate the entire proof to aesop
. I think that with some experimentation I should be able to get it to work for my main code as it did for the test example.
import Aesop
import Mathlib.Data.Fin.Basic
import Mathlib.Algebra.Group.Prod
declare_aesop_rule_sets [Q]
/-- The Klein Four group. -/
@[aesop safe (rule_sets [Q])]
abbrev Q := Fin 2 × Fin 2
instance : AddCommGroup Q := inferInstance
namespace Q
/-! The elements of the Klein Four group `Q`. -/
/-- The identity element of `Q`. -/
@[aesop norm unfold (rule_sets [Q]), match_pattern]
abbrev e : Q := (⟨0, by decide⟩, ⟨0, by decide⟩)
/-- The first generator of `Q`. -/
@[aesop norm unfold (rule_sets [Q]), match_pattern]
abbrev a : Q := (⟨1, by decide⟩, ⟨0, by decide⟩)
/-- The second generator of `Q`. -/
@[aesop norm unfold (rule_sets [Q]), match_pattern]
abbrev b : Q := (⟨0, by decide⟩, ⟨1, by decide⟩)
/-- The product of the generators of `Q`. -/
@[aesop norm unfold (rule_sets [Q]), match_pattern]
abbrev c : Q := (⟨1, by decide⟩, ⟨1, by decide⟩)
@[aesop safe forward (rule_sets [Q])]
theorem split : ∀ q : Q, q = .e ∨ q = .a ∨ q = .b ∨ q = .c
| .e | .a | .b | .c => by aesop
end Q
example : ∀ q : Q, q + q = Q.e := by aesop (rule_sets [Q])
Last updated: Dec 20 2023 at 11:08 UTC