File: Mathlib/Computability/ContextFreeGrammar.lean

full_name: ContextFreeRule.input
code: /-- Rule that rewrites a single nonterminal to any string (a list of symbols). -/
structure ContextFreeRule (T : Type uT) (N : Type uN) where
  /-- Input nonterminal a.k.a. left-hand side. -/
  input : N
  /-- Output string a.k.a. right-hand side. -/
  output : List (Symbol T N)
goal: N

full_name: ContextFreeRule
code: /-- Rule that rewrites a single nonterminal to any string (a list of symbols). -/
structure ContextFreeRule (T : Type uT) (N : Type uN) where
  /-- Input nonterminal a.k.a. left-hand side. -/
  input : N
  /-- Output string a.k.a. right-hand side. -/
  output : List (Symbol T N)
goal: Type (max uN uT)

full_name: ContextFreeRule.output
code: /-- Rule that rewrites a single nonterminal to any string (a list of symbols). -/
structure ContextFreeRule (T : Type uT) (N : Type uN) where
  /-- Input nonterminal a.k.a. left-hand side. -/
  input : N
  /-- Output string a.k.a. right-hand side. -/
  output : List (Symbol T N)
goal: List (Symbol T N)

full_name: ContextFreeGrammar.NT
code: /-- Context-free grammar that generates words over the alphabet `T` (a type of terminals). -/
structure ContextFreeGrammar.{uN,uT} (T : Type uT) where
  /-- Type of nonterminals. -/
  NT : Type uN
  /-- Initial nonterminal. -/
  initial : NT
  /-- Rewrite rules. -/
  rules : List (ContextFreeRule T NT)
goal: Type uN

full_name: ContextFreeGrammar.initial
code: /-- Context-free grammar that generates words over the alphabet `T` (a type of terminals). -/
structure ContextFreeGrammar.{uN,uT} (T : Type uT) where
  /-- Type of nonterminals. -/
  NT : Type uN
  /-- Initial nonterminal. -/
  initial : NT
  /-- Rewrite rules. -/
  rules : List (ContextFreeRule T NT)
goal: self.NT

full_name: ContextFreeGrammar.rules
code: /-- Context-free grammar that generates words over the alphabet `T` (a type of terminals). -/
structure ContextFreeGrammar.{uN,uT} (T : Type uT) where
  /-- Type of nonterminals. -/
  NT : Type uN
  /-- Initial nonterminal. -/
  initial : NT
  /-- Rewrite rules. -/
  rules : List (ContextFreeRule T NT)
goal: List (ContextFreeRule T self.NT)

full_name: ContextFreeRule.Rewrites.head
code: /-- Inductive definition of a single application of a given context-free rule `r` to a string `u`;
`r.Rewrites u v` means that the `r` sends `u` to `v` (there may be multiple such strings `v`). -/
inductive Rewrites (r : ContextFreeRule T N) : List (Symbol T N) → List (Symbol T N) → Prop
  /-- The replacement is at the start of the remaining string. -/
  | head (s : List (Symbol T N)) :
      r.Rewrites (Symbol.nonterminal r.input :: s) (r.output ++ s)
  /-- There is a replacement later in the string. -/
  | cons (x : Symbol T N) {s₁ s₂ : List (Symbol T N)} (hrs : Rewrites r s₁ s₂) :
      r.Rewrites (x :: s₁) (x :: s₂)
goal: r.Rewrites (Symbol.nonterminal r.input :: s) (r.output ++ s)

full_name: ContextFreeRule.Rewrites
code: /-- Inductive definition of a single application of a given context-free rule `r` to a string `u`;
`r.Rewrites u v` means that the `r` sends `u` to `v` (there may be multiple such strings `v`). -/
inductive Rewrites (r : ContextFreeRule T N) : List (Symbol T N) → List (Symbol T N) → Prop
  /-- The replacement is at the start of the remaining string. -/
  | head (s : List (Symbol T N)) :
      r.Rewrites (Symbol.nonterminal r.input :: s) (r.output ++ s)
  /-- There is a replacement later in the string. -/
  | cons (x : Symbol T N) {s₁ s₂ : List (Symbol T N)} (hrs : Rewrites r s₁ s₂) :
      r.Rewrites (x :: s₁) (x :: s₂)
