Files
LithosAnanake/proof/StarForth_Transition.thy
T

257 lines
12 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
theory StarForth_Transition
imports StarForth_Mutex
begin
(* =========================================================================
StarForth_Transition — Labeled Transition System
SPECIFICATION ROLE: ground truth for how ExecThread and HeartbeatThread
interact. C code must be written so that every execution of vm_tick()
satisfies heartbeat_exec_neutral and every word satisfies
word_physics_transparent.
EXPLICIT AXIOM INVENTORY (this theory) — 2 axioms total:
A1 ×1 heartbeat_exec_neutral (C audit: src/vm_time.c)
A4'×1 word_physics_transparent (definition audit: Level 1 word theories)
The former 8 field axioms are now PROVED from A1 via exec_equiv. The
physics substate (rolling_window, heartbeat rate, decay_slope_q48, …) is
intentionally unconstrained — the heartbeat is designed to evolve it
non-monotonically. exec_equiv makes that silence explicit and structural.
======================================================================== *)
(* =========================================================================
Section 1: Thread and action datatypes
======================================================================== *)
datatype thread = ExecThread | HeartbeatThread
datatype action =
ExecWord nat
| HeartTick
| AcquireTuning nat
| ReleaseTuning nat
| AcquireDict nat
| ReleaseDict nat
type_synonym event = "thread \<times> action"
(* =========================================================================
Section 2: Exec-equivalence — the quotient that separates exec from physics
Two vm_states are exec-equivalent when they agree on every field that word
execution depends on. Physics fields are ABSENT by design: the heartbeat
is an adaptive non-monotone controller of those fields, and no ordering or
preservation claim is made about them here.
exec_equiv is the congruence that collapses heartbeat_step to the identity
in the exec quotient vm_state/≃, and under which word execution is a
well-defined endomorphism.
======================================================================== *)
definition exec_equiv :: "vm_state \<Rightarrow> vm_state \<Rightarrow> bool" (infix "\<simeq>" 50) where
"s1 \<simeq> s2 \<longleftrightarrow>
data_stack s1 = data_stack s2 \<and>
return_stack s1 = return_stack s2 \<and>
memory s1 = memory s2 \<and>
word_table s1 = word_table s2"
lemma exec_equiv_refl [simp, intro]: "vm \<simeq> vm"
by (simp add: exec_equiv_def)
lemma exec_equiv_sym: "s1 \<simeq> s2 \<Longrightarrow> s2 \<simeq> s1"
by (simp add: exec_equiv_def)
lemma exec_equiv_trans: "s1 \<simeq> s2 \<Longrightarrow> s2 \<simeq> s3 \<Longrightarrow> s1 \<simeq> s3"
by (simp add: exec_equiv_def)
lemma exec_equiv_ds: "s1 \<simeq> s2 \<Longrightarrow> data_stack s1 = data_stack s2" by (simp add: exec_equiv_def)
lemma exec_equiv_rs: "s1 \<simeq> s2 \<Longrightarrow> return_stack s1 = return_stack s2" by (simp add: exec_equiv_def)
lemma exec_equiv_mem:"s1 \<simeq> s2 \<Longrightarrow> memory s1 = memory s2" by (simp add: exec_equiv_def)
lemma exec_equiv_wt: "s1 \<simeq> s2 \<Longrightarrow> word_table s1 = word_table s2" by (simp add: exec_equiv_def)
(* =========================================================================
Section 3: Heartbeat axiom — A1 ×1 (collapsed from ×8)
The heartbeat step is the IDENTITY in the exec quotient: heartbeat_step vm
and vm are exec-equivalent. This is the only claim the proof framework
makes about heartbeat_step relative to exec-visible state.
The physics substate (rolling_window, heartbeat rate, decay_slope_q48,
pipeline_metrics, last_inference, ssm_l8, tuning_lock, dict_lock, heat
thresholds, dictionary, vm_error, vm_halted, vm_mode) is not mentioned —
the heartbeat may evolve it freely, non-monotonically, as the adaptive
feedback loops require. That freedom is the design intent.
⚠ AUDIT OBLIGATION (src/vm_time.c):
Read every code path reachable from vm_tick() — including
vm_tick_window_tuner, vm_tick_slope_validator, and all
inference_engine.c callees — and verify that NONE of those paths write
to the following four fields:
data_stack (vm->data_stack / vm->ds_top)
return_stack (vm->return_stack / vm->rs_top)
memory (vm->memory[])
word_table (vm->word_table)
Those four fields are exactly exec_equiv. Everything else is free.
○ CODE-MUST-MATCH: if a future refactor moves any of those four fields into
the heartbeat's write set, exec_equiv must be updated and a new audit
performed before the axiom can be accepted.
======================================================================== *)
axiomatization heartbeat_step :: "vm_state \<Rightarrow> vm_state"
where
heartbeat_exec_neutral: "heartbeat_step vm \<simeq> vm"
(* =========================================================================
Section 4: Single-step field lemmas — PROVED from A1 (not axioms)
These carry [simp] so downstream proofs continue to work without change.
======================================================================== *)
lemma heartbeat_ds [simp]: "data_stack (heartbeat_step vm) = data_stack vm"
using heartbeat_exec_neutral by (simp add: exec_equiv_def)
lemma heartbeat_rs [simp]: "return_stack (heartbeat_step vm) = return_stack vm"
using heartbeat_exec_neutral by (simp add: exec_equiv_def)
lemma heartbeat_mem [simp]: "memory (heartbeat_step vm) = memory vm"
using heartbeat_exec_neutral by (simp add: exec_equiv_def)
lemma heartbeat_wt [simp]: "word_table (heartbeat_step vm) = word_table vm"
using heartbeat_exec_neutral by (simp add: exec_equiv_def)
(* =========================================================================
Section 5: n-fold heartbeat exec-neutrality and field preservation
======================================================================== *)
lemma heartbeat_n_exec_neutral: "heartbeat_step ^^ n $ vm \<simeq> vm"
proof (induction n)
case 0 show ?case by simp
next
case (Suc k)
show "heartbeat_step ^^ Suc k $ vm \<simeq> vm"
using exec_equiv_trans [OF heartbeat_exec_neutral Suc.IH] by simp
qed
lemma heartbeat_n_steps_ds [simp]: "data_stack (heartbeat_step ^^ n $ vm) = data_stack vm"
using heartbeat_n_exec_neutral by (simp add: exec_equiv_def)
lemma heartbeat_n_steps_rs [simp]: "return_stack (heartbeat_step ^^ n $ vm) = return_stack vm"
using heartbeat_n_exec_neutral by (simp add: exec_equiv_def)
lemma heartbeat_n_steps_mem [simp]: "memory (heartbeat_step ^^ n $ vm) = memory vm"
using heartbeat_n_exec_neutral by (simp add: exec_equiv_def)
lemma heartbeat_n_steps_wt [simp]: "word_table (heartbeat_step ^^ n $ vm) = word_table vm"
using heartbeat_n_exec_neutral by (simp add: exec_equiv_def)
(* =========================================================================
Section 6: Word physics transparency — A4' ×1 (congruence form)
Word execution is a well-defined endomorphism on the exec quotient: if two
states are exec-equivalent, executing any word on each produces identical
results. This is the congruence law that makes word sequences independent
of interleaved heartbeat ticks.
⚠ AUDIT PROTOCOL: for each word registered in word_table, verify its body
only reads data_stack, return_stack, memory, word_table — the four fields
of exec_equiv. These are exactly the fields a FORTH word may observe.
○ CODE-MUST-MATCH: no word in src/word_source/ may read rolling_window,
heartbeat, decay_slope_q48, pipeline_metrics, last_inference, ssm_l8,
tuning_lock, dict_lock, heat thresholds, or any other physics field.
======================================================================== *)
axiomatization where
word_physics_transparent:
"\<And> (s1 :: vm_state) (s2 :: vm_state) n.
s1 \<simeq> s2 \<Longrightarrow> word_table s1 n s1 = word_table s2 n s2"
(* =========================================================================
Section 7: Consequences — all proved from A1 + A4'
======================================================================== *)
lemma exec_after_heartbeat_eq:
"word_table (heartbeat_step vm) n (heartbeat_step vm) = word_table vm n vm"
by (rule word_physics_transparent [OF heartbeat_exec_neutral])
lemma exec_after_heartbeat_ds:
"data_stack (word_table (heartbeat_step vm) n (heartbeat_step vm))
= data_stack (word_table vm n vm)"
using exec_after_heartbeat_eq by simp
lemma exec_after_heartbeat_rs:
"return_stack (word_table (heartbeat_step vm) n (heartbeat_step vm))
= return_stack (word_table vm n vm)"
using exec_after_heartbeat_eq by simp
lemma exec_after_n_heartbeats_eq:
"word_table (heartbeat_step ^^ k $ vm) n (heartbeat_step ^^ k $ vm)
= word_table vm n vm"
by (rule word_physics_transparent [OF heartbeat_n_exec_neutral])
(* =========================================================================
Section 8: Single-step transition relation
======================================================================== *)
inductive vm_step :: "vm_state \<Rightarrow> event \<Rightarrow> vm_state \<Rightarrow> bool"
("_ \<rightarrow>[_] _" [60, 0, 61] 60)
where
StepExec:
"\<not> vm_error vm \<Longrightarrow> \<not> vm_halted vm \<Longrightarrow>
vm' = word_table vm n vm \<Longrightarrow>
vm \<rightarrow>[(ExecThread, ExecWord n)] vm'"
| StepHeartTick:
"\<not> vm_halted vm \<Longrightarrow>
vm' = heartbeat_step vm \<Longrightarrow>
vm \<rightarrow>[(HeartbeatThread, HeartTick)] vm'"
| StepAcqTuning:
"tuning_lock vm = LockFree \<Longrightarrow>
vm' = vm\<lparr>tuning_lock := LockHeld t\<rparr> \<Longrightarrow>
vm \<rightarrow>[(if t = EXEC_THREAD then ExecThread else HeartbeatThread, AcquireTuning t)] vm'"
| StepRelTuning:
"tuning_lock vm = LockHeld t \<Longrightarrow>
vm' = vm\<lparr>tuning_lock := LockFree\<rparr> \<Longrightarrow>
vm \<rightarrow>[(if t = EXEC_THREAD then ExecThread else HeartbeatThread, ReleaseTuning t)] vm'"
| StepAcqDict:
"dict_lock vm = LockFree \<Longrightarrow>
vm' = vm\<lparr>dict_lock := LockHeld t\<rparr> \<Longrightarrow>
vm \<rightarrow>[(if t = EXEC_THREAD then ExecThread else HeartbeatThread, AcquireDict t)] vm'"
| StepRelDict:
"dict_lock vm = LockHeld t \<Longrightarrow>
vm' = vm\<lparr>dict_lock := LockFree\<rparr> \<Longrightarrow>
vm \<rightarrow>[(if t = EXEC_THREAD then ExecThread else HeartbeatThread, ReleaseDict t)] vm'"
(* =========================================================================
Section 9: Traces and reachability
======================================================================== *)
type_synonym trace = "(vm_state \<times> event \<times> vm_state) list"
fun valid_trace :: "trace \<Rightarrow> bool" where
"valid_trace [] = True"
| "valid_trace [(s, e, s')] = (s \<rightarrow>[e] s')"
| "valid_trace ((s, e, s') # rest) =
(s \<rightarrow>[e] s' \<and>
(case rest of [] \<Rightarrow> True | (s0, _, _) # _ \<Rightarrow> s0 = s') \<and>
valid_trace rest)"
definition reachable :: "vm_state \<Rightarrow> vm_state \<Rightarrow> bool" where
"reachable s0 s' \<longleftrightarrow>
s0 = s' \<or>
(\<exists>tr. valid_trace tr \<and> tr \<noteq> [] \<and>
fst (hd tr) = s0 \<and>
snd (snd (last tr)) = s')"
definition exec_events :: "trace \<Rightarrow> (vm_state \<times> nat \<times> vm_state) list" where
"exec_events tr =
[(s, n, s'). (s, (ExecThread, ExecWord n), s') \<leftarrow> tr]"
end