Theorem: List.list_reverse_induction
File: Mathlib/Data/List/Indexes.lean

tactic: let q := fun l ↦ p (reverse l)
state_before: α : Type u
β : Type v
p : List α → Prop
base : p []
ind : ∀ (l : List α) (e : α), p l → p (l ++ [e])
⊢ ∀ (l : List α), p l
state_after: α : Type u
β : Type v
p : List α → Prop
base : p []
ind : ∀ (l : List α) (e : α), p l → p (l ++ [e])
q : List α → Prop := fun l => p l.reverse
⊢ ∀ (l : List α), p l

tactic: have pq : ∀ l, p (reverse l) → q l := by simp only [q, reverse_reverse]; intro; exact id
state_before: α : Type u
β : Type v
p : List α → Prop
base : p []
ind : ∀ (l : List α) (e : α), p l → p (l ++ [e])
q : List α → Prop := fun l => p l.reverse
⊢ ∀ (l : List α), p l
state_after: α : Type u
β : Type v
p : List α → Prop
base : p []
ind : ∀ (l : List α) (e : α), p l → p (l ++ [e])
q : List α → Prop := fun l => p l.reverse
pq : ∀ (l : List α), p l.reverse → q l
⊢ ∀ (l : List α), p l

tactic: have qp : ∀ l, q (reverse l) → p l := by simp only [q, reverse_reverse]; intro; exact id
state_before: α : Type u
β : Type v
p : List α → Prop
base : p []
ind : ∀ (l : List α) (e : α), p l → p (l ++ [e])
q : List α → Prop := fun l => p l.reverse
pq : ∀ (l : List α), p l.reverse → q l
⊢ ∀ (l : List α), p l
state_after: α : Type u
β : Type v
p : List α → Prop
base : p []
ind : ∀ (l : List α) (e : α), p l → p (l ++ [e])
q : List α → Prop := fun l => p l.reverse
pq : ∀ (l : List α), p l.reverse → q l
qp : ∀ (l : List α), q l.reverse → p l
⊢ ∀ (l : List α), p l

tactic: intro l
state_before: α : Type u
β : Type v
p : List α → Prop
base : p []
ind : ∀ (l : List α) (e : α), p l → p (l ++ [e])
q : List α → Prop := fun l => p l.reverse
pq : ∀ (l : List α), p l.reverse → q l
qp : ∀ (l : List α), q l.reverse → p l
⊢ ∀ (l : List α), p l
state_after: α : Type u
β : Type v
p : List α → Prop
base : p []
ind : ∀ (l : List α) (e : α), p l → p (l ++ [e])
q : List α → Prop := fun l => p l.reverse
pq : ∀ (l : List α), p l.reverse → q l
qp : ∀ (l : List α), q l.reverse → p l
l : List α
⊢ p l

tactic: apply qp
state_before: α : Type u
β : Type v
p : List α → Prop
base : p []
ind : ∀ (l : List α) (e : α), p l → p (l ++ [e])
q : List α → Prop := fun l => p l.reverse
pq : ∀ (l : List α), p l.reverse → q l
qp : ∀ (l : List α), q l.reverse → p l
l : List α
⊢ p l
state_after: case a
α : Type u
β : Type v
p : List α → Prop
base : p []
ind : ∀ (l : List α) (e : α), p l → p (l ++ [e])
q : List α → Prop := fun l => p l.reverse
pq : ∀ (l : List α), p l.reverse → q l
qp : ∀ (l : List α), q l.reverse → p l
l : List α
⊢ q l.reverse

tactic: generalize (reverse l) = l
state_before: case a
α : Type u
β : Type v
p : List α → Prop
base : p []
ind : ∀ (l : List α) (e : α), p l → p (l ++ [e])
q : List α → Prop := fun l => p l.reverse
pq : ∀ (l : List α), p l.reverse → q l
qp : ∀ (l : List α), q l.reverse → p l
l : List α
⊢ q l.reverse
state_after: case a
α : Type u
β : Type v
p : List α → Prop
base : p []
ind : ∀ (l : List α) (e : α), p l → p (l ++ [e])
q : List α → Prop := fun l => p l.reverse
pq : ∀ (l : List α), p l.reverse → q l
qp : ∀ (l : List α), q l.reverse → p l
l✝ l : List α
⊢ q l

tactic: induction' l with head tail ih
state_before: case a
α : Type u
β : Type v
p : List α → Prop
base : p []
ind : ∀ (l : List α) (e : α), p l → p (l ++ [e])
q : List α → Prop := fun l => p l.reverse
pq : ∀ (l : List α), p l.reverse → q l
qp : ∀ (l : List α), q l.reverse → p l
l✝ l : List α
⊢ q l
state_after: case a.nil
α : Type u
β : Type v
p : List α → Prop
base : p []
ind : ∀ (l : List α) (e : α), p l → p (l ++ [e])
q : List α → Prop := fun l => p l.reverse
pq : ∀ (l : List α), p l.reverse → q l
qp : ∀ (l : List α), q l.reverse → p l
l : List α
⊢ q []