goal: List (Symbol T N) → List (Symbol T N) → Prop

full_name: ContextFreeRule.Rewrites.cons
code: /-- Inductive definition of a single application of a given context-free rule `r` to a string `u`;
`r.Rewrites u v` means that the `r` sends `u` to `v` (there may be multiple such strings `v`). -/
inductive Rewrites (r : ContextFreeRule T N) : List (Symbol T N) → List (Symbol T N) → Prop
  /-- The replacement is at the start of the remaining string. -/
  | head (s : List (Symbol T N)) :
      r.Rewrites (Symbol.nonterminal r.input :: s) (r.output ++ s)
  /-- There is a replacement later in the string. -/
  | cons (x : Symbol T N) {s₁ s₂ : List (Symbol T N)} (hrs : Rewrites r s₁ s₂) :
      r.Rewrites (x :: s₁) (x :: s₂)
goal: r.Rewrites (x :: s₁) (x :: s₂)

full_name: ContextFreeRule.Rewrites.exists_parts
code: lemma Rewrites.exists_parts {r : ContextFreeRule T N} {u v : List (Symbol T N)}
    (hyp : r.Rewrites u v) :
    ∃ p q : List (Symbol T N),
      u = p ++ [Symbol.nonterminal r.input] ++ q ∧ v = p ++ r.output ++ q 
goal: ∃ p q, u = p ++ [Symbol.nonterminal r.input] ++ q ∧ v = p ++ r.output ++ q

full_name: ContextFreeRule.rewrites_of_exists_parts
code: lemma rewrites_of_exists_parts (r : ContextFreeRule T N) (p q : List (Symbol T N)) :
    r.Rewrites (p ++ [Symbol.nonterminal r.input] ++ q) (p ++ r.output ++ q) 
goal: r.Rewrites (p ++ [Symbol.nonterminal r.input] ++ q) (p ++ r.output ++ q)

full_name: ContextFreeRule.rewrites_iff
code: /-- Rule `r` rewrites string `u` is to string `v` iff they share both a prefix `p` and postfix `q`
such that the remaining middle part of `u` is the input of `r` and the remaining middle part
of `u` is the output of `r`. -/
theorem rewrites_iff {r : ContextFreeRule T N} (u v : List (Symbol T N)) :
    r.Rewrites u v ↔ ∃ p q : List (Symbol T N),
      u = p ++ [Symbol.nonterminal r.input] ++ q ∧ v = p ++ r.output ++ q 
goal: r.Rewrites u v ↔ ∃ p q, u = p ++ [Symbol.nonterminal r.input] ++ q ∧ v = p ++ r.output ++ q

full_name: ContextFreeRule.Rewrites.append_left
code: /-- Add extra prefix to context-free rewriting. -/
lemma Rewrites.append_left {r : ContextFreeRule T N} {v w : List (Symbol T N)}
    (hvw : r.Rewrites v w) (p : List (Symbol T N)) : r.Rewrites (p ++ v) (p ++ w) 
goal: r.Rewrites (p ++ v) (p ++ w)

full_name: ContextFreeRule.Rewrites.append_right
code: /-- Add extra postfix to context-free rewriting. -/
lemma Rewrites.append_right {r : ContextFreeRule T N} {v w : List (Symbol T N)}
    (hvw : r.Rewrites v w) (p : List (Symbol T N)) : r.Rewrites (v ++ p) (w ++ p) 
goal: r.Rewrites (v ++ p) (w ++ p)

