~james/remy

remy/src/core/Model.thy -rw-r--r--5.2 KiB ViewLogBlameView rawPermalink edf26390ae — feat(allocator): retain intermediates in registers and spill nested values 12 days ago
1theory Model
2 imports "HOL-Library.Word" "HOL-Library.Code_Target_Numeral"
3begin
4
5unbundle bit_operations_syntax
6
7type_synonym pixel = "64 word"
8
9datatype input = X | Y | T
10
11datatype operator = Add | Sub | Mul | And | Or | Xor | Shl | Shr | Less
12
13fun operate :: "operator \<Rightarrow> pixel \<Rightarrow> pixel \<Rightarrow> pixel" where
14 "operate Add a b = a + b"
15| "operate Sub a b = a - b"
16| "operate Mul a b = a * b"
17| "operate And a b = a AND b"
18| "operate Or a b = a OR b"
19| "operate Xor a b = a XOR b"
20| "operate Shl a b = push_bit (unat b mod 64) a"
21| "operate Shr a b = drop_bit (unat b mod 64) a"
22| "operate Less a b = (if a < b then 1 else 0)"
23
24datatype expression = Literal pixel | Input input | Variable nat
25 | Binary operator expression expression
26 | Cond expression expression expression
27 | Let expression expression
28
29fun evaluate :: "expression \<Rightarrow> pixel list \<Rightarrow> (input \<Rightarrow> pixel) \<Rightarrow> pixel" where
30 "evaluate (Literal v) env inputs = v"
31| "evaluate (Input i) env inputs = inputs i"
32| "evaluate (Variable i) env inputs = env ! i"
33| "evaluate (Binary op a b) env inputs = operate op (evaluate a env inputs) (evaluate b env inputs)"
34| "evaluate (Cond c a b) env inputs = (if evaluate c env inputs = 0 then evaluate b env inputs else evaluate a env inputs)"
35| "evaluate (Let a b) env inputs = evaluate b (evaluate a env inputs # env) inputs"
36
37fun scoped :: "nat \<Rightarrow> expression \<Rightarrow> bool" where
38 "scoped n (Literal v) = True"
39| "scoped n (Input i) = True"
40| "scoped n (Variable i) = (i < n)"
41| "scoped n (Binary op a b) = (scoped n a \<and> scoped n b)"
42| "scoped n (Cond c a b) = (scoped n c \<and> scoped n a \<and> scoped n b)"
43| "scoped n (Let a b) = (scoped n a \<and> scoped (Suc n) b)"
44
45fun fold_binary :: "operator \<Rightarrow> expression \<Rightarrow> expression \<Rightarrow> expression" where
46 "fold_binary op (Literal a) (Literal b) = Literal (operate op a b)"
47| "fold_binary op a b = (if b = Literal 0 \<and> op \<in> {Add,Sub,Or,Xor,Shl,Shr} then a
48 else if a = Literal 0 \<and> op \<in> {Add,Or,Xor} then b
49 else if b = Literal 1 \<and> op = Mul then a
50 else if a = Literal 1 \<and> op = Mul then b
51 else if b = Literal (-1) \<and> op = And then a
52 else if a = Literal (-1) \<and> op = And then b
53 else if b = Literal 0 \<and> op \<in> {Mul,And} then Literal 0
54 else if a = Literal 0 \<and> op \<in> {Mul,And,Shl,Shr} then Literal 0
55 else if b = Literal (-1) \<and> op = Or then Literal (-1)
56 else if a = Literal (-1) \<and> op = Or then Literal (-1) else Binary op a b)"
57
58fun fold_cond :: "expression \<Rightarrow> expression \<Rightarrow> expression \<Rightarrow> expression" where
59 "fold_cond (Literal c) a b = (if c = 0 then b else a)"
60| "fold_cond c a b = (if a = b then a else Cond c a b)"
61
62fun optimise :: "expression \<Rightarrow> expression" where
63 "optimise (Binary op a b) = fold_binary op (optimise a) (optimise b)"
64| "optimise (Cond c a b) = fold_cond (optimise c) (optimise a) (optimise b)"
65| "optimise (Let a b) = Let (optimise a) (optimise b)"
66| "optimise e = e"
67
68lemma fold_binary_value:
69 "evaluate (fold_binary op a b) env inputs = operate op (evaluate a env inputs) (evaluate b env inputs)"
70 by (cases op; cases a; cases b) auto
71
72lemma fold_cond_value:
73 "evaluate (fold_cond c a b) env inputs = (if evaluate c env inputs = 0 then evaluate b env inputs else evaluate a env inputs)"
74 by (cases c) auto
75
76theorem optimise_correct:
77 "evaluate (optimise e) env inputs = evaluate e env inputs"
78 by (induction e arbitrary: env) (simp_all add: fold_binary_value fold_cond_value)
79
80lemma fold_binary_scoped:
81 "scoped n a \<Longrightarrow> scoped n b \<Longrightarrow> scoped n (fold_binary op a b)"
82 by (cases a; cases b) auto
83
84lemma fold_cond_scoped:
85 "scoped n c \<Longrightarrow> scoped n a \<Longrightarrow> scoped n b \<Longrightarrow> scoped n (fold_cond c a b)"
86 by (cases c) auto
87
88theorem optimise_scoped: "scoped n e \<Longrightarrow> scoped n (optimise e)"
89 by (induction e arbitrary: n) (auto intro: fold_binary_scoped fold_cond_scoped)
90
91fun nodes :: "expression \<Rightarrow> nat" where
92 "nodes (Binary op a b) = Suc (nodes a + nodes b)"
93| "nodes (Cond c a b) = Suc (nodes c + nodes a + nodes b)"
94| "nodes (Let a b) = Suc (nodes a + nodes b)"
95| "nodes _ = 1"
96
97lemma fold_binary_nodes: "nodes (fold_binary op a b) \<le> Suc (nodes a + nodes b)"
98 by (cases a; cases b) auto
99
100lemma fold_cond_nodes: "nodes (fold_cond c a b) \<le> Suc (nodes c + nodes a + nodes b)"
101 by (cases c) auto
102
103theorem optimise_size: "nodes (optimise e) \<le> nodes e"
104 by (induction e) (auto intro: order_trans[OF fold_binary_nodes] order_trans[OF fold_cond_nodes])
105
106lemma fold_binary_idempotent:
107 "optimise a = a \<Longrightarrow> optimise b = b \<Longrightarrow>
108 optimise (fold_binary op a b) = fold_binary op a b"
109 by (cases a; cases b) auto
110
111lemma fold_cond_idempotent:
112 "optimise c = c \<Longrightarrow> optimise a = a \<Longrightarrow> optimise b = b \<Longrightarrow>
113 optimise (fold_cond c a b) = fold_cond c a b"
114 by (cases c) auto
115
116theorem optimise_idempotent: "optimise (optimise e) = optimise e"
117 by (induction e) (auto intro: fold_binary_idempotent fold_cond_idempotent)
118
119theorem scoped_weaken: "scoped n e \<Longrightarrow> n \<le> m \<Longrightarrow> scoped m e"
120 by (induction e arbitrary: n m) auto
121
122end