]> matita.cs.unibo.it Git - helm.git/blob - helm/software/matita/contribs/assembly/freescale/byte8.ma
Preparing for 0.5.9 release.
[helm.git] / helm / software / matita / contribs / assembly / freescale / byte8.ma
1 (**************************************************************************)
2 (*       ___                                                              *)
3 (*      ||M||                                                             *)
4 (*      ||A||       A project by Andrea Asperti                           *)
5 (*      ||T||                                                             *)
6 (*      ||I||       Developers:                                           *)
7 (*      ||T||         The HELM team.                                      *)
8 (*      ||A||         http://helm.cs.unibo.it                             *)
9 (*      \   /                                                             *)
10 (*       \ /        This file is distributed under the terms of the       *)
11 (*        v         GNU General Public License Version 2                  *)
12 (*                                                                        *)
13 (**************************************************************************)
14
15 (* ********************************************************************** *)
16 (*                           Progetto FreeScale                           *)
17 (*                                                                        *)
18 (* Sviluppato da:                                                         *)
19 (*   Cosimo Oliboni, oliboni@cs.unibo.it                                  *)
20 (*                                                                        *)
21 (* Questo materiale fa parte della tesi:                                  *)
22 (*   "Formalizzazione Interattiva dei Microcontroller a 8bit FreeScale"   *)
23 (*                                                                        *)
24 (*                    data ultima modifica 15/11/2007                     *)
25 (* ********************************************************************** *)
26
27 include "freescale/exadecim.ma".
28
29 (* ******************** *)
30 (* DEFINIZIONE DEI BYTE *)
31 (* ******************** *)
32
33 record byte8 : Type ≝
34  {
35  b8h: exadecim;
36  b8l: exadecim
37  }.
38
39 (* \langle \rangle *)
40 notation "〈x,y〉" non associative with precedence 80
41  for @{ 'mk_byte8 $x $y }.
42 interpretation "mk_byte8" 'mk_byte8 x y = (mk_byte8 x y).
43
44 (* operatore = *)
45 definition eq_b8 ≝ λb1,b2:byte8.(eq_ex (b8h b1) (b8h b2)) ⊗ (eq_ex (b8l b1) (b8l b2)).
46
47 (* operatore < *)
48 definition lt_b8 ≝
49 λb1,b2:byte8.match lt_ex (b8h b1) (b8h b2) with
50  [ true ⇒ true
51  | false ⇒ match gt_ex (b8h b1) (b8h b2) with
52   [ true ⇒ false
53   | false ⇒ lt_ex (b8l b1) (b8l b2) ]].
54
55 (* operatore ≤ *)
56 definition le_b8 ≝ λb1,b2:byte8.(eq_b8 b1 b2) ⊕ (lt_b8 b1 b2). 
57
58 (* operatore > *)
59 definition gt_b8 ≝ λb1,b2:byte8.⊖ (le_b8 b1 b2).
60
61 (* operatore ≥ *)
62 definition ge_b8 ≝ λb1,b2:byte8.⊖ (lt_b8 b1 b2).
63
64 (* operatore and *)
65 definition and_b8 ≝
66 λb1,b2:byte8.mk_byte8 (and_ex (b8h b1) (b8h b2)) (and_ex (b8l b1) (b8l b2)).
67
68 (* operatore or *)
69 definition or_b8 ≝
70 λb1,b2:byte8.mk_byte8 (or_ex (b8h b1) (b8h b2)) (or_ex (b8l b1) (b8l b2)).
71
72 (* operatore xor *)
73 definition xor_b8 ≝
74 λb1,b2:byte8.mk_byte8 (xor_ex (b8h b1) (b8h b2)) (xor_ex (b8l b1) (b8l b2)).
75
76 (* operatore rotazione destra con carry *)
77 definition rcr_b8 ≝
78 λb:byte8.λc:bool.match rcr_ex (b8h b) c with
79  [ pair bh' c' ⇒ match rcr_ex (b8l b) c' with
80   [ pair bl' c'' ⇒ pair ?? (mk_byte8 bh' bl') c'' ]]. 
81
82 (* operatore shift destro *)
83 definition shr_b8 ≝
84 λb:byte8.match rcr_ex (b8h b) false with
85  [ pair bh' c' ⇒ match rcr_ex (b8l b) c' with
86   [ pair bl' c'' ⇒ pair ?? (mk_byte8 bh' bl') c'' ]].
87
88 (* operatore rotazione destra *)
89 definition ror_b8 ≝
90 λb:byte8.match rcr_ex (b8h b) false with
91  [ pair bh' c' ⇒ match rcr_ex (b8l b) c' with
92   [ pair bl' c'' ⇒ match c'' with
93    [ true ⇒ mk_byte8 (or_ex x8 bh') bl'
94    | false ⇒ mk_byte8 bh' bl' ]]].
95
96 (* operatore rotazione destra n-volte *)
97 let rec ror_b8_n (b:byte8) (n:nat) on n ≝
98  match n with
99   [ O ⇒ b
100   | S n' ⇒ ror_b8_n (ror_b8 b) n' ].
101
102 (* operatore rotazione sinistra con carry *)
103 definition rcl_b8 ≝
104 λb:byte8.λc:bool.match rcl_ex (b8l b) c with
105  [ pair bl' c' ⇒ match rcl_ex (b8h b) c' with
106   [ pair bh' c'' ⇒ pair ?? (mk_byte8 bh' bl') c'' ]]. 
107
108 (* operatore shift sinistro *)
109 definition shl_b8 ≝
110 λb:byte8.match rcl_ex (b8l b) false with
111  [ pair bl' c' ⇒ match rcl_ex (b8h b) c' with
112   [ pair bh' c'' ⇒ pair ?? (mk_byte8 bh' bl') c'' ]].
113
114 (* operatore rotazione sinistra *)
115 definition rol_b8 ≝
116 λb:byte8.match rcl_ex (b8l b) false with
117  [ pair bl' c' ⇒ match rcl_ex (b8h b) c' with
118   [ pair bh' c'' ⇒ match c'' with
119    [ true ⇒ mk_byte8 bh' (or_ex x1 bl')
120    | false ⇒ mk_byte8 bh' bl' ]]].
121
122 (* operatore rotazione sinistra n-volte *)
123 let rec rol_b8_n (b:byte8) (n:nat) on n ≝
124  match n with
125   [ O ⇒ b
126   | S n' ⇒ rol_b8_n (rol_b8 b) n' ].
127
128 (* operatore not/complemento a 1 *)
129 definition not_b8 ≝
130 λb:byte8.mk_byte8 (not_ex (b8h b)) (not_ex (b8l b)).
131
132 (* operatore somma con carry *)
133 definition plus_b8 ≝
134 λb1,b2:byte8.λc:bool.
135  match plus_ex (b8l b1) (b8l b2) c with
136   [ pair l c' ⇒ match plus_ex (b8h b1) (b8h b2) c' with
137    [ pair h c'' ⇒ pair ?? (mk_byte8 h l) c'' ]].
138
139 (* operatore somma senza carry *)
140 definition plus_b8nc ≝
141 λb1,b2:byte8.fst ?? (plus_b8 b1 b2 false).
142
143 (* operatore carry della somma *)
144 definition plus_b8c ≝
145 λb1,b2:byte8.snd ?? (plus_b8 b1 b2 false).
146
147 (* operatore Most Significant Bit *)
148 definition MSB_b8 ≝ λb:byte8.eq_ex x8 (and_ex x8 (b8h b)).
149
150 (* byte → naturali *)
151 definition nat_of_byte8 ≝ λb:byte8.16*(b8h b) + (b8l b).
152
153 coercion nat_of_byte8.
154
155 (* naturali → byte *)
156 definition byte8_of_nat ≝ λn.mk_byte8 (exadecim_of_nat (n/16)) (exadecim_of_nat n).
157
158 (* operatore predecessore *)
159 definition pred_b8 ≝
160 λb:byte8.match eq_ex (b8l b) x0 with
161  [ true ⇒ mk_byte8 (pred_ex (b8h b)) (pred_ex (b8l b))
162  | false ⇒ mk_byte8 (b8h b) (pred_ex (b8l b)) ]. 
163
164 (* operatore successore *)
165 definition succ_b8 ≝
166 λb:byte8.match eq_ex (b8l b) xF with
167  [ true ⇒ mk_byte8 (succ_ex (b8h b)) (succ_ex (b8l b))
168  | false ⇒ mk_byte8 (b8h b) (succ_ex (b8l b)) ]. 
169
170 (* operatore neg/complemento a 2 *)
171 definition compl_b8 ≝
172 λb:byte8.match MSB_b8 b with
173  [ true ⇒ succ_b8 (not_b8 b)
174  | false ⇒ not_b8 (pred_b8 b) ].
175
176 (* operatore moltiplicazione senza segno: e*e=[0x00,0xE1] *)
177 definition mul_ex ≝
178 λe1,e2:exadecim.match e1 with
179  [ x0 ⇒ match e2 with
180   [ x0 ⇒ 〈x0,x0〉   | x1 ⇒ 〈x0,x0〉   | x2 ⇒ 〈x0,x0〉   | x3 ⇒ 〈x0,x0〉
181   | x4 ⇒ 〈x0,x0〉   | x5 ⇒ 〈x0,x0〉   | x6 ⇒ 〈x0,x0〉   | x7 ⇒ 〈x0,x0〉
182   | x8 ⇒ 〈x0,x0〉   | x9 ⇒ 〈x0,x0〉   | xA ⇒ 〈x0,x0〉   | xB ⇒ 〈x0,x0〉
183   | xC ⇒ 〈x0,x0〉   | xD ⇒ 〈x0,x0〉   | xE ⇒ 〈x0,x0〉   | xF ⇒ 〈x0,x0〉 ]
184  | x1 ⇒ match e2 with
185   [ x0 ⇒ 〈x0,x0〉   | x1 ⇒ 〈x0,x1〉   | x2 ⇒ 〈x0,x2〉   | x3 ⇒ 〈x0,x3〉
186   | x4 ⇒ 〈x0,x4〉   | x5 ⇒ 〈x0,x5〉   | x6 ⇒ 〈x0,x6〉   | x7 ⇒ 〈x0,x7〉
187   | x8 ⇒ 〈x0,x8〉   | x9 ⇒ 〈x0,x9〉   | xA ⇒ 〈x0,xA〉   | xB ⇒ 〈x0,xB〉
188   | xC ⇒ 〈x0,xC〉   | xD ⇒ 〈x0,xD〉   | xE ⇒ 〈x0,xE〉   | xF ⇒ 〈x0,xF〉 ]
189  | x2 ⇒ match e2 with
190   [ x0 ⇒ 〈x0,x0〉   | x1 ⇒ 〈x0,x2〉   | x2 ⇒ 〈x0,x4〉   | x3 ⇒ 〈x0,x6〉
191   | x4 ⇒ 〈x0,x8〉   | x5 ⇒ 〈x0,xA〉   | x6 ⇒ 〈x0,xC〉   | x7 ⇒ 〈x0,xE〉
192   | x8 ⇒ 〈x1,x0〉   | x9 ⇒ 〈x1,x2〉   | xA ⇒ 〈x1,x4〉   | xB ⇒ 〈x1,x6〉
193   | xC ⇒ 〈x1,x8〉   | xD ⇒ 〈x1,xA〉   | xE ⇒ 〈x1,xC〉   | xF ⇒ 〈x1,xE〉 ]
194  | x3 ⇒ match e2 with
195   [ x0 ⇒ 〈x0,x0〉   | x1 ⇒ 〈x0,x3〉   | x2 ⇒ 〈x0,x6〉   | x3 ⇒ 〈x0,x9〉
196   | x4 ⇒ 〈x0,xC〉   | x5 ⇒ 〈x0,xF〉   | x6 ⇒ 〈x1,x2〉   | x7 ⇒ 〈x1,x5〉
197   | x8 ⇒ 〈x1,x8〉   | x9 ⇒ 〈x1,xB〉   | xA ⇒ 〈x1,xE〉   | xB ⇒ 〈x2,x1〉
198   | xC ⇒ 〈x2,x4〉   | xD ⇒ 〈x2,x7〉   | xE ⇒ 〈x2,xA〉   | xF ⇒ 〈x2,xD〉 ]
199  | x4 ⇒ match e2 with
200   [ x0 ⇒ 〈x0,x0〉   | x1 ⇒ 〈x0,x4〉   | x2 ⇒ 〈x0,x8〉   | x3 ⇒ 〈x0,xC〉
201   | x4 ⇒ 〈x1,x0〉   | x5 ⇒ 〈x1,x4〉   | x6 ⇒ 〈x1,x8〉   | x7 ⇒ 〈x1,xC〉
202   | x8 ⇒ 〈x2,x0〉   | x9 ⇒ 〈x2,x4〉   | xA ⇒ 〈x2,x8〉   | xB ⇒ 〈x2,xC〉
203   | xC ⇒ 〈x3,x0〉   | xD ⇒ 〈x3,x4〉   | xE ⇒ 〈x3,x8〉   | xF ⇒ 〈x3,xC〉 ]
204  | x5 ⇒ match e2 with
205   [ x0 ⇒ 〈x0,x0〉   | x1 ⇒ 〈x0,x5〉   | x2 ⇒ 〈x0,xA〉   | x3 ⇒ 〈x0,xF〉
206   | x4 ⇒ 〈x1,x4〉   | x5 ⇒ 〈x1,x9〉   | x6 ⇒ 〈x1,xE〉   | x7 ⇒ 〈x2,x3〉
207   | x8 ⇒ 〈x2,x8〉   | x9 ⇒ 〈x2,xD〉   | xA ⇒ 〈x3,x2〉   | xB ⇒ 〈x3,x7〉
208   | xC ⇒ 〈x3,xC〉   | xD ⇒ 〈x4,x1〉   | xE ⇒ 〈x4,x6〉   | xF ⇒ 〈x4,xB〉 ]
209  | x6 ⇒ match e2 with
210   [ x0 ⇒ 〈x0,x0〉   | x1 ⇒ 〈x0,x6〉   | x2 ⇒ 〈x0,xC〉   | x3 ⇒ 〈x1,x2〉
211   | x4 ⇒ 〈x1,x8〉   | x5 ⇒ 〈x1,xE〉   | x6 ⇒ 〈x2,x4〉   | x7 ⇒ 〈x2,xA〉
212   | x8 ⇒ 〈x3,x0〉   | x9 ⇒ 〈x3,x6〉   | xA ⇒ 〈x3,xC〉   | xB ⇒ 〈x4,x2〉
213   | xC ⇒ 〈x4,x8〉   | xD ⇒ 〈x4,xE〉   | xE ⇒ 〈x5,x4〉   | xF ⇒ 〈x5,xA〉 ]
214  | x7 ⇒ match e2 with
215   [ x0 ⇒ 〈x0,x0〉   | x1 ⇒ 〈x0,x7〉   | x2 ⇒ 〈x0,xE〉   | x3 ⇒ 〈x1,x5〉
216   | x4 ⇒ 〈x1,xC〉   | x5 ⇒ 〈x2,x3〉   | x6 ⇒ 〈x2,xA〉   | x7 ⇒ 〈x3,x1〉
217   | x8 ⇒ 〈x3,x8〉   | x9 ⇒ 〈x3,xF〉   | xA ⇒ 〈x4,x6〉   | xB ⇒ 〈x4,xD〉
218   | xC ⇒ 〈x5,x4〉   | xD ⇒ 〈x5,xB〉   | xE ⇒ 〈x6,x2〉   | xF ⇒ 〈x6,x9〉 ]
219  | x8 ⇒ match e2 with
220   [ x0 ⇒ 〈x0,x0〉   | x1 ⇒ 〈x0,x8〉   | x2 ⇒ 〈x1,x0〉   | x3 ⇒ 〈x1,x8〉
221   | x4 ⇒ 〈x2,x0〉   | x5 ⇒ 〈x2,x8〉   | x6 ⇒ 〈x3,x0〉   | x7 ⇒ 〈x3,x8〉
222   | x8 ⇒ 〈x4,x0〉   | x9 ⇒ 〈x4,x8〉   | xA ⇒ 〈x5,x0〉   | xB ⇒ 〈x5,x8〉
223   | xC ⇒ 〈x6,x0〉   | xD ⇒ 〈x6,x8〉   | xE ⇒ 〈x7,x0〉   | xF ⇒ 〈x7,x8〉 ]
224  | x9 ⇒ match e2 with
225   [ x0 ⇒ 〈x0,x0〉   | x1 ⇒ 〈x0,x9〉   | x2 ⇒ 〈x1,x2〉   | x3 ⇒ 〈x1,xB〉
226   | x4 ⇒ 〈x2,x4〉   | x5 ⇒ 〈x2,xD〉   | x6 ⇒ 〈x3,x6〉   | x7 ⇒ 〈x3,xF〉
227   | x8 ⇒ 〈x4,x8〉   | x9 ⇒ 〈x5,x1〉   | xA ⇒ 〈x5,xA〉   | xB ⇒ 〈x6,x3〉
228   | xC ⇒ 〈x6,xC〉   | xD ⇒ 〈x7,x5〉   | xE ⇒ 〈x7,xE〉   | xF ⇒ 〈x8,x7〉 ]
229  | xA ⇒ match e2 with
230   [ x0 ⇒ 〈x0,x0〉   | x1 ⇒ 〈x0,xA〉   | x2 ⇒ 〈x1,x4〉   | x3 ⇒ 〈x1,xE〉
231   | x4 ⇒ 〈x2,x8〉   | x5 ⇒ 〈x3,x2〉   | x6 ⇒ 〈x3,xC〉   | x7 ⇒ 〈x4,x6〉
232   | x8 ⇒ 〈x5,x0〉   | x9 ⇒ 〈x5,xA〉   | xA ⇒ 〈x6,x4〉   | xB ⇒ 〈x6,xE〉
233   | xC ⇒ 〈x7,x8〉   | xD ⇒ 〈x8,x2〉   | xE ⇒ 〈x8,xC〉   | xF ⇒ 〈x9,x6〉 ]
234  | xB ⇒ match e2 with
235   [ x0 ⇒ 〈x0,x0〉   | x1 ⇒ 〈x0,xB〉   | x2 ⇒ 〈x1,x6〉   | x3 ⇒ 〈x2,x1〉
236   | x4 ⇒ 〈x2,xC〉   | x5 ⇒ 〈x3,x7〉   | x6 ⇒ 〈x4,x2〉   | x7 ⇒ 〈x4,xD〉
237   | x8 ⇒ 〈x5,x8〉   | x9 ⇒ 〈x6,x3〉   | xA ⇒ 〈x6,xE〉   | xB ⇒ 〈x7,x9〉
238   | xC ⇒ 〈x8,x4〉   | xD ⇒ 〈x8,xF〉   | xE ⇒ 〈x9,xA〉   | xF ⇒ 〈xA,x5〉 ]
239  | xC ⇒ match e2 with
240   [ x0 ⇒ 〈x0,x0〉   | x1 ⇒ 〈x0,xC〉   | x2 ⇒ 〈x1,x8〉   | x3 ⇒ 〈x2,x4〉
241   | x4 ⇒ 〈x3,x0〉   | x5 ⇒ 〈x3,xC〉   | x6 ⇒ 〈x4,x8〉   | x7 ⇒ 〈x5,x4〉
242   | x8 ⇒ 〈x6,x0〉   | x9 ⇒ 〈x6,xC〉   | xA ⇒ 〈x7,x8〉   | xB ⇒ 〈x8,x4〉
243   | xC ⇒ 〈x9,x0〉   | xD ⇒ 〈x9,xC〉   | xE ⇒ 〈xA,x8〉   | xF ⇒ 〈xB,x4〉 ]
244  | xD ⇒ match e2 with
245   [ x0 ⇒ 〈x0,x0〉   | x1 ⇒ 〈x0,xD〉   | x2 ⇒ 〈x1,xA〉   | x3 ⇒ 〈x2,x7〉
246   | x4 ⇒ 〈x3,x4〉   | x5 ⇒ 〈x4,x1〉   | x6 ⇒ 〈x4,xE〉   | x7 ⇒ 〈x5,xB〉
247   | x8 ⇒ 〈x6,x8〉   | x9 ⇒ 〈x7,x5〉   | xA ⇒ 〈x8,x2〉   | xB ⇒ 〈x8,xF〉
248   | xC ⇒ 〈x9,xC〉   | xD ⇒ 〈xA,x9〉   | xE ⇒ 〈xB,x6〉   | xF ⇒ 〈xC,x3〉 ]
249  | xE ⇒ match e2 with
250   [ x0 ⇒ 〈x0,x0〉   | x1 ⇒ 〈x0,xE〉   | x2 ⇒ 〈x1,xC〉   | x3 ⇒ 〈x2,xA〉
251   | x4 ⇒ 〈x3,x8〉   | x5 ⇒ 〈x4,x6〉   | x6 ⇒ 〈x5,x4〉   | x7 ⇒ 〈x6,x2〉
252   | x8 ⇒ 〈x7,x0〉   | x9 ⇒ 〈x7,xE〉   | xA ⇒ 〈x8,xC〉   | xB ⇒ 〈x9,xA〉
253   | xC ⇒ 〈xA,x8〉   | xD ⇒ 〈xB,x6〉   | xE ⇒ 〈xC,x4〉   | xF ⇒ 〈xD,x2〉 ]
254  | xF ⇒ match e2 with
255   [ x0 ⇒ 〈x0,x0〉   | x1 ⇒ 〈x0,xF〉   | x2 ⇒ 〈x1,xE〉   | x3 ⇒ 〈x2,xD〉
256   | x4 ⇒ 〈x3,xC〉   | x5 ⇒ 〈x4,xB〉   | x6 ⇒ 〈x5,xA〉   | x7 ⇒ 〈x6,x9〉
257   | x8 ⇒ 〈x7,x8〉   | x9 ⇒ 〈x8,x7〉   | xA ⇒ 〈x9,x6〉   | xB ⇒ 〈xA,x5〉
258   | xC ⇒ 〈xB,x4〉   | xD ⇒ 〈xC,x3〉   | xE ⇒ 〈xD,x2〉   | xF ⇒ 〈xE,x1〉 ]
259  ].
260
261 (* correzione per somma su BCD *)
262 (* input: halfcarry,carry,X(BCD+BCD) *)
263 (* output: X',carry' *)
264 definition daa_b8 ≝
265 λh,c:bool.λX:byte8.
266  match lt_b8 X 〈x9,xA〉 with
267   (* [X:0x00-0x99] *)
268   (* c' = c *)
269   (* X' = [(b16l X):0x0-0x9] X + [h=1 ? 0x06 : 0x00] + [c=1 ? 0x60 : 0x00]
270           [(b16l X):0xA-0xF] X + 0x06 + [c=1 ? 0x60 : 0x00] *)
271   [ true ⇒
272    let X' ≝ match (lt_ex (b8l X) xA) ⊗ (⊖h) with
273     [ true ⇒ X
274     | false ⇒ plus_b8nc X 〈x0,x6〉 ] in
275    let X'' ≝ match c with
276     [ true ⇒ plus_b8nc X' 〈x6,x0〉
277     | false ⇒ X' ] in
278    pair ?? X'' c
279   (* [X:0x9A-0xFF] *)
280   (* c' = 1 *)
281   (* X' = [X:0x9A-0xFF]
282           [(b16l X):0x0-0x9] X + [h=1 ? 0x06 : 0x00] + 0x60
283           [(b16l X):0xA-0xF] X + 0x6 + 0x60 *) 
284   | false ⇒
285    let X' ≝ match (lt_ex (b8l X) xA) ⊗ (⊖h) with
286     [ true ⇒ X
287     | false ⇒ plus_b8nc X 〈x0,x6〉 ] in
288    let X'' ≝ plus_b8nc X' 〈x6,x0〉 in
289    pair ?? X'' true
290   ].
291
292 (* iteratore sui byte *)
293 definition forall_byte8 ≝
294  λP.
295   forall_exadecim (λbh.
296   forall_exadecim (λbl.
297    P (mk_byte8 bh bl))).
298
299 (* ********************** *)
300 (* TEOREMI/LEMMMI/ASSIOMI *)
301 (* ********************** *)
302
303 lemma byte8_of_nat_nat_of_byte8: ∀b. byte8_of_nat (nat_of_byte8 b) = b.
304  intros;
305  elim b;
306  elim e;
307  elim e1;
308  reflexivity.
309 qed.
310
311 lemma lt_nat_of_byte8_256: ∀b. nat_of_byte8 b < 256.
312  intro;
313  unfold nat_of_byte8;
314  letin H ≝ (lt_nat_of_exadecim_16 (b8h b)); clearbody H;
315  letin K ≝ (lt_nat_of_exadecim_16 (b8l b)); clearbody K;
316  unfold lt in H K ⊢ %;
317  letin H' ≝ (le_S_S_to_le ? ? H); clearbody H'; clear H;
318  letin K' ≝ (le_S_S_to_le ? ? K); clearbody K'; clear K;
319  apply le_S_S;
320  cut (16*b8h b ≤ 16*15);
321   [ letin Hf ≝ (le_plus ? ? ? ? Hcut K'); clearbody Hf;
322     simplify in Hf:(? ? %);
323     assumption
324   | apply le_times_r. apply H'.
325   ]
326 qed.
327
328 lemma nat_of_byte8_byte8_of_nat: ∀n. nat_of_byte8 (byte8_of_nat n) = n \mod 256.
329  intro;
330  letin H ≝ (lt_nat_of_byte8_256 (byte8_of_nat n)); clearbody H;
331  rewrite < (lt_to_eq_mod ? ? H); clear H;
332  unfold byte8_of_nat;
333  unfold nat_of_byte8;
334  change with ((16*(exadecim_of_nat (n/16)) + exadecim_of_nat n) \mod 256 = n \mod 256);
335  letin H ≝ (div_mod n 16 ?); clearbody H; [ autobatch | ];
336  rewrite > symmetric_times in H;
337  rewrite > nat_of_exadecim_exadecim_of_nat in ⊢ (? ? (? (? % ?) ?) ?);
338  rewrite > nat_of_exadecim_exadecim_of_nat in ⊢ (? ? (? (? ? %) ?) ?);
339  rewrite > H in ⊢ (? ? ? (? % ?)); clear H;
340  rewrite > mod_plus in ⊢ (? ? % ?);
341  rewrite > mod_plus in ⊢ (? ? ? %);
342  apply eq_mod_to_eq_plus_mod;
343  rewrite < mod_mod in ⊢ (? ? ? %); [ | autobatch by divides_n_n];
344  rewrite < mod_mod in ⊢ (? ? % ?); [ | autobatch by divides_n_n];
345  rewrite < (eq_mod_times_times_mod ? ? 16 256) in ⊢ (? ? (? % ?) ?); [2: reflexivity | ];
346  rewrite < mod_mod in ⊢ (? ? % ?);
347   [ reflexivity
348   | autobatch by divides_n_n
349   ].
350 qed.
351
352 lemma eq_nat_of_byte8_n_nat_of_byte8_mod_n_256:
353  ∀n. byte8_of_nat n = byte8_of_nat (n \mod 256).
354  intro;
355  unfold byte8_of_nat;
356  apply eq_f2;
357   [ rewrite > exadecim_of_nat_mod in ⊢ (? ? % ?);
358     rewrite > exadecim_of_nat_mod in ⊢ (? ? ? %);
359     apply eq_f;
360     elim daemon
361   | rewrite > exadecim_of_nat_mod;
362     rewrite > exadecim_of_nat_mod in ⊢ (? ? ? %);
363     rewrite > divides_to_eq_mod_mod_mod;
364      [ reflexivity
365      | apply (witness ? ? 16). reflexivity.
366      ]
367   ]
368 qed.
369
370 lemma plusb8_ok:
371  ∀b1,b2,c.
372   match plus_b8 b1 b2 c with
373    [ pair r c' ⇒ b1 + b2 + nat_of_bool c = nat_of_byte8 r + nat_of_bool c' * 256
374    ].
375  intros; elim daemon.
376 qed.
377
378 lemma plusb8_O_x:
379  ∀b. plus_b8 (mk_byte8 x0 x0) b false = pair ?? b false.
380  intros;
381  elim b;
382  elim e;
383  elim e1;
384  reflexivity.
385 qed.
386
387 lemma plusb8nc_O_x:
388  ∀x. plus_b8nc (mk_byte8 x0 x0) x = x.
389  intros;
390  unfold plus_b8nc;
391  rewrite > plusb8_O_x;
392  reflexivity.
393 qed.
394
395 lemma eq_nat_of_byte8_mod: ∀b. nat_of_byte8 b = nat_of_byte8 b \mod 256.
396  intro;
397  lapply (lt_nat_of_byte8_256 b);
398  rewrite > (lt_to_eq_mod ? ? Hletin) in ⊢ (? ? ? %);
399  reflexivity.
400 qed.
401
402 theorem plusb8nc_ok:
403  ∀b1,b2:byte8.nat_of_byte8 (plus_b8nc b1 b2) = (b1 + b2) \mod 256.
404  intros;
405  unfold plus_b8nc;
406  generalize in match (plusb8_ok b1 b2 false);
407  elim (plus_b8 b1 b2 false);
408  simplify in H ⊢ %;
409  change with (nat_of_byte8 a = (b1 + b2) \mod 256);
410  rewrite < plus_n_O in H;
411  rewrite > H; clear H;
412  rewrite > mod_plus;
413  letin K ≝ (eq_nat_of_byte8_mod a); clearbody K;
414  letin K' ≝ (eq_mod_times_n_m_m_O (nat_of_bool b) 256 ?); clearbody K';
415   [ unfold;apply le_S_S;apply le_O_n| ];
416  rewrite > K' in ⊢ (? ? ? (? (? ? %) ?));
417  rewrite < K in ⊢ (? ? ? (? (? % ?) ?));
418  rewrite < plus_n_O;
419  apply K;
420 qed.
421
422 lemma eq_eqb8_x0_x0_byte8_of_nat_S_false:
423  ∀b. b < 255 → eq_b8 (mk_byte8 x0 x0) (byte8_of_nat (S b)) = false.
424  intros;
425  unfold byte8_of_nat;
426  cut (b < 15 ∨ b ≥ 15);
427   [ elim Hcut;
428     [ unfold eq_b8;
429       change in ⊢ (? ? (? ? %) ?) with (eq_ex x0 (exadecim_of_nat (S b))); 
430       rewrite > eq_eqex_S_x0_false;
431        [ elim (eq_ex (b8h (mk_byte8 x0 x0))
432           (b8h (mk_byte8 (exadecim_of_nat (S b/16)) (exadecim_of_nat (S b)))));
433          simplify;
434          reflexivity
435        | assumption
436        ]
437     | unfold eq_b8;
438       change in ⊢ (? ? (? % ?) ?) with (eq_ex x0 (exadecim_of_nat (S b/16)));
439       letin K ≝ (leq_m_n_to_eq_div_n_m_S (S b) 16 ? ?);
440        [ unfold; autobatch by le_S_S,le_O_n;
441        | unfold in H1;
442          apply le_S_S;
443          assumption
444        | clearbody K;
445          elim K; clear K;
446          rewrite > H2;
447          rewrite > eq_eqex_S_x0_false;
448           [ reflexivity
449           | unfold lt;
450             unfold lt in H;
451             rewrite < H2;
452             clear H2; clear a; clear H1; clear Hcut;
453             apply (le_times_to_le 16) [ autobatch by le_S_S,le_O_n;| ] ;
454             rewrite > (div_mod (S b) 16) in H;[2:unfold; autobatch by le_S_S,le_O_n;|]
455             rewrite > (div_mod 255 16) in H:(? ? %);[2:unfold; autobatch by le_S_S,le_O_n;|]
456             lapply (le_to_le_plus_to_le ? ? ? ? ? H);
457             [apply lt_S_to_le;
458              apply lt_mod_m_m; unfold; apply le_S_S; apply le_O_n;
459             |rewrite > sym_times;
460              rewrite > sym_times in ⊢ (? ? %);
461              normalize in ⊢ (? ? %);apply Hletin;
462             ]
463           ] 
464        ]
465     ]
466   | elim (or_lt_le b 15);unfold ge;autobatch
467   ].
468 qed.
469
470 axiom eq_mod_O_to_exists: ∀n,m. n \mod m = 0 → ∃z. n = z*m.
471
472 lemma eq_b8pred_S_a_a:
473  ∀a. a < 255 → pred_b8 (byte8_of_nat (S a)) = byte8_of_nat a.
474  intros;
475  unfold pred_b8;
476  apply (bool_elim ? (eq_ex (b8l (byte8_of_nat (S a))) x0)); intros;
477   [ change with (mk_byte8 (pred_ex (b8h (byte8_of_nat (S a)))) (pred_ex (b8l (byte8_of_nat (S a))))
478      = byte8_of_nat a);
479     rewrite > (eqex_true_to_eq ? ? H1);
480     normalize in ⊢ (? ? (? ? %) ?);
481     unfold byte8_of_nat;
482     change with (mk_byte8 (pred_ex (exadecim_of_nat (S a/16))) xF =
483                  mk_byte8 (exadecim_of_nat (a/16)) (exadecim_of_nat a));
484     lapply (eqex_true_to_eq ? ? H1); clear H1;
485     unfold byte8_of_nat in Hletin;
486     change in Hletin with (exadecim_of_nat (S a) = x0);
487     lapply (eq_f ? ? nat_of_exadecim ? ? Hletin); clear Hletin;
488     normalize in Hletin1:(? ? ? %);
489     rewrite > nat_of_exadecim_exadecim_of_nat in Hletin1;
490     elim (eq_mod_O_to_exists ? ? Hletin1); clear Hletin1;
491     rewrite > H1;
492     rewrite > lt_O_to_div_times; [2: unfold; apply le_S_S; apply le_O_n; | ]
493     lapply (eq_f ? ? (λx.x/16) ? ? H1);
494     rewrite > lt_O_to_div_times in Hletin; [2: unfold; apply le_S_S; apply le_O_n; | ]
495     lapply (eq_f ? ? (λx.x \mod 16) ? ? H1);
496     rewrite > eq_mod_times_n_m_m_O in Hletin1;
497     elim daemon
498   | change with (mk_byte8 (b8h (byte8_of_nat (S a))) (pred_ex (b8l (byte8_of_nat (S a))))
499     = byte8_of_nat a);
500     unfold byte8_of_nat;
501     change with (mk_byte8 (exadecim_of_nat (S a/16)) (pred_ex (exadecim_of_nat (S a)))
502     = mk_byte8 (exadecim_of_nat (a/16)) (exadecim_of_nat a));
503     lapply (eqex_false_to_not_eq ? ? H1);
504     unfold byte8_of_nat in Hletin;
505     change in Hletin with (exadecim_of_nat (S a) ≠ x0);
506     cut (nat_of_exadecim (exadecim_of_nat (S a)) ≠ 0);
507      [2: intro;
508        apply Hletin;
509        lapply (eq_f ? ? exadecim_of_nat ? ? H2);
510        rewrite > exadecim_of_nat_nat_of_exadecim in Hletin1;
511        apply Hletin1
512      | ];
513     elim daemon
514   ]
515 qed.
516
517 lemma plusb8nc_S:
518  ∀x:byte8.∀n.plus_b8nc (byte8_of_nat (x*n)) x = byte8_of_nat (x * S n).
519  intros;
520  rewrite < byte8_of_nat_nat_of_byte8;
521  rewrite > (plusb8nc_ok (byte8_of_nat (x*n)) x);
522  rewrite < times_n_Sm;
523  rewrite > nat_of_byte8_byte8_of_nat in ⊢ (? ? (? (? (? % ?) ?)) ?);
524  rewrite > eq_nat_of_byte8_n_nat_of_byte8_mod_n_256 in ⊢ (? ? ? %);
525  rewrite > mod_plus in ⊢ (? ? (? %) ?);
526  rewrite > mod_plus in ⊢ (? ? ? (? %));
527  rewrite < mod_mod in ⊢ (? ? (? (? (? % ?) ?)) ?); [2: apply divides_n_n; | ];
528  rewrite > sym_plus in ⊢ (? ? (? (? % ?)) ?);
529  reflexivity.
530 qed.
531
532 lemma eq_plusb8c_x0_x0_x_false:
533  ∀x.plus_b8c (mk_byte8 x0 x0) x = false.
534  intro;
535  elim x;
536  elim e;
537  elim e1;
538  reflexivity.
539 qed.
540
541 axiom eqb8_true_to_eq: ∀b,b'. eq_b8 b b' = true → b=b'.
542
543 axiom eqb8_false_to_not_eq: ∀b,b'. eq_b8 b b' = false → b ≠ b'.
544
545 axiom byte8_of_nat_mod: ∀n.byte8_of_nat n = byte8_of_nat (n \mod 256).
546
547 (* nuovi *)
548
549 lemma ok_mul_ex :
550 ∀e1,e2.nat_of_byte8 (mul_ex e1 e2) = (nat_of_exadecim e1) * (nat_of_exadecim e2).
551 intros;
552 elim e1;
553 elim e2;
554 reflexivity.
555 qed.