1 (**************************************************************************)
4 (* ||A|| A project by Andrea Asperti *)
6 (* ||I|| Developers: *)
7 (* ||T|| The HELM team. *)
8 (* ||A|| http://helm.cs.unibo.it *)
10 (* \ / This file is distributed under the terms of the *)
11 (* v GNU General Public License Version 2 *)
13 (**************************************************************************)
15 set "baseuri" "cic:/matita/assembly/test/".
17 include "assembly/vm.ma".
19 definition mult_source : list byte ≝
20 [#LDAi; 〈x0, x0〉; (* A := 0 *)
21 #STAd; 〈x2, x0〉; (* Z := A *)
22 #LDAd; 〈x1, xF〉; (* (l1) A := Y *)
23 #BEQ; 〈x0, xA〉; (* if A == 0 then goto l2 *)
24 #LDAd; 〈x2, x0〉; (* A := Z *)
25 #DECd; 〈x1, xF〉; (* Y := Y - 1 *)
26 #ADDd; 〈x1, xE〉; (* A += X *)
27 #STAd; 〈x2, x0〉; (* Z := A *)
28 #BRA; 〈xF, x2〉; (* goto l1 *)
29 #LDAd; 〈x2, x0〉].(* (l2) *)
31 definition mult_memory ≝
34 [ true ⇒ nth ? mult_source 〈x0, x0〉 a
42 definition mult_status ≝
44 mk_status 〈x0, x0〉 0 0 false false (mult_memory x y) 0.
46 notation " 'M' \sub (x y)" non associative with precedence 80 for
49 interpretation "mult_memory" 'memory x y =
50 (cic:/matita/assembly/test/mult_memory.con x y).
52 notation " 'M' \sub (x y) \nbsp a" non associative with precedence 80 for
53 @{ 'memory4 $x $y $a }.
55 interpretation "mult_memory4" 'memory4 x y a =
56 (cic:/matita/assembly/test/mult_memory.con x y a).
58 notation " \Sigma \sub (x y)" non associative with precedence 80 for
61 interpretation "mult_status" 'status x y =
62 (cic:/matita/assembly/test/mult_status.con x y).
66 let s ≝ execute (mult_status 〈x0, x0〉 〈x0, x0〉) i in
67 pc s = 20 ∧ mem s 32 = byte_of_nat 0.
77 let i ≝ 14 + 23 * nat_of_byte y in
78 let s ≝ execute (mult_status x y) i in
79 pc s = 20 ∧ mem s 32 = plusbytenc x x.
89 let i ≝ 14 + 23 * nat_of_byte y in
90 let s ≝ execute (mult_status x y) i in
91 pc s = 20 ∧ mem s 32 = x.
95 | change in ⊢ (? ? % ?) with (plusbytenc 〈x0, x0〉 x);
96 rewrite > plusbytenc_O_x;
105 let i ≝ 14 + 23 * nat_of_byte y in
106 let s ≝ execute (mult_status x y) i in
107 pc s = 20 ∧ mem s 32 = plusbytenc x x.
111 | change in ⊢ (? ? % ?) with
112 (plusbytenc (plusbytenc 〈x0, x0〉 x) x);
113 rewrite > plusbytenc_O_x;
119 lemma loop_invariant':
120 ∀x,y:byte.∀j:nat. j ≤ y →
121 execute (mult_status x y) (5 + 23*j)
123 mk_status (byte_of_nat (x * j)) 4 0 (eqbyte 〈x0, x0〉 (byte_of_nat (x*j)))
124 (plusbytec (byte_of_nat (x*pred j)) x)
125 (update (update (update (mult_memory x y) 30 x) 31 (byte_of_nat (y - j))) 32
126 (byte_of_nat (x * j)))
130 [ do 2 (rewrite < times_n_O);
132 [1,2,3,4,7: normalize; reflexivity
133 | rewrite > eq_plusbytec_x0_x0_x_false;
138 normalize in ⊢ (? ? (? (? ? %) ?) ?);
139 change in ⊢ (? ? % ?) with (update (mult_memory x y) 32 〈x0, x0〉 a);
140 change in ⊢ (? ? ? %) with (update (update (update (mult_memory x y) 30 x) 31
141 (byte_of_nat y)) 32 (byte_of_nat 0) a);
142 change in ⊢ (? ? ? (? (? (? ? ? %) ? ?) ? ? ?)) with (mult_memory x y 30);
143 rewrite > byte_of_nat_nat_of_byte;
144 change in ⊢ (? ? ? (? (? ? ? %) ? ? ?)) with (mult_memory x y 31);
147 rewrite > (eq_update_s_a_sa (update (mult_memory x y) 30 (mult_memory x y 30))
148 31 a) in ⊢ (? ? ? %);
149 rewrite > eq_update_s_a_sa;
152 | cut (5 + 23 * S n = 5 + 23 * n + 23);
153 [ letin K ≝ (breakpoint (mult_status x y) (5 + 23 * n) 23); clearbody K;
154 letin H' ≝ (H ?); clearbody H'; clear H;
156 | letin xxx ≝ (eq_f ? ? (λz. execute (mult_status x y) z) ? ? Hcut); clearbody xxx;
160 apply (transitive_eq ? ? ? ? K);
164 cut (∃z.y-n=S z ∧ z < 255);
165 [ elim Hcut; clear Hcut;
168 (* instruction LDAd *)
171 (mk_status (byte_of_nat (x*n)) 4 O
172 (eqbyte 〈x0, x0〉 (byte_of_nat (x*n)))
173 (plusbytec (byte_of_nat (x*pred n)) x)
174 (update (update (update (mult_memory x y) 30 x) 31 (byte_of_nat (S a))) 32
175 (byte_of_nat (x*n))) O)
177 normalize in K:(? ? (? ? %) ?);
178 apply transitive_eq; [2: apply K | skip | ]; clear K;
179 whd in ⊢ (? ? (? % ?) ?);
180 normalize in ⊢ (? ? (? (? ? % ? ? ? ? ?) ?) ?);
181 change in ⊢ (? ? (? (? % ? ? ? ? ? ?) ?) ?)
182 with (byte_of_nat (S a));
183 change in ⊢ (? ? (? (? ? ? ? (? ? %) ? ? ?) ?) ?) with
185 (* instruction BEQ *)
188 (mk_status (byte_of_nat (S a)) 6 O
189 (eqbyte 〈x0, x0〉 (byte_of_nat (S a)))
190 (plusbytec (byte_of_nat (x*pred n)) x)
191 (update (update (update (mult_memory x y) 30 x) 31 (byte_of_nat (S a))) 32
192 (byte_of_nat (x*n))) O)
194 normalize in K:(? ? (? ? %) ?);
195 apply transitive_eq; [2: apply K | skip | ]; clear K;
196 whd in ⊢ (? ? (? % ?) ?);
197 letin K ≝ (eq_eqbyte_x0_x0_byte_of_nat_S_false ? H3); clearbody K;
198 rewrite > K; clear K;
199 simplify in ⊢ (? ? (? (? ? % ? ? ? ? ?) ?) ?);
200 (* instruction LDAd *)
203 (mk_status (byte_of_nat (S a)) 8 O
204 (eqbyte 〈x0, x0〉 (byte_of_nat (S a)))
205 (plusbytec (byte_of_nat (x*pred n)) x)
206 (update (update (update (mult_memory x y) 30 x) 31 (byte_of_nat (S a))) 32
207 (byte_of_nat (x*n))) O)
209 normalize in K:(? ? (? ? %) ?);
210 apply transitive_eq; [2: apply K | skip | ]; clear K;
211 whd in ⊢ (? ? (? % ?) ?);
212 change in ⊢ (? ? (? (? % ? ? ? ? ? ?) ?) ?) with (byte_of_nat (x*n));
213 normalize in ⊢ (? ? (? (? ? % ? ? ? ? ?) ?) ?);
214 change in ⊢ (? ? (? (? ? ? ? % ? ? ?) ?) ?) with (eqbyte 〈x0, x0〉 (byte_of_nat (x*n)));
215 (* instruction DECd *)
218 (mk_status (byte_of_nat (x*n)) 10 O
219 (eqbyte 〈x0, x0〉 (byte_of_nat (x*n)))
220 (plusbytec (byte_of_nat (x*pred n)) x)
221 (update (update (update (mult_memory x y) 30 x) 31 (byte_of_nat (S a))) 32
222 (byte_of_nat (x*n))) O)
224 normalize in K:(? ? (? ? %) ?);
225 apply transitive_eq; [2: apply K | skip | ]; clear K;
226 whd in ⊢ (? ? (? % ?) ?);
227 change in ⊢ (? ? (? (? ? ? ? (? ? %) ? ? ?) ?) ?) with (bpred (byte_of_nat (S a)));
228 rewrite > (eq_bpred_S_a_a ? H3);
229 normalize in ⊢ (? ? (? (? ? % ? ? ? ? ?) ?) ?);
230 normalize in ⊢ (? ? (? (? ? ? ? ? ? (? ? % ?) ?) ?) ?);
232 [2: rewrite > eq_minus_S_pred;
235 rewrite < Hcut; clear Hcut; clear H3; clear H2; clear a;
236 (* instruction ADDd *)
239 (mk_status (byte_of_nat (x*n)) 12
240 O (eqbyte 〈x0, x0〉 (byte_of_nat (y-S n)))
241 (plusbytec (byte_of_nat (x*pred n)) x)
243 (update (update (update (mult_memory x y) 30 x) 31 (byte_of_nat (S (y-S n))))
244 32 (byte_of_nat (x*n))) 31
245 (byte_of_nat (y-S n))) O)
247 normalize in K:(? ? (? ? %) ?);
248 apply transitive_eq; [2: apply K | skip | ]; clear K;
249 whd in ⊢ (? ? (? % ?) ?);
250 change in ⊢ (? ? (? (? % ? ? ? ? ? ?) ?) ?) with
251 (plusbytenc (byte_of_nat (x*n)) x);
252 change in ⊢ (? ? (? (? ? ? ? (? ? %) ? ? ?) ?) ?) with
253 (plusbytenc (byte_of_nat (x*n)) x);
254 normalize in ⊢ (? ? (? (? ? % ? ? ? ? ?) ?) ?);
255 change in ⊢ (? ? (? (? ? ? ? ? % ? ?) ?) ?)
256 with (plusbytec (byte_of_nat (x*n)) x);
257 rewrite > plusbytenc_S;
258 (* instruction STAd *)
261 (mk_status (byte_of_nat (x*S n)) 14 O
262 (eqbyte 〈x0, x0〉 (byte_of_nat (x*S n)))
263 (plusbytec (byte_of_nat (x*n)) x)
265 (update (update (update (mult_memory x y) 30 x) 31 (byte_of_nat (S (y-S n))))
266 32 (byte_of_nat (x*n))) 31
267 (byte_of_nat (y-S n))) O)
269 normalize in K:(? ? (? ? %) ?);
270 apply transitive_eq; [2: apply K | skip | ]; clear K;
271 whd in ⊢ (? ? (? % ?) ?);
272 normalize in ⊢ (? ? (? (? ? % ? ? ? ? ?) ?) ?);
273 (* instruction BRA *)
275 normalize in ⊢ (? ? (? ? % ? ? ? ? ?) ?);
278 [1,2,3,4,7: normalize; reflexivity
279 | change with (plusbytec (byte_of_nat (x*n)) x =
280 plusbytec (byte_of_nat (x*n)) x);
283 simplify in ⊢ (? ? ? %);
284 change in ⊢ (? ? % ?) with
288 (update (update (mult_memory x y) 30 x) 31
289 (byte_of_nat (S (nat_of_byte y-S n)))) 32 (byte_of_nat (nat_of_byte x*n))) 31
290 (byte_of_nat (nat_of_byte y-S n)))
294 (update (update (mult_memory x y) 30 x) 31
295 (byte_of_nat (S (nat_of_byte y-S n)))) 32 (byte_of_nat (nat_of_byte x*n))) 31
296 (byte_of_nat (nat_of_byte y-S n)) 15))
297 (byte_of_nat (nat_of_byte x*S n)) a);
298 normalize in ⊢ (? ? (? ? % ? ?) ?);
303 rewrite > not_eq_a_b_to_eq_update_a_b in ⊢ (? ? % ?); [2: apply H | ];
304 rewrite > not_eq_a_b_to_eq_update_a_b in ⊢ (? ? % ?);
312 [ rewrite < (minus_S_S y n);
313 apply (minus_Sn_m (nat_of_byte y) (S n) H1)
314 | letin K ≝ (lt_nat_of_byte_256 y); clearbody K;
315 letin K' ≝ (lt_minus_m y (S n) ? ?); clearbody K';
321 | rewrite > associative_plus;
322 rewrite < times_n_Sm;
323 rewrite > sym_plus in ⊢ (? ? ? (? ? %));
332 let i ≝ 14 + 23 * y in
333 execute (mult_status x y) i =
334 mk_status (#(x*y)) 20 0
335 (eqbyte 〈x0, x0〉 (#(x*y)))
336 (plusbytec (byte_of_nat (x*pred y)) x)
338 (update (mult_memory x y) 31 〈x0, x0〉)
339 32 (byte_of_nat (x*y)))
342 cut (14 + 23 * y = 5 + 23*y + 9);
343 [2: autobatch paramodulation;
344 | rewrite > Hcut; (* clear Hcut; *)
345 rewrite > (breakpoint (mult_status x y) (5 + 23*y) 9);
346 rewrite > loop_invariant';
348 | rewrite < minus_n_n;
350 [1,2,3,4,5,7: normalize; reflexivity
352 letin xxx \def ((mult_memory x y) { a ↦ x }).
353 change with (update (update (update (mult_memory x y) 30 x) 31 (byte_of_nat O)) 32
354 (byte_of_nat (nat_of_byte x*nat_of_byte y)) a =
355 update (update (mult_memory x y) 31 〈x0, x0〉) 32
356 (byte_of_nat (nat_of_byte x*nat_of_byte y)) a);
357 apply inj_update; intro;
358 apply inj_update; intro;
359 change in ⊢ (? ? (? ? ? % ?) ?) with (mult_memory x y 30);
360 apply eq_update_s_a_sa