case a.cons
α : Type u
β : Type v
p : List α → Prop
base : p []
ind : ∀ (l : List α) (e : α), p l → p (l ++ [e])
q : List α → Prop := fun l => p l.reverse
pq : ∀ (l : List α), p l.reverse → q l
qp : ∀ (l : List α), q l.reverse → p l
l : List α
head : α
tail : List α
ih : q tail
⊢ q (head :: tail)

tactic: simp only [q, reverse_reverse]
state_before: α : Type u
β : Type v
p : List α → Prop
base : p []
ind : ∀ (l : List α) (e : α), p l → p (l ++ [e])
q : List α → Prop := fun l => p l.reverse
⊢ ∀ (l : List α), p l.reverse → q l
state_after: α : Type u
β : Type v
p : List α → Prop
base : p []
ind : ∀ (l : List α) (e : α), p l → p (l ++ [e])
q : List α → Prop := fun l => p l.reverse
⊢ ∀ (l : List α), p l.reverse → p l.reverse

tactic: intro
state_before: α : Type u
β : Type v
p : List α → Prop
base : p []
ind : ∀ (l : List α) (e : α), p l → p (l ++ [e])
q : List α → Prop := fun l => p l.reverse
⊢ ∀ (l : List α), p l.reverse → p l.reverse
state_after: α : Type u
β : Type v
p : List α → Prop
base : p []
ind : ∀ (l : List α) (e : α), p l → p (l ++ [e])
q : List α → Prop := fun l => p l.reverse
l✝ : List α
⊢ p l✝.reverse → p l✝.reverse

tactic: exact id
state_before: α : Type u
β : Type v
p : List α → Prop
base : p []
ind : ∀ (l : List α) (e : α), p l → p (l ++ [e])
q : List α → Prop := fun l => p l.reverse
l✝ : List α
⊢ p l✝.reverse → p l✝.reverse
state_after: no goals

tactic: simp only [q, reverse_reverse]
state_before: α : Type u
β : Type v
p : List α → Prop
base : p []
ind : ∀ (l : List α) (e : α), p l → p (l ++ [e])
q : List α → Prop := fun l => p l.reverse
pq : ∀ (l : List α), p l.reverse → q l
⊢ ∀ (l : List α), q l.reverse → p l
state_after: α : Type u
β : Type v
p : List α → Prop
base : p []
ind : ∀ (l : List α) (e : α), p l → p (l ++ [e])
q : List α → Prop := fun l => p l.reverse
pq : ∀ (l : List α), p l.reverse → q l
⊢ ∀ (l : List α), p l → p l

tactic: intro
state_before: α : Type u
β : Type v
p : List α → Prop
base : p []
ind : ∀ (l : List α) (e : α), p l → p (l ++ [e])
q : List α → Prop := fun l => p l.reverse
pq : ∀ (l : List α), p l.reverse → q l
⊢ ∀ (l : List α), p l → p l
state_after: α : Type u
β : Type v
p : List α → Prop
base : p []
ind : ∀ (l : List α) (e : α), p l → p (l ++ [e])
q : List α → Prop := fun l => p l.reverse
pq : ∀ (l : List α), p l.reverse → q l
l✝ : List α
⊢ p l✝ → p l✝

tactic: exact id
state_before: α : Type u
β : Type v
p : List α → Prop
base : p []
ind : ∀ (l : List α) (e : α), p l → p (l ++ [e])
q : List α → Prop := fun l => p l.reverse
pq : ∀ (l : List α), p l.reverse → q l
l✝ : List α
⊢ p l✝ → p l✝
state_after: no goals

tactic: apply pq
state_before: case a.nil
α : Type u
β : Type v
p : List α → Prop
base : p []
ind : ∀ (l : List α) (e : α), p l → p (l ++ [e])
q : List α → Prop := fun l => p l.reverse
pq : ∀ (l : List α), p l.reverse → q l
qp : ∀ (l : List α), q l.reverse → p l
l : List α
⊢ q []
state_after: case a.nil.a
α : Type u
β : Type v
p : List α → Prop
base : p []
ind : ∀ (l : List α) (e : α), p l → p (l ++ [e])
q : List α → Prop := fun l => p l.reverse
pq : ∀ (l : List α), p l.reverse → q l
qp : ∀ (l : List α), q l.reverse → p l
l : List α
⊢ p [].reverse

tactic: simp only [reverse_nil, base]
state_before: case a.nil.a
α : Type u
β : Type v
p : List α → Prop
base : p []
ind : ∀ (l : List α) (e : α), p l → p (l ++ [e])
q : List α → Prop := fun l => p l.reverse
pq : ∀ (l : List α), p l.reverse → q l
qp : ∀ (l : List α), q l.reverse → p l
l : List α
⊢ p [].reverse
state_after: no goals

