Imports
Concrete verifier: certificate and unary-parser phases
namespace CLRS.Chapter34.Turing.GeneralCircuitVerifieropen Computability StateTransitionprivate abbrev transition := flip Option.bind stepCompose two exact verifier-machine segments.
theorem step_comp {A B C : Option machine.Cfg} (n₁ n₂ : Nat)
(h₁ : transition^[n₁] A = B) (h₂ : transition^[n₂] B = C) :
transition^[n₂ + n₁] A = C := by
rw [Function.iterate_add_apply, h₁, h₂]Compose one concrete step with a following exact phase.
theorem step_then {A : Option machine.Cfg} {B C : machine.Cfg} (n : Nat)
(h₁ : step B = some C) (h₂ : transition^[n] (some C) = A) :
transition^[n + 1] (some B) = A := by
rw [Function.iterate_add_apply]
change transition^[n] (step B) = A
rw [h₁]
exact h₂Scanning a certificate reverses its Boolean interpretation onto scratch, counts every symbol, and accumulates exactly the public legality check.
theorem scan_phase (state : State) (certificate : List CircuitSym)
(input : List (Option CircuitSym)) (output stored values scratch : List Bool)
(gateCount index saved : Nat) :
∃ finalState,
finalState.validAssignment =
(state.validAssignment && certificate.all isAssignmentSymbol) ∧
transition^[certificate.length + 1]
(some (cfg (some .scanCertificate) state
(List.map some certificate ++ none :: input)
output stored values scratch gateCount index saved)) =
some (cfg (some .reverseCertificate) finalState input output stored values
((certificate.map assignmentSymbolValue).reverse ++ scratch)
(gateCount + certificate.length) index saved) := by
induction certificate generalizing state scratch gateCount with
| nil =>
refine ⟨{ state with inputBuffer := some none }, ?_, ?_⟩
· simp
· change step (cfg (some .scanCertificate) state (none :: input)
output stored values scratch gateCount index saved) = _
exact scan_separator_step state input output stored values scratch
gateCount index saved
| cons symbol rest ih =>
let nextState : State :=
{ state with inputBuffer := some (some symbol), validAssignment :=
state.validAssignment && isAssignmentSymbol symbol }
rcases ih nextState (assignmentSymbolValue symbol :: scratch) (gateCount + 1) with
⟨finalState, hvalid, hrun⟩
refine ⟨finalState, ?_, ?_⟩
· simpa [nextState, Bool.and_assoc] using hvalid
· have hfirst := scan_symbol_step state symbol
(List.map some rest ++ none :: input) output stored values scratch
gateCount index saved
have hcomposed := step_then (rest.length + 1) hfirst hrun
simpa [nextState, List.reverse_cons, List.append_assoc, Nat.add_assoc,
Nat.add_left_comm, Nat.add_comm] using hcomposedReversing the scratch stack restores the certificate in source order.
theorem reverse_phase (state : State) (bits : List Bool)
(input : List (Option CircuitSym)) (output certificate values : List Bool)
(gateCount index saved : Nat) :
∃ finalState,
finalState.validAssignment = state.validAssignment ∧
transition^[bits.length + 1]
(some (cfg (some .reverseCertificate) state input output certificate values bits
gateCount index saved)) =
some (cfg (some .inputCount) finalState input output
(bits.reverse ++ certificate) values [] gateCount index saved) := by
induction bits generalizing state certificate with
| nil =>
refine ⟨{ state with boolBuffer := none }, rfl, ?_⟩
change step (cfg (some .reverseCertificate) state input output certificate values []
gateCount index saved) = _
exact reverse_empty_step state input output certificate values gateCount index saved
| cons bit rest ih =>
rcases ih { state with boolBuffer := some bit } (bit :: certificate) with
⟨finalState, hvalid, hrun⟩
refine ⟨finalState, by simpa using hvalid, ?_⟩
have hfirst := reverse_symbol_step state bit input output certificate values rest
gateCount index saved
have hcomposed := step_then (rest.length + 1) hfirst hrun
simpa [List.reverse_cons, List.append_assoc] using hcomposedLabel reached after a terminated unary index.
def parsedLabel : Return → Label
| .inputGate => .certificateLookup
| .outputGate => .checkTrailing
| ret => .gateSubtract rettheorem parse_nat_end_step (state : State) (ret : Return)
(input : List (Option CircuitSym)) (output certificate values scratch : List Bool)
(gateCount index saved : Nat) :
step (cfg (some (.parseNat ret)) state (some .endMark :: input)
output certificate values scratch gateCount index saved) =
some (cfg (some (parsedLabel ret))
{ state with inputBuffer := some (some .endMark) }
input output certificate values scratch gateCount index saved) := by
cases ret
· simpa [parsedLabel] using parse_nat_end_input_step state input output certificate
values scratch gateCount index saved
· exact parse_nat_end_gate_step state .notGate (by decide) (by decide)
input output certificate values scratch gateCount index saved
· exact parse_nat_end_gate_step state .andLeft (by decide) (by decide)
input output certificate values scratch gateCount index saved
· rename_i left
exact parse_nat_end_gate_step state (.andRight left) (by simp) (by simp)
input output certificate values scratch gateCount index saved
· exact parse_nat_end_gate_step state .orLeft (by decide) (by decide)
input output certificate values scratch gateCount index saved
· rename_i left
exact parse_nat_end_gate_step state (.orRight left) (by simp) (by simp)
input output certificate values scratch gateCount index saved
· simpa [parsedLabel] using parse_nat_end_output_step state input output certificate
values scratch gateCount index saved
The unary parser consumes encNat n, adds n to the index counter, and
reaches the continuation determined only by its finite return tag.
theorem parse_nat_phase (state : State) (ret : Return) (n offset : Nat)
(input : List (Option CircuitSym)) (output certificate values scratch : List Bool)
(gateCount saved : Nat) :
∃ finalState,
transition^[n + 1]
(some (cfg (some (.parseNat ret)) state
(List.map some (encNat n) ++ input)
output certificate values scratch gateCount offset saved)) =
some (cfg (some (parsedLabel ret)) finalState input output certificate values
scratch gateCount (offset + n) saved) := by
induction n generalizing state offset with
| zero =>
refine ⟨{ state with inputBuffer := some (some .endMark) }, ?_⟩
change step (cfg (some (.parseNat ret)) state (some .endMark :: input)
output certificate values scratch gateCount offset saved) = _
exact parse_nat_end_step state ret input output certificate values scratch
gateCount offset saved
| succ n ih =>
rcases ih { state with inputBuffer := some (some .argMark) } (offset + 1) with
⟨finalState, hrun⟩
refine ⟨finalState, ?_⟩
have hfirst := parse_nat_arg_step state ret
(List.map some (encNat n) ++ input) output certificate values scratch
gateCount offset saved
have hcomposed := step_then (n + 1) hfirst hrun
simpa [encNat, List.replicate_succ, Nat.add_assoc, Nat.add_left_comm,
Nat.add_comm] using hcomposedend CLRS.Chapter34.Turing.GeneralCircuitVerifier