From the canonical pair encoding to the w # y form
The canonical encoding of a pair of bit lists
DefinitionConverter encoding of the first component#✓fully proved
For a bit list \(x\), the bit list obtained by replacing every bit \(b\) of \(x\), in order, with the six bits true, true, true, \(b\), true, false.
DefinitionConverter encoding of the second component#✓fully proved
For a bit list \(w\), the bit list obtained by replacing every bit \(b\) of \(w\), in order, with the three bits true, \(b\), false.
Used by 7
TheoremCanonical encoding of a pair of bit lists#✓fully proved
For bit lists \(x\) and \(w\), the canonical bitstring encoding of the pair \((x, w)\) is the concatenation of three parts: every bit \(b\) of \(x\), in order, written as the six bits true, true, true, \(b\), true, false; then a single false; then every bit \(b\) of \(w\), in order, written as the three bits true, \(b\), false.
theorem bitEncode_pair_eq (x w : List Bool) :
(BitstringEncoding.toEncoding (α := List Bool × List Bool)).encode (x, w) =
encFst x ++ false :: encSnd w
class BitstringEncoding α extends Computability.Encoding α Bool
MathlibExt/Computability/Complexity.lean:48
def encFst (x : List Bool) : List Bool := x.flatMap fun b => [true, true, true, b, true, false]
CSLibExt/Computability/Complexity/PairEncodingConverter.lean:45
def encSnd (w : List Bool) : List Bool := w.flatMap fun b => [true, b, false]
CSLibExt/Computability/Complexity/PairEncodingConverter.lean:48
Uses 10 · Used by 2
The machine
InductiveStacks of the pair-encoding converter#✓fully proved
The machine that rewrites the canonical encoding of a pair of bit lists into the verifier's input form has four stacks: the input stack, the output stack, and two stash stacks, one for each component of the pair.
inductive Stk | inp | out | fst | snd
deriving DecidableEq
Used by 7
DefinitionStack alphabets of the pair-encoding converter#✓fully proved
The output stack of the converter has as its alphabet the verifier's work alphabet \(G = \{0,1\} \sqcup (\{0,1\} \cup \{\#\})\); the input stack and the two stash stacks have the bits \(\{0,1\}\) as their alphabet.
@[reducible] def Γ : Stk → Type
| .out => Verifier.G
| _ => Bool
inductive Stk | inp | out | fst | snd
deriving DecidableEq
CSLibExt/Computability/Complexity/PairEncodingConverter.lean:86
abbrev G := Bool ⊕ Option Bool
CSLibExt/Computability/Complexity/DenseSATVerifier.lean:67
Uses 2 · Used by 6
InductiveLabels of the pair-encoding converter#✓fully proved
The five labels of the converter program: read the first component, read the second component, emit the second component, emit the separator, and emit the first component.
inductive Lab | readFst | readSnd | emitSnd | sep | emitFst
deriving DecidableEq
AbbreviationState of the pair-encoding converter#✓fully proved
The internal state of the converter is an optional bit: either a bit or nothing. It records the last bit the program stored.
DefinitionProgram of the pair-encoding converter#✓fully proved
The program over the converter's four stacks, five labels and states (a bit or nothing). Each pop either stores the popped bit in the state (nothing if the stack is empty) or leaves the state unchanged, and each push of the stored bit uses false when the state holds nothing.
At read first: pop the input, storing; if the state is true, pop the input twice without storing, once storing and twice without storing, push the stored bit onto the first stash and go to read first; otherwise go to read second. At read second: pop the input, storing; if the state is true, pop the input once storing and once without storing, push the stored bit onto the second stash and go to read second; otherwise go to emit second. At emit second: pop the second stash, storing; if a bit was popped, push it onto the output as a right-tagged bit and go to emit second; otherwise go to separator. At separator: push the separator onto the output and go to emit first. At emit first: pop the first stash, storing; if a bit was popped, push it onto the output as a left-tagged bit and go to emit first; otherwise halt.
Cslib.Complexity.DenseSAT.Converter.prog · 21 lines
def prog : Lab → TM2.Stmt Γ Lab St
| .readFst =>
.pop .inp (fun _ o => o) <| .branch (fun s => s == some true)
(.pop .inp (fun s _ => s) <| .pop .inp (fun s _ => s) <| .pop .inp (fun _ o => o) <|
.pop .inp (fun s _ => s) <| .pop .inp (fun s _ => s) <|
.push .fst (fun s => s.getD false) <| .goto fun _ => .readFst)
(.goto fun _ => .readSnd)
| .readSnd =>
.pop .inp (fun _ o => o) <| .branch (fun s => s == some true)
(.pop .inp (fun _ o => o) <| .pop .inp (fun s _ => s) <|
.push .snd (fun s => s.getD false) <| .goto fun _ => .readSnd)
(.goto fun _ => .emitSnd)
| .emitSnd =>
.pop .snd (fun _ o => o) <| .branch (fun s => s.isSome)
(.push .out (fun s => .inr (some (s.getD false))) <| .goto fun _ => .emitSnd)
(.goto fun _ => .sep)
| .sep => .push .out (fun _ => .inr none) <| .goto fun _ => .emitFst
| .emitFst =>
.pop .fst (fun _ o => o) <| .branch (fun s => s.isSome)
(.push .out (fun s => .inl (s.getD false)) <| .goto fun _ => .emitFst)
.halt
inductive Lab | readFst | readSnd | emitSnd | sep | emitFst
deriving DecidableEq
CSLibExt/Computability/Complexity/PairEncodingConverter.lean:100
@[reducible] def Γ : Stk → Type
| .out => Verifier.G
| _ => Bool
CSLibExt/Computability/Complexity/PairEncodingConverter.lean:94
abbrev St := Option Bool
CSLibExt/Computability/Complexity/PairEncodingConverter.lean:108
Uses 4 · Used by 4
DefinitionThe pair-encoding converter machine#✓fully proved
The converter is the finite multi-stack Turing machine whose stacks are the input stack, the output stack and the two stash stacks, with bits as the alphabet of every stack except the output stack, which holds the verifier's symbols. Its labels are the five phases (read the first component, read the second, emit the second, emit the separator, emit the first), and it starts in the phase that reads the first component. Its internal state is an optional bit (the last bit popped), initially empty, and it runs the converter program. Input is read from the input stack, which holds bits, and output is written to the output stack.
def tm : FinTM2 where
K := Stk
k₀ := .inp
k₁ := .out
Γ := Γ
Λ := Lab
main := .readFst
σ := St
initialState := none
Γk₀Fin := (inferInstance : Fintype Bool)
m := prog
inductive Stk | inp | out | fst | snd
deriving DecidableEq
CSLibExt/Computability/Complexity/PairEncodingConverter.lean:86
@[reducible] def Γ : Stk → Type
| .out => Verifier.G
| _ => Bool
CSLibExt/Computability/Complexity/PairEncodingConverter.lean:94
inductive Lab | readFst | readSnd | emitSnd | sep | emitFst
deriving DecidableEq
CSLibExt/Computability/Complexity/PairEncodingConverter.lean:100
abbrev St := Option Bool
CSLibExt/Computability/Complexity/PairEncodingConverter.lean:108
def prog : Lab → TM2.Stmt Γ Lab St
| .readFst =>
.pop .inp (fun _ o => o) <| .branch (fun s => s == some true)
(.pop .inp (fun s _ => s) <| .pop .inp (fun s _ => s) <| .pop .inp (fun _ o => o) <|
.pop .inp (fun s _ => s) <| .pop .inp (fun s _ => s) <|
.push .fst (fun s => s.getD false) <| .goto fun _ => .readFst)
(.goto fun _ => .readSnd)
| .readSnd =>
.pop .inp (fun _ o => o) <| .branch (fun s => s == some true)
(.pop .inp (fun _ o => o) <| .pop .inp (fun s _ => s) <|
.push .snd (fun s => s.getD false) <| .goto fun _ => .readSnd)
(.goto fun _ => .emitSnd)
⋯
CSLibExt/Computability/Complexity/PairEncodingConverter.lean:111
Uses 5 · Used by 1
Configurations and runs
DefinitionStack contents of the pair-encoding converter#✓fully proved
For bit lists \(i\), \(a\), \(b\) and a list \(o\) of verifier symbols, the contents of the converter's four stacks with \(i\) on the input stack, \(o\) on the output stack, \(a\) on the first stash and \(b\) on the second stash.
def stk (i : List Bool) (o : List Verifier.G) (a b : List Bool) : ∀ k, List (Γ k)
| .inp => i
| .out => o
| .fst => a
| .snd => b
abbrev G := Bool ⊕ Option Bool
CSLibExt/Computability/Complexity/DenseSATVerifier.lean:67
@[reducible] def Γ : Stk → Type
| .out => Verifier.G
| _ => Bool
CSLibExt/Computability/Complexity/PairEncodingConverter.lean:94
AbbreviationRuns of the pair-encoding converter#✓fully proved
For \(n \in \mathbb{N}\) and configurations \(c\) and \(d\) of the converter, the statement that \(n\) steps of the converter program lead from \(c\) to \(d\).
abbrev Run (n : ℕ) (c d : TM2.Cfg Γ Lab St) : Prop := TM2Program.Run prog n c d
@[reducible] def Γ : Stk → Type
| .out => Verifier.G
| _ => Bool
CSLibExt/Computability/Complexity/PairEncodingConverter.lean:94
inductive Lab | readFst | readSnd | emitSnd | sep | emitFst
deriving DecidableEq
CSLibExt/Computability/Complexity/PairEncodingConverter.lean:100
abbrev St := Option Bool
CSLibExt/Computability/Complexity/PairEncodingConverter.lean:108
def Run (n : ℕ) (c d : TM2.Cfg Γ Λ σ) : Prop :=
(flip bind (TM2.step M))^[n] (some c) = some d
MathlibExt/Computability/TuringMachine/Program.lean:84
def prog : Lab → TM2.Stmt Γ Lab St
| .readFst =>
.pop .inp (fun _ o => o) <| .branch (fun s => s == some true)
(.pop .inp (fun s _ => s) <| .pop .inp (fun s _ => s) <| .pop .inp (fun _ o => o) <|
.pop .inp (fun s _ => s) <| .pop .inp (fun s _ => s) <|
.push .fst (fun s => s.getD false) <| .goto fun _ => .readFst)
(.goto fun _ => .readSnd)
| .readSnd =>
.pop .inp (fun _ o => o) <| .branch (fun s => s == some true)
(.pop .inp (fun _ o => o) <| .pop .inp (fun s _ => s) <|
.push .snd (fun s => s.getD false) <| .goto fun _ => .readSnd)
(.goto fun _ => .emitSnd)
⋯
CSLibExt/Computability/Complexity/PairEncodingConverter.lean:111
TheoremFull run of the pair-encoding converter#✓fully proved
For bit lists \(x\) and \(w\), the converter program goes in exactly \(2|x| + 2|w| + 5\) steps from the configuration at the label read first, with no bit in the state, the input stack holding every bit \(b\) of \(x\) in order as the six bits true, true, true, \(b\), true, false, then a single false, then every bit \(b\) of \(w\) in order as the three bits true, \(b\), false, and the other three stacks empty, to the halted configuration with no bit in the state, the verifier's pair encoding of \((x, w)\) on the output stack and the other three stacks empty.
theorem convert_run (x w : List Bool) :
Run (2 * x.length + 2 * w.length + 5)
⟨some .readFst, none, stk (encFst x ++ false :: encSnd w) [] [] []⟩
⟨none, none, stk [] (Verifier.pairEncode (x, w)) [] []⟩
abbrev Run (n : ℕ) (c d : TM2.Cfg Γ Lab St) : Prop := TM2Program.Run prog n c d
CSLibExt/Computability/Complexity/PairEncodingConverter.lean:169
def stk (i : List Bool) (o : List Verifier.G) (a b : List Bool) : ∀ k, List (Γ k)
| .inp => i
| .out => o
| .fst => a
| .snd => b
CSLibExt/Computability/Complexity/PairEncodingConverter.lean:149
def encFst (x : List Bool) : List Bool := x.flatMap fun b => [true, true, true, b, true, false]
CSLibExt/Computability/Complexity/PairEncodingConverter.lean:45
def encSnd (w : List Bool) : List Bool := w.flatMap fun b => [true, b, false]
CSLibExt/Computability/Complexity/PairEncodingConverter.lean:48
def pairEncode (p : List Bool × List Bool) : List G :=
p.1.map Sum.inl ++ Sum.inr none :: p.2.map fun b => Sum.inr (some b)
CSLibExt/Computability/Complexity/DenseSATVerifier.lean:71
Uses 13 · Used by 1
DefinitionPolynomial-time conversion to the verifier's pair encoding#✓fully proved
A polynomial-time computation of the identity map on pairs \((x, w)\) of bit lists, from the canonical bitstring encoding of \((x, w)\) to the verifier's pair encoding of \((x, w)\) (the bits of \(x\), the separator, then the bits of \(w\)), by the converter machine, with the bits and the verifier's symbols themselves as input and output alphabets and time bound \(n + 5\): started on the canonical encoding of \((x, w)\), a list of length \(n\), the converter halts within \(n + 5\) steps with no bit in its state, the verifier's pair encoding of \((x, w)\) on its output stack and every other stack empty.
Cslib.Complexity.DenseSAT.Converter.computable · 21 lines
noncomputable def computable :
TM2ComputableInPolyTime (BitstringEncoding.toEncoding (α := List Bool × List Bool)).encode
Verifier.pairEncode id where
tm := tm
inputAlphabet := Equiv.refl Bool
outputAlphabet := Equiv.refl Verifier.G
time := Polynomial.X + Polynomial.C 5
outputsFun := fun p => by
obtain ⟨x, w⟩ := p
unfold TM2OutputsInTime
refine { steps := 2 * x.length + 2 * w.length + 5, evals_in_steps := ?_, steps_le_m := ?_ }
· change (flip bind (TM2.step prog))^[_] (some (initList tm _)) =
Option.map (haltList tm) (some _)
rw [bitEncode_pair_eq]
erw [List.map_id, List.map_id, initList_tm, Option.map_some, haltList_tm]
exact convert_run x w
· rw [bitEncode_pair_eq]
simp only [encFst, encSnd, List.length_append, List.length_cons, List.length_flatMap,
Polynomial.eval_add, Polynomial.eval_X, Polynomial.eval_C]
simp only [List.map_const', List.sum_replicate, smul_eq_mul, List.length_nil]
omega
class BitstringEncoding α extends Computability.Encoding α Bool
MathlibExt/Computability/Complexity.lean:48
def pairEncode (p : List Bool × List Bool) : List G :=
p.1.map Sum.inl ++ Sum.inr none :: p.2.map fun b => Sum.inr (some b)
CSLibExt/Computability/Complexity/DenseSATVerifier.lean:71
def tm : FinTM2 where
K := Stk
k₀ := .inp
k₁ := .out
Γ := Γ
Λ := Lab
main := .readFst
σ := St
initialState := none
Γk₀Fin := (inferInstance : Fintype Bool)
m := prog
CSLibExt/Computability/Complexity/PairEncodingConverter.lean:134
abbrev G := Bool ⊕ Option Bool
CSLibExt/Computability/Complexity/DenseSATVerifier.lean:67
Uses 21 · Used by 4
Loading dependency explorer…
The dependency explorer needs JavaScript and its graph data.