Zulip Chat Archive
Stream: general
Topic: custom well-founded
Kenny Lau (Apr 19 2018 at 05:37):
inductive red.step : list (α × bool) → list (α × bool) → Prop | bnot {L₁ L₂ x b} : red.step (L₁ ++ (x, b) :: (x, bnot b) :: L₂) (L₁ ++ L₂)
How do I tell Lean that whenever red.step L1 L2
is true, it is also true that list.sizeof L2 < list.sizeof L1
?
Kenny Lau (Apr 19 2018 at 05:37):
I don't want to provide a custom proof at the end of every recursion
Mario Carneiro (Apr 19 2018 at 05:38):
You could prove that red.step
itself is well-founded...
Kenny Lau (Apr 19 2018 at 05:38):
it's in the wrong direction though
Mario Carneiro (Apr 19 2018 at 05:38):
swap red.step
then
Kenny Lau (Apr 19 2018 at 05:39):
what is swap?
Mario Carneiro (Apr 19 2018 at 05:39):
exactly what it sounds like
Mario Carneiro (Apr 19 2018 at 05:40):
it's defined in init.function
and swaps a binary operator (aka relation converse)
Mario Carneiro (Apr 19 2018 at 05:40):
oh, I guess it is in function
ns
Kenny Lau (Apr 19 2018 at 05:40):
right
Kenny Lau (Apr 19 2018 at 05:40):
so if I prove that swap red.step
is well-founded, then I won't have to worry about anything?
Kenny Lau (Apr 19 2018 at 05:42):
do you suppose I prove has_well_founded (list (α × bool))
?
Mario Carneiro (Apr 19 2018 at 05:42):
No, except perhaps locally if you like
Kenny Lau (Apr 19 2018 at 05:42):
I mean, is it has_well_founded (list (α × bool))
that I should prove?
Kenny Lau (Apr 19 2018 at 05:42):
and then I can use recursion?
Mario Carneiro (Apr 19 2018 at 05:42):
yes
Kenny Lau (Apr 19 2018 at 05:43):
because "prove well-founded" is kinda vague of an instruction
Mario Carneiro (Apr 19 2018 at 05:43):
you can also define a well_founded
proof and then refer to it in your wf definition using using_well_founded
Mario Carneiro (Apr 19 2018 at 05:43):
there are several examples of that in mathlib, just look for the keyword
Kenny Lau (Apr 19 2018 at 05:44):
as I said, I don't want to write a custom proof at the end of every recursion
Kenny Lau (Apr 19 2018 at 05:44):
I will be doing recurison much
Kenny Lau (Apr 19 2018 at 05:46):
how would I prove that red.step
is well-founded?
Kenny Lau (Apr 19 2018 at 05:46):
I don't know how to use list lengths to prove that it is well-founded
Johannes Hölzl (Apr 19 2018 at 05:53):
my first idea would be to use subrelation.wf
and inv_image.wf
.
Kenny Lau (Apr 19 2018 at 06:35):
H1 : step L₁ L₄, ⊢ function.swap step L₄ L₁
Kenny Lau (Apr 19 2018 at 06:35):
Lean's automater couldn't match this with "assumption"
Kenny Lau (Apr 19 2018 at 06:35):
@Mario Carneiro
Mario Carneiro (Apr 19 2018 at 06:37):
try exact this
as the tactic instead
Kenny Lau (Apr 19 2018 at 06:40):
can I not change the tactic ;_;
Kenny Lau (Apr 19 2018 at 06:42):
Now I used λ L₁ L₂, red.step L₂ L₁
as the well-founded relation instead and Lean is giving me ths ;_;
Kenny Lau (Apr 19 2018 at 06:42):
match failed state: α : Type u, L₃ : list (α × bool), red.trans : ∀ (_p : Σ' {L₁ L₂ : list (α × bool)} (a : red L₁ L₂), red L₂ L₃), red (_p.fst) L₃, L₁ L₂ L₄ : list (α × bool), H1 : step L₁ L₄, H2 : red L₄ L₂, H23 : red L₂ L₃ ⊢ step L₁ L₄
Kenny Lau (Apr 19 2018 at 06:43):
keru mouri
Kenny Lau (Apr 19 2018 at 06:45):
@Mario Carneiro sauva mi
Mario Carneiro (Apr 19 2018 at 06:46):
You should use using_well_founded
like I said
Kenny Lau (Apr 19 2018 at 06:46):
I don’t want to use it after every single recursion ;_;
Mario Carneiro (Apr 19 2018 at 06:46):
it's just one line, which you can copy around
Chris Hughes (Apr 20 2018 at 21:09):
@Kenny Lau
def red : list α → list α → Prop := sorry axiom red_length (l₁ l₂ : list α) : red l₁ l₂ → l₁.length < l₂.length lemma red_well_founded : well_founded (@red α) := subrelation.wf red_length (measure_wf list.length)
This might help if you haven't already worked it out.
Kenny Lau (Apr 20 2018 at 23:51):
@Chris Hughes thanks, but it still bugs me to provide a proof of well-foundedness
Kenny Lau (Apr 20 2018 at 23:52):
so in the end I proved
theorem red.sizeof : ∀ {L₁ L₂ : list (α × bool)}, red.step L₁ L₂ → L₂.sizeof < L₁.sizeof
and then in recursions I do:
theorem red.append : ∀ {L₁ L₂ L₃ L₄ : list (α × bool)}, red L₁ L₃ → red L₂ L₄ → red (L₁ ++ L₂) (L₃ ++ L₄) | _ _ _ _ red.refl red.refl := red.refl | _ _ _ _ red.refl (red.step_trans H3 H4) := have _ := red.sizeof H3, red.step_trans (red.step.append_left H3) (red.append red.refl H4) | _ _ _ _ (red.step_trans H1 H2) H3 := have _ := red.sizeof H1, red.step_trans (red.step.append_right H1) (red.append H2 H3)
Last updated: Dec 20 2023 at 11:08 UTC