l3lab/ntp-mathlib huggingface dataset:
protected theorem DFinsupp.wellFoundedLT [∀ i, Zero (α i)] [∀ i, Preorder (α i)]
    [∀ i, WellFoundedLT (α i)] (hbot : ∀ ⦃i⦄ ⦃a : α i⦄, ¬a < 0) : WellFoundedLT (Π₀ i, α i) :=
  ⟨by
    set β := fun i ↦ Antisymmetrization (α i) (· ≤ ·)
    set e : (i : ι) → α i → β i := fun i ↦ toAntisymmetrization (· ≤ ·)
    let _ : ∀ i, Zero (β i) := fun i ↦ ⟨e i 0⟩
    have : WellFounded (DFinsupp.Lex (Function.swap <| @WellOrderingRel ι)
      (fun _ ↦ (· < ·) : (i : ι) → β i → β i → Prop))
    · have := IsTrichotomous.swap (@WellOrderingRel ι)
      refine Lex.wellFounded' ?_ (fun i ↦ IsWellFounded.wf) ?_
      · rintro i ⟨a⟩
        apply hbot
      · simp (config := { unfoldPartialApp := true }) only [Function.swap]
        exact IsWellFounded.wf
    refine Subrelation.wf (fun h => ?_) <| InvImage.wf (mapRange (fun i ↦ e i) fun _ ↦ rfl) this
    

Proof state:
ι : Type u_1
α : ι → Type u_2
r : ι → ι → Prop
s : (i : ι) → α i → α i → Prop
inst✝² : (i : ι) → Zero (α i)
inst✝¹ : (i : ι) → Preorder (α i)
inst✝ : ∀ (i : ι), WellFoundedLT (α i)
hbot : ∀ ⦃i : ι⦄ ⦃a : α i⦄, ¬a < 0
β : ι → Type u_2 := fun i => Antisymmetrization (α i) fun x x_1 => x ≤ x_1
e : (i : ι) → α i → β i := fun i => toAntisymmetrization fun x x_1 => x ≤ x_1
x✝¹ : (i : ι) → Zero (β i) := fun i => { zero := e i 0 }
this : WellFounded (DFinsupp.Lex (Function.swap WellOrderingRel) fun x x_1 x_2 => x_1 < x_2)
x✝ y✝ : Π₀ (i : ι), α i
h : x✝ < y✝
⊢ InvImage (DFinsupp.Lex (Function.swap WellOrderingRel) fun x x_1 x_2 => x_1 < x_2)
    (mapRange (fun i => e i) (_ : ∀ (x : ι), (fun i => e i) x 0 = (fun i => e i) x 0)) x✝ y✝

Next tactic:
have := IsStrictOrder.swap (@WellOrderingRel ι)
protected theorem DFinsupp.wellFoundedLT [∀ i, Zero (α i)] [∀ i, Preorder (α i)]
    [∀ i, WellFoundedLT (α i)] (hbot : ∀ ⦃i⦄ ⦃a : α i⦄, ¬a < 0) : WellFoundedLT (Π₀ i, α i) :=
  ⟨by
    set β := fun i ↦ Antisymmetrization (α i) (· ≤ ·)
    set e : (i : ι) → α i → β i := fun i ↦ toAntisymmetrization (· ≤ ·)
    let _ : ∀ i, Zero (β i) := fun i ↦ ⟨e i 0⟩
    have : WellFounded (DFinsupp.Lex (Function.swap <| @WellOrderingRel ι)
      (fun _ ↦ (· < ·) : (i : ι) → β i → β i → Prop))
    · have := IsTrichotomous.swap (@WellOrderingRel ι)
      refine Lex.wellFounded' ?_ (fun i ↦ IsWellFounded.wf) ?_
      · rintro i ⟨a⟩
        apply hbot
      · simp (config := { unfoldPartialApp := true }) only [Function.swap]
        exact IsWellFounded.wf
    refine Subrelation.wf (fun h => ?_) <| InvImage.wf (mapRange (fun i ↦ e i) fun _ ↦ rfl) this
    have := IsStrictOrder.swap (@WellOrderingRel ι)
    

Proof state:
ι : Type u_1
α : ι → Type u_2
r : ι → ι → Prop
s : (i : ι) → α i → α i → Prop
inst✝² : (i : ι) → Zero (α i)
inst✝¹ : (i : ι) → Preorder (α i)
inst✝ : ∀ (i : ι), WellFoundedLT (α i)
hbot : ∀ ⦃i : ι⦄ ⦃a : α i⦄, ¬a < 0
β : ι → Type u_2 := fun i => Antisymmetrization (α i) fun x x_1 => x ≤ x_1
e : (i : ι) → α i → β i := fun i => toAntisymmetrization fun x x_1 => x ≤ x_1
x✝¹ : (i : ι) → Zero (β i) := fun i => { zero := e i 0 }
this✝ : WellFounded (DFinsupp.Lex (Function.swap WellOrderingRel) fun x x_1 x_2 => x_1 < x_2)
x✝ y✝ : Π₀ (i : ι), α i
h : x✝ < y✝
this : IsStrictOrder ι (Function.swap WellOrderingRel)
⊢ InvImage (DFinsupp.Lex (Function.swap WellOrderingRel) fun x x_1 x_2 => x_1 < x_2)
    (mapRange (fun i => e i) (_ : ∀ (x : ι), (fun i => e i) x 0 = (fun i => e i) x 0)) x✝ y✝

