Theorem: ContextFreeGrammar.reverse_derives
File: Mathlib/Computability/ContextFreeGrammar.lean

tactic: induction hgs with
| refl =>
  rw [List.reverse_singleton]
  apply ContextFreeGrammar.Derives.refl
| tail _ orig ih =>
  apply ContextFreeGrammar.Derives.trans_produces ih
  obtain ⟨r, rin, rewr⟩ := orig
  simp only [ContextFreeGrammar.reverse, List.mem_map] at rin
  obtain ⟨r₀, rin₀, rfl⟩ := rin
  refine ⟨r₀, rin₀, ?_⟩
  rw [ContextFreeRule.rewrites_iff] at rewr ⊢
  rcases rewr with ⟨p, q, rfl, rfl⟩
  use q.reverse, p.reverse
  simp [ContextFreeRule.reverse]
state_before: T : Type uT
g : ContextFreeGrammar T
s : List (Symbol T g.NT)
hgs : g.reverse.Derives [Symbol.nonterminal g.reverse.initial] s
⊢ g.Derives [Symbol.nonterminal g.initial] s.reverse
state_after: no goals

tactic: rw [List.reverse_singleton]
state_before: case refl
T : Type uT
g : ContextFreeGrammar T
s : List (Symbol T g.NT)
⊢ g.Derives [Symbol.nonterminal g.initial] [Symbol.nonterminal g.reverse.initial].reverse
state_after: case refl
T : Type uT
g : ContextFreeGrammar T
s : List (Symbol T g.NT)
⊢ g.Derives [Symbol.nonterminal g.initial] [Symbol.nonterminal g.reverse.initial]

tactic: apply ContextFreeGrammar.Derives.refl
state_before: case refl
T : Type uT
g : ContextFreeGrammar T
s : List (Symbol T g.NT)
⊢ g.Derives [Symbol.nonterminal g.initial] [Symbol.nonterminal g.reverse.initial]
state_after: no goals

tactic: apply ContextFreeGrammar.Derives.trans_produces ih
state_before: case tail
T : Type uT
g : ContextFreeGrammar T
s b✝ c✝ : List (Symbol T g.NT)
a✝ : Relation.ReflTransGen g.reverse.Produces [Symbol.nonterminal g.reverse.initial] b✝
orig : g.reverse.Produces b✝ c✝
ih : g.Derives [Symbol.nonterminal g.initial] b✝.reverse
⊢ g.Derives [Symbol.nonterminal g.initial] c✝.reverse
state_after: case tail
T : Type uT
g : ContextFreeGrammar T
s b✝ c✝ : List (Symbol T g.NT)
a✝ : Relation.ReflTransGen g.reverse.Produces [Symbol.nonterminal g.reverse.initial] b✝
orig : g.reverse.Produces b✝ c✝
ih : g.Derives [Symbol.nonterminal g.initial] b✝.reverse
⊢ g.Produces b✝.reverse c✝.reverse

tactic: obtain ⟨r, rin, rewr⟩ := orig
state_before: case tail
T : Type uT
g : ContextFreeGrammar T
s b✝ c✝ : List (Symbol T g.NT)
a✝ : Relation.ReflTransGen g.reverse.Produces [Symbol.nonterminal g.reverse.initial] b✝
orig : g.reverse.Produces b✝ c✝
ih : g.Derives [Symbol.nonterminal g.initial] b✝.reverse
⊢ g.Produces b✝.reverse c✝.reverse
state_after: case tail.intro.intro
T : Type uT
g : ContextFreeGrammar T
s b✝ c✝ : List (Symbol T g.NT)
a✝ : Relation.ReflTransGen g.reverse.Produces [Symbol.nonterminal g.reverse.initial] b✝
ih : g.Derives [Symbol.nonterminal g.initial] b✝.reverse
r : ContextFreeRule T g.reverse.NT
rin : r ∈ g.reverse.rules
rewr : r.Rewrites b✝ c✝
⊢ g.Produces b✝.reverse c✝.reverse

tactic: simp only [ContextFreeGrammar.reverse, List.mem_map] at rin
state_before: case tail.intro.intro
T : Type uT
g : ContextFreeGrammar T
s b✝ c✝ : List (Symbol T g.NT)
a✝ : Relation.ReflTransGen g.reverse.Produces [Symbol.nonterminal g.reverse.initial] b✝
ih : g.Derives [Symbol.nonterminal g.initial] b✝.reverse
r : ContextFreeRule T g.reverse.NT
rin : r ∈ g.reverse.rules
rewr : r.Rewrites b✝ c✝
⊢ g.Produces b✝.reverse c✝.reverse
state_after: case tail.intro.intro
T : Type uT
g : ContextFreeGrammar T
s b✝ c✝ : List (Symbol T g.NT)
a✝ : Relation.ReflTransGen g.reverse.Produces [Symbol.nonterminal g.reverse.initial] b✝
ih : g.Derives [Symbol.nonterminal g.initial] b✝.reverse
r : ContextFreeRule T g.reverse.NT
rewr : r.Rewrites b✝ c✝
rin : ∃ a ∈ g.rules, a.reverse = r
⊢ g.Produces b✝.reverse c✝.reverse

