-
Notifications
You must be signed in to change notification settings - Fork 9
/
CircuitProperties.v
308 lines (267 loc) · 8.71 KB
/
CircuitProperties.v
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
(*! Circuits | Lemmas used in the compiler-correctness proof !*)
Require Export Koika.CircuitGeneration Koika.CircuitOptimization.
Require Import Koika.Common Koika.Environments Koika.Types Koika.Lowering.
Section Bools.
Definition bool_le b1 b2 :=
b2 = false ->
b1 = false.
Lemma bool_le_impl b1 b2 :
bool_le b1 b2 <-> (orb (negb b1) b2) = true.
Proof.
destruct b1, b2; unfold bool_le; cbn; intuition.
Qed.
Lemma bool_le_and :
forall b1 b1' b2 b2',
bool_le b1 b1' ->
bool_le b2 b2' ->
bool_le (andb b1 b2) (andb b1' b2').
Proof.
unfold bool_le; intros.
destruct b1, b2, b1', b2'; cbn;
intuition discriminate.
Qed.
Lemma bool_le_and_l :
forall b1 b1' b2,
bool_le b1 b1' ->
bool_le (andb b1 b2) b1'.
Proof.
unfold bool_le; intros.
destruct b1, b2, b1'; cbn;
intuition discriminate.
Qed.
Lemma bool_le_or :
forall b1 b1' b2 b2',
bool_le b1 b1' ->
bool_le b2 b2' ->
bool_le (orb b1 b2) (orb b1' b2').
Proof.
unfold bool_le; intros.
destruct b1, b2, b1', b2'; cbn;
intuition discriminate.
Qed.
Lemma bool_le_mux :
forall (s: bool) b1 b1' b2 b2',
bool_le b1 b1' ->
bool_le b2 b2' ->
bool_le (if s then b1 else b2) (if s then b1' else b2').
Proof.
unfold bool_le; intros.
destruct s; cbn;
intuition discriminate.
Qed.
Lemma bool_le_not :
forall b1 b2,
bool_le b1 b2 ->
bool_le (negb b2) (negb b1).
Proof.
unfold bool_le; intros.
destruct b1, b2; cbn;
intuition discriminate.
Qed.
Lemma bool_le_true :
forall b, bool_le b true.
Proof.
unfold bool_le; intros;
destruct b; intuition discriminate.
Qed.
Lemma bool_le_false :
forall b, bool_le false b.
Proof.
unfold bool_le; intros;
destruct b; intuition discriminate.
Qed.
End Bools.
Section Circuits.
Context {pos_t var_t rule_name_t reg_t ext_fn_t: Type}.
Context {CR: reg_t -> nat}.
Context {CSigma: ext_fn_t -> CExternalSignature}.
Context {REnv: Env reg_t}.
Context (cr: REnv.(env_t) (fun idx => bits (CR idx))).
Context {Show_rule_name_t : Show rule_name_t}.
Context (csigma: forall f, CSig_denote (CSigma f)).
Context (lco: (@local_circuit_optimizer
rule_name_t reg_t ext_fn_t CR CSigma
(rwdata (rule_name_t := rule_name_t) CR CSigma)
csigma)).
Notation circuit := (circuit (rule_name_t := rule_name_t)
(rwdata := rwdata (rule_name_t := rule_name_t) CR CSigma)
CR CSigma).
Notation interp_circuit := (interp_circuit cr csigma).
Definition circuit_le (c1 c2: circuit 1) :=
bool_le (Bits.single (interp_circuit c1)) (Bits.single (interp_circuit c2)).
Lemma interp_circuit_circuit_le_helper_false :
forall c1 c2,
circuit_le c1 c2 ->
interp_circuit c2 = Ob~0 ->
interp_circuit c1 = Ob~0.
Proof.
unfold circuit_le; intros * Hlt Heq;
destruct (interp_circuit c1) as (? & [ ]), (interp_circuit c2) as (? & []).
inversion Heq; cbv; f_equal; apply Hlt; cbn; congruence.
Qed.
Lemma interp_circuit_circuit_le_helper_true :
forall c1 c2,
circuit_le c1 c2 ->
interp_circuit c1 = Ob~1 ->
interp_circuit c2 = Ob~1.
Proof.
unfold circuit_le; intros * Hlt Heq;
destruct (interp_circuit c1) as (? & [ ]), (interp_circuit c2) as ([ | ] & []);
inversion Heq; subst; cbv; f_equal; symmetry; apply Hlt; cbn; congruence.
Qed.
Lemma circuit_le_CAnnot :
forall s c1 c2,
circuit_le c1 c2 ->
circuit_le (CAnnot s c1) (CAnnot s c2).
Proof. firstorder. Qed.
Lemma circuit_le_CAnnot_l :
forall s c1 c2,
circuit_le c1 c2 ->
circuit_le (CAnnot s c1) c2.
Proof. firstorder. Qed.
Lemma circuit_le_CAnnot_r :
forall s c1 c2,
circuit_le c1 c2 ->
circuit_le c1 (CAnnot s c2).
Proof. firstorder. Qed.
Lemma circuit_le_CBundleRef :
forall rl1 rl2 rs1 rs2 b1 b2 field1 field2 c1 c2,
circuit_le c1 c2 ->
circuit_le (CBundleRef rl1 rs1 b1 field1 c1) (CBundleRef rl2 rs2 b2 field2 c2).
Proof. firstorder. Qed.
Lemma circuit_le_CBundleRef_l :
forall rl1 rs1 b1 field1 c1 c2,
circuit_le c1 c2 ->
circuit_le (CBundleRef rl1 rs1 b1 field1 c1) c2.
Proof. firstorder. Qed.
Lemma circuit_le_CBundleRef_r :
forall rl2 rs2 b2 field2 c1 c2,
circuit_le c1 c2 ->
circuit_le c1 (CBundleRef rl2 rs2 b2 field2 c2).
Proof. firstorder. Qed.
Lemma circuit_le_CAnd :
forall c1 c1' c2 c2',
circuit_le c1 c1' ->
circuit_le c2 c2' ->
circuit_le (CAnd c1 c2) (CAnd c1' c2').
Proof. unfold circuit_le; cbn; eauto using bool_le_and. Qed.
Lemma circuit_le_CAnd_l :
forall c1 c1' c2,
circuit_le c1 c1' ->
circuit_le (CAnd c1 c2) c1'.
Proof. unfold circuit_le; cbn; eauto using bool_le_and_l. Qed.
Lemma circuit_le_CAnd_r :
forall c1 c1' c2',
circuit_le c1 c1' ->
interp_circuit c2' = Ob~1 ->
circuit_le c1 (CAnd c1' c2').
Proof. unfold circuit_le; cbn. intros * ? ->.
cbn; rewrite Bool.andb_true_r; eauto. Qed.
Lemma circuit_le_COr :
forall c1 c1' c2 c2',
circuit_le c1 c1' ->
circuit_le c2 c2' ->
circuit_le (COr c1 c2) (COr c1' c2').
Proof. unfold circuit_le; cbn; eauto using bool_le_or. Qed.
Lemma circuit_le_CMux :
forall s c1 c1' c2 c2',
circuit_le c1 c1' ->
circuit_le c2 c2' ->
circuit_le (CMux s c1 c2) (CMux s c1' c2').
Proof.
unfold circuit_le; cbn;
intros; destruct (Bits.single (interp_circuit s)); eauto.
Qed.
Lemma circuit_le_CMux_l :
forall s c1 c2 c3,
(interp_circuit s = Ob~1 -> circuit_le c1 c3) ->
(interp_circuit s = Ob~0 -> circuit_le c2 c3) ->
circuit_le (CMux s c1 c2) c3.
Proof.
unfold circuit_le; cbn;
intros * Heq1 Heq2; destruct (interp_circuit s) as [ b [] ]; cbn.
destruct b; eauto.
Qed.
Lemma circuit_le_CMux_r :
forall s c1 c2 c3,
(interp_circuit s = Ob~1 -> circuit_le c1 c2) ->
(interp_circuit s = Ob~0 -> circuit_le c1 c3) ->
circuit_le c1 (CMux s c2 c3).
Proof.
unfold circuit_le; cbn;
intros * Heq1 Heq2; destruct (interp_circuit s) as [ b [] ]; cbn.
destruct b; eauto.
Qed.
Lemma circuit_le_CNot :
forall c1 c2,
circuit_le c1 c2 ->
circuit_le (CNot c2) (CNot c1).
Proof. unfold circuit_le; cbn; eauto using bool_le_not. Qed.
Lemma circuit_le_true :
forall c, circuit_le c (CConst Ob~1).
Proof. unfold circuit_le; cbn; eauto using bool_le_true. Qed.
Lemma circuit_le_false :
forall c, circuit_le (CConst Ob~0) c.
Proof. unfold circuit_le; cbn; eauto using bool_le_false. Qed.
Lemma circuit_le_fold_right {X} :
forall (xs: list X) f0 f1 c0 c1,
circuit_le c1 c0 ->
(forall x acc1 acc0, circuit_le acc1 acc0 -> circuit_le (f1 x acc1) (f0 x acc0)) ->
circuit_le (List.fold_right f1 c1 xs) (List.fold_right f0 c0 xs).
Proof.
induction xs; cbn; intros * Hlt Hxlt; eauto.
Qed.
Lemma circuit_le_refl :
forall c, circuit_le c c.
Proof. firstorder. Qed.
Lemma circuit_le_trans :
forall c1 c2 c3,
circuit_le c1 c2 ->
circuit_le c2 c3 ->
circuit_le c1 c3.
Proof. firstorder. Qed.
Lemma circuit_le_opt_l :
forall c1 c2,
circuit_le c1 c2 ->
circuit_le (lco.(lco_fn) c1) c2.
Proof.
unfold circuit_le; intros; rewrite lco.(lco_proof); assumption.
Qed.
Lemma circuit_le_opt_r :
forall c1 c2,
circuit_le c1 c2 ->
circuit_le c1 (lco.(lco_fn) c2).
Proof.
unfold circuit_le; intros; rewrite lco.(lco_proof); assumption.
Qed.
Lemma circuit_le_willFire_of_canFire_canFire :
forall rl_name c1 (cLog: scheduler_circuit (rule_name_t := rule_name_t) CR CSigma REnv) rws,
circuit_le (willFire_of_canFire lco rl_name {| canFire := c1; regs := rws |} cLog) c1.
Proof.
unfold willFire_of_canFire; intros.
eapply circuit_le_trans.
- eapply circuit_le_fold_right.
+ apply circuit_le_refl.
+ intros; rewrite !getenv_zip.
eapply circuit_le_opt_l, circuit_le_CAnd.
* eassumption.
* apply circuit_le_true.
- cbn.
induction finite_elements; cbn.
+ apply circuit_le_CAnnot_l, circuit_le_refl.
+ apply circuit_le_CAnd_l; eassumption.
Qed.
End Circuits.
Ltac circuit_le_f_equal :=
repeat (apply circuit_le_CAnnot_l ||
apply circuit_le_CAnnot_r ||
apply circuit_le_opt_l ||
apply circuit_le_opt_r ||
apply circuit_le_CBundleRef_l ||
apply circuit_le_CBundleRef_r ||
apply circuit_le_CAnd ||
apply circuit_le_COr ||
apply circuit_le_CNot ||
apply circuit_le_true ||
apply circuit_le_false ||
apply circuit_le_refl).