Documentation

Complexity.Foundations.Data.StackTape

Indexed observations and Mathlib ListBlank equivalence for finite stack tapes #

These additions give Bolton Bailey's upstream StackTape an indexed view that reads blank outside its stored list, together with the canonical equivalence with Mathlib's quotient one-sided tape _root_.Turing.ListBlank (Option Symbol).

Main definitions #

Main results #

References #

Ports the additions to Foundations/Data/StackTape.lean on the cslib crypto branch at 5ff69ca93402e7c947208dc56396d6d86203ccd8, retaining the upstream tape representation.

theorem Cslib.Turing.StackTape.ext {Symbol : Type u_1} {left right : StackTape Symbol} (h : left.toList = right.toList) :
left = right

Equality of stored lists determines equality of stack tapes.

theorem Cslib.Turing.StackTape.ext_iff {Symbol : Type u_1} {left right : StackTape Symbol} :
left = right ↔ left.toList = right.toList
@[simp]
theorem Cslib.Turing.StackTape.tail_toList {Symbol : Type u_1} (tape : StackTape Symbol) :
tape.tail.toList = tape.toList.tail

The stored list of tail is the tail of the stored list.

theorem Cslib.Turing.StackTape.cons_toList {Symbol : Type u_1} (symbol : Option Symbol) (tape : StackTape Symbol) :
(cons symbol tape).toList = if (symbol.isSome || !tape.toList.isEmpty) = true then symbol :: tape.toList else []

Prepending retains blank cells only when there is stored data beyond them.

def Cslib.Turing.StackTape.read {Symbol : Type u_1} :
StackTape Symbol → ℕ → Option Symbol

Read a cell, treating every position beyond the finite representation as blank.

Instances For
    @[simp]
    theorem Cslib.Turing.StackTape.read_zero {Symbol : Type u_1} (tape : StackTape Symbol) :
    tape.read 0 = tape.head

    Reading at 0 is reading the head.

    @[simp]
    theorem Cslib.Turing.StackTape.read_succ {Symbol : Type u_1} (tape : StackTape Symbol) (position : ℕ) :
    tape.read (position + 1) = tape.tail.read position

    Reading at position + 1 is reading the tail at position.

    @[simp]
    theorem Cslib.Turing.StackTape.read_nil {Symbol : Type u_1} (position : ℕ) :
    nil.read position = none

    The empty stack tape reads blank everywhere.

    theorem Cslib.Turing.StackTape.read_eq_getElem? {Symbol : Type u_1} (tape : StackTape Symbol) (position : ℕ) :
    tape.read position = tape.toList[position]?.join

    The indexed view agrees with the stored list, with absent cells read as blanks.

    @[simp]
    theorem Cslib.Turing.StackTape.read_mapSome {Symbol : Type u_1} (values : List Symbol) (position : ℕ) :
    (mapSome values).read position = values[position]?

    The tape loaded with a word reads its symbol at each position, and blank past its end.

    @[simp]

    Prepending a blank to the empty stack tape leaves it empty.

    def Cslib.Turing.StackTape.ofList {Symbol : Type u_1} (values : List (Option Symbol)) :
    StackTape Symbol

    Construct a StackTape from an arbitrary list of optional symbols by folding cons.

    Instances For
      @[simp]

      ofList turns the empty list into the empty stack tape.

      @[simp]
      theorem Cslib.Turing.StackTape.ofList_cons {Symbol : Type u_1} (a : Option Symbol) (l : List (Option Symbol)) :
      ofList (a :: l) = cons a (ofList l)

      ofList turns list prepending into cons.

      @[simp]

      A list of blanks gives the empty stack tape.

      Trailing blanks do not change ofList.

      @[simp]
      theorem Cslib.Turing.StackTape.ofList_toList {Symbol : Type u_1} (tape : StackTape Symbol) :
      ofList tape.toList = tape

      ofList recovers a stack tape from its stored list.

      @[simp]
      theorem Cslib.Turing.StackTape.ofList_map_some {Symbol : Type u_1} (l : List Symbol) :

      ofList of the symbols of a word wrapped in some is mapSome of the word.

      @[simp]

      The stored list of ofList l gives the same ListBlank as l.

      Canonical equivalence between StackTape Symbol and Mathlib's _root_.Turing.ListBlank (Option Symbol).

      Instances For
        @[simp]

        equivListBlank sends the empty stack tape to the blank ListBlank.

        @[simp]

        The inverse of equivListBlank sends the blank ListBlank to the empty stack tape.

        @[simp]

        The inverse of equivListBlank sends the ListBlank of a list l to ofList l.

        @[simp]

        equivListBlank sends ofList l to the ListBlank of l.

        @[simp]
        theorem Cslib.Turing.StackTape.equivListBlank_cons {Symbol : Type u_1} (a : Option Symbol) (tape : StackTape Symbol) :

        equivListBlank turns stack-tape cons into ListBlank.cons.

        @[simp]

        The inverse of equivListBlank turns ListBlank.cons into stack-tape cons.

        @[simp]
        theorem Cslib.Turing.StackTape.head_equivListBlank {Symbol : Type u_1} (tape : StackTape Symbol) :

        equivListBlank preserves the head.

        @[simp]

        The inverse of equivListBlank preserves the head.

        @[simp]

        equivListBlank commutes with taking the tail.

        @[simp]

        The inverse of equivListBlank commutes with taking the tail.

        @[simp]

        equivListBlank sends mapSome l to the ListBlank of l.map some.

        @[simp]
        theorem Cslib.Turing.StackTape.nth_equivListBlank {Symbol : Type u_1} (tape : StackTape Symbol) (n : ℕ) :
        (equivListBlank tape).nth n = tape.read n

        Reading the ListBlank at n is reading the tape at n.

        @[simp]

        Reading the stack tape equivListBlank.symm lb at n is reading lb at n.