Next tactic:
obtain ⟨i, he, hl⟩ := lex_lt_of_lt_of_preorder (Function.swap WellOrderingRel) h
protected theorem DFinsupp.wellFoundedLT [∀ i, Zero (α i)] [∀ i, Preorder (α i)]
    [∀ i, WellFoundedLT (α i)] (hbot : ∀ ⦃i⦄ ⦃a : α i⦄, ¬a < 0) : WellFoundedLT (Π₀ i, α i) :=
  ⟨by
    set β := fun i ↦ Antisymmetrization (α i) (· ≤ ·)
    set e : (i : ι) → α i → β i := fun i ↦ toAntisymmetrization (· ≤ ·)
    let _ : ∀ i, Zero (β i) := fun i ↦ ⟨e i 0⟩
    have : WellFounded (DFinsupp.Lex (Function.swap <| @WellOrderingRel ι)
      (fun _ ↦ (· < ·) : (i : ι) → β i → β i → Prop))
    · have := IsTrichotomous.swap (@WellOrderingRel ι)
      refine Lex.wellFounded' ?_ (fun i ↦ IsWellFounded.wf) ?_
      · rintro i ⟨a⟩
        apply hbot
      · simp (config := { unfoldPartialApp := true }) only [Function.swap]
        exact IsWellFounded.wf
    refine Subrelation.wf (fun h => ?_) <| InvImage.wf (mapRange (fun i ↦ e i) fun _ ↦ rfl) this
    have := IsStrictOrder.swap (@WellOrderingRel ι)
    obtain ⟨i, he, hl⟩ := lex_lt_of_lt_of_preorder (Function.swap WellOrderingRel) h
    

Proof state:
case intro.intro
ι : Type u_1
α : ι → Type u_2
r : ι → ι → Prop
s : (i : ι) → α i → α i → Prop
inst✝² : (i : ι) → Zero (α i)
inst✝¹ : (i : ι) → Preorder (α i)
inst✝ : ∀ (i : ι), WellFoundedLT (α i)
hbot : ∀ ⦃i : ι⦄ ⦃a : α i⦄, ¬a < 0
β : ι → Type u_2 := fun i => Antisymmetrization (α i) fun x x_1 => x ≤ x_1
e : (i : ι) → α i → β i := fun i => toAntisymmetrization fun x x_1 => x ≤ x_1
x✝¹ : (i : ι) → Zero (β i) := fun i => { zero := e i 0 }
this✝ : WellFounded (DFinsupp.Lex (Function.swap WellOrderingRel) fun x x_1 x_2 => x_1 < x_2)
x✝ y✝ : Π₀ (i : ι), α i
h : x✝ < y✝
this : IsStrictOrder ι (Function.swap WellOrderingRel)
i : ι
he : ∀ (j : ι), Function.swap WellOrderingRel j i → x✝ j ≤ y✝ j ∧ y✝ j ≤ x✝ j
hl : x✝ i < y✝ i
⊢ InvImage (DFinsupp.Lex (Function.swap WellOrderingRel) fun x x_1 x_2 => x_1 < x_2)
    (mapRange (fun i => e i) (_ : ∀ (x : ι), (fun i => e i) x 0 = (fun i => e i) x 0)) x✝ y✝

Next tactic:
exact ⟨i, fun j hj ↦ Quot.sound (he j hj), hl⟩
instance Pi.wellFoundedLT [Finite ι] [∀ i, Preorder (α i)] [hw : ∀ i, WellFoundedLT (α i)] :
    WellFoundedLT (∀ i, α i) :=
  ⟨by
    

Proof state:
ι : Type u_1
α : ι → Type u_2
r : ι → ι → Prop
s : (i : ι) → α i → α i → Prop
inst✝¹ : Finite ι
inst✝ : (i : ι) → Preorder (α i)
hw : ∀ (i : ι), WellFoundedLT (α i)
⊢ WellFounded fun x x_1 => x < x_1

Next tactic:
obtain h | ⟨⟨x⟩⟩ := isEmpty_or_nonempty (∀ i, α i)
instance Pi.wellFoundedLT [Finite ι] [∀ i, Preorder (α i)] [hw : ∀ i, WellFoundedLT (α i)] :
    WellFoundedLT (∀ i, α i) :=
  ⟨by
    obtain h | ⟨⟨x⟩⟩ := isEmpty_or_nonempty (∀ i, α i)
    · 

Proof state:
case inl
ι : Type u_1
α : ι → Type u_2
r : ι → ι → Prop
s : (i : ι) → α i → α i → Prop
inst✝¹ : Finite ι
inst✝ : (i : ι) → Preorder (α i)
hw : ∀ (i : ι), WellFoundedLT (α i)
h : IsEmpty ((i : ι) → α i)
⊢ WellFounded fun x x_1 => x < x_1

