~james/remy

ref: 175b8b22df89336d3a03eb1209d760f6f426315b remy/src/Checker.thy -rw-r--r-- 2.3 KiB
175b8b22 — james test(compiler): exhaustively compare optimised small expressions 11 days ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
theory Checker
  imports Encoding
begin

fun effect :: "opcode \<Rightarrow> nat \<Rightarrow> nat option" where
  "effect (Push r) n = Some (Suc n)"
| "effect (Pop r) n = (if n = 0 then None else Some (n - 1))"
| "effect (Peek i) n = (if i < n then Some n else None)"
| "effect _ n = Some n"

fun audit :: "opcode list \<Rightarrow> nat \<Rightarrow> nat option" where
  "audit [] n = Some n"
| "audit (op # code) n = (if writes op \<subseteq> {Rax,Rcx,Rbx} then
    Option.bind (effect op n) (\<lambda>m. if m \<le> 512 then audit code m else None) else None)"

lemma effect_sound:
  "effect op (length (stack s)) = Some n \<Longrightarrow>
    \<exists>t. transition op s = Some t \<and> length (stack t) = n"
  by (cases op; cases "stack s") (auto split: if_splits)

theorem audit_sound:
  "audit code (length (stack s)) = Some n \<Longrightarrow>
    \<exists>t. run code s = Some t \<and> length (stack t) = n"
proof (induction code arbitrary: s)
  case Nil
  then show ?case by simp
next
  case (Cons op code)
  then show ?case
    by (auto dest!: effect_sound split: if_splits bind_splits; fastforce)
qed

lemma audit_scratch:
  "audit code n = Some m \<Longrightarrow> list_all (\<lambda>op. writes op \<subseteq> {Rax,Rcx,Rbx}) code"
  by (induction code arbitrary: n) (auto split: if_splits bind_splits)

theorem audit_inputs:
  "audit code n = Some m \<Longrightarrow> run code s = Some t \<Longrightarrow> inputs t = inputs s"
proof -
  assume audited: "audit code n = Some m" and ran: "run code s = Some t"
  have scratch: "list_all (\<lambda>op. writes op \<subseteq> {Rax,Rcx,Rbx}) code"
    using audit_scratch[OF audited] .
  show ?thesis
  proof (rule ext)
    fix i
    have keep: "list_all (\<lambda>op. input_register i \<notin> writes op) code"
      unfolding list_all_iff
    proof (rule ballI)
      fix op
      assume member: "op \<in> set code"
      have bound: "writes op \<subseteq> {Rax,Rcx,Rbx}"
        using scratch member by (auto simp: list_all_iff)
      show "input_register i \<notin> writes op"
      proof
        assume written: "input_register i \<in> writes op"
        have "input_register i \<in> {Rax,Rcx,Rbx}"
          using subsetD[OF bound written] .
        then show False by simp
      qed
    qed
    show "inputs t i = inputs s i"
      unfolding inputs_def using run_preserves[OF ran keep] .
  qed
qed

end