Canonical projection of lists of binary Nat pairs

TheoremProjected pair lists total at most four times the input length#✓fully proved

Both projected canonical lists together are bounded by four times the original raw list length, including noncanonical input payloads.

theorem projection_length_le {x : List Bool} {as : List (Nat × Nat)}
    (h : bitDecode x = some as) :
    (bitEncode (as.map Prod.fst)).length +
      (bitEncode (as.map Prod.snd)).length ≤ 4 * x.length
Uses 11 · Used by 2

InductiveStacks of the pair-list projector#✓fully proved

Raw outer input, two reversed accumulators, two outputs, and the existing Nat-pair component's workspace.

inductive K | input | acc (right : Bool) | output (right : Bool)
  | pair (k : NatPair.K)
  deriving DecidableEq
Uses 1 · Used by 21

InductiveControl labels of the pair-list projector#✓fully proved

Read one outer frame, normalize its pair, emit both fields, repeat.

inductive Lab | loop | block | back | pair (l : NatPair.Lab)
  | emit (right : Bool) | finish (right : Bool) | good | bad
  deriving DecidableEq
Uses 1 · Used by 16

DefinitionStack embedding of the pair normalizer in the pair-list projector#✓fully proved

The Nat-pair component is embedded without changing its alphabets.

def pairEmb : SEmb (fun _ : NatPair.K => Bool) (fun _ : K => Bool) where
  e := K.pair
  inj _ _ h := K.pair.inj h
  ι _ := Equiv.refl Bool
Uses 3 · Used by 3

DefinitionPair-normalizer halt redirection in the pair-list projector#✓fully proved

Only the pair component's actual halts are redirected.

def pairLabel : NatPair.Lab → Lab
  | .good => .emit false
  | .bad => .bad
  | l => .pair l
Uses 4 · Used by 3

DefinitionProgram of the pair-list projector#✓fully proved

Concrete outer parsing, pair normalization, and two framed streams.

def prog : Lab → TM2.Stmt (fun _ : K => Bool) Lab Bool
  | .loop => .peek .input (fun _ o => o.isSome) <| .branch id
      (.goto fun _ => .block) (.goto fun _ => .finish false)
  | .block => FramedCNF.Block.read .input (.pair (.pair .scratch))
      some id .block .back .bad
  | .back => moveB (.pair (.pair .scratch)) (.pair (.pair .input))
      some id .back (.pair (.pair .read))
  | .pair l => mapS pairEmb pairLabel (NatPair.prog l)
  | .emit right => emitFrame
      (if right then .pair .right else .pair .left) (.acc right)
      some id (.emit right) (if right then .loop else .emit true)
  | .finish right => moveB (.acc right) (.output right) some id
      (.finish right) (if right then .good else .finish true)
  | .good | .bad => .halt
Uses 14 · Used by 10

DefinitionEleven-stack invariant of the pair-list projector#✓fully proved

The exact eleven-stack invariant, with caller output suffixes.

def st (input aw av ow ov : List Bool) (P : NatPair.K → List Bool) :
    K → List Bool
  | .input => input
  | .acc right => if right then av else aw
  | .output right => if right then ov else ow
  | .pair k => P k
Uses 2 · Used by 9

TheoremPair-list projector emits one weight and one value frame per item#✓fully proved

One successfully decoded item contributes one canonical weight frame and one canonical value frame, with pair scratch emptied again.

theorem element_run {p : List Bool} {m n : Nat}
    (h : bitDecode p = some (m, n)) (r aw av ow ov : List Bool) (v : Bool) :
    RunLe prog (12 * (delimit p).length)
      ⟨some .loop, v, st (delimit p ++ r) aw av ow ov
        (NatPair.st [] [] [] [] [] [])⟩
      ⟨some .loop, false,
        st r ((delimit (Computability.encodeNat m)).reverse ++ aw)
          ((delimit (Computability.encodeNat n)).reverse ++ av) ow ov
          (NatPair.st [] [] [] [] [] [])⟩
Uses 34 · Used by 2

TheoremPair-list projector main loop emits both lists in reverse#✓fully proved

The main loop emits both lists in reverse, ready for the two final stack reversals. Order and multiplicity follow the decoded input.

theorem blocks_run (bs : List (List Bool)) (as : List (Nat × Nat))
    (h : bitDecode (bs.map delimit).flatten = some as)
    (aw av ow ov : List Bool) (v : Bool) :
    RunLe prog (12 * ((bs.map delimit).flatten).length + 1)
      ⟨some .loop, v, st (bs.map delimit).flatten aw av ow ov
        (NatPair.st [] [] [] [] [] [])⟩
      ⟨some (.finish false), false,
        st [] ((bitEncode (as.map Prod.fst)).reverse ++ aw)
          ((bitEncode (as.map Prod.snd)).reverse ++ av) ow ov
          (NatPair.st [] [] [] [] [] [])⟩
