Langlib

Langlib.Grammars.Indexed.NormalForm.Aho.Scheduler.BoundedAccounting

The compressed-block budget along a consumption route #

Unary push/pop stretches of a chosen consumption route may be compressed into one index block. Crossing a binary node ends the current stretch and starts another one. Thus the number of maximal binary-free chunks is one plus the number of binary barriers on the route.

barrierOwners already charges every barrier to a distinct terminal in the off-route child. The missing final charge is a terminal in the child followed by the route. Adding this owner makes the bound sharp: the number of chunks, rather than merely the number of barriers, is at most the terminal yield length.

def IndexedGrammar.NFParse.ConsumeRoute.followedOwner {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} {p : g.NFParse A stack w} {k : } :
ConsumeRoute g p kFin w.length

A terminal position that stays inside the branch followed by a consumption route.

Equations
Instances For
    theorem IndexedGrammar.NFParse.ConsumeRoute.followedOwner_not_mem_barrierOwners {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} {p : g.NFParse A stack w} {k : } (route : ConsumeRoute g p k) :

    The on-route terminal owner is disjoint from every off-route barrier owner.

    theorem IndexedGrammar.NFParse.ConsumeRoute.followedOwner_cons_barrierOwners_nodup {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} {p : g.NFParse A stack w} {k : } (route : ConsumeRoute g p k) :

    The terminal followed by the route together with all off-route charges is duplicate-free.

    theorem IndexedGrammar.NFParse.ConsumeRoute.barrierOwners_length_add_one_le {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} {p : g.NFParse A stack w} {k : } (route : ConsumeRoute g p k) :

    There is room for both every binary barrier and the final followed branch in the yield.

    def IndexedGrammar.NFParse.ConsumeRoute.noBinaryChunkCount {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} {p : g.NFParse A stack w} {k : } :
    ConsumeRoute g p k

    Number of maximal binary-free chunks on a consumption route. Unary constructors stay in the current chunk; each binary constructor starts exactly one further chunk.

    Equations
    Instances For

      Chunk count is precisely one plus the existing barrier count.

      theorem IndexedGrammar.NFParse.ConsumeRoute.noBinary_iff_chunkCount_eq_one {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} {p : g.NFParse A stack w} {k : } (route : ConsumeRoute g p k) :

      A route is one maximal chunk exactly when it is binary-free.

      theorem IndexedGrammar.NFParse.ConsumeRoute.noBinaryChunkCount_le_yield_length {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} {p : g.NFParse A stack w} {k : } (route : ConsumeRoute g p k) :

      The number of compressed blocks needed by the maximal binary-free decomposition is bounded by the terminal yield. This is the index-payload inequality needed by ScheduleInvariant.

      Prefix truncation of a chosen consumption route #

      @[irreducible]
      def IndexedGrammar.NFParse.ConsumeRoute.truncate {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} {p : g.NFParse A stack w} {k : } (route : ConsumeRoute g p k) (j : ) (hjk : j k) :

      Follow the same branch choices only as far as a shallower inherited occurrence. This is a structural truncation, not a fresh classical choice of route, so it preserves the absence of binary barriers.

      Equations
      Instances For
        theorem IndexedGrammar.NFParse.ConsumeRoute.truncate_noBinary {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} {p : g.NFParse A stack w} {k : } (route : ConsumeRoute g p k) (hroute : route.NoBinary) (j : ) (hjk : j k) :
        (route.truncate j hjk).NoBinary

        Truncating a binary-free route to a shallower occurrence remains binary-free.

        theorem IndexedGrammar.NFParse.ConsumeRoute.barrierOwners_truncate_prefix {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} {p : g.NFParse A stack w} {k : } (route : ConsumeRoute g p k) (j : ) (hjk : j k) :

        Truncation keeps an initial segment of the original route's barrier charges. In particular, it neither invents a binary barrier nor changes the owner assigned to a barrier it retains.

        theorem IndexedGrammar.NFParse.ConsumeRoute.noBinaryChunkCount_truncate_le {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} {p : g.NFParse A stack w} {k : } (route : ConsumeRoute g p k) (j : ) (hjk : j k) :

        Consequently truncation cannot increase the number of maximal binary-free chunks.

        theorem IndexedGrammar.NFParse.ConsumeRoute.barrierOwners_ne_nil_of_truncate_not_noBinary {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} {p : g.NFParse A stack w} {k j : } (route : ConsumeRoute g p k) (hjk : j k) (hunsafe : ¬(route.truncate j hjk).NoBinary) :

        If a structural truncation is unsafe for unary compression, the original route has at least one binary-barrier owner.

        theorem IndexedGrammar.NFParse.ConsumeRoute.two_le_noBinaryChunkCount_of_truncate_not_noBinary {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} {p : g.NFParse A stack w} {k j : } (route : ConsumeRoute g p k) (hjk : j k) (hunsafe : ¬(route.truncate j hjk).NoBinary) :

        Equivalently, an unsafe truncation certifies that the original route needs at least two maximal binary-free chunks.

        def IndexedGrammar.NFParse.eventDepths {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} :
        g.NFParse A stack wFinset

        Stack depths at which a productive parse event can end a compressed unary block.

        Terminal leaves and binary forks contribute the current depth. A pop shifts every deeper event one position away from the root, while a push removes the freshly pushed position.

        Equations
        Instances For
          def IndexedGrammar.Aho.ScheduleTask.embedYieldOwner {T : Type} {g : IndexedGrammar T} {input : List T} (task : ScheduleTask g input) :
          Fin task.yield.lengthFin input.length

          Embed a terminal position of a pending task's yield into the complete input word.

          Equations
          Instances For

            The task's ordinary owner is the embedding of the first terminal in its yield.

            def IndexedGrammar.Aho.ScheduleTask.routeBlockOwners {T : Type} {g : IndexedGrammar T} {input : List T} (task : ScheduleTask g input) {k : } (route : NFParse.ConsumeRoute g task.parse k) :
            List (Fin input.length)

            Absolute input owners for all compressed blocks in the maximal binary-free decomposition of a chosen consumption route belonging to this task.

            Equations
            Instances For
              theorem IndexedGrammar.Aho.ScheduleTask.routeBlockOwners_nodup {T : Type} {g : IndexedGrammar T} {input : List T} (task : ScheduleTask g input) {k : } (route : NFParse.ConsumeRoute g task.parse k) :
              (task.routeBlockOwners route).Nodup

              Block owners belonging to one task are pairwise distinct.

              @[simp]
              theorem IndexedGrammar.Aho.ScheduleTask.routeBlockOwners_length {T : Type} {g : IndexedGrammar T} {input : List T} (task : ScheduleTask g input) {k : } (route : NFParse.ConsumeRoute g task.parse k) :

              A task's compressed blocks fit within its own yield interval.

              theorem IndexedGrammar.Aho.ScheduleTask.routeBlockOwners_length_le_input {T : Type} {g : IndexedGrammar T} {input : List T} (task : ScheduleTask g input) {k : } (route : NFParse.ConsumeRoute g task.parse k) :
              (task.routeBlockOwners route).length input.length

              In particular, the local block-owner count satisfies the global input-length budget used by ScheduleInvariant.indexCount_le.

              def IndexedGrammar.Aho.ScheduleTask.YieldBefore {T : Type} {g : IndexedGrammar T} {input : List T} (left right : ScheduleTask g input) :

              The yield interval of left lies completely before the yield interval of right.

              Equations
              Instances For
                theorem IndexedGrammar.Aho.ScheduleTask.embedYieldOwner_ne_of_yieldBefore {T : Type} {g : IndexedGrammar T} {input : List T} {left right : ScheduleTask g input} (hbefore : left.YieldBefore right) (i : Fin left.yield.length) (j : Fin right.yield.length) :

                Owners embedded from disjointly ordered task intervals cannot coincide.

                theorem IndexedGrammar.Aho.ScheduleTask.routeBlockOwners_disjoint_of_yieldBefore {T : Type} {g : IndexedGrammar T} {input : List T} {left right : ScheduleTask g input} (hbefore : left.YieldBefore right) {i j : } (leftRoute : NFParse.ConsumeRoute g left.parse i) (rightRoute : NFParse.ConsumeRoute g right.parse j) :
                (left.routeBlockOwners leftRoute).Disjoint (right.routeBlockOwners rightRoute)

                Compressed-block owner lists from disjoint pending-task intervals are disjoint.

                theorem IndexedGrammar.Aho.ScheduleTask.routeBlockOwners_append_nodup_of_yieldBefore {T : Type} {g : IndexedGrammar T} {input : List T} {left right : ScheduleTask g input} (hbefore : left.YieldBefore right) {i j : } (leftRoute : NFParse.ConsumeRoute g left.parse i) (rightRoute : NFParse.ConsumeRoute g right.parse j) :
                (left.routeBlockOwners leftRoute ++ right.routeBlockOwners rightRoute).Nodup

                Consequently concatenating the compressed blocks of two ordered task intervals preserves the global no-duplicate ownership invariant.

                Persistent ownership of inherited block partitions #

                structure IndexedGrammar.Aho.BlockOwnership (N : ) {X : Type} (blocks : List X) :

                A block list together with one pairwise-distinct owner in an ambient finite budget for each block. The carrier is independent of how a child refines its local event cuts, so ancestor owners can persist unchanged throughout the runner.

                Instances For
                  Equations
                  Instances For
                    def IndexedGrammar.Aho.BlockOwnership.cons {N : } {X : Type} {blocks : List X} (block : X) (owner : Fin N) (ownership : BlockOwnership N blocks) (hfresh : ownerownership.owners) :
                    BlockOwnership N (block :: blocks)

                    Add a fresh owner in front of an existing aligned block list.

                    Equations
                    Instances For
                      def IndexedGrammar.Aho.BlockOwnership.take {N : } {X : Type} {blocks : List X} (n : ) (ownership : BlockOwnership N blocks) :

                      Retain ownership for the first n blocks.

                      Equations
                      Instances For
                        def IndexedGrammar.Aho.BlockOwnership.drop {N : } {X : Type} {blocks : List X} (n : ) (ownership : BlockOwnership N blocks) :

                        Retain ownership for the blocks after the first n.

                        Equations
                        Instances For
                          def IndexedGrammar.Aho.BlockOwnership.Disjoint {N : } {X Y : Type} {leftBlocks : List X} {rightBlocks : List Y} (left : BlockOwnership N leftBlocks) (right : BlockOwnership N rightBlocks) :

                          Ownership carriers are disjoint when their concrete owner lists are disjoint.

                          Equations
                          Instances For
                            theorem IndexedGrammar.Aho.BlockOwnership.disjoint_comm {N : } {X Y : Type} {leftBlocks : List X} {rightBlocks : List Y} {left : BlockOwnership N leftBlocks} {right : BlockOwnership N rightBlocks} :
                            left.Disjoint right right.Disjoint left
                            def IndexedGrammar.Aho.BlockOwnership.append {N : } {X : Type} {leftBlocks rightBlocks : List X} (left : BlockOwnership N leftBlocks) (right : BlockOwnership N rightBlocks) (hdisjoint : left.Disjoint right) :
                            BlockOwnership N (leftBlocks ++ rightBlocks)

                            Concatenate two aligned carriers whose owner sets are disjoint.

                            Equations
                            Instances For
                              theorem IndexedGrammar.Aho.BlockOwnership.disjoint_take_drop {N : } {X : Type} {blocks : List X} (n : ) (ownership : BlockOwnership N blocks) :
                              (take n ownership).Disjoint (drop n ownership)

                              The prefix and suffix inherited from one carrier have disjoint owner sets.

                              theorem IndexedGrammar.Aho.BlockOwnership.blocks_length_le {N : } {X : Type} {blocks : List X} (ownership : BlockOwnership N blocks) :
                              blocks.length N

                              Distinct finite owners give the required ambient block-count bound.

                              Transient-index accounting #

                              theorem IndexedGrammar.Aho.framed_cell_count_le_eight_mul_of_index_add_one_le_two_mul {tasks indices frames n : } (htasks : tasks n) (hindices : indices + 1 2 * n) (hframes : frames indices) (hn : 0 < n) :
                              tasks + indices + 2 * frames + 2 8 * n

                              Arithmetic form used by the transient compressed-token scheduler. Tasks still inject into the n terminal positions. Persistent indices together with the one currently transient index fit in two copies of those positions, and every open frame is charged to a persistent index.

                              Accounting carried by every compressed-runner edge #

                              Does a physical work symbol close one currently open scheduler frame?

                              Equations
                              Instances For

                                Physical task/terminal payload count of one concrete configuration.

                                Equations
                                Instances For

                                  Physical compressed-index count of one concrete configuration.

                                  Equations
                                  Instances For

                                    Physical open-frame count, measured by closing delimiters.

                                    Equations
                                    Instances For

                                      Exact count formulas for runner configurations #

                                      @[simp]
                                      theorem IndexedGrammar.Aho.workTaskCount_config_mk {T : Type} {g : IndexedGrammar T} (inputPos : ) (left : List (WorkSym g)) (focus : WorkSym g) (right : List (WorkSym g)) :
                                      workTaskCount { inputPos := inputPos, work := { left := left, focus := focus, right := right } } = List.countP WorkSym.isTaskPayload left + List.countP WorkSym.isTaskPayload [focus] + List.countP WorkSym.isTaskPayload right
                                      @[simp]
                                      theorem IndexedGrammar.Aho.workIndexCount_config_mk {T : Type} {g : IndexedGrammar T} (inputPos : ) (left : List (WorkSym g)) (focus : WorkSym g) (right : List (WorkSym g)) :
                                      workIndexCount { inputPos := inputPos, work := { left := left, focus := focus, right := right } } = List.countP WorkSym.isIndex left + List.countP WorkSym.isIndex [focus] + List.countP WorkSym.isIndex right
                                      @[simp]
                                      theorem IndexedGrammar.Aho.workFrameCount_config_mk {T : Type} {g : IndexedGrammar T} (inputPos : ) (left : List (WorkSym g)) (focus : WorkSym g) (right : List (WorkSym g)) :
                                      workFrameCount { inputPos := inputPos, work := { left := left, focus := focus, right := right } } = List.countP WorkSym.isClose left + List.countP WorkSym.isClose [focus] + List.countP WorkSym.isClose right
                                      theorem IndexedGrammar.Aho.countP_markProductivePrefix_of_index_mark_invariant {T : Type} {g : IndexedGrammar T} (predicate : WorkSym gBool) (hmark : ∀ (R : CFlag g) (d : IndexMark), predicate (WorkSym.index R d.markUsed) = predicate (WorkSym.index R d)) (xs : List (WorkSym g)) :
                                      List.countP predicate (markProductivePrefix xs) = List.countP predicate xs

                                      Marking the rightmost index changes no count computed from a mark-insensitive predicate.

                                      @[simp]
                                      theorem IndexedGrammar.Aho.workIndexCount_wordConfig {T : Type} {g : IndexedGrammar T} (inputPos : ) (alpha word : List (WorkSym g)) :
                                      @[simp]
                                      theorem IndexedGrammar.Aho.workFrameCount_wordConfig {T : Type} {g : IndexedGrammar T} (inputPos : ) (alpha word : List (WorkSym g)) :
                                      @[simp]
                                      theorem IndexedGrammar.Aho.workTaskCount_active_plain {T : Type} {g : IndexedGrammar T} (inputPos : ) (alpha beta : List (WorkSym g)) (A : g.nt) :
                                      workTaskCount { inputPos := inputPos, work := { left := alpha ++ [WorkSym.dollar], focus := WorkSym.plain A, right := beta } } = List.countP WorkSym.isTaskPayload alpha + List.countP WorkSym.isTaskPayload beta + 1
                                      @[simp]
                                      theorem IndexedGrammar.Aho.workIndexCount_active_plain {T : Type} {g : IndexedGrammar T} (inputPos : ) (alpha beta : List (WorkSym g)) (A : g.nt) :
                                      workIndexCount { inputPos := inputPos, work := { left := alpha ++ [WorkSym.dollar], focus := WorkSym.plain A, right := beta } } = List.countP WorkSym.isIndex alpha + List.countP WorkSym.isIndex beta
                                      @[simp]
                                      theorem IndexedGrammar.Aho.workFrameCount_active_plain {T : Type} {g : IndexedGrammar T} (inputPos : ) (alpha beta : List (WorkSym g)) (A : g.nt) :
                                      workFrameCount { inputPos := inputPos, work := { left := alpha ++ [WorkSym.dollar], focus := WorkSym.plain A, right := beta } } = List.countP WorkSym.isClose alpha + List.countP WorkSym.isClose beta
                                      @[simp]
                                      theorem IndexedGrammar.Aho.workTaskCount_active_live {T : Type} {g : IndexedGrammar T} (inputPos : ) (alpha beta : List (WorkSym g)) (A : g.nt) :
                                      workTaskCount { inputPos := inputPos, work := { left := alpha ++ [WorkSym.dollar], focus := WorkSym.live A, right := beta } } = List.countP WorkSym.isTaskPayload alpha + List.countP WorkSym.isTaskPayload beta + 1
                                      @[simp]
                                      theorem IndexedGrammar.Aho.workIndexCount_active_live {T : Type} {g : IndexedGrammar T} (inputPos : ) (alpha beta : List (WorkSym g)) (A : g.nt) :
                                      workIndexCount { inputPos := inputPos, work := { left := alpha ++ [WorkSym.dollar], focus := WorkSym.live A, right := beta } } = List.countP WorkSym.isIndex alpha + List.countP WorkSym.isIndex beta
                                      @[simp]
                                      theorem IndexedGrammar.Aho.workFrameCount_active_live {T : Type} {g : IndexedGrammar T} (inputPos : ) (alpha beta : List (WorkSym g)) (A : g.nt) :
                                      workFrameCount { inputPos := inputPos, work := { left := alpha ++ [WorkSym.dollar], focus := WorkSym.live A, right := beta } } = List.countP WorkSym.isClose alpha + List.countP WorkSym.isClose beta
                                      @[simp]
                                      theorem IndexedGrammar.Aho.workTaskCount_popOpen_plain {T : Type} {g : IndexedGrammar T} (inputPos : ) (alpha beta gamma : List (WorkSym g)) (R : CFlag g) (d : IndexMark) (B : g.nt) :
                                      @[simp]
                                      theorem IndexedGrammar.Aho.workIndexCount_popOpen_plain {T : Type} {g : IndexedGrammar T} (inputPos : ) (alpha beta gamma : List (WorkSym g)) (R : CFlag g) (d : IndexMark) (B : g.nt) :
                                      @[simp]
                                      theorem IndexedGrammar.Aho.workFrameCount_popOpen_plain {T : Type} {g : IndexedGrammar T} (inputPos : ) (alpha beta gamma : List (WorkSym g)) (R : CFlag g) (d : IndexMark) (B : g.nt) :
                                      @[simp]
                                      theorem IndexedGrammar.Aho.workTaskCount_popOpen_live {T : Type} {g : IndexedGrammar T} (inputPos : ) (alpha beta gamma : List (WorkSym g)) (R : CFlag g) (d : IndexMark) (B : g.nt) :
                                      @[simp]
                                      theorem IndexedGrammar.Aho.workIndexCount_popOpen_live {T : Type} {g : IndexedGrammar T} (inputPos : ) (alpha beta gamma : List (WorkSym g)) (R : CFlag g) (d : IndexMark) (B : g.nt) :
                                      @[simp]
                                      theorem IndexedGrammar.Aho.workFrameCount_popOpen_live {T : Type} {g : IndexedGrammar T} (inputPos : ) (alpha beta gamma : List (WorkSym g)) (R : CFlag g) (d : IndexMark) (B : g.nt) :
                                      theorem IndexedGrammar.Aho.workTaskCount_returnFrame_eq {T : Type} {g : IndexedGrammar T} (inputPos : ) (alpha beta gamma : List (WorkSym g)) (Z : WorkSym g) :
                                      workTaskCount { inputPos := inputPos, work := { left := alpha ++ [WorkSym.dollar, Z] ++ beta ++ [WorkSym.dollar], focus := WorkSym.close, right := gamma } } = workTaskCount { inputPos := inputPos, work := { left := alpha ++ [WorkSym.dollar], focus := Z, right := beta ++ gamma } }

                                      Returning a frame preserves task and index counts and removes exactly its closing marker.

                                      theorem IndexedGrammar.Aho.workIndexCount_returnFrame_eq {T : Type} {g : IndexedGrammar T} (inputPos : ) (alpha beta gamma : List (WorkSym g)) (Z : WorkSym g) :
                                      workIndexCount { inputPos := inputPos, work := { left := alpha ++ [WorkSym.dollar, Z] ++ beta ++ [WorkSym.dollar], focus := WorkSym.close, right := gamma } } = workIndexCount { inputPos := inputPos, work := { left := alpha ++ [WorkSym.dollar], focus := Z, right := beta ++ gamma } }
                                      theorem IndexedGrammar.Aho.workFrameCount_returnFrame_eq_add_one {T : Type} {g : IndexedGrammar T} (inputPos : ) (alpha beta gamma : List (WorkSym g)) (Z : WorkSym g) :
                                      workFrameCount { inputPos := inputPos, work := { left := alpha ++ [WorkSym.dollar, Z] ++ beta ++ [WorkSym.dollar], focus := WorkSym.close, right := gamma } } = workFrameCount { inputPos := inputPos, work := { left := alpha ++ [WorkSym.dollar], focus := Z, right := beta ++ gamma } } + 1
                                      structure IndexedGrammar.Aho.CompressedAccounting {T : Type} (g : IndexedGrammar T) [Fintype g.nt] (input : List T) (c : Config g) :

                                      Accounting for one concrete compressed-runner configuration. Every count is computed from the physical word itself; event-depth invariants prove the count bounds, while shape_bound records the delimiter layout.

                                      Instances For

                                        Package explicit bounds on the three physical count functions.

                                        theorem IndexedGrammar.Aho.CompressedAccounting.within {T : Type} {g : IndexedGrammar T} [Fintype g.nt] {input : List T} {c : Config g} (accounting : CompressedAccounting g input c) (hinput : 0 < input.length) :
                                        Config.Within (15 * input.length) c

                                        The accounting inequalities turn a local witness into the physical work-tape bound.

                                        The initial work word has one task payload and no indices or frames.

                                        theorem IndexedGrammar.Aho.finalConfig_compressedAccounting {T : Type} (g : IndexedGrammar T) [Fintype g.nt] (input : List T) (hinput : 0 < input.length) :

                                        The final work word has no task, index, or frame payload.

                                        def IndexedGrammar.Aho.CompressedReaches {T : Type} (g : IndexedGrammar T) [Fintype g.nt] (input : List T) (c c' : Config g) :

                                        Composite reachability with an event-depth accounting witness on the initial configuration and on both endpoints of every edge. This shape composes at exact Config endpoints and prevents a runner proof from silently passing through an unbounded intermediate configuration.

                                        Equations
                                        • One or more equations did not get rendered due to their size.
                                        Instances For
                                          theorem IndexedGrammar.Aho.CompressedReaches.refl {T : Type} {g : IndexedGrammar T} [Fintype g.nt] {input : List T} {c : Config g} (hc : CompressedAccounting g input c) :
                                          CompressedReaches g input c c
                                          theorem IndexedGrammar.Aho.CompressedReaches.single {T : Type} {g : IndexedGrammar T} [Fintype g.nt] {input : List T} {c c' : Config g} (hc : CompressedAccounting g input c) (hstep : CompositeStep g input c c') (hc' : CompressedAccounting g input c') :
                                          CompressedReaches g input c c'
                                          theorem IndexedGrammar.Aho.CompressedReaches.trans {T : Type} {g : IndexedGrammar T} [Fintype g.nt] {input : List T} {c₁ c₂ c₃ : Config g} (h₁₂ : CompressedReaches g input c₁ c₂) (h₂₃ : CompressedReaches g input c₂ c₃) :
                                          CompressedReaches g input c₁ c₃
                                          theorem IndexedGrammar.Aho.CompressedReaches.target_accounting {T : Type} {g : IndexedGrammar T} [Fintype g.nt] {input : List T} {c c' : Config g} (run : CompressedReaches g input c c') :

                                          The last configuration of an accounted trace retains an accounting witness, including in the reflexive case.

                                          theorem IndexedGrammar.Aho.CompressedReaches.toReflTransGen {T : Type} {g : IndexedGrammar T} [Fintype g.nt] {input : List T} {c c' : Config g} (run : CompressedReaches g input c c') :

                                          Forget accounting annotations and retain ordinary composite reachability.

                                          theorem IndexedGrammar.Aho.CompressedReaches.toBoundedReaches {T : Type} {g : IndexedGrammar T} [Fintype g.nt] {input : List T} {c c' : Config g} (hinput : 0 < input.length) (run : CompressedReaches g input c c') :
                                          BoundedReaches g input (15 * input.length) c c'

                                          Every accounted compressed trace is a bounded composite trace at the desired linear bound.

                                          Binary-free block continuations #

                                          theorem IndexedGrammar.Aho.consumeRoute_popContinuation_noBinary_with_consumption {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} {p : g.NFParse A stack w} {k : } (route : NFParse.ConsumeRoute g p k) (hroute : route.NoBinary) :
                                          ∃ (Y : g.nt) (suffix : List g.flag) (rest : g.NFParse Y suffix w), suffix = List.drop (k + 1) stack PopPath g A (List.take (k + 1) stack) Y rest.nodeCount < p.nodeCount (∀ (j : ), rest.ConsumesAt j p.ConsumesAt (k + 1 + j)) ∀ (d : ), d rest.eventDepths k + 1 + d p.eventDepths

                                          Strengthening of consumeRoute_popContinuation_noBinary: after the whole compressed block through occurrence k is popped, consumption by the residual parse at position j is exactly consumption by the original parse at position k + 1 + j. Thus an atomic multi-flag pop can continue against lower compressed blocks without losing the live/plain boundary information.

                                          Visible prefixes represented by compressed blocks #

                                          inductive IndexedGrammar.Aho.BlockLayout {T : Type} (g : IndexedGrammar T) [Fintype g.nt] :
                                          List g.flagList (List g.flag)List (WorkSym g)List (WorkSym g)Prop

                                          A compressed visible-stack layout. flags is partitioned by the nonempty lists in blocks; every block is represented by one relation token which denotes exactly that concrete flag list. Gaps may contain ordinary control symbols (including close) but neither another index nor $. The third and fourth word indices differ only by marking every selected token used.

                                          Instances For
                                            theorem IndexedGrammar.Aho.BlockLayout.flags_eq_flatten {T : Type} {g : IndexedGrammar T} [Fintype g.nt] {flags : List g.flag} {blocks : List (List g.flag)} {word used : List (WorkSym g)} (layout : BlockLayout g flags blocks word used) :
                                            flags = blocks.flatten

                                            The concrete visible prefix is exactly the flattening of its block partition.

                                            theorem IndexedGrammar.Aho.BlockLayout.blocks_nonempty {T : Type} {g : IndexedGrammar T} [Fintype g.nt] {flags : List g.flag} {blocks : List (List g.flag)} {word used : List (WorkSym g)} (layout : BlockLayout g flags blocks word used) (block : List g.flag) :
                                            block blocksblock []

                                            Every member of the partition is a nonempty concrete flag block.

                                            theorem IndexedGrammar.Aho.BlockLayout.head_denotation {T : Type} {g : IndexedGrammar T} [Fintype g.nt] {block flags : List g.flag} {blocks : List (List g.flag)} {word used : List (WorkSym g)} (layout : BlockLayout g flags (block :: blocks) word used) :
                                            ∃ (beta : List (WorkSym g)) (tail : List (WorkSym g)) (tail' : List (WorkSym g)) (R : CFlag g) (d : IndexMark), CFlag.Denotes g block R block [] IndexFree beta DollarFree beta word = beta ++ WorkSym.index R d :: tail used = beta ++ WorkSym.index R d.markUsed :: tail'

                                            Every relation stored by the layout retains a concrete denotation witness.

                                            theorem IndexedGrammar.Aho.BlockLayout.idempotent {T : Type} {g : IndexedGrammar T} [Fintype g.nt] {flags : List g.flag} {blocks : List (List g.flag)} {word used : List (WorkSym g)} (layout : BlockLayout g flags blocks word used) :
                                            BlockLayout g flags blocks used used

                                            Re-selecting an all-used block layout is physically idempotent.

                                            theorem IndexedGrammar.Aho.BlockLayout.prepend {T : Type} {g : IndexedGrammar T} [Fintype g.nt] {flags : List g.flag} {blocks : List (List g.flag)} {word used : List (WorkSym g)} (pref : List (WorkSym g)) (hindex : IndexFree pref) (hdollar : DollarFree pref) (layout : BlockLayout g flags blocks word used) :
                                            BlockLayout g flags blocks (pref ++ word) (pref ++ used)

                                            Insert an ordinary control prefix into the gap before the first selected block.

                                            theorem IndexedGrammar.Aho.BlockLayout.blocks_eq_nil_of_flags_eq_nil {T : Type} {g : IndexedGrammar T} [Fintype g.nt] {flags : List g.flag} {blocks : List (List g.flag)} {word used : List (WorkSym g)} (layout : BlockLayout g flags blocks word used) (hflags : flags = []) :
                                            blocks = []

                                            A layout with no concrete flags has no blocks. The nonempty-block invariant is essential: without it flatten blocks = [] would not force blocks = [].

                                            theorem IndexedGrammar.Aho.BlockLayout.take_flatten_take {T : Type} {g : IndexedGrammar T} [Fintype g.nt] {flags : List g.flag} {blocks : List (List g.flag)} {word used : List (WorkSym g)} (layout : BlockLayout g flags blocks word used) (n : ) :
                                            List.take (List.take n blocks).flatten.length flags = (List.take n blocks).flatten

                                            Taking the concrete number of flags covered by the first n blocks ends exactly at their physical block boundary.

                                            theorem IndexedGrammar.Aho.BlockLayout.splitTake {T : Type} {g : IndexedGrammar T} [Fintype g.nt] {flags : List g.flag} {blocks : List (List g.flag)} {word used : List (WorkSym g)} (n : ) (layout : BlockLayout g flags blocks word used) :
                                            ∃ (middle : List (WorkSym g)), BlockLayout g (List.take n blocks).flatten (List.take n blocks) word middle BlockLayout g flags blocks middle used

                                            Restrict a layout to its first n whole blocks. The remaining selected tokens become part of the intermediate word. Unlike a flagwise split, this operation can never cut through the concrete denotation of one compressed relation.

                                            structure IndexedGrammar.Aho.BlockLayout.Boundary {T : Type} {g : IndexedGrammar T} [Fintype g.nt] (blocks : List (List g.flag)) (flagCount : ) :

                                            A concrete flag position is aligned to the compressed layout when it is the total length of some whole-block prefix. The explicit block count is the physical index-token budget at that boundary.

                                            Instances For
                                              def IndexedGrammar.Aho.BlockLayout.Boundary.ofBlockCount {T : Type} {g : IndexedGrammar T} [Fintype g.nt] (blocks : List (List g.flag)) (blockCount : ) (h : blockCount blocks.length) :
                                              Boundary blocks (List.take blockCount blocks).flatten.length

                                              Every prefix measured in whole blocks determines an aligned concrete boundary.

                                              Equations
                                              Instances For

                                                The initial concrete position is always a block boundary.

                                                Equations
                                                Instances For

                                                  The end of the concrete visible prefix is a block boundary.

                                                  Equations
                                                  Instances For
                                                    def IndexedGrammar.Aho.BlockLayout.Boundary.cons {T : Type} {g : IndexedGrammar T} [Fintype g.nt] (block : List g.flag) {blocks : List (List g.flag)} {d : } (boundary : Boundary blocks d) :
                                                    Boundary (block :: blocks) (block.length + d)

                                                    Prefixing one concrete block shifts every old boundary by that block's length.

                                                    Equations
                                                    Instances For
                                                      def IndexedGrammar.Aho.BlockLayout.Boundary.tail_of_cons {T : Type} {g : IndexedGrammar T} [Fintype g.nt] {block : List g.flag} {blocks : List (List g.flag)} {d : } (hblock : block []) (boundary : Boundary (block :: blocks) (block.length + d)) :
                                                      Boundary blocks d

                                                      Removing a nonempty first block transports a shifted boundary to the tail partition.

                                                      Equations
                                                      • One or more equations did not get rendered due to their size.
                                                      Instances For
                                                        theorem IndexedGrammar.Aho.BlockLayout.Boundary.first_length_le_of_pos {T : Type} {g : IndexedGrammar T} [Fintype g.nt] {block : List g.flag} {blocks : List (List g.flag)} {d : } (_hblock : block []) (boundary : Boundary (block :: blocks) d) (hd : 0 < d) :
                                                        block.length d

                                                        Every positive boundary of a partition beginning with a nonempty block lies at or below the end of that first block. This is the arithmetic fact used to show that a first block is event-free once depth zero is not productive.

                                                        def IndexedGrammar.Aho.BlockLayout.Boundary.singletonCons {T : Type} {g : IndexedGrammar T} [Fintype g.nt] (f : g.flag) {blocks : List (List g.flag)} {d : } (boundary : Boundary blocks d) :
                                                        Boundary ([f] :: blocks) (d + 1)

                                                        A fresh singleton top block shifts every old boundary by exactly one flag.

                                                        Equations
                                                        Instances For
                                                          def IndexedGrammar.Aho.BlockLayout.Boundary.extendHead_of_pos {T : Type} {g : IndexedGrammar T} [Fintype g.nt] (f : g.flag) {block : List g.flag} {blocks : List (List g.flag)} {d : } (hd : 0 < d) (boundary : Boundary (block :: blocks) d) :
                                                          Boundary ((f :: block) :: blocks) (d + 1)

                                                          Extending the first block by one flag shifts every positive boundary by one while keeping the same physical block count.

                                                          Equations
                                                          • One or more equations did not get rendered due to their size.
                                                          Instances For
                                                            theorem IndexedGrammar.Aho.BlockLayout.splitAtBoundary {T : Type} {g : IndexedGrammar T} [Fintype g.nt] {flags : List g.flag} {blocks : List (List g.flag)} {word used : List (WorkSym g)} {flagCount : } (layout : BlockLayout g flags blocks word used) (boundary : Boundary blocks flagCount) :
                                                            ∃ (middle : List (WorkSym g)), BlockLayout g (List.take flagCount flags) (List.take boundary.blockCount blocks) word middle BlockLayout g flags blocks middle used

                                                            Split at an explicitly aligned concrete flag position. The boundary witness makes it impossible for callers to request a split inside the denotation of a compressed block.

                                                            theorem IndexedGrammar.Aho.BlockLayout.exists_selectedPrefixes {T : Type} {g : IndexedGrammar T} [Fintype g.nt] {flags : List g.flag} {blocks : List (List g.flag)} {word used : List (WorkSym g)} (layout : BlockLayout g flags blocks word used) :
                                                            ∃ (selected : List (WorkSym g)) (selectedUsed : List (WorkSym g)) (tail : List (WorkSym g)), word = selected ++ tail used = selectedUsed ++ tail List.countP WorkSym.isIndex selected = blocks.length List.countP WorkSym.isIndex selectedUsed = blocks.length

                                                            The selected physical part of a block layout consists of parallel prefixes followed by one common unselected tail.

                                                            theorem IndexedGrammar.Aho.BlockLayout.exists_selectedPrefix_indexCount_eq_blockCount {T : Type} {g : IndexedGrammar T} [Fintype g.nt] {flags : List g.flag} {blocks : List (List g.flag)} {word used : List (WorkSym g)} (layout : BlockLayout g flags blocks word used) :
                                                            ∃ (selected : List (WorkSym g)) (tail : List (WorkSym g)), word = selected ++ tail List.countP WorkSym.isIndex selected = blocks.length

                                                            Consequently the physical selected-index count is exactly the number of concrete blocks.

                                                            Canonical stack-depth event cuts #

                                                            theorem IndexedGrammar.NFParse.eventDepths_nonempty {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} (p : g.NFParse A stack w) :

                                                            Every parse has at least the cut contributed by one terminal leaf.

                                                            theorem IndexedGrammar.NFParse.consumesAt_iff_exists_mem_eventDepths_lt {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} (p : g.NFParse A stack w) (k : ) :
                                                            p.ConsumesAt k dp.eventDepths, k < d

                                                            Root-stack position k is consumed exactly when some canonical event cut lies strictly below it. Hence eventDepths is a finite cut profile for every consumption decision made by the bounded scheduler.

                                                            theorem IndexedGrammar.NFParse.eventDepths_le_stack_length {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} (p : g.NFParse A stack w) (d : ) :
                                                            d p.eventDepthsd stack.length

                                                            Every canonical event depth denotes an actual cut of the current root stack.

                                                            The finite cut profile uses no more entries than all productive parse events.

                                                            theorem IndexedGrammar.NFParse.eventDepths_card_le_twice_yield_length_sub_one {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} (p : g.NFParse A stack w) :

                                                            There are at most 2|w|-1 distinct event cuts. This is the global bound needed when the scheduler allocates at most one compressed index token per canonical cut.

                                                            theorem IndexedGrammar.NFParse.productiveCount_eq_twice_yield_length_sub_one {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} (p : g.NFParse A stack w) :

                                                            Productive nodes are exactly the binary nodes plus terminal leaves, hence 2|w|-1.

                                                            Coherent productive-event owners #

                                                            Canonical inverse used when a push maps event depths through Nat.pred. At depth zero we prefer the old zero event when it exists; otherwise the unique relevant preimage is one.

                                                            Equations
                                                            Instances For
                                                              @[simp]
                                                              theorem IndexedGrammar.NFParse.pushEventPreimage_injective_on {events : Finset } {d e : } (hd : d Finset.image Nat.pred events) (he : e Finset.image Nat.pred events) (h : pushEventPreimage events d = pushEventPreimage events e) :
                                                              d = e

                                                              The canonical push inverse is injective on actual image depths.

                                                              def IndexedGrammar.NFParse.eventOwnerNat {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} (p : g.NFParse A stack w) (d : ) :

                                                              The natural-number code underlying a coherent productive-node ID. Binary roots own zero; left and right child codes occupy disjoint successive ranges. Unary nodes transport codes.

                                                              Equations
                                                              Instances For
                                                                theorem IndexedGrammar.NFParse.eventOwnerNat_lt_productiveCount {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} (p : g.NFParse A stack w) {d : } (hd : d p.eventDepths) :

                                                                Every actual event code fits inside the productive-node count.

                                                                def IndexedGrammar.NFParse.eventOwner {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} (p : g.NFParse A stack w) (d : ) (hd : d p.eventDepths) :

                                                                A coherent productive-node ID for a canonical event depth.

                                                                Equations
                                                                Instances For
                                                                  @[simp]
                                                                  theorem IndexedGrammar.NFParse.eventOwner_val {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} (p : g.NFParse A stack w) (d : ) (hd : d p.eventDepths) :
                                                                  (p.eventOwner d hd) = p.eventOwnerNat d
                                                                  theorem IndexedGrammar.NFParse.eventOwnerNat_injective {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} (p : g.NFParse A stack w) {d e : } (_hd : d p.eventDepths) (_he : e p.eventDepths) :
                                                                  p.eventOwnerNat d = p.eventOwnerNat ed = e

                                                                  The natural-number event codes are injective on actual event depths.

                                                                  theorem IndexedGrammar.NFParse.eventOwner_injective {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} (p : g.NFParse A stack w) {d e : } (hd : d p.eventDepths) (he : e p.eventDepths) :
                                                                  p.eventOwner d hd = p.eventOwner e hed = e

                                                                  Coherent finite event IDs are injective in the represented stack depth.

                                                                  @[simp]
                                                                  theorem IndexedGrammar.NFParse.eventOwnerNat_pop_succ {T : Type} {g : IndexedGrammar T} {A B : g.nt} {f : g.flag} {stack : List g.flag} {w : List T} {r : IRule T g.nt g.flag} (hr : r g.rules) (hlhs : r.lhs = A) (hc : r.consume = some f) (hrhs : r.rhs = [IRhsSymbol.nonterminal B none]) (rest : g.NFParse B stack w) (d : ) :
                                                                  (pop hr hlhs hc hrhs rest).eventOwnerNat (d + 1) = rest.eventOwnerNat d
                                                                  @[simp]
                                                                  theorem IndexedGrammar.NFParse.eventOwnerNat_push {T : Type} {g : IndexedGrammar T} {A B : g.nt} {f : g.flag} {stack : List g.flag} {w : List T} {r : IRule T g.nt g.flag} (hr : r g.rules) (hlhs : r.lhs = A) (hc : r.consume = none) (hrhs : r.rhs = [IRhsSymbol.nonterminal B (some f)]) (rest : g.NFParse B (f :: stack) w) (d : ) :
                                                                  (push hr hlhs hc hrhs rest).eventOwnerNat d = rest.eventOwnerNat (pushEventPreimage rest.eventDepths d)
                                                                  @[simp]
                                                                  theorem IndexedGrammar.NFParse.eventOwnerNat_binary_zero {T : Type} {g : IndexedGrammar T} {A B C : g.nt} {stack : List g.flag} {u v : List T} {r : IRule T g.nt g.flag} (hr : r g.rules) (hlhs : r.lhs = A) (hc : r.consume = none) (hrhs : r.rhs = [IRhsSymbol.nonterminal B none, IRhsSymbol.nonterminal C none]) (left : g.NFParse B stack u) (right : g.NFParse C stack v) :
                                                                  (binary hr hlhs hc hrhs left right).eventOwnerNat 0 = 0
                                                                  theorem IndexedGrammar.NFParse.eventOwnerNat_binary_left {T : Type} {g : IndexedGrammar T} {A B C : g.nt} {stack : List g.flag} {u v : List T} {r : IRule T g.nt g.flag} (hr : r g.rules) (hlhs : r.lhs = A) (hc : r.consume = none) (hrhs : r.rhs = [IRhsSymbol.nonterminal B none, IRhsSymbol.nonterminal C none]) (left : g.NFParse B stack u) (right : g.NFParse C stack v) {d : } (hd0 : d 0) (hd : d left.eventDepths) :
                                                                  (binary hr hlhs hc hrhs left right).eventOwnerNat d = left.eventOwnerNat d + 1
                                                                  theorem IndexedGrammar.NFParse.eventOwnerNat_binary_right {T : Type} {g : IndexedGrammar T} {A B C : g.nt} {stack : List g.flag} {u v : List T} {r : IRule T g.nt g.flag} (hr : r g.rules) (hlhs : r.lhs = A) (hc : r.consume = none) (hrhs : r.rhs = [IRhsSymbol.nonterminal B none, IRhsSymbol.nonterminal C none]) (left : g.NFParse B stack u) (right : g.NFParse C stack v) {d : } (hd0 : d 0) (hd : dleft.eventDepths) :
                                                                  (binary hr hlhs hc hrhs left right).eventOwnerNat d = left.productiveCount + right.eventOwnerNat d + 1

                                                                  Canonical physical blocks at productive-event cuts #

                                                                  Successive widths represented by an increasing list of absolute cut positions.

                                                                  Equations
                                                                  Instances For
                                                                    @[simp]
                                                                    theorem IndexedGrammar.NFParse.successiveWidths_length (previous : ) (cuts : List ) :
                                                                    (successiveWidths previous cuts).length = cuts.length
                                                                    theorem IndexedGrammar.NFParse.successiveWidths_take (previous : ) (cuts : List ) (n : ) :
                                                                    List.take n (successiveWidths previous cuts) = successiveWidths previous (List.take n cuts)

                                                                    Taking the first n widths is the same as first taking the corresponding cuts.

                                                                    theorem IndexedGrammar.NFParse.successiveWidths_sum_take_add_previous_eq_getElem {previous : } {cuts : List } (hsorted : List.Pairwise (fun (a b : ) => a < b) (previous :: cuts)) (i : ) (hi : i < cuts.length) :
                                                                    (List.take (i + 1) (successiveWidths previous cuts)).sum + previous = cuts[i]

                                                                    The widths through cut i telescope back to that absolute cut.

                                                                    theorem IndexedGrammar.NFParse.successiveWidths_pos {previous : } {cuts : List } (hsorted : List.Pairwise (fun (a b : ) => a < b) (previous :: cuts)) (width : ) :
                                                                    width successiveWidths previous cuts0 < width

                                                                    Every width between consecutive strictly increasing cuts is positive.

                                                                    theorem IndexedGrammar.NFParse.successiveWidths_sum_add_previous_le {previous limit : } {cuts : List } (hprevious : previous limit) (hsorted : List.Pairwise (fun (a b : ) => a < b) (previous :: cuts)) (hcuts : dcuts, d limit) :
                                                                    (successiveWidths previous cuts).sum + previous limit

                                                                    Telescoping widths stay inside any common upper bound for the absolute cuts.

                                                                    def IndexedGrammar.NFParse.eventCuts {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} (p : g.NFParse A stack w) :

                                                                    Positive productive-event depths, in their unique increasing order.

                                                                    Equations
                                                                    Instances For
                                                                      @[simp]
                                                                      theorem IndexedGrammar.NFParse.eventCuts_length {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} (p : g.NFParse A stack w) :
                                                                      theorem IndexedGrammar.NFParse.mem_eventCuts_iff {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} (p : g.NFParse A stack w) (d : ) :
                                                                      theorem IndexedGrammar.NFParse.eventCuts_sortedLT {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} (p : g.NFParse A stack w) :
                                                                      List.Pairwise (fun (a b : ) => a < b) p.eventCuts

                                                                      Canonical cuts are strictly increasing.

                                                                      theorem IndexedGrammar.NFParse.zero_cons_eventCuts_sortedLT {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} (p : g.NFParse A stack w) :
                                                                      List.Pairwise (fun (a b : ) => a < b) (0 :: p.eventCuts)

                                                                      Adding the implicit initial boundary preserves strict increase.

                                                                      theorem IndexedGrammar.NFParse.eventCuts_le_stack_length {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} (p : g.NFParse A stack w) (d : ) :
                                                                      d p.eventCutsd stack.length

                                                                      Every cut is an actual position in the root stack.

                                                                      theorem IndexedGrammar.NFParse.eventCuts_getLast_le_stack_length {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} (p : g.NFParse A stack w) (hne : p.eventCuts []) :

                                                                      In particular, the last canonical cut lies inside the root stack.

                                                                      def IndexedGrammar.NFParse.eventWidths {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} (p : g.NFParse A stack w) :

                                                                      Concrete lengths of the successive canonical event blocks.

                                                                      Equations
                                                                      Instances For
                                                                        @[simp]
                                                                        theorem IndexedGrammar.NFParse.eventWidths_length {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} (p : g.NFParse A stack w) :
                                                                        theorem IndexedGrammar.NFParse.eventWidths_pos {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} (p : g.NFParse A stack w) (width : ) :
                                                                        width p.eventWidths0 < width
                                                                        theorem IndexedGrammar.NFParse.eventWidths_sum_le_stack_length {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} (p : g.NFParse A stack w) :

                                                                        The total visible prefix selected by all event cuts fits in the root stack.

                                                                        theorem IndexedGrammar.NFParse.flatten_splitLengths_eq_take {X : Type} (xs : List X) (widths : List ) (hfit : widths.sum xs.length) :
                                                                        (widths.splitLengths xs).flatten = List.take widths.sum xs

                                                                        Splitting a list by widths whose total fits returns exactly the corresponding prefix.

                                                                        def IndexedGrammar.NFParse.eventBlocks {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} (p : g.NFParse A stack w) :

                                                                        Canonical nonempty concrete flag blocks cut from the consumed root-stack prefix.

                                                                        Equations
                                                                        Instances For
                                                                          @[simp]
                                                                          theorem IndexedGrammar.NFParse.eventBlocks_length {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} (p : g.NFParse A stack w) :
                                                                          theorem IndexedGrammar.NFParse.eventBlocks_map_length {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} (p : g.NFParse A stack w) :

                                                                          Each physical block has exactly its positive successive width.

                                                                          theorem IndexedGrammar.NFParse.eventBlocks_nonempty {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} (p : g.NFParse A stack w) (block : List g.flag) :
                                                                          block p.eventBlocksblock []

                                                                          No canonical physical block is empty.

                                                                          theorem IndexedGrammar.NFParse.eventBlocks_flatten {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} (p : g.NFParse A stack w) :

                                                                          The generated blocks flatten to the concrete stack prefix ending at the final event cut.

                                                                          theorem IndexedGrammar.NFParse.eventWidths_sum_take_eq_getElem {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} (p : g.NFParse A stack w) (i : ) (hi : i < p.eventCuts.length) :

                                                                          Widths through the ith block telescope to the ith absolute event cut.

                                                                          theorem IndexedGrammar.NFParse.eventBlocks_take_flatten_eq_take_getElem {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} (p : g.NFParse A stack w) (i : ) (hi : i < p.eventCuts.length) :

                                                                          Every prefix of canonical blocks ends at the corresponding absolute event cut.

                                                                          theorem IndexedGrammar.NFParse.eventBlocks_take_flatten_length_eq_getElem {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} (p : g.NFParse A stack w) (i : ) (hi : i < p.eventCuts.length) :

                                                                          Numerically, the prefix endpoints of eventBlocks are exactly eventCuts.

                                                                          theorem IndexedGrammar.NFParse.eventCuts_nodup {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} (p : g.NFParse A stack w) :

                                                                          The canonical cut list has no duplicate endpoints.

                                                                          def IndexedGrammar.NFParse.eventBlockOwner {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} (p : g.NFParse A stack w) (i : Fin p.eventBlocks.length) :

                                                                          Assign a physical block its productive-event-depth owner: the endpoint of that block.

                                                                          Equations
                                                                          Instances For
                                                                            theorem IndexedGrammar.NFParse.eventBlockOwner_mem_eventDepths {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} (p : g.NFParse A stack w) (i : Fin p.eventBlocks.length) :

                                                                            Every physical block owner is an actual productive-event depth.

                                                                            theorem IndexedGrammar.NFParse.eventBlockOwner_injective {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} (p : g.NFParse A stack w) :

                                                                            Different physical blocks receive different productive-event-depth owners. This is the global injection needed for the token budget; unlike one-way boundary compatibility it rules out arbitrary extra protected-child blocks.

                                                                            def IndexedGrammar.NFParse.eventBlockGlobalOwner {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} (p : g.NFParse A stack w) (i : Fin p.eventBlocks.length) :
                                                                            Fin (2 * w.length - 1)

                                                                            Root-capacity owner of a canonical physical block. Unlike its raw depth endpoint, this ID is stable under the unary transports and binary embeddings encoded by eventOwnerNat.

                                                                            Equations
                                                                            Instances For
                                                                              @[simp]
                                                                              theorem IndexedGrammar.NFParse.eventBlockGlobalOwner_val {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} (p : g.NFParse A stack w) (i : Fin p.eventBlocks.length) :

                                                                              Canonical block owners are globally collision-free in the exact 2|w|-1 carrier.

                                                                              theorem IndexedGrammar.NFParse.exists_eventBlocks_boundary {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} (p : g.NFParse A stack w) {d : } (hd : d p.eventDepths) :
                                                                              blockCountp.eventBlocks.length, d = (List.take blockCount p.eventBlocks).flatten.length

                                                                              Every productive-event depth is a whole-block prefix boundary (with depth zero represented by the empty block prefix).

                                                                              The number of canonical physical blocks obeys the same 2|w|-1 bound as event cuts.

                                                                              def IndexedGrammar.NFParse.eventBlocksOwnership {T : Type} {g : IndexedGrammar T} {A : g.nt} {stack : List g.flag} {w : List T} (p : g.NFParse A stack w) :

                                                                              Canonical blocks come with a persistent finite ownership carrier of the exact global 2|w|-1 capacity. Descendants can retain these owners through take/drop, so protected boundaries remain charged even when they are extra relative to the child's local event cuts.

                                                                              Equations
                                                                              Instances For