theory Machine imports Encoding begin fun machine_advance :: "operation \ nat \ nat \ (nat \ nat) option" where "machine_advance Idle pc a = Some (Suc pc, a)" | "machine_advance Raise pc a = Some (Suc pc, Suc a)" | "machine_advance Lower pc a = Some (Suc pc, a - 1)" | "machine_advance Finish pc a = None" | "machine_advance (Branch c wide d) pc a = (let next = pc + (if wide then 3 else 2) in if c \ a \ 0 then Some (next, a) else if 0 \ int next + d then Some (nat (int next + d), a) else None)" definition machine_step :: "nat list \ nat \ nat \ (nat \ nat) option" where "machine_step code s = (case map_option fst (decode (drop (fst s) code)) of None \ None | Some op \ machine_advance op (fst s) (snd s))" definition relocate :: "nat instruction list \ nat set \ nat \ nat \ nat \ nat" where "relocate p W s = (address p W (fst s), snd s)" lemma lower_advance: assumes "i < length p" shows "machine_advance (lower p W i (p ! i)) (address p W i) a = map_option (relocate p W) (advance (p ! i) i a)" using assms unfolding relocate_def by (cases "p ! i") (auto simp: displacement_def destination_def width_def branches_def Let_def of_nat_add) lemma source_closed: "wellformed p \ i \ length p \ source_step p (i,a) = Some (j,b) \ j \ length p" unfolding wellformed_def source_step_def branches_def destination_def by (cases "p ! i") (auto split: if_splits) theorem step_correspondence: assumes "valid p W" "i \ length p" shows "machine_step (bytecode p W) (relocate p W (i,a)) = map_option (relocate p W) (source_step p (i,a))" proof (cases "i < length p") case True show ?thesis using fetch_instruction[OF assms(1) True] lower_advance[OF True, of W a] True by (auto simp: machine_step_def source_step_def relocate_def split: option.splits prod.splits) next case False with assms have "i = length p" by simp then show ?thesis by (simp add: machine_step_def source_step_def relocate_def bytecode_length[symmetric]) qed theorem execution_correspondence: assumes "wellformed p" "valid p W" "i \ length p" shows "execute (machine_step (bytecode p W)) fuel (relocate p W (i,a)) = relocate p W (execute (source_step p) fuel (i,a))" using assms(3) proof (induction fuel arbitrary: i a) case 0 then show ?case by simp next case (Suc fuel) show ?case using Suc.IH source_closed[OF assms(1) Suc.prems] step_correspondence[OF assms(2) Suc.prems, of a] by (cases "source_step p (i,a)") (auto split: prod.splits) qed definition assemble :: "nat instruction list \ nat list option" where "assemble p = (if wellformed p \ valid p (layout p) then Some (bytecode p (layout p)) else None)" theorem assembly_complete: "assemble p \ None \ wellformed p \ (\W. valid p W)" by (simp add: assemble_def layout_complete) theorem assembly_minimum: "assemble p = Some code \ valid p V \ length code \ address p V (length p)" using layout_minimum[of p V] by (auto simp: assemble_def bytecode_length split: if_splits) theorem assembly_execution: assumes "assemble p = Some code" shows "execute (machine_step code) fuel (0,a) = relocate p (layout p) (execute (source_step p) fuel (0,a))" using assms execution_correspondence[of p "layout p" 0 fuel a] by (auto simp: assemble_def relocate_def split: if_splits) end