tactic: apply pq
state_before: case a.cons
α : Type u
β : Type v
p : List α → Prop
base : p []
ind : ∀ (l : List α) (e : α), p l → p (l ++ [e])
q : List α → Prop := fun l => p l.reverse
pq : ∀ (l : List α), p l.reverse → q l
qp : ∀ (l : List α), q l.reverse → p l
l : List α
head : α
tail : List α
ih : q tail
⊢ q (head :: tail)
state_after: case a.cons.a
α : Type u
β : Type v
p : List α → Prop
base : p []
ind : ∀ (l : List α) (e : α), p l → p (l ++ [e])
q : List α → Prop := fun l => p l.reverse
pq : ∀ (l : List α), p l.reverse → q l
qp : ∀ (l : List α), q l.reverse → p l
l : List α
head : α
tail : List α
ih : q tail
⊢ p (head :: tail).reverse

tactic: simp only [reverse_cons]
state_before: case a.cons.a
α : Type u
β : Type v
p : List α → Prop
base : p []
ind : ∀ (l : List α) (e : α), p l → p (l ++ [e])
q : List α → Prop := fun l => p l.reverse
pq : ∀ (l : List α), p l.reverse → q l
qp : ∀ (l : List α), q l.reverse → p l
l : List α
head : α
tail : List α
ih : q tail
⊢ p (head :: tail).reverse
state_after: case a.cons.a
α : Type u
β : Type v
p : List α → Prop
base : p []
ind : ∀ (l : List α) (e : α), p l → p (l ++ [e])
q : List α → Prop := fun l => p l.reverse
pq : ∀ (l : List α), p l.reverse → q l
qp : ∀ (l : List α), q l.reverse → p l
l : List α
head : α
tail : List α
ih : q tail
⊢ p (tail.reverse ++ [head])

tactic: apply ind
state_before: case a.cons.a
α : Type u
β : Type v
p : List α → Prop
base : p []
ind : ∀ (l : List α) (e : α), p l → p (l ++ [e])
q : List α → Prop := fun l => p l.reverse
pq : ∀ (l : List α), p l.reverse → q l
qp : ∀ (l : List α), q l.reverse → p l
l : List α
head : α
tail : List α
ih : q tail
⊢ p (tail.reverse ++ [head])
state_after: case a.cons.a.a
α : Type u
β : Type v
p : List α → Prop
base : p []
ind : ∀ (l : List α) (e : α), p l → p (l ++ [e])
q : List α → Prop := fun l => p l.reverse
pq : ∀ (l : List α), p l.reverse → q l
qp : ∀ (l : List α), q l.reverse → p l
l : List α
head : α
tail : List α
ih : q tail
⊢ p tail.reverse

tactic: apply qp
state_before: case a.cons.a.a
α : Type u
β : Type v
p : List α → Prop
base : p []
ind : ∀ (l : List α) (e : α), p l → p (l ++ [e])
q : List α → Prop := fun l => p l.reverse
pq : ∀ (l : List α), p l.reverse → q l
qp : ∀ (l : List α), q l.reverse → p l
l : List α
head : α
tail : List α
ih : q tail
⊢ p tail.reverse
state_after: case a.cons.a.a.a
α : Type u
β : Type v
p : List α → Prop
base : p []
ind : ∀ (l : List α) (e : α), p l → p (l ++ [e])
q : List α → Prop := fun l => p l.reverse
pq : ∀ (l : List α), p l.reverse → q l
qp : ∀ (l : List α), q l.reverse → p l
l : List α
head : α
tail : List α
ih : q tail
⊢ q tail.reverse.reverse

tactic: rw [reverse_reverse]
state_before: case a.cons.a.a.a
α : Type u
β : Type v
p : List α → Prop
base : p []
ind : ∀ (l : List α) (e : α), p l → p (l ++ [e])
q : List α → Prop := fun l => p l.reverse
pq : ∀ (l : List α), p l.reverse → q l
qp : ∀ (l : List α), q l.reverse → p l
l : List α
head : α
tail : List α
ih : q tail
⊢ q tail.reverse.reverse
state_after: case a.cons.a.a.a
α : Type u
β : Type v
p : List α → Prop
base : p []
ind : ∀ (l : List α) (e : α), p l → p (l ++ [e])
q : List α → Prop := fun l => p l.reverse
pq : ∀ (l : List α), p l.reverse → q l
qp : ∀ (l : List α), q l.reverse → p l
l : List α
head : α
tail : List α
ih : q tail
⊢ q tail

tactic: exact ih
state_before: case a.cons.a.a.a
α : Type u
β : Type v
p : List α → Prop
base : p []
ind : ∀ (l : List α) (e : α), p l → p (l ++ [e])
q : List α → Prop := fun l => p l.reverse
pq : ∀ (l : List α), p l.reverse → q l
qp : ∀ (l : List α), q l.reverse → p l
l : List α
head : α
tail : List α
ih : q tail
⊢ q tail
state_after: no goals