Documentation

Complexity.Algorithms.WordRAM.DynamicArray

Doubling arrays on the word RAM #

A fixed twelve-register append routine uses the charged zeroing allocator and a charged copy loop. Old blocks are retained: the space theorem concerns total allocated words over append-only histories, rather than reclamation. The abstract state exposes only the list. A companion two-instruction indexed read routine and a fixed operation dispatcher connect the doubling array to Cslib.Stateful and Cslib.Stateful.Amortized.

Main definitions #

Main results #

References #

@[reducible, inline]

Pointer to the live block.

Instances For
    @[reducible, inline]

    New block pointer and operation dispatch tag.

    Instances For
      @[reducible, inline]

      Logical length.

      Instances For
        @[reducible, inline]

        Copy/allocation loop cursor.

        Instances For
          @[reducible, inline]

          Temporary address.

          Instances For
            @[reducible, inline]

            Temporary copied value and read output register.

            Instances For
              @[reducible, inline]

              Constant one.

              Instances For
                @[reducible, inline]

                Current capacity.

                Instances For
                  @[reducible, inline]

                  Bump allocator frontier.

                  Instances For
                    @[reducible, inline]

                    Caller-supplied value to append or index to read.

                    Instances For
                      @[reducible, inline]

                      Requested allocation size.

                      Instances For
                        @[reducible, inline]

                        Constant zero.

                        Instances For

                          The copy routine embedded in the first seven registers.

                          Instances For

                            Allocate twice the capacity, copy the live prefix, and switch the pointer.

                            Instances For

                              Append a word, growing precisely when the array is full.

                              Instances For

                                Allocate the initial one-word block at address zero and install the empty representation.

                                Instances For

                                  The live prefix, capacity and total allocation. The equalities express the geometric allocation series starting with a single cell at address zero.

                                  Instances For
                                    theorem Cslib.Algorithms.WordRAM.DynamicArray.Rep.space {vs : List ℕ} {x : WordRAM.Data 12} (h : Rep vs x) (hne : vs ≠ []) :

                                    Capacity and all historically allocated blocks occupy fewer than four words per live element once the array is nonempty.

                                    The doubled frontier bound x.regs frontier + 2 * x.regs cap is bounded by 8 * vs.length + 3 for every represented state.

                                    The natural-valued credit used to pay for allocation and copying.

                                    Instances For

                                      The exact copy contract lifts to a larger register file without charging a meta-level call.

                                      theorem Cslib.Algorithms.WordRAM.DynamicArray.grow_exec {w : ℕ} (x : WordRAM.Data 12) (h1 : WordRAM.Fits w 1) (hn : x.regs len = x.regs cap) (hp : x.regs ptr + x.regs len ≤ x.regs frontier) (hw : WordRAM.Fits w (x.regs frontier + 2 * x.regs cap)) :
                                      ∃ (y : WordRAM.Data 12), WordRAM.ExecWithin w grow x y (15 * x.regs cap + 14) ∧ y.regs ptr = x.regs frontier ∧ y.regs cap = 2 * x.regs cap ∧ y.regs frontier = x.regs frontier + 2 * x.regs cap ∧ (∀ i < x.regs len, y.mem (y.regs ptr + i) = x.mem (x.regs ptr + i)) ∧ ∀ (a : ℕ), a < x.regs frontier ∨ x.regs frontier + 2 * x.regs cap ≤ a → y.mem a = x.mem a

                                      A growth phase preserves the live values and sets aside a zeroed block, charging both allocation and copying. The resulting capacity, frontier, and frame are explicit.

                                      Four-instruction suffix of program: set one ← #1, write arg at ptr + len, and increment len.

                                      theorem Cslib.Algorithms.WordRAM.DynamicArray.append_exec {w : ℕ} {vs : List ℕ} {x : WordRAM.Data 12} (hr : Rep vs x) (hw : WordRAM.Fits w (x.regs frontier + 2 * x.regs cap)) :
                                      ∃ (y : WordRAM.Data 12) (n : ℕ), WordRAM.Exec w program x y n ∧ Rep (vs ++ [x.regs arg]) y ∧ (∀ (a : ℕ), a < x.regs ptr ∨ y.regs frontier ≤ a → y.mem a = x.mem a) ∧ n + potential (vs ++ [x.regs arg]) y ≤ 49 + potential vs x ∧ n + potential (vs ++ [x.regs arg]) y - potential vs x ≤ 49

                                      Appending a word preserves the doubling-array invariant, modifies only cells in [x.regs ptr, y.regs frontier) (hence only within [0, y.regs frontier)), and satisfies the potential-method amortized bound with constant 49.

                                      theorem Cslib.Algorithms.WordRAM.DynamicArray.get_exec {w : ℕ} {vs : List ℕ} {x : WordRAM.Data 12} (hr : Rep vs x) (hi : x.regs arg < vs.length) (hw : WordRAM.Fits w (x.regs frontier)) :
                                      ∃ (y : WordRAM.Data 12), WordRAM.Exec w getProgram x y 2 ∧ y.regs temp = vs.getD (x.regs arg) 0 ∧ Rep vs y ∧ y.mem = x.mem ∧ potential vs y = potential vs x

                                      Indexed read returns vs[x.regs arg] in temp in two instructions without changing the representation, memory, or potential.

                                      theorem Cslib.Algorithms.WordRAM.DynamicArray.init_exec {w : ℕ} (x : WordRAM.Data 12) (h1 : WordRAM.Fits w 1) :
                                      ∃ (y : WordRAM.Data 12), WordRAM.Exec w initProgram x y 15 ∧ Rep [] y ∧ y.regs frontier = 1 ∧ potential [] y = 0 ∧ y.mem 0 = 0 ∧ ∀ (a : ℕ), 1 ≤ a → y.mem a = x.mem a

                                      Charged initialization allocates the initial one-word block at address zero in fifteen instructions, establishing Rep [] with zero potential and frontier 1.

                                      Connection to Cslib.Stateful and Cslib.Stateful.Amortized #

                                      Doubling-array operations: append a word at the end or read an existing index.

                                      • append (value : ℕ) : Op

                                        Append a word to the array.

                                      • get (index : ℕ) : Op

                                        Read the word at a zero-based index.

                                      Instances For
                                        @[reducible, inline]

                                        Mathematical specification of a bounded-word dynamic array. Appending requires the value and the worst-case doubled frontier bound 8 * vs.length + 4 to fit in a machine word; indexed reads require a valid index fitting a machine word.

                                        Instances For

                                          Fixed operation dispatcher: dest = 0 runs program (append), dest = 1 runs getProgram.

                                          Instances For

                                            Register calling convention for dispatch.

                                            Instances For

                                              Bounded-word doubling-array representation for DynamicCertificate.

                                              Instances For

                                                Amortized instruction charge per operation, including dispatch and final halt.

                                                Instances For
                                                  theorem Cslib.Algorithms.WordRAM.DynamicArray.arguments_fit {w : ℕ} (h1 : WordRAM.Fits w 1) {vs : List ℕ} (o : Op) (hv : (spec w).valid vs o) (i : Fin 12) :

                                                  Encoded arguments fit the word width whenever 1 fits and the operation is valid.

                                                  theorem Cslib.Algorithms.WordRAM.DynamicArray.prepare_rep {vs : List ℕ} {x : WordRAM.Data 12} (hr : Rep vs x) (w : ℕ) (o : Op) :

                                                  Argument delivery preserves Rep because dest and arg are not persistent representation registers.

                                                  theorem Cslib.Algorithms.WordRAM.DynamicArray.dispatch_exec {w : ℕ} (h1 : WordRAM.Fits w 1) {vs : List ℕ} {x : WordRAM.Data 12} (hr : BoundedRep w vs x) (o : Op) (hv : (spec w).valid vs o) :
                                                  ∃ (y : WordRAM.Data 12) (n : ℕ), WordRAM.Exec w dispatch ((implementation w).prepare o x) y n ∧ (implementation w).decode o y.regs = some ((spec w).step vs o).2 ∧ BoundedRep w ((spec w).step vs o).1 y ∧ (∀ (a : ℕ), y.regs frontier ≤ a → y.mem a = x.mem a) ∧ n + 1 + potential ((spec w).step vs o).1 y ≤ charge o + potential vs x

                                                  Every admissible operation executes dispatch, preserves BoundedRep, modifies only cells below y.regs frontier, and satisfies the potential inequality with charge o (counting the final halt).

                                                  Semantic realization certificate for the bounded-word dynamic array.

                                                  Instances For

                                                    Amortized instruction-cost certificate for the dynamic array (52 per append, 6 per get, including dispatch and final halt).

                                                    Uniform amortized instruction-cost certificate (52 instructions per operation).

                                                    theorem Cslib.Algorithms.WordRAM.DynamicArray.modifies {w : ℕ} (h1 : WordRAM.Fits w 1) {vs : List ℕ} {x y : WordRAM.Data 12} {o : Op} {a : (spec w).Result o} {trace : WordRAM.DynamicProgram.OperationTrace} (hr : BoundedRep w vs x) (hv : (spec w).valid vs o) (he : (implementation w).ExecOp w x o a y trace) :

                                                    Every concrete call modifies only cells below y.regs frontier.

                                                    theorem Cslib.Algorithms.WordRAM.DynamicArray.frame {w : ℕ} (h1 : WordRAM.Fits w 1) {vs : List ℕ} {x y : WordRAM.Data 12} {o : Op} {a : (spec w).Result o} {trace : WordRAM.DynamicProgram.OperationTrace} (hr : BoundedRep w vs x) (hv : (spec w).valid vs o) (he : (implementation w).ExecOp w x o a y trace) {Q : WordRAM.HeapAssertion} (hQ : Q.holds x.mem) (hd : Disjoint Q.footprint (Finset.range (y.regs frontier))) :

                                                    Disjoint heap assertions above y.regs frontier survive every dynamic-array call.

                                                    theorem Cslib.Algorithms.WordRAM.DynamicArray.run_client {w : ℕ} (h1 : WordRAM.Fits w 1) {α : Type} (p : (spec w).Client α) {vs : List ℕ} {x : WordRAM.Data 12} (hr : BoundedRep w vs x) (hv : (spec w).ValidHistory vs ((spec w).runClient vs p).2.2) :

                                                    Every admissible adaptive client executes with total instructions bounded by 52 per operation plus initial credit, retaining final credit and the < 4 * m space invariant.

                                                    Starting from arbitrary bounded machine data, run initProgram (15 instructions) followed by any admissible adaptive client p. Total instructions across initialization and m operations are at most 15 + 52 * m, and the allocator frontier is < 4 * n whenever the final list of length n is nonempty.

                                                    Client that appends each element of us in order.

                                                    Instances For
                                                      @[simp]

                                                      Mathematical execution of appendAll appends us to vs and records us.map Op.append.

                                                      theorem Cslib.Algorithms.WordRAM.DynamicArray.validHistory_appendAll {w : ℕ} {vs us : List ℕ} (hvals : ∀ v ∈ us, WordRAM.Fits w v) (hlen : WordRAM.Fits w (8 * (vs.length + us.length) + 4)) :
                                                      (spec w).ValidHistory vs ((spec w).runClient vs (appendAll us)).2.2

                                                      appendAll us is admissible from vs whenever every element of us fits w and 8 * (vs.length + us.length) + 4 fits w.

                                                      Any sequence of m = vs.length appends starting from the charged initializer executes in at most 15 + 52 * m total charged instructions and uses fewer than 4 * m total allocated words whenever vs ≠ [].