~james/split

feat(model): formalise writable frame exclusivity

commit
8607a1f0203849a9b6c9c17c2abccc1ea56220fd browse tree
author
james <j@cpl0.zip>
signature
Verified ~james signed with a key registered by ~james
date
2026-05-04 18:14 UTC

3 files changed, +165 −0

.gitignore added

@@ -0,0 +1,3 @@
1+/build/
2+
3+/staging.txt

Model.thy added

@@ -0,0 +1,158 @@
1+theory Model
2+ imports Main
3+begin
4+
5+type_synonym page = "nat \<Rightarrow> nat"
6+type_synonym memory = "nat \<Rightarrow> page"
7+
8+record pager =
9+ ptable :: "nat \<Rightarrow> nat"
10+ physical :: memory
11+ writable :: "nat \<Rightarrow> bool"
12+ frontier :: nat
13+
14+definition view :: "pager \<Rightarrow> memory" where
15+ "view s k = physical s (ptable s k)"
16+
17+definition bounded :: "nat \<Rightarrow> pager \<Rightarrow> bool" where
18+ "bounded n s \<longleftrightarrow> (\<forall>k<n. ptable s k < frontier s)"
19+
20+definition exclusive :: "nat \<Rightarrow> pager \<Rightarrow> bool" where
21+ "exclusive n s \<longleftrightarrow>
22+ (\<forall>k<n. writable s k \<longrightarrow> (\<forall>j<n. ptable s j = ptable s k \<longrightarrow> j = k))"
23+
24+definition invariant :: "nat \<Rightarrow> pager \<Rightarrow> bool" where
25+ "invariant n s \<longleftrightarrow> bounded n s \<and> exclusive n s"
26+
27+definition initial :: "nat \<Rightarrow> memory \<Rightarrow> pager" where
28+ "initial pages contents =
29+ \<lparr>ptable = (\<lambda>k. k mod pages), physical = contents,
30+ writable = (\<lambda>_. False), frontier = pages\<rparr>"
31+
32+definition detach :: "pager \<Rightarrow> nat \<Rightarrow> pager" where
33+ "detach s k = s\<lparr>ptable := (ptable s)(k := frontier s),
34+ physical := (physical s)(frontier s := view s k),
35+ writable := (writable s)(k := True), frontier := Suc (frontier s)\<rparr>"
36+
37+definition prepare :: "pager \<Rightarrow> nat \<Rightarrow> pager" where
38+ "prepare s k = (if writable s k then s else detach s k)"
39+
40+definition store :: "pager \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> pager" where
41+ "store s k offset byte = (let t = prepare s k in
42+ t\<lparr>physical := (physical t)(ptable t k := (view t k)(offset := byte))\<rparr>)"
43+
44+lemma initial_ptable [simp]: "ptable (initial pages contents) k = k mod pages"
45+ by (simp add: initial_def)
46+
47+lemma initial_physical [simp]: "physical (initial pages contents) = contents"
48+ by (simp add: initial_def)
49+
50+lemma initial_writable [simp]: "\<not> writable (initial pages contents) k"
51+ by (simp add: initial_def)
52+
53+lemma initial_frontier [simp]: "frontier (initial pages contents) = pages"
54+ by (simp add: initial_def)
55+
56+lemma initial_view [simp]: "view (initial pages contents) k = contents (k mod pages)"
57+ by (simp add: view_def)
58+
59+lemma initial_bounded:
60+ "0 < pages \<Longrightarrow> bounded n (initial pages contents)"
61+ by (simp add: bounded_def)
62+
63+lemma initial_exclusive: "exclusive n (initial pages contents)"
64+ by (simp add: exclusive_def)
65+
66+theorem initial_invariant:
67+ "0 < pages \<Longrightarrow> invariant n (initial pages contents)"
68+ by (simp add: invariant_def initial_bounded initial_exclusive)
69+
70+lemma bounded_frame:
71+ "bounded n s \<Longrightarrow> k < n \<Longrightarrow> ptable s k < frontier s"
72+ by (simp add: bounded_def)
73+
74+lemma fresh_frame:
75+ "bounded n s \<Longrightarrow> k < n \<Longrightarrow> ptable s k \<noteq> frontier s"
76+ using bounded_frame by fastforce
77+
78+lemma writable_unique:
79+ "exclusive n s \<Longrightarrow> k < n \<Longrightarrow> j < n \<Longrightarrow>
80+ writable s k \<Longrightarrow> ptable s j = ptable s k \<Longrightarrow> j = k"
81+ by (auto simp: exclusive_def)
82+
83+lemma detach_ptable [simp]:
84+ "ptable (detach s k) j = (if j = k then frontier s else ptable s j)"
85+ by (simp add: detach_def)
86+
87+lemma detach_writable [simp]:
88+ "writable (detach s k) j = (j = k \<or> writable s j)"
89+ by (simp add: detach_def)
90+
91+lemma detach_frontier [simp]: "frontier (detach s k) = Suc (frontier s)"
92+ by (simp add: detach_def)
93+
94+lemma detach_copy [simp]: "physical (detach s k) (frontier s) = view s k"
95+ by (simp add: detach_def)
96+
97+lemma detach_other_frame:
98+ "f \<noteq> frontier s \<Longrightarrow> physical (detach s k) f = physical s f"
99+ by (simp add: detach_def)
100+
101+lemma detach_target_view [simp]: "view (detach s k) k = view s k"
102+ by (simp add: view_def detach_def)
103+
104+lemma detach_view:
105+ assumes "bounded n s" "j < n"
106+ shows "view (detach s k) j = view s j"
107+ using fresh_frame[OF assms] by (auto simp: view_def detach_def)
108+
109+lemma detach_bounded:
110+ "bounded n s \<Longrightarrow> bounded n (detach s k)"
111+ by (auto simp: bounded_def less_Suc_eq_le)
112+
113+lemma detach_exclusive:
114+ assumes "bounded n s" "exclusive n s"
115+ shows "exclusive n (detach s k)"
116+ using assms by (auto simp: exclusive_def bounded_def split: if_splits)
117+
118+theorem detach_invariant:
119+ "invariant n s \<Longrightarrow> invariant n (detach s k)"
120+ by (simp add: invariant_def detach_bounded detach_exclusive)
121+
122+lemma prepare_writable [simp]: "writable (prepare s k) k"
123+ by (simp add: prepare_def)
124+
125+lemma prepare_invariant:
126+ "invariant n s \<Longrightarrow> invariant n (prepare s k)"
127+ by (simp add: prepare_def detach_invariant)
128+
129+lemma prepare_view:
130+ "bounded n s \<Longrightarrow> j < n \<Longrightarrow> view (prepare s k) j = view s j"
131+ by (simp add: prepare_def detach_view)
132+
133+lemma prepare_frontier:
134+ "frontier (prepare s k) = frontier s + (if writable s k then 0 else 1)"
135+ by (simp add: prepare_def)
136+
137+lemma prepare_ptable_other:
138+ "j \<noteq> k \<Longrightarrow> ptable (prepare s k) j = ptable s j"
139+ by (simp add: prepare_def)
140+
141+lemma prepare_idempotent [simp]: "prepare (prepare s k) k = prepare s k"
142+ by (simp add: prepare_def detach_def)
143+
144+lemma write_ptable [simp]: "ptable (store s k offset byte) = ptable (prepare s k)"
145+ by (simp add: store_def Let_def)
146+
147+lemma write_writable [simp]: "writable (store s k offset byte) = writable (prepare s k)"
148+ by (simp add: store_def Let_def)
149+
150+lemma write_frontier [simp]: "frontier (store s k offset byte) = frontier (prepare s k)"
151+ by (simp add: store_def Let_def)
152+
153+theorem write_invariant:
154+ "invariant n s \<Longrightarrow> invariant n (store s k offset byte)"
155+ using prepare_invariant[of n s k]
156+ by (simp add: invariant_def bounded_def exclusive_def)
157+
158+end

ROOT added

@@ -0,0 +1,4 @@
1+session Split = HOL +
2+ options [document = false]
3+ theories
4+ Model