tactic: obtain ⟨r₀, rin₀, rfl⟩ := rin
state_before: case tail.intro.intro
T : Type uT
g : ContextFreeGrammar T
s b✝ c✝ : List (Symbol T g.NT)
a✝ : Relation.ReflTransGen g.reverse.Produces [Symbol.nonterminal g.reverse.initial] b✝
ih : g.Derives [Symbol.nonterminal g.initial] b✝.reverse
r : ContextFreeRule T g.reverse.NT
rewr : r.Rewrites b✝ c✝
rin : ∃ a ∈ g.rules, a.reverse = r
⊢ g.Produces b✝.reverse c✝.reverse
state_after: case tail.intro.intro.intro.intro
T : Type uT
g : ContextFreeGrammar T
s b✝ c✝ : List (Symbol T g.NT)
a✝ : Relation.ReflTransGen g.reverse.Produces [Symbol.nonterminal g.reverse.initial] b✝
ih : g.Derives [Symbol.nonterminal g.initial] b✝.reverse
r₀ : ContextFreeRule T g.NT
rin₀ : r₀ ∈ g.rules
rewr : r₀.reverse.Rewrites b✝ c✝
⊢ g.Produces b✝.reverse c✝.reverse

tactic: refine ⟨r₀, rin₀, ?_⟩
state_before: case tail.intro.intro.intro.intro
T : Type uT
g : ContextFreeGrammar T
s b✝ c✝ : List (Symbol T g.NT)
a✝ : Relation.ReflTransGen g.reverse.Produces [Symbol.nonterminal g.reverse.initial] b✝
ih : g.Derives [Symbol.nonterminal g.initial] b✝.reverse
r₀ : ContextFreeRule T g.NT
rin₀ : r₀ ∈ g.rules
rewr : r₀.reverse.Rewrites b✝ c✝
⊢ g.Produces b✝.reverse c✝.reverse
state_after: case tail.intro.intro.intro.intro
T : Type uT
g : ContextFreeGrammar T
s b✝ c✝ : List (Symbol T g.NT)
a✝ : Relation.ReflTransGen g.reverse.Produces [Symbol.nonterminal g.reverse.initial] b✝
ih : g.Derives [Symbol.nonterminal g.initial] b✝.reverse
r₀ : ContextFreeRule T g.NT
rin₀ : r₀ ∈ g.rules
rewr : r₀.reverse.Rewrites b✝ c✝
⊢ r₀.Rewrites b✝.reverse c✝.reverse

tactic: rw [ContextFreeRule.rewrites_iff] at rewr ⊢
state_before: case tail.intro.intro.intro.intro
T : Type uT
g : ContextFreeGrammar T
s b✝ c✝ : List (Symbol T g.NT)
a✝ : Relation.ReflTransGen g.reverse.Produces [Symbol.nonterminal g.reverse.initial] b✝
ih : g.Derives [Symbol.nonterminal g.initial] b✝.reverse
r₀ : ContextFreeRule T g.NT
rin₀ : r₀ ∈ g.rules
rewr : r₀.reverse.Rewrites b✝ c✝
⊢ r₀.Rewrites b✝.reverse c✝.reverse
state_after: case tail.intro.intro.intro.intro
T : Type uT
g : ContextFreeGrammar T
s b✝ c✝ : List (Symbol T g.NT)
a✝ : Relation.ReflTransGen g.reverse.Produces [Symbol.nonterminal g.reverse.initial] b✝
ih : g.Derives [Symbol.nonterminal g.initial] b✝.reverse
r₀ : ContextFreeRule T g.NT
rin₀ : r₀ ∈ g.rules
rewr : ∃ p q, b✝ = p ++ [Symbol.nonterminal r₀.reverse.input] ++ q ∧ c✝ = p ++ r₀.reverse.output ++ q
⊢ ∃ p q, b✝.reverse = p ++ [Symbol.nonterminal r₀.input] ++ q ∧ c✝.reverse = p ++ r₀.output ++ q