Next tactic:
convert emptyWf.wf
instance Pi.wellFoundedLT [Finite ι] [∀ i, Preorder (α i)] [hw : ∀ i, WellFoundedLT (α i)] :
    WellFoundedLT (∀ i, α i) :=
  ⟨by
    obtain h | ⟨⟨x⟩⟩ := isEmpty_or_nonempty (∀ i, α i)
    · convert emptyWf.wf
    

Proof state:
case inr.intro
ι : Type u_1
α : ι → Type u_2
r : ι → ι → Prop
s : (i : ι) → α i → α i → Prop
inst✝¹ : Finite ι
inst✝ : (i : ι) → Preorder (α i)
hw : ∀ (i : ι), WellFoundedLT (α i)
x : (i : ι) → α i
⊢ WellFounded fun x x_1 => x < x_1

Next tactic:
letI : ∀ i, Zero (α i) := fun i => ⟨(hw i).wf.min ⊤ ⟨x i, trivial⟩⟩
instance Pi.wellFoundedLT [Finite ι] [∀ i, Preorder (α i)] [hw : ∀ i, WellFoundedLT (α i)] :
    WellFoundedLT (∀ i, α i) :=
  ⟨by
    obtain h | ⟨⟨x⟩⟩ := isEmpty_or_nonempty (∀ i, α i)
    · convert emptyWf.wf
    letI : ∀ i, Zero (α i) := fun i => ⟨(hw i).wf.min ⊤ ⟨x i, trivial⟩⟩
    

Proof state:
case inr.intro
ι : Type u_1
α : ι → Type u_2
r : ι → ι → Prop
s : (i : ι) → α i → α i → Prop
inst✝¹ : Finite ι
inst✝ : (i : ι) → Preorder (α i)
hw : ∀ (i : ι), WellFoundedLT (α i)
x : (i : ι) → α i
this : (i : ι) → Zero (α i) :=
  fun i => { zero := WellFounded.min (_ : WellFounded fun x x_1 => x < x_1) ⊤ (_ : ∃ x, x ∈ ⊤) }
⊢ WellFounded fun x x_1 => x < x_1

Next tactic:
haveI := Fintype.ofFinite ι
instance Pi.wellFoundedLT [Finite ι] [∀ i, Preorder (α i)] [hw : ∀ i, WellFoundedLT (α i)] :
    WellFoundedLT (∀ i, α i) :=
  ⟨by
    obtain h | ⟨⟨x⟩⟩ := isEmpty_or_nonempty (∀ i, α i)
    · convert emptyWf.wf
    letI : ∀ i, Zero (α i) := fun i => ⟨(hw i).wf.min ⊤ ⟨x i, trivial⟩⟩
    haveI := Fintype.ofFinite ι
    

Proof state:
case inr.intro
ι : Type u_1
α : ι → Type u_2
r : ι → ι → Prop
s : (i : ι) → α i → α i → Prop
inst✝¹ : Finite ι
inst✝ : (i : ι) → Preorder (α i)
hw : ∀ (i : ι), WellFoundedLT (α i)
x : (i : ι) → α i
this✝ : (i : ι) → Zero (α i) :=
  fun i => { zero := WellFounded.min (_ : WellFounded fun x x_1 => x < x_1) ⊤ (_ : ∃ x, x ∈ ⊤) }
this : Fintype ι
⊢ WellFounded fun x x_1 => x < x_1

Next tactic:
refine' InvImage.wf equivFunOnFintype.symm (DFinsupp.wellFoundedLT fun i a => _).wf
instance Pi.wellFoundedLT [Finite ι] [∀ i, Preorder (α i)] [hw : ∀ i, WellFoundedLT (α i)] :
    WellFoundedLT (∀ i, α i) :=
  ⟨by
    obtain h | ⟨⟨x⟩⟩ := isEmpty_or_nonempty (∀ i, α i)
    · convert emptyWf.wf
    letI : ∀ i, Zero (α i) := fun i => ⟨(hw i).wf.min ⊤ ⟨x i, trivial⟩⟩
    haveI := Fintype.ofFinite ι
    refine' InvImage.wf equivFunOnFintype.symm (DFinsupp.wellFoundedLT fun i a => _).wf
    

Proof state:
case inr.intro
ι : Type u_1
α : ι → Type u_2
r : ι → ι → Prop
s : (i : ι) → α i → α i → Prop
inst✝¹ : Finite ι
inst✝ : (i : ι) → Preorder (α i)
hw : ∀ (i : ι), WellFoundedLT (α i)
x : (i : ι) → α i
this✝ : (i : ι) → Zero (α i) :=
  fun i => { zero := WellFounded.min (_ : WellFounded fun x x_1 => x < x_1) ⊤ (_ : ∃ x, x ∈ ⊤) }
this : Fintype ι
i : ι
a : α i
⊢ ¬a < 0

