theory Execution imports Isolation begin datatype action = Read nat nat | Write nat nat nat fun valid :: "nat \ nat \ action \ bool" where "valid slots bytes (Read k offset) = (k < slots \ offset < bytes)" | "valid slots bytes (Write k offset byte) = (k < slots \ offset < bytes \ byte < 256)" fun advance :: "pager \ action \ pager" where "advance s (Read k offset) = s" | "advance s (Write k offset byte) = store s k offset byte" fun reference :: "memory \ action \ memory" where "reference m (Read k offset) = m" | "reference m (Write k offset byte) = reference_write m k offset byte" fun observe :: "pager \ action \ nat" where "observe s (Read k offset) = view s k offset" | "observe s (Write k offset byte) = byte" fun reference_observe :: "memory \ action \ nat" where "reference_observe m (Read k offset) = m k offset" | "reference_observe m (Write k offset byte) = byte" fun execute :: "pager \ action list \ pager" where "execute s [] = s" | "execute s (a # actions) = execute (advance s a) actions" fun reference_execute :: "memory \ action list \ memory" where "reference_execute m [] = m" | "reference_execute m (a # actions) = reference_execute (reference m a) actions" fun observations :: "pager \ action list \ nat list" where "observations s [] = []" | "observations s (a # actions) = observe s a # observations (advance s a) actions" fun reference_observations :: "memory \ action list \ nat list" where "reference_observations m [] = []" | "reference_observations m (a # actions) = reference_observe m a # reference_observations (reference m a) actions" lemma advance_invariant: "invariant n s \ invariant n (advance s a)" by (cases a; simp add: write_invariant) lemma advance_simulation: "invariant n s \ represents n s m \ valid n bytes a \ represents n (advance s a) (reference m a)" by (cases a; auto intro: simulation) lemma observe_simulation: "represents n s m \ valid n bytes a \ observe s a = reference_observe m a" by (cases a; auto simp: represents_def) theorem execute_invariant: "invariant n s \ invariant n (execute s actions)" by (induction actions arbitrary: s) (auto intro: advance_invariant) theorem execute_refinement: assumes "invariant n s" "represents n s m" "list_all (valid n bytes) actions" shows "represents n (execute s actions) (reference_execute m actions)" using assms by (induction actions arbitrary: s m) (auto intro: advance_invariant advance_simulation) theorem observable_equivalence: assumes "invariant n s" "represents n s m" "list_all (valid n bytes) actions" shows "observations s actions = reference_observations m actions" using assms by (induction actions arbitrary: s m) (auto intro: advance_invariant advance_simulation observe_simulation) definition admitted :: "nat \ nat \ nat \ pager \ action \ bool" where "admitted slots bytes capacity s a \ valid slots bytes a \ (case a of Read k offset \ True | Write k offset byte \ writable s k \ frontier s < capacity)" definition checked :: "nat \ nat \ nat \ pager \ action \ pager option" where "checked slots bytes capacity s a = (if admitted slots bytes capacity s a then Some (advance s a) else None)" lemma checked_failure: "\ admitted slots bytes capacity s a \ checked slots bytes capacity s a = None" by (simp add: checked_def) lemma checked_success: "checked slots bytes capacity s a = Some t \ t = advance s a" by (auto simp: checked_def split: if_splits) theorem checked_invariant: "invariant slots s \ checked slots bytes capacity s a = Some t \ invariant slots t" using checked_success advance_invariant by blast theorem checked_capacity: "frontier s \ capacity \ checked slots bytes capacity s a = Some t \ frontier t \ capacity" by (cases a; auto simp: checked_def admitted_def prepare_frontier split: if_splits) theorem checked_simulation: "invariant slots s \ represents slots s m \ checked slots bytes capacity s a = Some t \ represents slots t (reference m a)" by (auto simp: checked_def admitted_def split: if_splits intro: advance_simulation) lemma invalid_slot_rejected: "slots \ k \ checked slots bytes capacity s (Write k offset byte) = None" by (simp add: checked_def admitted_def) lemma invalid_offset_rejected: "bytes \ offset \ checked slots bytes capacity s (Write k offset byte) = None" by (simp add: checked_def admitted_def) lemma invalid_byte_rejected: "256 \ byte \ checked slots bytes capacity s (Write k offset byte) = None" by (simp add: checked_def admitted_def) lemma exhausted_readonly_rejected: "\ writable s k \ capacity \ frontier s \ checked slots bytes capacity s (Write k offset byte) = None" by (simp add: checked_def admitted_def) lemma exhausted_writable_allowed: "writable s k \ valid slots bytes (Write k offset byte) \ checked slots bytes capacity s (Write k offset byte) = Some (store s k offset byte)" by (simp add: checked_def admitted_def) end