tactic: rcases rewr with ⟨p, q, rfl, rfl⟩
state_before: case tail.intro.intro.intro.intro
T : Type uT
g : ContextFreeGrammar T
s b✝ c✝ : List (Symbol T g.NT)
a✝ : Relation.ReflTransGen g.reverse.Produces [Symbol.nonterminal g.reverse.initial] b✝
ih : g.Derives [Symbol.nonterminal g.initial] b✝.reverse
r₀ : ContextFreeRule T g.NT
rin₀ : r₀ ∈ g.rules
rewr : ∃ p q, b✝ = p ++ [Symbol.nonterminal r₀.reverse.input] ++ q ∧ c✝ = p ++ r₀.reverse.output ++ q
⊢ ∃ p q, b✝.reverse = p ++ [Symbol.nonterminal r₀.input] ++ q ∧ c✝.reverse = p ++ r₀.output ++ q
state_after: case tail.intro.intro.intro.intro.intro.intro.intro
T : Type uT
g : ContextFreeGrammar T
s : List (Symbol T g.NT)
r₀ : ContextFreeRule T g.NT
rin₀ : r₀ ∈ g.rules
p q : List (Symbol T g.reverse.NT)
a✝ :
  Relation.ReflTransGen g.reverse.Produces [Symbol.nonterminal g.reverse.initial]
    (p ++ [Symbol.nonterminal r₀.reverse.input] ++ q)
ih : g.Derives [Symbol.nonterminal g.initial] (p ++ [Symbol.nonterminal r₀.reverse.input] ++ q).reverse
⊢ ∃ p_1 q_1,
    (p ++ [Symbol.nonterminal r₀.reverse.input] ++ q).reverse = p_1 ++ [Symbol.nonterminal r₀.input] ++ q_1 ∧
      (p ++ r₀.reverse.output ++ q).reverse = p_1 ++ r₀.output ++ q_1

tactic: use q.reverse, p.reverse
state_before: case tail.intro.intro.intro.intro.intro.intro.intro
T : Type uT
g : ContextFreeGrammar T
s : List (Symbol T g.NT)
r₀ : ContextFreeRule T g.NT
rin₀ : r₀ ∈ g.rules
p q : List (Symbol T g.reverse.NT)
a✝ :
  Relation.ReflTransGen g.reverse.Produces [Symbol.nonterminal g.reverse.initial]
    (p ++ [Symbol.nonterminal r₀.reverse.input] ++ q)
ih : g.Derives [Symbol.nonterminal g.initial] (p ++ [Symbol.nonterminal r₀.reverse.input] ++ q).reverse
⊢ ∃ p_1 q_1,
    (p ++ [Symbol.nonterminal r₀.reverse.input] ++ q).reverse = p_1 ++ [Symbol.nonterminal r₀.input] ++ q_1 ∧
      (p ++ r₀.reverse.output ++ q).reverse = p_1 ++ r₀.output ++ q_1
state_after: case h
T : Type uT
g : ContextFreeGrammar T
s : List (Symbol T g.NT)
r₀ : ContextFreeRule T g.NT
rin₀ : r₀ ∈ g.rules
p q : List (Symbol T g.reverse.NT)
a✝ :
  Relation.ReflTransGen g.reverse.Produces [Symbol.nonterminal g.reverse.initial]
    (p ++ [Symbol.nonterminal r₀.reverse.input] ++ q)
ih : g.Derives [Symbol.nonterminal g.initial] (p ++ [Symbol.nonterminal r₀.reverse.input] ++ q).reverse
⊢ (p ++ [Symbol.nonterminal r₀.reverse.input] ++ q).reverse = q.reverse ++ [Symbol.nonterminal r₀.input] ++ p.reverse ∧
    (p ++ r₀.reverse.output ++ q).reverse = q.reverse ++ r₀.output ++ p.reverse

tactic: simp [ContextFreeRule.reverse]
state_before: case h
T : Type uT
g : ContextFreeGrammar T
s : List (Symbol T g.NT)
r₀ : ContextFreeRule T g.NT
rin₀ : r₀ ∈ g.rules
p q : List (Symbol T g.reverse.NT)
a✝ :
  Relation.ReflTransGen g.reverse.Produces [Symbol.nonterminal g.reverse.initial]
    (p ++ [Symbol.nonterminal r₀.reverse.input] ++ q)
ih : g.Derives [Symbol.nonterminal g.initial] (p ++ [Symbol.nonterminal r₀.reverse.input] ++ q).reverse
⊢ (p ++ [Symbol.nonterminal r₀.reverse.input] ++ q).reverse = q.reverse ++ [Symbol.nonterminal r₀.input] ++ p.reverse ∧
    (p ++ r₀.reverse.output ++ q).reverse = q.reverse ++ r₀.output ++ p.reverse
state_after: no goals