Next tactic:
exact (hw i).wf.not_lt_min ⊤ _ trivial
theorem perm_comp_perm : (Perm ∘r Perm : List α → List α → Prop) = Perm := by
  

Proof state:
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a : α
γ : Type u_3
δ : Type u_4
r : α → β → Prop
p : γ → δ → Prop
⊢ Perm ∘r Perm = Perm

Next tactic:
funext a c
theorem perm_comp_perm : (Perm ∘r Perm : List α → List α → Prop) = Perm := by
  funext a c; 

Proof state:
case h.h
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a✝ : α
γ : Type u_3
δ : Type u_4
r : α → β → Prop
p : γ → δ → Prop
a c : List α
⊢ (Perm ∘r Perm) a c = (a ~ c)

Next tactic:
apply propext
theorem perm_comp_perm : (Perm ∘r Perm : List α → List α → Prop) = Perm := by
  funext a c; apply propext
  

Proof state:
case h.h.a
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a✝ : α
γ : Type u_3
δ : Type u_4
r : α → β → Prop
p : γ → δ → Prop
a c : List α
⊢ (Perm ∘r Perm) a c ↔ a ~ c

Next tactic:
constructor
theorem perm_comp_perm : (Perm ∘r Perm : List α → List α → Prop) = Perm := by
  funext a c; apply propext
  constructor
  · 

Proof state:
case h.h.a.mp
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a✝ : α
γ : Type u_3
δ : Type u_4
r : α → β → Prop
p : γ → δ → Prop
a c : List α
⊢ (Perm ∘r Perm) a c → a ~ c

Next tactic:
exact fun ⟨b, hab, hba⟩ => Perm.trans hab hba
theorem perm_comp_perm : (Perm ∘r Perm : List α → List α → Prop) = Perm := by
  funext a c; apply propext
  constructor
  · exact fun ⟨b, hab, hba⟩ => Perm.trans hab hba
  · 

Proof state:
case h.h.a.mpr
α : Type u_1
β : Type u_2
l l₁ l₂ : List α
a✝ : α
γ : Type u_3
δ : Type u_4
r : α → β → Prop
p : γ → δ → Prop
a c : List α
⊢ a ~ c → (Perm ∘r Perm) a c

Next tactic:
exact fun h => ⟨a, Perm.refl a, h⟩
theorem perm_comp_forall₂ {l u v} (hlu : Perm l u) (huv : Forall₂ r u v) :
    (Forall₂ r ∘r Perm) l v := by
  

Proof state:
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a : α
γ : Type u_3
δ : Type u_4
r : α → β → Prop
p : γ → δ → Prop
l u : List α
v : List β
hlu : l ~ u
huv : Forall₂ r u v
⊢ (Forall₂ r ∘r Perm) l v

Next tactic:
induction hlu generalizing v
theorem perm_comp_forall₂ {l u v} (hlu : Perm l u) (huv : Forall₂ r u v) :
    (Forall₂ r ∘r Perm) l v := by
  induction hlu generalizing v
  

Proof state:
case nil
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a : α
γ : Type u_3
δ : Type u_4
r : α → β → Prop
p : γ → δ → Prop
l u : List α
v : List β
huv : Forall₂ r [] v
⊢ (Forall₂ r ∘r Perm) [] v
case cons
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a : α
γ : Type u_3
δ : Type u_4
r : α → β → Prop
p : γ → δ → Prop
l u : List α
x✝ : α
l₁✝ l₂✝ : List α
a✝ : l₁✝ ~ l₂✝
a_ih✝ : ∀ {v : List β}, Forall₂ r l₂✝ v → (Forall₂ r ∘r Perm) l₁✝ v
v : List β
huv : Forall₂ r (x✝ :: l₂✝) v
⊢ (Forall₂ r ∘r Perm) (x✝ :: l₁✝) v
case swap
α : Type u_1
β : Type u_2
l✝¹ l₁ l₂ : List α
a : α
γ : Type u_3
δ : Type u_4
r : α → β → Prop
p : γ → δ → Prop
l u : List α
x✝ y✝ : α
l✝ : List α
v : List β
huv : Forall₂ r (x✝ :: y✝ :: l✝) v
⊢ (Forall₂ r ∘r Perm) (y✝ :: x✝ :: l✝) v
case trans
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a : α
γ : Type u_3
δ : Type u_4
r : α → β → Prop
p : γ → δ → Prop
l u l₁✝ l₂✝ l₃✝ : List α
a✝¹ : l₁✝ ~ l₂✝
a✝ : l₂✝ ~ l₃✝
a_ih✝¹ : ∀ {v : List β}, Forall₂ r l₂✝ v → (Forall₂ r ∘r Perm) l₁✝ v
a_ih✝ : ∀ {v : List β}, Forall₂ r l₃✝ v → (Forall₂ r ∘r Perm) l₂✝ v
v : List β
huv : Forall₂ r l₃✝ v
⊢ (Forall₂ r ∘r Perm) l₁✝ v

