proof/: all 23 Isabelle theory files now verify under Isabelle2025-2
Isabelle toolchain replaced (was genuinely 2011, 14+ years stale) and every theory file fixed to actually compile -- most had apparently never been checked under a working Isabelle at all. Fixed the vm_state self-reference in StarForth_Base.thy properly (word_table is now a free-standing global constant, not a circular record field), corrected the word_physics_transparent axiom (was claiming full state equality from mere exec-equivalence, provably too strong), and worked through 14 years of HOL-Library drift plus several missing-hypothesis bugs across the physics-loop and ACL theories. Two genuine (non-tactical) bugs found and left oops-flagged rather than silently resolved: forth_roll's index arithmetic disagrees with both its own test lemma and the real C ROLL implementation (three-way inconsistency), and pm_wf isn't actually preserved by pm_record_hit/pm_record_miss. Both need a decision, not a proof-script fix. Full writeup in FABRIC-2.md item 5.2.
This commit is contained in:
@@ -23,28 +23,40 @@ begin
|
||||
Section 1: Pipeline accuracy
|
||||
======================================================================== *)
|
||||
|
||||
(* CORRECTED 2026-08-13: was "* Q48_SCALE" directly -- Q48_SCALE :: q48
|
||||
(64 word), this function is nat. Same fix as StarForth_Loop5_WinInf.thy's
|
||||
ANOVA_VARIANCE_THRESHOLD: unat Q48_SCALE converts to the equivalent nat. *)
|
||||
definition pm_accuracy_q48 :: "pipeline_metrics_state \<Rightarrow> nat" where
|
||||
"pm_accuracy_q48 pm =
|
||||
(if pm_prefetch_attempts pm = 0
|
||||
then 0
|
||||
else (pm_prefetch_hits pm * Q48_SCALE) div pm_prefetch_attempts pm)"
|
||||
else (pm_prefetch_hits pm * unat Q48_SCALE) div pm_prefetch_attempts pm)"
|
||||
|
||||
lemma pm_accuracy_zero_attempts [simp]:
|
||||
"pm_accuracy_q48 (pm\<lparr>pm_prefetch_attempts := 0\<rparr>) = 0"
|
||||
by (simp add: pm_accuracy_q48_def)
|
||||
|
||||
(* CORRECTED 2026-08-13: "\<le> Q48_ONE" was comparing nat to q48 (64 word) --
|
||||
a type error, could not have type-checked under any Isabelle version.
|
||||
Fixed via unat Q48_ONE, same pattern as pm_accuracy_q48_def above.
|
||||
Internal proof also fixed: Q48_SCALE needs unat for the same reason, and
|
||||
div_le_iff_le_mult doesn't exist under this name any more (same finding
|
||||
as StarForth_Q48_16.thy's q48_accuracy_upper_bound) -- replaced with the
|
||||
same div_le_mono-based argument used there. *)
|
||||
lemma pm_accuracy_upper_bound:
|
||||
assumes "pm_prefetch_hits pm \<le> pm_prefetch_attempts pm"
|
||||
shows "pm_accuracy_q48 pm \<le> Q48_ONE"
|
||||
shows "pm_accuracy_q48 pm \<le> unat Q48_ONE"
|
||||
proof (cases "pm_prefetch_attempts pm = 0")
|
||||
case True thus ?thesis by (simp add: pm_accuracy_q48_def Q48_ONE_def)
|
||||
next
|
||||
case False
|
||||
have "pm_prefetch_hits pm * Q48_SCALE \<le> pm_prefetch_attempts pm * Q48_SCALE"
|
||||
using assms by (simp add: mult_le_mono1)
|
||||
hence "(pm_prefetch_hits pm * Q48_SCALE) div pm_prefetch_attempts pm \<le> Q48_SCALE"
|
||||
using False by (simp add: div_le_iff_le_mult)
|
||||
thus ?thesis by (simp add: pm_accuracy_q48_def Q48_ONE_def False)
|
||||
have "(pm_prefetch_hits pm * unat Q48_SCALE) div pm_prefetch_attempts pm
|
||||
\<le> (pm_prefetch_attempts pm * unat Q48_SCALE) div pm_prefetch_attempts pm"
|
||||
using assms by (intro div_le_mono mult_le_mono1)
|
||||
also have "\<dots> = unat Q48_SCALE"
|
||||
using False by simp
|
||||
finally show ?thesis
|
||||
by (simp add: pm_accuracy_q48_def Q48_ONE_def False)
|
||||
qed
|
||||
|
||||
lemma pm_accuracy_non_negative:
|
||||
@@ -65,8 +77,12 @@ definition pm_wf :: "pipeline_metrics_state \<Rightarrow> bool" where
|
||||
|
||||
lemma pm_wf_accuracy_range:
|
||||
assumes "pm_wf pm"
|
||||
shows "pm_accuracy_q48 pm \<le> Q48_ONE"
|
||||
using assms by (simp add: pm_accuracy_upper_bound pm_wf_def)
|
||||
shows "pm_accuracy_q48 pm \<le> unat Q48_ONE"
|
||||
proof -
|
||||
have "pm_prefetch_hits pm \<le> pm_prefetch_attempts pm"
|
||||
using assms by (simp add: pm_wf_def)
|
||||
thus ?thesis by (rule pm_accuracy_upper_bound)
|
||||
qed
|
||||
|
||||
(* =========================================================================
|
||||
Section 3: Recording a prefetch hit or miss
|
||||
@@ -97,15 +113,26 @@ lemma pm_record_miss_hits_unchanged:
|
||||
"pm_prefetch_hits (pm_record_miss pm) = pm_prefetch_hits pm"
|
||||
by (simp add: pm_record_miss_def)
|
||||
|
||||
(* FLAGGED, NOT FIXED 2026-08-13: pm_wf is not actually closed under
|
||||
pm_record_hit/pm_record_miss as currently defined. pm_wf only requires
|
||||
"pm_last_accuracy_den pm > 0" when pm_prefetch_attempts pm > 0 -- when
|
||||
attempts = 0, den is completely unconstrained (could be 0). Both
|
||||
pm_record_hit and pm_record_miss increment attempts from 0 to 1 without
|
||||
touching pm_last_accuracy_den, so pm_wf's postcondition needs den > 0
|
||||
in a state where nothing in the precondition ever guaranteed it. Not a
|
||||
proof-script issue -- a genuine gap in what pm_wf requires versus what
|
||||
these two operations can establish. Left failing rather than silently
|
||||
strengthening pm_wf's own definition (a design decision, not a
|
||||
mechanical fix) or weakening these lemmas' claim. *)
|
||||
lemma pm_record_hit_preserves_wf:
|
||||
assumes "pm_wf pm"
|
||||
shows "pm_wf (pm_record_hit pm)"
|
||||
using assms by (simp add: pm_wf_def pm_record_hit_def)
|
||||
oops
|
||||
|
||||
lemma pm_record_miss_preserves_wf:
|
||||
assumes "pm_wf pm"
|
||||
shows "pm_wf (pm_record_miss pm)"
|
||||
using assms by (simp add: pm_wf_def pm_record_miss_def)
|
||||
oops
|
||||
|
||||
(* After a hit, hits ≤ attempts still holds. *)
|
||||
lemma pm_record_hit_hits_le_attempts:
|
||||
|
||||
Reference in New Issue
Block a user