~james/remy

1
0c936dff3ac8cddb8c0c8a477151e4a03d4c40b6
main
remy/src/Model.thy -rw-r--r--5.0 KiB ViewLogBlameView rawPermalink 0c936dff3a perf(optimiser): fold neutral arithmetic and bitwise operations 2 months 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 else Binary op a b)"
53
54fun fold_cond :: "expression \<Rightarrow> expression \<Rightarrow> expression \<Rightarrow> expression" where
55 "fold_cond (Literal c) a b = (if c = 0 then b else a)"
56| "fold_cond c a b = Cond c a b"
57
58fun optimise :: "expression \<Rightarrow> expression" where
59 "optimise (Binary op a b) = fold_binary op (optimise a) (optimise b)"
60| "optimise (Cond c a b) = fold_cond (optimise c) (optimise a) (optimise b)"
61| "optimise (Let a b) = Let (optimise a) (optimise b)"
62| "optimise e = e"
63
64lemma fold_binary_value:
65 "evaluate (fold_binary op a b) env inputs = operate op (evaluate a env inputs) (evaluate b env inputs)"
66 by (cases op; cases a; cases b) auto
67
68lemma fold_cond_value:
69 "evaluate (fold_cond c a b) env inputs = (if evaluate c env inputs = 0 then evaluate b env inputs else evaluate a env inputs)"
70 by (cases c) auto
71
72theorem optimise_correct:
73 "evaluate (optimise e) env inputs = evaluate e env inputs"
74 by (induction e arbitrary: env) (simp_all add: fold_binary_value fold_cond_value)
75
76lemma fold_binary_scoped:
77 "scoped n a \<Longrightarrow> scoped n b \<Longrightarrow> scoped n (fold_binary op a b)"
78 by (cases a; cases b) auto
79
80lemma fold_cond_scoped:
81 "scoped n c \<Longrightarrow> scoped n a \<Longrightarrow> scoped n b \<Longrightarrow> scoped n (fold_cond c a b)"
82 by (cases c) auto
83
84theorem optimise_scoped: "scoped n e \<Longrightarrow> scoped n (optimise e)"
85 by (induction e arbitrary: n) (auto intro: fold_binary_scoped fold_cond_scoped)
86
87fun nodes :: "expression \<Rightarrow> nat" where
88 "nodes (Binary op a b) = Suc (nodes a + nodes b)"
89| "nodes (Cond c a b) = Suc (nodes c + nodes a + nodes b)"
90| "nodes (Let a b) = Suc (nodes a + nodes b)"
91| "nodes _ = 1"
92
93lemma fold_binary_nodes: "nodes (fold_binary op a b) \<le> Suc (nodes a + nodes b)"
94 by (cases a; cases b) auto
95
96lemma fold_cond_nodes: "nodes (fold_cond c a b) \<le> Suc (nodes c + nodes a + nodes b)"
97 by (cases c) auto
98
99theorem optimise_size: "nodes (optimise e) \<le> nodes e"
100 by (induction e) (auto intro: order_trans[OF fold_binary_nodes] order_trans[OF fold_cond_nodes])
101
102lemma fold_binary_idempotent:
103 "optimise a = a \<Longrightarrow> optimise b = b \<Longrightarrow>
104 optimise (fold_binary op a b) = fold_binary op a b"
105 by (cases a; cases b) auto
106
107lemma fold_cond_idempotent:
108 "optimise c = c \<Longrightarrow> optimise a = a \<Longrightarrow> optimise b = b \<Longrightarrow>
109 optimise (fold_cond c a b) = fold_cond c a b"
110 by (cases c) auto
111
112theorem optimise_idempotent: "optimise (optimise e) = optimise e"
113 by (induction e) (auto intro: fold_binary_idempotent fold_cond_idempotent)
114
115theorem scoped_weaken: "scoped n e \<Longrightarrow> n \<le> m \<Longrightarrow> scoped m e"
116 by (induction e arbitrary: n m) auto
117
118end