Next tactic:
case nil => cases huv; exact ⟨[], Forall₂.nil, Perm.nil⟩
theorem perm_comp_forall₂ {l u v} (hlu : Perm l u) (huv : Forall₂ r u v) :
    (Forall₂ r ∘r Perm) l v := by
  induction hlu generalizing v
  

Proof state:
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a : α
γ : Type u_3
δ : Type u_4
r : α → β → Prop
p : γ → δ → Prop
l u : List α
v : List β
huv : Forall₂ r [] v
⊢ (Forall₂ r ∘r Perm) [] v

Next tactic:
case nil => cases huv; exact ⟨[], Forall₂.nil, Perm.nil⟩
theorem perm_comp_forall₂ {l u v} (hlu : Perm l u) (huv : Forall₂ r u v) :
    (Forall₂ r ∘r Perm) l v := by
  induction hlu generalizing v
  case nil => 

Proof state:
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a : α
γ : Type u_3
δ : Type u_4
r : α → β → Prop
p : γ → δ → Prop
l u : List α
v : List β
huv : Forall₂ r [] v
⊢ (Forall₂ r ∘r Perm) [] v

Next tactic:
cases huv
theorem perm_comp_forall₂ {l u v} (hlu : Perm l u) (huv : Forall₂ r u v) :
    (Forall₂ r ∘r Perm) l v := by
  induction hlu generalizing v
  case nil => cases huv; 

Proof state:
case nil
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a : α
γ : Type u_3
δ : Type u_4
r : α → β → Prop
p : γ → δ → Prop
l u : List α
⊢ (Forall₂ r ∘r Perm) [] []

Next tactic:
exact ⟨[], Forall₂.nil, Perm.nil⟩
theorem perm_comp_forall₂ {l u v} (hlu : Perm l u) (huv : Forall₂ r u v) :
    (Forall₂ r ∘r Perm) l v := by
  induction hlu generalizing v
  case nil => cases huv; exact ⟨[], Forall₂.nil, Perm.nil⟩
  

Proof state:
case cons
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a : α
γ : Type u_3
δ : Type u_4
r : α → β → Prop
p : γ → δ → Prop
l u : List α
x✝ : α
l₁✝ l₂✝ : List α
a✝ : l₁✝ ~ l₂✝
a_ih✝ : ∀ {v : List β}, Forall₂ r l₂✝ v → (Forall₂ r ∘r Perm) l₁✝ v
v : List β
huv : Forall₂ r (x✝ :: l₂✝) v
⊢ (Forall₂ r ∘r Perm) (x✝ :: l₁✝) v
case swap
α : Type u_1
β : Type u_2
l✝¹ l₁ l₂ : List α
a : α
γ : Type u_3
δ : Type u_4
r : α → β → Prop
p : γ → δ → Prop
l u : List α
x✝ y✝ : α
l✝ : List α
v : List β
huv : Forall₂ r (x✝ :: y✝ :: l✝) v
⊢ (Forall₂ r ∘r Perm) (y✝ :: x✝ :: l✝) v
case trans
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a : α
γ : Type u_3
δ : Type u_4
r : α → β → Prop
p : γ → δ → Prop
l u l₁✝ l₂✝ l₃✝ : List α
a✝¹ : l₁✝ ~ l₂✝
a✝ : l₂✝ ~ l₃✝
a_ih✝¹ : ∀ {v : List β}, Forall₂ r l₂✝ v → (Forall₂ r ∘r Perm) l₁✝ v
a_ih✝ : ∀ {v : List β}, Forall₂ r l₃✝ v → (Forall₂ r ∘r Perm) l₂✝ v
v : List β
huv : Forall₂ r l₃✝ v
⊢ (Forall₂ r ∘r Perm) l₁✝ v

Next tactic:
case cons a l u _hlu ih =>
    cases' huv with _ b _ v hab huv'
    rcases ih huv' with ⟨l₂, h₁₂, h₂₃⟩
    exact ⟨b :: l₂, Forall₂.cons hab h₁₂, h₂₃.cons _⟩
theorem perm_comp_forall₂ {l u v} (hlu : Perm l u) (huv : Forall₂ r u v) :
    (Forall₂ r ∘r Perm) l v := by
  induction hlu generalizing v
  case nil => cases huv; exact ⟨[], Forall₂.nil, Perm.nil⟩
  

Proof state:
α : Type u_1
β : Type u_2
l✝¹ l₁ l₂ : List α
a✝ : α
γ : Type u_3
δ : Type u_4
r : α → β → Prop
p : γ → δ → Prop
l✝ u✝ : List α
a : α
l u : List α
_hlu : l ~ u
ih : ∀ {v : List β}, Forall₂ r u v → (Forall₂ r ∘r Perm) l v
v : List β
huv : Forall₂ r (a :: u) v
⊢ (Forall₂ r ∘r Perm) (a :: l) v

Next tactic:
case cons a l u _hlu ih =>
    cases' huv with _ b _ v hab huv'
    rcases ih huv' with ⟨l₂, h₁₂, h₂₃⟩
    exact ⟨b :: l₂, Forall₂.cons hab h₁₂, h₂₃.cons _⟩
