Langlib

Langlib.Classes.ContextFree.Pumping.UnitElimination

Unit-Rule Elimination for CFGs #

This file computes unit pairs and removes unit productions without changing the language.

Main declarations #

theorem ContextFreeGrammar.Produces.rule {T : Type uT} {g : ContextFreeGrammar T} {n : g.NT} {u : List (Symbol T g.NT)} (hnu : g.Produces [Symbol.nonterminal n] u) :
{ input := n, output := u } g.rules
@[reducible, inline]
abbrev ContextFreeGrammar.unitRule {T : Type uT} {g : ContextFreeGrammar T} (nᵢ nₒ : g.NT) :

Convenient to talk about the rule rewriting a nonterminal nᵢ to another nonterminal nₒ

Equations
Instances For
    inductive ContextFreeGrammar.UnitPair {T : Type uT} {g : ContextFreeGrammar T} [DecidableEq g.NT] :
    g.NTg.NTProp

    UnitPair n₁ n₂, (w.r.t. a ContextFreeGrammar g) means that g can derive n₂ from n₁ only using unitRules

    Instances For
      @[reducible, inline]
      abbrev ContextFreeGrammar.NonUnit {T : Type uT} {N : Type u_1} (u : List (Symbol T N)) :

      We use this to concisely state a rule is not a unitRule if its output is NonUnit

      Equations
      Instances For
        theorem ContextFreeGrammar.DerivesIn.unitPair_prefix {T : Type uT} {g : ContextFreeGrammar T} [DecidableEq g.NT] {u : List T} {v : List (Symbol T g.NT)} {n : g.NT} {m : } (hvu : g.DerivesIn v (List.map Symbol.terminal u) m) (hng : n g.generators) (hv : [Symbol.nonterminal n] = v) :
        ∃ (n' : g.NT) (w : List (Symbol T g.NT)) (k : ), UnitPair n n' g.Produces [Symbol.nonterminal n'] w NonUnit w k m g.DerivesIn w (List.map Symbol.terminal u) k

        Fixpoint iteration to compute all UnitPairs. A unit pair is a pair (n₁, n₂) of nonterminals s.t. g can transform n₁ to n₂ only using unitRules, i.e., a chain of productions rewriting nonterminals to nonterminals

        generatorsProdDiag g is the diagonal of g.generators × g.generators

        Equations
        Instances For
          def ContextFreeGrammar.addUnitPair {T : Type uT} {g : ContextFreeGrammar T} [DecidableEq g.NT] (nᵢ nₒ : g.NT) (p : g.NT × g.NT) (l : Finset (g.NT × g.NT)) :
          Finset (g.NT × g.NT)

          Reflects transitivity of unit pairs. If (n₂, n₃) is a unit pair and g rewrites n₁ to n₂ then (n₁, n₃) are also a unit pair

          Equations
          Instances For

            If r is a unit rule, add all unit pairs (r.input, n) to l for all unit pairs (r.output, n) in l

            Equations
            Instances For
              theorem ContextFreeGrammar.collectUnitPairs_unitPair_rec {T : Type uT} {g : ContextFreeGrammar T} [DecidableEq g.NT] {nᵢ nₒ : g.NT} {p : g.NT × g.NT} {l : List (g.NT × g.NT)} {x : Finset (g.NT × g.NT)} (hp : p List.foldr (addUnitPair nᵢ nₒ) x l) :
              p x ∃ (v : g.NT), (nₒ, v) l p = (nᵢ, v)
              theorem ContextFreeGrammar.collectUnitPairs_unitPair {T : Type uT} {g : ContextFreeGrammar T} [DecidableEq g.NT] {r : ContextFreeRule T g.NT} {l : List (g.NT × g.NT)} (hrg : r g.rules) (hp : pl, UnitPair p.1 p.2) (p : g.NT × g.NT) :
              p collectUnitPairs r lUnitPair p.1 p.2
              noncomputable def ContextFreeGrammar.addUnitPairs {T : Type uT} {g : ContextFreeGrammar T} [DecidableEq g.NT] (l : Finset (g.NT × g.NT)) :
              Finset (g.NT × g.NT)

              Single step of fixpoint iteration, adding unit pairs to l for all rules r in g.rules

              Equations
              • One or more equations did not get rendered due to their size.
              Instances For
                @[irreducible]
                noncomputable def ContextFreeGrammar.addUnitPairsIter {T : Type uT} {g : ContextFreeGrammar T} [DecidableEq g.NT] (l : Finset (g.NT × g.NT)) (hlg : l g.generators ×ˢ g.generators) :
                Finset (g.NT × g.NT)

                Fixpoint iteration computing the unit pairs of g.

                Equations
                Instances For

                  Compute the least-fixpoint of add_unitPairs_iter, i.e., all (and only) unit pairs

                  Equations
                  Instances For
                    theorem ContextFreeGrammar.mem_addUnitPairs_unitPair {T : Type uT} {g : ContextFreeGrammar T} [DecidableEq g.NT] (l : Finset (g.NT × g.NT)) (hl : pl, UnitPair p.1 p.2) (p : g.NT × g.NT) :
                    p addUnitPairs lUnitPair p.1 p.2
                    @[irreducible]
                    theorem ContextFreeGrammar.mem_addUnitPairIter_unitPair {T : Type uT} {g : ContextFreeGrammar T} [DecidableEq g.NT] (l : Finset (g.NT × g.NT)) (hlg : l g.generators ×ˢ g.generators) (hl : pl, UnitPair p.1 p.2) (p : g.NT × g.NT) :
                    p addUnitPairsIter l hlgUnitPair p.1 p.2
                    theorem ContextFreeGrammar.mem_collectUnitPairs {T : Type uT} {g : ContextFreeGrammar T} [DecidableEq g.NT] {l : List (g.NT × g.NT)} {n₁ n₂ n₃ : g.NT} (hl : (n₂, n₃) l) :
                    (n₁, n₃) collectUnitPairs (unitRule n₁ n₂) l
                    theorem ContextFreeGrammar.mem_addUnitPairs {T : Type uT} {g : ContextFreeGrammar T} [DecidableEq g.NT] {l : Finset (g.NT × g.NT)} {n₁ n₂ n₃ : g.NT} (hl : (n₂, n₃) l) (hg : { input := n₁, output := [Symbol.nonterminal n₂] } g.rules) :
                    (n₁, n₃) addUnitPairs l
                    theorem ContextFreeGrammar.unitPair_mem_addUnitPairsIter {T : Type uT} {g : ContextFreeGrammar T} [DecidableEq g.NT] {l : Finset (g.NT × g.NT)} {n₁ n₂ : g.NT} (hlg : l g.generators ×ˢ g.generators) (hgl : generatorsProdDiag l) (hp : UnitPair n₁ n₂) :
                    (n₁, n₂) addUnitPairsIter l hlg

                    For a given unit pair (n₁, n₂), computes rules r : n₁ → o, s.t. there is a rule r' : n₂ → o in g (and o is non-unit)

                    Equations
                    • One or more equations did not get rendered due to their size.
                    Instances For

                      Given g, computes a new grammar g' in which all unit rules are removed and, for each unit pair (n₁, n₂), we add rules r : n₁ → o if the rule r' : n₂ → o is in the grammar (and non-unit)

                      Equations
                      Instances For
                        theorem ContextFreeGrammar.nonUnit_rules_mem {T : Type uT} {g : ContextFreeGrammar T} [DecidableEq g.NT] {p : g.NT × g.NT} {r : ContextFreeRule T g.NT} (hrp : r computeUnitPairRules p) :
                        r.input = p.1 r'g.rules, r.output = r'.output r'.input = p.2
                        theorem ContextFreeGrammar.mem_removeUnitRules_exists_UnitPair {T : Type uT} {g : ContextFreeGrammar T} [DecidableEq g.NT] [DecidableEq T] {l : Finset (g.NT × g.NT)} {r : ContextFreeRule T g.NT} (hrl : r removeUnitRules l) :
                        ∃ (p : g.NT × g.NT) (r' : ContextFreeRule T g.NT), p l r' g.rules r.input = p.1 r.output = r'.output r'.input = p.2
                        theorem ContextFreeGrammar.nonUnit_mem_computeUnitPairRules {T : Type uT} {g : ContextFreeGrammar T} [DecidableEq g.NT] {n₁ n₂ : g.NT} {w : List (Symbol T g.NT)} (hg : { input := n₁, output := w } g.rules) (hw : NonUnit w) :
                        { input := n₂, output := w } computeUnitPairRules (n₂, n₁)
                        theorem ContextFreeGrammar.nonUnit_mem_removeUnitRules {T : Type uT} {g : ContextFreeGrammar T} [DecidableEq g.NT] [DecidableEq T] {n₁ n₂ : g.NT} {u : List (Symbol T g.NT)} {l : Finset (g.NT × g.NT)} (hug : { input := n₂, output := u } g.rules) (hu : NonUnit u) (hnn : (n₁, n₂) l) :
                        { input := n₁, output := u } removeUnitRules l