full_name: ContextFreeGrammar.Produces
code: /-- Given a context-free grammar `g` and strings `u` and `v`
`g.Produces u v` means that one step of a context-free transformation by a rule from `g` sends
`u` to `v`. -/
def Produces (g : ContextFreeGrammar.{uN} T) (u v : List (Symbol T g.NT)) : Prop 
goal: Prop

full_name: ContextFreeGrammar.Derives
code: /-- Given a context-free grammar `g` and strings `u` and `v`
`g.Derives u v` means that `g` can transform `u` to `v` in some number of rewriting steps. -/
abbrev Derives (g : ContextFreeGrammar.{uN} T) :
    List (Symbol T g.NT) → List (Symbol T g.NT) → Prop 
goal: List (Symbol T g.NT) → List (Symbol T g.NT) → Prop

full_name: ContextFreeGrammar.Generates
code: /-- Given a context-free grammar `g` and a string `s`
`g.Generates s` means that `g` can transform its initial nonterminal to `s` in some number of
rewriting steps. -/
def Generates (g : ContextFreeGrammar.{uN} T) (s : List (Symbol T g.NT)) : Prop 
goal: Prop

full_name: ContextFreeGrammar.language
code: /-- The language (set of words) that can be generated by a given context-free grammar `g`. -/
def language (g : ContextFreeGrammar.{uN} T) : Language T 
goal: Language T

full_name: ContextFreeGrammar.mem_language_iff
code: /-- A given word `w` belongs to the language generated by a given context-free grammar `g` iff
`g` can derive the word `w` (wrapped as a string) from the initial nonterminal of `g` in some
number of steps. -/
@[simp]
lemma mem_language_iff (g : ContextFreeGrammar.{uN} T) (w : List T) :
    w ∈ g.language ↔ g.Derives [Symbol.nonterminal g.initial] (List.map Symbol.terminal w) 
goal: w ∈ g.language ↔ g.Derives [Symbol.nonterminal g.initial] (List.map Symbol.terminal w)

full_name: ContextFreeGrammar.Derives.refl
code: @[refl]
lemma Derives.refl (w : List (Symbol T g.NT)) : g.Derives w w 
goal: g.Derives w w

full_name: ContextFreeGrammar.Produces.single
code: lemma Produces.single {v w : List (Symbol T g.NT)} (hvw : g.Produces v w) : g.Derives v w 
goal: g.Derives v w

full_name: ContextFreeGrammar.Derives.trans
code: @[trans]
lemma Derives.trans {u v w : List (Symbol T g.NT)} (huv : g.Derives u v) (hvw : g.Derives v w) :
    g.Derives u w 
goal: g.Derives u w

full_name: ContextFreeGrammar.Derives.trans_produces
code: lemma Derives.trans_produces {u v w : List (Symbol T g.NT)}
    (huv : g.Derives u v) (hvw : g.Produces v w) :
    g.Derives u w 
goal: g.Derives u w

full_name: ContextFreeGrammar.Produces.trans_derives
code: lemma Produces.trans_derives {u v w : List (Symbol T g.NT)}
    (huv : g.Produces u v) (hvw : g.Derives v w) :
    g.Derives u w 
goal: g.Derives u w

full_name: ContextFreeGrammar.Derives.eq_or_head
code: lemma Derives.eq_or_head {u w : List (Symbol T g.NT)} (huw : g.Derives u w) :
    u = w ∨ ∃ v : List (Symbol T g.NT), g.Produces u v ∧ g.Derives v w 
goal: u = w ∨ ∃ v, g.Produces u v ∧ g.Derives v w

full_name: ContextFreeGrammar.Derives.eq_or_tail
code: lemma Derives.eq_or_tail {u w : List (Symbol T g.NT)} (huw : g.Derives u w) :
    u = w ∨ ∃ v : List (Symbol T g.NT), g.Derives u v ∧ g.Produces v w 
goal: u = w ∨ ∃ v, g.Derives u v ∧ g.Produces v w