theorem perm_comp_forall₂ {l u v} (hlu : Perm l u) (huv : Forall₂ r u v) :
    (Forall₂ r ∘r Perm) l v := by
  induction hlu generalizing v
  case nil => cases huv; exact ⟨[], Forall₂.nil, Perm.nil⟩
  case cons a l u _hlu ih =>
    

Proof state:
α : Type u_1
β : Type u_2
l✝¹ l₁ l₂ : List α
a✝ : α
γ : Type u_3
δ : Type u_4
r : α → β → Prop
p : γ → δ → Prop
l✝ u✝ : List α
a : α
l u : List α
_hlu : l ~ u
ih : ∀ {v : List β}, Forall₂ r u v → (Forall₂ r ∘r Perm) l v
v : List β
huv : Forall₂ r (a :: u) v
⊢ (Forall₂ r ∘r Perm) (a :: l) v

Next tactic:
cases' huv with _ b _ v hab huv'
theorem perm_comp_forall₂ {l u v} (hlu : Perm l u) (huv : Forall₂ r u v) :
    (Forall₂ r ∘r Perm) l v := by
  induction hlu generalizing v
  case nil => cases huv; exact ⟨[], Forall₂.nil, Perm.nil⟩
  case cons a l u _hlu ih =>
    cases' huv with _ b _ v hab huv'
    

Proof state:
case cons
α : Type u_1
β : Type u_2
l✝¹ l₁ l₂ : List α
a✝ : α
γ : Type u_3
δ : Type u_4
r : α → β → Prop
p : γ → δ → Prop
l✝ u✝ : List α
a : α
l u : List α
_hlu : l ~ u
ih : ∀ {v : List β}, Forall₂ r u v → (Forall₂ r ∘r Perm) l v
b : β
v : List β
hab : r a b
huv' : Forall₂ r u v
⊢ (Forall₂ r ∘r Perm) (a :: l) (b :: v)

Next tactic:
rcases ih huv' with ⟨l₂, h₁₂, h₂₃⟩
theorem perm_comp_forall₂ {l u v} (hlu : Perm l u) (huv : Forall₂ r u v) :
    (Forall₂ r ∘r Perm) l v := by
  induction hlu generalizing v
  case nil => cases huv; exact ⟨[], Forall₂.nil, Perm.nil⟩
  case cons a l u _hlu ih =>
    cases' huv with _ b _ v hab huv'
    rcases ih huv' with ⟨l₂, h₁₂, h₂₃⟩
    

Proof state:
case cons.intro.intro
α : Type u_1
β : Type u_2
l✝¹ l₁ l₂✝ : List α
a✝ : α
γ : Type u_3
δ : Type u_4
r : α → β → Prop
p : γ → δ → Prop
l✝ u✝ : List α
a : α
l u : List α
_hlu : l ~ u
ih : ∀ {v : List β}, Forall₂ r u v → (Forall₂ r ∘r Perm) l v
b : β
v : List β
hab : r a b
huv' : Forall₂ r u v
l₂ : List β
h₁₂ : Forall₂ r l l₂
h₂₃ : l₂ ~ v
⊢ (Forall₂ r ∘r Perm) (a :: l) (b :: v)

Next tactic:
exact ⟨b :: l₂, Forall₂.cons hab h₁₂, h₂₃.cons _⟩
theorem perm_comp_forall₂ {l u v} (hlu : Perm l u) (huv : Forall₂ r u v) :
    (Forall₂ r ∘r Perm) l v := by
  induction hlu generalizing v
  case nil => cases huv; exact ⟨[], Forall₂.nil, Perm.nil⟩
  case cons a l u _hlu ih =>
    cases' huv with _ b _ v hab huv'
    rcases ih huv' with ⟨l₂, h₁₂, h₂₃⟩
    exact ⟨b :: l₂, Forall₂.cons hab h₁₂, h₂₃.cons _⟩
  

Proof state:
case swap
α : Type u_1
β : Type u_2
l✝¹ l₁ l₂ : List α
a : α
γ : Type u_3
δ : Type u_4
r : α → β → Prop
p : γ → δ → Prop
l u : List α
x✝ y✝ : α
l✝ : List α
v : List β
huv : Forall₂ r (x✝ :: y✝ :: l✝) v
⊢ (Forall₂ r ∘r Perm) (y✝ :: x✝ :: l✝) v
case trans
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a : α
γ : Type u_3
δ : Type u_4
r : α → β → Prop
p : γ → δ → Prop
l u l₁✝ l₂✝ l₃✝ : List α
a✝¹ : l₁✝ ~ l₂✝
a✝ : l₂✝ ~ l₃✝
a_ih✝¹ : ∀ {v : List β}, Forall₂ r l₂✝ v → (Forall₂ r ∘r Perm) l₁✝ v
a_ih✝ : ∀ {v : List β}, Forall₂ r l₃✝ v → (Forall₂ r ∘r Perm) l₂✝ v
v : List β
huv : Forall₂ r l₃✝ v
⊢ (Forall₂ r ∘r Perm) l₁✝ v

