Langlib

Langlib.Classes.RecursivelyEnumerable.Closure.Concatenation

RE Closure Under Concatenation #

This file constructs an unrestricted grammar for the concatenation of two recursively enumerable languages.

Proof idea: take the two unrestricted grammars, tag their nonterminals so they cannot interfere, and add a fresh start rule that emits the lifted left start symbol followed by the lifted right start symbol. The forward and backward lemmas show that derivations in the combined grammar are exactly a left derivation followed by a right derivation, hence the generated language is L₁ * L₂.

Main declarations #

def nnn (T N₁ N₂ : Type) :
Equations
Instances For
    @[reducible, inline]
    abbrev nst (T N₁ N₂ : Type) :
    Equations
    Instances For
      def wrap_symbol₁ {T N₁ : Type} (N₂ : Type) :
      symbol T N₁nst T N₁ N₂
      Equations
      Instances For
        def wrap_symbol₂ {T N₂ : Type} (N₁ : Type) :
        symbol T N₂nst T N₁ N₂
        Equations
        Instances For
          def wrap_grule₁ {T N₁ : Type} (N₂ : Type) (r : grule T N₁) :
          grule T (nnn T N₁ N₂)
          Equations
          • One or more equations did not get rendered due to their size.
          Instances For
            def wrap_grule₂ {T N₂ : Type} (N₁ : Type) (r : grule T N₂) :
            grule T (nnn T N₁ N₂)
            Equations
            • One or more equations did not get rendered due to their size.
            Instances For
              def rules_for_terminals₁ {T : Type} (N₂ : Type) (g : grammar T) :
              List (grule T (nnn T g.nt N₂))
              Equations
              Instances For
                def rules_for_terminals₂ {T : Type} (N₁ : Type) (g : grammar T) :
                List (grule T (nnn T N₁ g.nt))
                Equations
                Instances For
                  def big_grammar {T : Type} (g₁ g₂ : grammar T) :
                  Equations
                  • One or more equations did not get rendered due to their size.
                  Instances For
                    theorem grammar_generates_only_legit_terminals {T : Type} {g : grammar T} {w : List (symbol T g.nt)} (ass : grammar_derives g [symbol.nonterminal g.initial] w) {s : symbol T g.nt} (symbol_derived : s w) :
                    theorem substitute_terminals {T : Type} {g₁ g₂ : grammar T} {side : TT T} {w : List T} (rule_for_each_terminal : tw, { input_L := [], input_N := Sum.inr (side t), input_R := [], output_string := [symbol.terminal t] } rules_for_terminals₁ g₂.nt g₁ ++ rules_for_terminals₂ g₁.nt g₂) :
                    theorem in_big_of_in_concatenated {T : Type} {g₁ g₂ : grammar T} {w : List T} (ass : w grammar_language g₁ * grammar_language g₂) :
                    theorem corresponding_symbols_self {T N₁ N₂ : Type} (s : nst T N₁ N₂) :
                    theorem corresponding_symbols_never₁ {T N₁ N₂ : Type} {s₁ : symbol T N₁} {s₂ : symbol T N₂} :
                    theorem corresponding_symbols_never₂ {T N₁ N₂ : Type} {s₁ : symbol T N₁} {s₂ : symbol T N₂} :
                    def corresponding_strings {T N₁ N₂ : Type} :
                    List (nst T N₁ N₂)List (nst T N₁ N₂)Prop
                    Equations
                    Instances For
                      theorem corresponding_strings_self {T N₁ N₂ : Type} {x : List (nst T N₁ N₂)} :
                      theorem corresponding_strings_singleton {T N₁ N₂ : Type} {s₁ s₂ : nst T N₁ N₂} (ass : corresponding_symbols s₁ s₂) :
                      theorem corresponding_strings_append {T N₁ N₂ : Type} {x₁ x₂ y₁ y₂ : List (nst T N₁ N₂)} (ass₁ : corresponding_strings x₁ y₁) (ass₂ : corresponding_strings x₂ y₂) :
                      corresponding_strings (x₁ ++ x₂) (y₁ ++ y₂)
                      theorem corresponding_strings_length {T N₁ N₂ : Type} {x y : List (nst T N₁ N₂)} (ass : corresponding_strings x y) :
                      theorem corresponding_strings_of_reverse {T N₁ N₂ : Type} {x y : List (nst T N₁ N₂)} (ass : corresponding_strings x.reverse y.reverse) :
                      theorem corresponding_strings_take {T N₁ N₂ : Type} {x y : List (nst T N₁ N₂)} (n : ) (ass : corresponding_strings x y) :
                      theorem corresponding_strings_drop {T N₁ N₂ : Type} {x y : List (nst T N₁ N₂)} (n : ) (ass : corresponding_strings x y) :
                      theorem corresponding_strings_split {T N₁ N₂ : Type} {x y : List (nst T N₁ N₂)} (n : ) (ass : corresponding_strings x y) :
                      theorem unwrap_eq_some_of_corresponding_symbols₁ {T N₁ N₂ : Type} {s₁ : symbol T N₁} {s : nst T N₁ N₂} (ass : corresponding_symbols (wrap_symbol₁ N₂ s₁) s) :
                      theorem unwrap_eq_some_of_corresponding_symbols₂ {T N₁ N₂ : Type} {s₂ : symbol T N₂} {s : nst T N₁ N₂} (ass : corresponding_symbols (wrap_symbol₂ N₁ s₂) s) :
                      theorem unwrap₁_of_wrap₂_eq_none {T N₁ N₂ : Type} (s : symbol T N₂) :
                      theorem unwrap₂_of_wrap₁_eq_none {T N₁ N₂ : Type} (s : symbol T N₁) :
                      theorem forall₂_append_split {α β : Type} {R : αβProp} {l₁ l₂ : List α} {m : List β} (h : List.Forall₂ R (l₁ ++ l₂) m) :
                      ∃ (m₁ : List β) (m₂ : List β), m = m₁ ++ m₂ List.Forall₂ R l₁ m₁ List.Forall₂ R l₂ m₂
                      theorem no_wrap₂_corr_sum_inl_inl {T N₁ N₂ : Type} {n₁ : N₁} {s₂ : symbol T N₂} :
                      theorem no_wrap₁_corr_sum_inl_inr {T N₁ N₂ : Type} {n₂ : N₂} {s₁ : symbol T N₁} :
                      theorem x_from_take_filterMap {T N₁ N₂ : Type} {x : List (symbol T N₁)} {y : List (symbol T N₂)} {a : List (nst T N₁ N₂)} (h : corresponding_strings (List.map (wrap_symbol₁ N₂) x ++ List.map (wrap_symbol₂ N₁) y) a) :
                      theorem y_from_drop_filterMap {T N₁ N₂ : Type} {x : List (symbol T N₁)} {y : List (symbol T N₂)} {a : List (nst T N₁ N₂)} (h : corresponding_strings (List.map (wrap_symbol₁ N₂) x ++ List.map (wrap_symbol₂ N₁) y) a) :
                      theorem rule_in_first_half {T N₁ N₂ : Type} {x : List (symbol T N₁)} {y : List (symbol T N₂)} {a u v : List (nst T N₁ N₂)} {r₁ : grule T N₁} (ih_concat : corresponding_strings (List.map (wrap_symbol₁ N₂) x ++ List.map (wrap_symbol₂ N₁) y) a) (bef : a = u ++ List.map (wrap_symbol₁ N₂) r₁.input_L ++ [symbol.nonterminal (Sum.inl (some (Sum.inl r₁.input_N)))] ++ List.map (wrap_symbol₁ N₂) r₁.input_R ++ v) :
                      theorem rule_in_second_half {T N₁ N₂ : Type} {x : List (symbol T N₁)} {y : List (symbol T N₂)} {a u v : List (nst T N₁ N₂)} {r₂ : grule T N₂} (ih_concat : corresponding_strings (List.map (wrap_symbol₁ N₂) x ++ List.map (wrap_symbol₂ N₁) y) a) (bef : a = u ++ List.map (wrap_symbol₂ N₁) r₂.input_L ++ [symbol.nonterminal (Sum.inl (some (Sum.inr r₂.input_N)))] ++ List.map (wrap_symbol₂ N₁) r₂.input_R ++ v) :
                      theorem take_of_append_five {α : Type} {u L : List α} {n : α} {R v : List α} {m : } (h_le : u.length + L.length + 1 + R.length m) :
                      List.take m (u ++ L ++ [n] ++ R ++ v) = u ++ L ++ [n] ++ R ++ List.take (m - (u.length + L.length + 1 + R.length)) v
                      theorem drop_of_append_five {α : Type} {u L : List α} {n : α} {R v : List α} {m : } (h_le : u.length + L.length + 1 + R.length m) (_h_le2 : m u.length + L.length + 1 + R.length + v.length) :
                      List.drop m (u ++ L ++ [n] ++ R ++ v) = List.drop (m - (u.length + L.length + 1 + R.length)) v
                      theorem induction_step_for_lifted_rule_from_g₁ {T : Type} {g₁ g₂ : grammar T} {a b u v : List (nst T g₁.nt g₂.nt)} {x : List (symbol T g₁.nt)} {y : List (symbol T g₂.nt)} {r : grule T (nnn T g₁.nt g₂.nt)} (rin : r List.map (wrap_grule₁ g₂.nt) g₁.rules) (bef : a = u ++ r.input_L ++ [symbol.nonterminal r.input_N] ++ r.input_R ++ v) (aft : b = u ++ r.output_string ++ v) (ih_x : grammar_derives g₁ [symbol.nonterminal g₁.initial] x) (ih_y : grammar_derives g₂ [symbol.nonterminal g₂.initial] y) (ih_concat : corresponding_strings (List.map (wrap_symbol₁ g₂.nt) x ++ List.map (wrap_symbol₂ g₁.nt) y) a) :
                      theorem induction_step_for_lifted_rule_from_g₂ {T : Type} {g₁ g₂ : grammar T} {a b u v : List (nst T g₁.nt g₂.nt)} {x : List (symbol T g₁.nt)} {y : List (symbol T g₂.nt)} {r : grule T (nnn T g₁.nt g₂.nt)} (rin : r List.map (wrap_grule₂ g₁.nt) g₂.rules) (bef : a = u ++ r.input_L ++ [symbol.nonterminal r.input_N] ++ r.input_R ++ v) (aft : b = u ++ r.output_string ++ v) (ih_x : grammar_derives g₁ [symbol.nonterminal g₁.initial] x) (ih_y : grammar_derives g₂ [symbol.nonterminal g₂.initial] y) (ih_concat : corresponding_strings (List.map (wrap_symbol₁ g₂.nt) x ++ List.map (wrap_symbol₂ g₁.nt) y) a) :
                      theorem induction_step_for_terminal_rule₁ {T : Type} {g₁ g₂ : grammar T} {a b u v : List (nst T g₁.nt g₂.nt)} {x : List (symbol T g₁.nt)} {y : List (symbol T g₂.nt)} {t : T} (ht : t all_used_terminals g₁) (bef : a = u ++ [symbol.nonterminal (Sum.inr (Sum.inl t))] ++ v) (aft : b = u ++ [symbol.terminal t] ++ v) (ih_concat : corresponding_strings (List.map (wrap_symbol₁ g₂.nt) x ++ List.map (wrap_symbol₂ g₁.nt) y) a) :
                      theorem induction_step_for_terminal_rule₂ {T : Type} {g₁ g₂ : grammar T} {a b u v : List (nst T g₁.nt g₂.nt)} {x : List (symbol T g₁.nt)} {y : List (symbol T g₂.nt)} {t : T} (_ht : t all_used_terminals g₂) (bef : a = u ++ [symbol.nonterminal (Sum.inr (Sum.inr t))] ++ v) (aft : b = u ++ [symbol.terminal t] ++ v) (ih_concat : corresponding_strings (List.map (wrap_symbol₁ g₂.nt) x ++ List.map (wrap_symbol₂ g₁.nt) y) a) :
                      theorem in_concatenated_of_in_big {T : Type} {g₁ g₂ : grammar T} {w : List T} (ass : w grammar_language (big_grammar g₁ g₂)) :
                      theorem RE_of_RE_c_RE {T : Type} (L₁ L₂ : Language T) :
                      is_RE L₁ is_RE L₂is_RE (L₁ * L₂)

                      The class of recursively enumerable languages is closed under concatenation.