full_name: ContextFreeGrammar.Produces.append_left
code: /-- Add extra prefix to context-free producing. -/
lemma Produces.append_left {v w : List (Symbol T g.NT)}
    (hvw : g.Produces v w) (p : List (Symbol T g.NT)) :
    g.Produces (p ++ v) (p ++ w) 
goal: g.Produces (p ++ v) (p ++ w)

full_name: ContextFreeGrammar.Produces.append_right
code: /-- Add extra postfix to context-free producing. -/
lemma Produces.append_right {v w : List (Symbol T g.NT)}
    (hvw : g.Produces v w) (p : List (Symbol T g.NT)) :
    g.Produces (v ++ p) (w ++ p) 
goal: g.Produces (v ++ p) (w ++ p)

full_name: ContextFreeGrammar.Derives.append_left
code: /-- Add extra prefix to context-free deriving. -/
lemma Derives.append_left {v w : List (Symbol T g.NT)}
    (hvw : g.Derives v w) (p : List (Symbol T g.NT)) :
    g.Derives (p ++ v) (p ++ w) 
goal: g.Derives (p ++ v) (p ++ w)

full_name: ContextFreeGrammar.Derives.append_right
code: /-- Add extra prefix to context-free deriving. -/
lemma Derives.append_right {v w : List (Symbol T g.NT)}
    (hvw : g.Derives v w) (p : List (Symbol T g.NT)) :
    g.Derives (v ++ p) (w ++ p) 
goal: g.Derives (v ++ p) (w ++ p)

full_name: Language.IsContextFree
code: /-- Context-free languages are defined by context-free grammars. -/
def Language.IsContextFree (L : Language T) : Prop 
goal: Prop

full_name: ContextFreeRule.reverse
code: /-- Rules for a grammar for a reversed language. -/
def ContextFreeRule.reverse {N : Type uN} (r : ContextFreeRule T N) : ContextFreeRule T N 
goal: ContextFreeRule T N

full_name: ContextFreeGrammar.reverse
code: /-- Grammar for a reversed language. -/
def ContextFreeGrammar.reverse (g : ContextFreeGrammar T) : ContextFreeGrammar T 
goal: ContextFreeGrammar T

full_name: ContextFreeRule.reverse_involutive
code: lemma ContextFreeRule.reverse_involutive {N : Type uN} :
    Function.Involutive (@ContextFreeRule.reverse T N) 
goal: Function.Involutive ContextFreeRule.reverse

full_name: ContextFreeGrammar.reverse_involutive
code: lemma ContextFreeGrammar.reverse_involutive :
    Function.Involutive (@ContextFreeGrammar.reverse T) 
goal: Function.Involutive ContextFreeGrammar.reverse

full_name: ContextFreeGrammar.reverse_derives
code: lemma ContextFreeGrammar.reverse_derives (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 
goal: g.Derives [Symbol.nonterminal g.initial] s.reverse

full_name: ContextFreeGrammar.reverse_mem_language_of_mem_reverse_language
code: lemma ContextFreeGrammar.reverse_mem_language_of_mem_reverse_language (g : ContextFreeGrammar T)
    {w : List T} (hgw : w ∈ g.reverse.language) :
    w.reverse ∈ g.language 
goal: w.reverse ∈ g.language

full_name: ContextFreeGrammar.mem_reverse_language_iff_reverse_mem_language
code: lemma ContextFreeGrammar.mem_reverse_language_iff_reverse_mem_language (g : ContextFreeGrammar T)
    (w : List T) :
    w ∈ g.reverse.language ↔ w.reverse ∈ g.language 
goal: w ∈ g.reverse.language ↔ w.reverse ∈ g.language

full_name: Language.IsContextFree.reverse
code: /-- The class of context-free languages is closed under reversal. -/
theorem Language.IsContextFree.reverse (L : Language T) :
    L.IsContextFree → L.reverse.IsContextFree 
goal: L.IsContextFree → L.reverse.IsContextFree