Next tactic:
case swap a₁ a₂ h₂₃ =>
    cases' huv with _ b₁ _ l₂ h₁ hr₂₃
    cases' hr₂₃ with _ b₂ _ l₂ h₂ h₁₂
    exact ⟨b₂ :: b₁ :: l₂, Forall₂.cons h₂ (Forall₂.cons h₁ h₁₂), Perm.swap _ _ _⟩
theorem perm_comp_forall₂ {l u v} (hlu : Perm l u) (huv : Forall₂ r u v) :
    (Forall₂ r ∘r Perm) l v := by
  induction hlu generalizing v
  case nil => cases huv; exact ⟨[], Forall₂.nil, Perm.nil⟩
  case cons a l u _hlu ih =>
    cases' huv with _ b _ v hab huv'
    rcases ih huv' with ⟨l₂, h₁₂, h₂₃⟩
    exact ⟨b :: l₂, Forall₂.cons hab h₁₂, h₂₃.cons _⟩
  

Proof state:
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a : α
γ : Type u_3
δ : Type u_4
r : α → β → Prop
p : γ → δ → Prop
l u : List α
a₁ a₂ : α
h₂₃ : List α
v : List β
huv : Forall₂ r (a₁ :: a₂ :: h₂₃) v
⊢ (Forall₂ r ∘r Perm) (a₂ :: a₁ :: h₂₃) v

Next tactic:
case swap a₁ a₂ h₂₃ =>
    cases' huv with _ b₁ _ l₂ h₁ hr₂₃
    cases' hr₂₃ with _ b₂ _ l₂ h₂ h₁₂
    exact ⟨b₂ :: b₁ :: l₂, Forall₂.cons h₂ (Forall₂.cons h₁ h₁₂), Perm.swap _ _ _⟩
theorem perm_comp_forall₂ {l u v} (hlu : Perm l u) (huv : Forall₂ r u v) :
    (Forall₂ r ∘r Perm) l v := by
  induction hlu generalizing v
  case nil => cases huv; exact ⟨[], Forall₂.nil, Perm.nil⟩
  case cons a l u _hlu ih =>
    cases' huv with _ b _ v hab huv'
    rcases ih huv' with ⟨l₂, h₁₂, h₂₃⟩
    exact ⟨b :: l₂, Forall₂.cons hab h₁₂, h₂₃.cons _⟩
  case swap a₁ a₂ h₂₃ =>
    

Proof state:
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a : α
γ : Type u_3
δ : Type u_4
r : α → β → Prop
p : γ → δ → Prop
l u : List α
a₁ a₂ : α
h₂₃ : List α
v : List β
huv : Forall₂ r (a₁ :: a₂ :: h₂₃) v
⊢ (Forall₂ r ∘r Perm) (a₂ :: a₁ :: h₂₃) v

Next tactic:
cases' huv with _ b₁ _ l₂ h₁ hr₂₃
theorem perm_comp_forall₂ {l u v} (hlu : Perm l u) (huv : Forall₂ r u v) :
    (Forall₂ r ∘r Perm) l v := by
  induction hlu generalizing v
  case nil => cases huv; exact ⟨[], Forall₂.nil, Perm.nil⟩
  case cons a l u _hlu ih =>
    cases' huv with _ b _ v hab huv'
    rcases ih huv' with ⟨l₂, h₁₂, h₂₃⟩
    exact ⟨b :: l₂, Forall₂.cons hab h₁₂, h₂₃.cons _⟩
  case swap a₁ a₂ h₂₃ =>
    cases' huv with _ b₁ _ l₂ h₁ hr₂₃
    

Proof state:
case cons
α : Type u_1
β : Type u_2
l✝ l₁ l₂✝ : List α
a : α
γ : Type u_3
δ : Type u_4
r : α → β → Prop
p : γ → δ → Prop
l u : List α
a₁ a₂ : α
h₂₃ : List α
b₁ : β
l₂ : List β
h₁ : r a₁ b₁
hr₂₃ : Forall₂ r (a₂ :: h₂₃) l₂
⊢ (Forall₂ r ∘r Perm) (a₂ :: a₁ :: h₂₃) (b₁ :: l₂)

Next tactic:
cases' hr₂₃ with _ b₂ _ l₂ h₂ h₁₂
theorem perm_comp_forall₂ {l u v} (hlu : Perm l u) (huv : Forall₂ r u v) :
    (Forall₂ r ∘r Perm) l v := by
  induction hlu generalizing v
  case nil => cases huv; exact ⟨[], Forall₂.nil, Perm.nil⟩
  case cons a l u _hlu ih =>
    cases' huv with _ b _ v hab huv'
    rcases ih huv' with ⟨l₂, h₁₂, h₂₃⟩
    exact ⟨b :: l₂, Forall₂.cons hab h₁₂, h₂₃.cons _⟩
  case swap a₁ a₂ h₂₃ =>
    cases' huv with _ b₁ _ l₂ h₁ hr₂₃
    cases' hr₂₃ with _ b₂ _ l₂ h₂ h₁₂
    