Uses 20 · Used by 1

TheoremPair-list projector yields canonical weight and value lists#✓fully proved

Successful generic decoding yields the canonical weight and value lists on separate stacks. All input and scratch stacks are emptied.

theorem run_some {x : List Bool} {as : List (Nat × Nat)}
    (h : bitDecode x = some as) (ow ov : List Bool) (v : Bool) :
    ∃ w, RunLe prog (16 * x.length + 3)
      ⟨some .loop, v, st x [] [] ow ov (NatPair.st [] [] [] [] [] [])⟩
      ⟨some .good, w, st [] [] [] (bitEncode (as.map Prod.fst) ++ ow)
        (bitEncode (as.map Prod.snd) ++ ov)
        (NatPair.st [] [] [] [] [] [])⟩
Uses 22 · Used by 3

TheoremPair-list projector fails on malformed input in linear time#✓fully proved

Malformed outer framing or any malformed pair reaches bad in linear time. Failed workspaces may contain partial data and need clearing.

theorem run_none {x : List Bool}
    (h : bitDecode (α := List (Nat × Nat)) x = none)
    (aw av ow ov : List Bool) (v : Bool) :
    ∃ w S, RunLe prog (12 * x.length + 2)
      ⟨some .loop, v, st x aw av ow ov (NatPair.st [] [] [] [] [] [])⟩
      ⟨some .bad, w, S⟩
Uses 38 · Used by 2

AbbreviationPair-list projector as a host component#✓fully proved

The concrete eleven-stack projector uses the existing Host model.

Cslib.Complexity.PolynomialEncoding.ListNatPair.component · 17 lines
abbrev component : Host.Comp where
  K := K
  Γ := fun _ => Bool
  L := Lab
  prog := prog
  ks := [.input, .acc false, .acc true, .output false, .output true,
    .pair (.pair .input), .pair (.pair .left), .pair (.pair .scratch),
    .pair .buffer, .pair .left, .pair .right]
  ks_nodup := by decide
  mem_ks k := by
    cases k with
    | input => decide
    | acc b | output b => cases b <;> decide
    | pair k =>
      cases k with
      | pair k => cases k <;> decide
      | buffer | left | right => decide
Uses 9 · Used by 1

TheoremPair-list projector always terminates at the decoding outcome#✓fully proved

Total decoder outcome. Success projects canonical lists with empty scratch; failure promises termination, not reusable workspace contents.

theorem run (x : List Bool) (v : Bool) :
    ∃ w S, RunLe prog (16 * x.length + 3)
      ⟨some .loop, v, st x [] [] [] [] (NatPair.st [] [] [] [] [] [])⟩
      ⟨some (if (bitDecode (α := List (Nat × Nat)) x).isSome
        then .good else .bad), w, S⟩ ∧
      ∀ as : List (Nat × Nat), bitDecode x = some as →
        S = st [] [] [] (bitEncode (as.map Prod.fst))
          (bitEncode (as.map Prod.snd)) (NatPair.st [] [] [] [] [] [])
Uses 19 · Used by 1

TheoremEmbedded pair-list projector preserves outside stacks#✓fully proved

Any stack embedding preserves the external frame on both outcomes. Only mapped-label reachability is promised: callers establish their own continuation-label separation. Failed private workspace needs clearing.

theorem run_embedded {J L : Type} [DecidableEq J] {Γ : J → Type}
    (E : SEmb (fun _ : K => Bool) Γ) (φ : Lab → L)
    {M : L → TM2.Stmt Γ L Bool} (hm : Embeds E φ prog M)
    (x : List Bool) (v : Bool) (S : ∀ j, List (Γ j))
    (hs : Agree E (st x [] [] [] [] (NatPair.st [] [] [] [] [] [])) S) :
    ∃ w T, RunLe M (16 * x.length + 3)
      ⟨some (φ .loop), v, S⟩
      ⟨some (φ (if (bitDecode (α := List (Nat × Nat)) x).isSome
        then .good else .bad)), w, T⟩ ∧ Frame E S T ∧
      ∀ as : List (Nat × Nat), bitDecode x = some as →
        Agree E (st [] [] [] (bitEncode (as.map Prod.fst))
          (bitEncode (as.map Prod.snd)) (NatPair.st [] [] [] [] [] [])) T
Uses 22
14 fully proved

The dependency explorer needs JavaScript and its graph data.

Download the complete graph data.