Proof state:
case cons.cons
α : Type u_1
β : Type u_2
l✝ l₁ l₂✝ : List α
a : α
γ : Type u_3
δ : Type u_4
r : α → β → Prop
p : γ → δ → Prop
l u : List α
a₁ a₂ : α
h₂₃ : List α
b₁ : β
h₁ : r a₁ b₁
b₂ : β
l₂ : List β
h₂ : r a₂ b₂
h₁₂ : Forall₂ r h₂₃ l₂
⊢ (Forall₂ r ∘r Perm) (a₂ :: a₁ :: h₂₃) (b₁ :: b₂ :: l₂)

Next tactic:
exact ⟨b₂ :: b₁ :: l₂, Forall₂.cons h₂ (Forall₂.cons h₁ h₁₂), Perm.swap _ _ _⟩
theorem perm_comp_forall₂ {l u v} (hlu : Perm l u) (huv : Forall₂ r u v) :
    (Forall₂ r ∘r Perm) l v := by
  induction hlu generalizing v
  case nil => cases huv; exact ⟨[], Forall₂.nil, Perm.nil⟩
  case cons a l u _hlu ih =>
    cases' huv with _ b _ v hab huv'
    rcases ih huv' with ⟨l₂, h₁₂, h₂₃⟩
    exact ⟨b :: l₂, Forall₂.cons hab h₁₂, h₂₃.cons _⟩
  case swap a₁ a₂ h₂₃ =>
    cases' huv with _ b₁ _ l₂ h₁ hr₂₃
    cases' hr₂₃ with _ b₂ _ l₂ h₂ h₁₂
    exact ⟨b₂ :: b₁ :: l₂, Forall₂.cons h₂ (Forall₂.cons h₁ h₁₂), Perm.swap _ _ _⟩
  

Proof state:
case trans
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a : α
γ : Type u_3
δ : Type u_4
r : α → β → Prop
p : γ → δ → Prop
l u l₁✝ l₂✝ l₃✝ : List α
a✝¹ : l₁✝ ~ l₂✝
a✝ : l₂✝ ~ l₃✝
a_ih✝¹ : ∀ {v : List β}, Forall₂ r l₂✝ v → (Forall₂ r ∘r Perm) l₁✝ v
a_ih✝ : ∀ {v : List β}, Forall₂ r l₃✝ v → (Forall₂ r ∘r Perm) l₂✝ v
v : List β
huv : Forall₂ r l₃✝ v
⊢ (Forall₂ r ∘r Perm) l₁✝ v

Next tactic:
case
    trans la₁ la₂ la₃ _ _ ih₁ ih₂ =>
    rcases ih₂ huv with ⟨lb₂, hab₂, h₂₃⟩
    rcases ih₁ hab₂ with ⟨lb₁, hab₁, h₁₂⟩
    exact ⟨lb₁, hab₁, Perm.trans h₁₂ h₂₃⟩
theorem perm_comp_forall₂ {l u v} (hlu : Perm l u) (huv : Forall₂ r u v) :
    (Forall₂ r ∘r Perm) l v := by
  induction hlu generalizing v
  case nil => cases huv; exact ⟨[], Forall₂.nil, Perm.nil⟩
  case cons a l u _hlu ih =>
    cases' huv with _ b _ v hab huv'
    rcases ih huv' with ⟨l₂, h₁₂, h₂₃⟩
    exact ⟨b :: l₂, Forall₂.cons hab h₁₂, h₂₃.cons _⟩
  case swap a₁ a₂ h₂₃ =>
    cases' huv with _ b₁ _ l₂ h₁ hr₂₃
    cases' hr₂₃ with _ b₂ _ l₂ h₂ h₁₂
    exact ⟨b₂ :: b₁ :: l₂, Forall₂.cons h₂ (Forall₂.cons h₁ h₁₂), Perm.swap _ _ _⟩
  

Proof state:
α : Type u_1
β : Type u_2
l✝ l₁ l₂ : List α
a : α
γ : Type u_3
δ : Type u_4
r : α → β → Prop
p : γ → δ → Prop
l u la₁ la₂ la₃ : List α
a✝¹ : la₁ ~ la₂
a✝ : la₂ ~ la₃
ih₁ : ∀ {v : List β}, Forall₂ r la₂ v → (Forall₂ r ∘r Perm) la₁ v
ih₂ : ∀ {v : List β}, Forall₂ r la₃ v → (Forall₂ r ∘r Perm) la₂ v
v : List β
huv : Forall₂ r la₃ v
⊢ (Forall₂ r ∘r Perm) la₁ v

Next tactic:
case
    trans la₁ la₂ la₃ _ _ ih₁ ih₂ =>
    rcases ih₂ huv with ⟨lb₂, hab₂, h₂₃⟩
    rcases ih₁ hab₂ with ⟨lb₁, hab₁, h₁₂⟩
    exact ⟨lb₁, hab₁, Perm.trans h₁₂ h₂₃⟩