1 (* ========================================================================= *)
2 (* Calculation with naturals. *)
4 (* John Harrison, University of Cambridge Computer Laboratory *)
6 (* (c) Copyright, University of Cambridge 1998 *)
7 (* (c) Copyright, John Harrison 1998-2007 *)
8 (* ========================================================================= *)
12 (* ------------------------------------------------------------------------- *)
13 (* Simple rule to get rid of NUMERAL constant. *)
14 (* ------------------------------------------------------------------------- *)
16 let DENUMERAL = GEN_REWRITE_RULE DEPTH_CONV [NUMERAL];;
18 (* ------------------------------------------------------------------------- *)
19 (* Big collection of rewrites to do trivial arithmetic. *)
21 (* Note that we have none for DIV and MOD, and that PRE and SUB are a bit *)
22 (* inefficient; log(n)^2 instead of log(n). *)
23 (* ------------------------------------------------------------------------- *)
25 let ARITH_ZERO = prove
28 REWRITE_TAC[NUMERAL; BIT0; DENUMERAL ADD_CLAUSES]);;
31 (`(!n. SUC(NUMERAL n) = NUMERAL(SUC n)) /\
33 (!n. SUC (BIT0 n) = BIT1 n) /\
34 (!n. SUC (BIT1 n) = BIT0 (SUC n))`,
35 REWRITE_TAC[NUMERAL; BIT0; BIT1; DENUMERAL ADD_CLAUSES]);;
38 (`(!n. PRE(NUMERAL n) = NUMERAL(PRE n)) /\
40 (!n. PRE(BIT0 n) = if n = _0 then _0 else BIT1 (PRE n)) /\
41 (!n. PRE(BIT1 n) = BIT0 n)`,
42 REWRITE_TAC[NUMERAL; BIT1; BIT0; DENUMERAL PRE] THEN INDUCT_TAC THEN
43 REWRITE_TAC[NUMERAL; DENUMERAL PRE; DENUMERAL ADD_CLAUSES; DENUMERAL NOT_SUC;
47 (`(!m n. NUMERAL(m) + NUMERAL(n) = NUMERAL(m + n)) /\
49 (!n. _0 + BIT0 n = BIT0 n) /\
50 (!n. _0 + BIT1 n = BIT1 n) /\
51 (!n. BIT0 n + _0 = BIT0 n) /\
52 (!n. BIT1 n + _0 = BIT1 n) /\
53 (!m n. BIT0 m + BIT0 n = BIT0 (m + n)) /\
54 (!m n. BIT0 m + BIT1 n = BIT1 (m + n)) /\
55 (!m n. BIT1 m + BIT0 n = BIT1 (m + n)) /\
56 (!m n. BIT1 m + BIT1 n = BIT0 (SUC(m + n)))`,
57 PURE_REWRITE_TAC[NUMERAL; BIT0; BIT1; DENUMERAL ADD_CLAUSES; SUC_INJ] THEN
58 REWRITE_TAC[ADD_AC]);;
60 let ARITH_MULT = prove
61 (`(!m n. NUMERAL(m) * NUMERAL(n) = NUMERAL(m * n)) /\
63 (!n. _0 * BIT0 n = _0) /\
64 (!n. _0 * BIT1 n = _0) /\
65 (!n. BIT0 n * _0 = _0) /\
66 (!n. BIT1 n * _0 = _0) /\
67 (!m n. BIT0 m * BIT0 n = BIT0 (BIT0 (m * n))) /\
68 (!m n. BIT0 m * BIT1 n = BIT0 m + BIT0 (BIT0 (m * n))) /\
69 (!m n. BIT1 m * BIT0 n = BIT0 n + BIT0 (BIT0 (m * n))) /\
70 (!m n. BIT1 m * BIT1 n = BIT1 m + BIT0 n + BIT0 (BIT0 (m * n)))`,
71 PURE_REWRITE_TAC[NUMERAL; BIT0; BIT1; DENUMERAL MULT_CLAUSES;
72 DENUMERAL ADD_CLAUSES; SUC_INJ] THEN
73 REWRITE_TAC[LEFT_ADD_DISTRIB; RIGHT_ADD_DISTRIB; ADD_AC]);;
76 (`(!m n. (NUMERAL m) EXP (NUMERAL n) = NUMERAL(m EXP n)) /\
77 (_0 EXP _0 = BIT1 _0) /\
78 (!m. (BIT0 m) EXP _0 = BIT1 _0) /\
79 (!m. (BIT1 m) EXP _0 = BIT1 _0) /\
80 (!n. _0 EXP (BIT0 n) = (_0 EXP n) * (_0 EXP n)) /\
81 (!m n. (BIT0 m) EXP (BIT0 n) = ((BIT0 m) EXP n) * ((BIT0 m) EXP n)) /\
82 (!m n. (BIT1 m) EXP (BIT0 n) = ((BIT1 m) EXP n) * ((BIT1 m) EXP n)) /\
83 (!n. _0 EXP (BIT1 n) = _0) /\
84 (!m n. (BIT0 m) EXP (BIT1 n) =
85 BIT0 m * ((BIT0 m) EXP n) * ((BIT0 m) EXP n)) /\
86 (!m n. (BIT1 m) EXP (BIT1 n) =
87 BIT1 m * ((BIT1 m) EXP n) * ((BIT1 m) EXP n))`,
88 REWRITE_TAC[NUMERAL] THEN REPEAT STRIP_TAC THEN
89 TRY(GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [BIT0; BIT1]) THEN
90 REWRITE_TAC[DENUMERAL EXP; DENUMERAL MULT_CLAUSES; EXP_ADD]);;
92 let ARITH_EVEN = prove
93 (`(!n. EVEN(NUMERAL n) <=> EVEN n) /\
95 (!n. EVEN(BIT0 n) <=> T) /\
96 (!n. EVEN(BIT1 n) <=> F)`,
97 REWRITE_TAC[NUMERAL; BIT1; BIT0; DENUMERAL EVEN; EVEN_ADD]);;
100 (`(!n. ODD(NUMERAL n) <=> ODD n) /\
102 (!n. ODD(BIT0 n) <=> F) /\
103 (!n. ODD(BIT1 n) <=> T)`,
104 REWRITE_TAC[NUMERAL; BIT1; BIT0; DENUMERAL ODD; ODD_ADD]);;
107 (`(!m n. NUMERAL m <= NUMERAL n <=> m <= n) /\
108 ((_0 <= _0) <=> T) /\
109 (!n. (BIT0 n <= _0) <=> n <= _0) /\
110 (!n. (BIT1 n <= _0) <=> F) /\
111 (!n. (_0 <= BIT0 n) <=> T) /\
112 (!n. (_0 <= BIT1 n) <=> T) /\
113 (!m n. (BIT0 m <= BIT0 n) <=> m <= n) /\
114 (!m n. (BIT0 m <= BIT1 n) <=> m <= n) /\
115 (!m n. (BIT1 m <= BIT0 n) <=> m < n) /\
116 (!m n. (BIT1 m <= BIT1 n) <=> m <= n)`,
117 REWRITE_TAC[NUMERAL; BIT1; BIT0; DENUMERAL NOT_SUC;
118 DENUMERAL(GSYM NOT_SUC); SUC_INJ] THEN
119 REWRITE_TAC[DENUMERAL LE_0] THEN REWRITE_TAC[DENUMERAL LE; GSYM MULT_2] THEN
120 REWRITE_TAC[LE_MULT_LCANCEL; SUC_INJ;
121 DENUMERAL MULT_EQ_0; DENUMERAL NOT_SUC] THEN
122 REWRITE_TAC[DENUMERAL NOT_SUC] THEN REWRITE_TAC[LE_SUC_LT] THEN
123 REWRITE_TAC[LT_MULT_LCANCEL] THEN
124 SUBGOAL_THEN `2 = SUC 1` (fun th -> REWRITE_TAC[th]) THENL
125 [REWRITE_TAC[NUMERAL; BIT0; BIT1; DENUMERAL ADD_CLAUSES];
126 REWRITE_TAC[DENUMERAL NOT_SUC; NOT_SUC; EQ_MULT_LCANCEL] THEN
127 REWRITE_TAC[ONCE_REWRITE_RULE[DISJ_SYM] LE_LT] THEN
128 MAP_EVERY X_GEN_TAC [`m:num`; `n:num`] THEN
129 SUBGOAL_THEN `~(SUC 1 * m = SUC (SUC 1 * n))`
130 (fun th -> REWRITE_TAC[th]) THEN
131 DISCH_THEN(MP_TAC o AP_TERM `EVEN`) THEN
132 REWRITE_TAC[EVEN_MULT; EVEN_ADD; NUMERAL; BIT1; EVEN]]);;
135 (`(!m n. NUMERAL m < NUMERAL n <=> m < n) /\
137 (!n. (BIT0 n < _0) <=> F) /\
138 (!n. (BIT1 n < _0) <=> F) /\
139 (!n. (_0 < BIT0 n) <=> _0 < n) /\
140 (!n. (_0 < BIT1 n) <=> T) /\
141 (!m n. (BIT0 m < BIT0 n) <=> m < n) /\
142 (!m n. (BIT0 m < BIT1 n) <=> m <= n) /\
143 (!m n. (BIT1 m < BIT0 n) <=> m < n) /\
144 (!m n. (BIT1 m < BIT1 n) <=> m < n)`,
145 REWRITE_TAC[NUMERAL; GSYM NOT_LE; ARITH_LE] THEN
146 REWRITE_TAC[DENUMERAL LE]);;
148 let ARITH_GE = REWRITE_RULE[GSYM GE; GSYM GT] ARITH_LE;;
150 let ARITH_GT = REWRITE_RULE[GSYM GE; GSYM GT] ARITH_LT;;
153 (`(!m n. (NUMERAL m = NUMERAL n) <=> (m = n)) /\
155 (!n. (BIT0 n = _0) <=> (n = _0)) /\
156 (!n. (BIT1 n = _0) <=> F) /\
157 (!n. (_0 = BIT0 n) <=> (_0 = n)) /\
158 (!n. (_0 = BIT1 n) <=> F) /\
159 (!m n. (BIT0 m = BIT0 n) <=> (m = n)) /\
160 (!m n. (BIT0 m = BIT1 n) <=> F) /\
161 (!m n. (BIT1 m = BIT0 n) <=> F) /\
162 (!m n. (BIT1 m = BIT1 n) <=> (m = n))`,
163 REWRITE_TAC[NUMERAL; GSYM LE_ANTISYM; ARITH_LE] THEN
164 REWRITE_TAC[LET_ANTISYM; LTE_ANTISYM; DENUMERAL LE_0]);;
166 let ARITH_SUB = prove
167 (`(!m n. NUMERAL m - NUMERAL n = NUMERAL(m - n)) /\
169 (!n. _0 - BIT0 n = _0) /\
170 (!n. _0 - BIT1 n = _0) /\
171 (!n. BIT0 n - _0 = BIT0 n) /\
172 (!n. BIT1 n - _0 = BIT1 n) /\
173 (!m n. BIT0 m - BIT0 n = BIT0 (m - n)) /\
174 (!m n. BIT0 m - BIT1 n = PRE(BIT0 (m - n))) /\
175 (!m n. BIT1 m - BIT0 n = if n <= m then BIT1 (m - n) else _0) /\
176 (!m n. BIT1 m - BIT1 n = BIT0 (m - n))`,
177 REWRITE_TAC[NUMERAL; DENUMERAL SUB_0] THEN PURE_REWRITE_TAC[BIT0; BIT1] THEN
178 REWRITE_TAC[GSYM MULT_2; SUB_SUC; LEFT_SUB_DISTRIB] THEN
179 REWRITE_TAC[SUB] THEN REPEAT GEN_TAC THEN COND_CASES_TAC THEN
180 REWRITE_TAC[DENUMERAL SUB_EQ_0] THEN
181 RULE_ASSUM_TAC(REWRITE_RULE[NOT_LE]) THEN
182 ASM_REWRITE_TAC[LE_SUC_LT; LT_MULT_LCANCEL; ARITH_EQ] THEN
183 POP_ASSUM(CHOOSE_THEN SUBST1_TAC o REWRITE_RULE[LE_EXISTS]) THEN
184 REWRITE_TAC[ADD1; LEFT_ADD_DISTRIB] THEN
185 REWRITE_TAC[ADD_SUB2; GSYM ADD_ASSOC]);;
187 let ARITH = end_itlist CONJ
188 [ARITH_ZERO; ARITH_SUC; ARITH_PRE;
189 ARITH_ADD; ARITH_MULT; ARITH_EXP;
190 ARITH_EVEN; ARITH_ODD;
191 ARITH_EQ; ARITH_LE; ARITH_LT; ARITH_GE; ARITH_GT;
194 (* ------------------------------------------------------------------------- *)
195 (* Now more delicate conversions for situations where efficiency matters. *)
196 (* ------------------------------------------------------------------------- *)
199 let tth,rths = CONJ_PAIR ARITH_EVEN in
200 GEN_REWRITE_CONV I [tth] THENC GEN_REWRITE_CONV I [rths];;
203 let tth,rths = CONJ_PAIR ARITH_ODD in
204 GEN_REWRITE_CONV I [tth] THENC GEN_REWRITE_CONV I [rths];;
206 let NUM_SUC_CONV,NUM_ADD_CONV,NUM_MULT_CONV,NUM_EXP_CONV,
207 NUM_LT_CONV,NUM_LE_CONV,NUM_EQ_CONV =
208 let Comb(NUMERAL_tm,Comb(BIT0_tm,Comb(BIT1_tm,zero_tm))) =
210 and suc_tm = rator(rand(concl TWO))
211 and one_tm = rand(mk_small_numeral 1)
212 and add_tm = rator(rator(lhand(snd(strip_forall(concl ADD_0)))))
213 and mul_tm = rator(rator(rand(snd(strip_forall(concl EXP_2)))))
214 and exp_tm = rator(rator(lhand(snd(strip_forall(concl EXP_2)))))
215 and eq_tm = rator(rator(concl TWO)) in
216 let num_0 = Int 0 and num_1 = Int 1 and num_2 = Int 2 in
226 and p_tm = `p:num` in
228 let ilist = [BIT0_tm,BIT0_tm; BIT1_tm,BIT1_tm; zero_tm,zero_tm;
229 suc_tm,suc_tm; add_tm,add_tm; mul_tm,mul_tm;
230 exp_tm,exp_tm; eq_tm,eq_tm; NUMERAL_tm,NUMERAL_tm;
231 a_tm,a_tm; b_tm,b_tm; c_tm,c_tm; d_tm,d_tm; e_tm,e_tm;
232 h_tm,h_tm; l_tm,l_tm; m_tm,m_tm; n_tm,n_tm; p_tm,p_tm] in
235 Var(_,_) | Const(_,_) -> rev_assocd tm ilist tm
236 | Comb(s,t) -> mk_comb(replace s,replace t)
237 | Abs(_,_) -> failwith "replace" in
238 fun th -> let tm' = replace (concl th) in EQ_MP (REFL tm') th in
239 let REFL_bit0 = STANDARDIZE(REFL BIT0_tm)
240 and REFL_bit1 = STANDARDIZE(REFL BIT1_tm) in
241 let AP_BIT0 th = MK_COMB(REFL_bit0,th)
242 and AP_BIT1 th = MK_COMB(REFL_bit1,th)
243 and QUICK_PROVE_HYP ath bth = EQ_MP (DEDUCT_ANTISYM_RULE ath bth) ath in
244 let rec dest_raw_numeral tm =
246 Comb(Const("BIT1",_),t) -> num_2 */ dest_raw_numeral t +/ num_1
247 | Comb(Const("BIT0",_),t) -> num_2 */ dest_raw_numeral t
248 | Const("_0",_) -> num_0 in
250 let rec bctr w z tm =
252 Const("_0",_) -> (w,z)
253 | Comb(Const("BIT0",_),t) -> bctr w (z + 1) t
254 | Comb(Const("BIT1",_),t) -> bctr (w + 1) z t
255 | _ -> failwith "malformed numeral" in
257 let rec wellformed tm =
259 Const("_0",_) -> true
260 | Comb(Const("BIT0",_),t)|Comb(Const("BIT1",_),t) -> wellformed t
262 let rec orderrelation mtm ntm =
264 if wellformed mtm then 0 else failwith "orderrelation"
267 Const("_0",_),Const("_0",_) -> 0
269 if wellformed ntm then -1 else failwith "orderrelation"
270 | _, Const("_0",_) ->
271 if wellformed ntm then 1 else failwith "orderrelation"
272 | Comb(Const("BIT0",_),mt),Comb(Const("BIT0",_),nt)
273 | Comb(Const("BIT1",_),mt),Comb(Const("BIT1",_),nt) ->
275 | Comb(Const("BIT0",_),mt),Comb(Const("BIT1",_),nt) ->
276 if orderrelation mt nt > 0 then 1 else -1
277 | Comb(Const("BIT1",_),mt),Comb(Const("BIT0",_),nt) ->
278 if orderrelation mt nt < 0 then -1 else 1 in
279 let doublebn tm = if tm = zero_tm then tm else mk_comb(BIT0_tm,tm) in
280 let rec subbn mtm ntm =
282 (_,Const("_0",_)) -> mtm
283 | (Comb(Const("BIT0",_),mt),Comb(Const("BIT0",_),nt)) ->
284 doublebn (subbn mt nt)
285 | (Comb(Const("BIT1",_),mt),Comb(Const("BIT1",_),nt)) ->
286 doublebn (subbn mt nt)
287 | (Comb(Const("BIT1",_),mt),Comb(Const("BIT0",_),nt)) ->
288 mk_comb(BIT1_tm,subbn mt nt)
289 | (Comb(Const("BIT0",_),mt),Comb(Const("BIT1",_),nt)) ->
290 mk_comb(BIT1_tm,sbcbn mt nt)
291 | _ -> failwith "malformed numeral or wrong relation"
294 | (Comb(Const("BIT0",_),mt),Const("_0",_)) ->
295 mk_comb(BIT1_tm,sbcbn mt ntm)
296 | (Comb(Const("BIT1",_),mt),Const("_0",_)) ->
298 | (Comb(Const("BIT0",_),mt),Comb(Const("BIT0",_),nt)) ->
299 mk_comb(BIT1_tm,sbcbn mt nt)
300 | (Comb(Const("BIT1",_),mt),Comb(Const("BIT1",_),nt)) ->
301 mk_comb(BIT1_tm,sbcbn mt nt)
302 | (Comb(Const("BIT1",_),mt),Comb(Const("BIT0",_),nt)) ->
303 doublebn (subbn mt nt)
304 | (Comb(Const("BIT0",_),mt),Comb(Const("BIT1",_),nt)) ->
305 doublebn (sbcbn mt nt)
306 | _ -> failwith "malformed numeral or wrong relation" in
309 Const("_0",_) -> 0,zero_tm
310 | Comb(Const("BIT1",_),Const("_0",_)) -> 1,zero_tm
311 | Comb(Const("BIT0",_),Comb(Const("BIT1",_),Const("_0",_))) -> 2,zero_tm
312 | Comb(Const("BIT1",_),Comb(Const("BIT1",_),Const("_0",_))) -> 3,zero_tm
313 | Comb(Const("BIT0",_),Comb(Const("BIT0",_),Comb(Const("BIT1",_),Const("_0",_)))) -> 4,zero_tm
314 | Comb(Const("BIT1",_),Comb(Const("BIT0",_),Comb(Const("BIT1",_),Const("_0",_)))) -> 5,zero_tm
315 | Comb(Const("BIT0",_),Comb(Const("BIT1",_),Comb(Const("BIT1",_),Const("_0",_)))) -> 6,zero_tm
316 | Comb(Const("BIT1",_),Comb(Const("BIT1",_),Comb(Const("BIT1",_),Const("_0",_)))) -> 7,zero_tm
317 | Comb(Const("BIT0",_),Comb(Const("BIT0",_),Comb(Const("BIT0",_),Comb(Const("BIT0",_),n)))) -> 0,n
318 | Comb(Const("BIT1",_),Comb(Const("BIT0",_),Comb(Const("BIT0",_),Comb(Const("BIT0",_),n)))) -> 1,n
319 | Comb(Const("BIT0",_),Comb(Const("BIT1",_),Comb(Const("BIT0",_),Comb(Const("BIT0",_),n)))) -> 2,n
320 | Comb(Const("BIT1",_),Comb(Const("BIT1",_),Comb(Const("BIT0",_),Comb(Const("BIT0",_),n)))) -> 3,n
321 | Comb(Const("BIT0",_),Comb(Const("BIT0",_),Comb(Const("BIT1",_),Comb(Const("BIT0",_),n)))) -> 4,n
322 | Comb(Const("BIT1",_),Comb(Const("BIT0",_),Comb(Const("BIT1",_),Comb(Const("BIT0",_),n)))) -> 5,n
323 | Comb(Const("BIT0",_),Comb(Const("BIT1",_),Comb(Const("BIT1",_),Comb(Const("BIT0",_),n)))) -> 6,n
324 | Comb(Const("BIT1",_),Comb(Const("BIT1",_),Comb(Const("BIT1",_),Comb(Const("BIT0",_),n)))) -> 7,n
325 | Comb(Const("BIT0",_),Comb(Const("BIT0",_),Comb(Const("BIT0",_),Comb(Const("BIT1",_),n)))) -> 8,n
326 | Comb(Const("BIT1",_),Comb(Const("BIT0",_),Comb(Const("BIT0",_),Comb(Const("BIT1",_),n)))) -> 9,n
327 | Comb(Const("BIT0",_),Comb(Const("BIT1",_),Comb(Const("BIT0",_),Comb(Const("BIT1",_),n)))) -> 10,n
328 | Comb(Const("BIT1",_),Comb(Const("BIT1",_),Comb(Const("BIT0",_),Comb(Const("BIT1",_),n)))) -> 11,n
329 | Comb(Const("BIT0",_),Comb(Const("BIT0",_),Comb(Const("BIT1",_),Comb(Const("BIT1",_),n)))) -> 12,n
330 | Comb(Const("BIT1",_),Comb(Const("BIT0",_),Comb(Const("BIT1",_),Comb(Const("BIT1",_),n)))) -> 13,n
331 | Comb(Const("BIT0",_),Comb(Const("BIT1",_),Comb(Const("BIT1",_),Comb(Const("BIT1",_),n)))) -> 14,n
332 | Comb(Const("BIT1",_),Comb(Const("BIT1",_),Comb(Const("BIT1",_),Comb(Const("BIT1",_),n)))) -> 15,n
333 | _ -> failwith "malformed numeral" in
334 let NUM_ADD_RULE,NUM_ADC_RULE =
335 let rec mk_compnumeral k base =
336 if k = 0 then base else
337 let t = mk_compnumeral (k / 2) base in
338 if k mod 2 = 1 then mk_comb(BIT1_tm,t) else mk_comb(BIT0_tm,t) in
340 let part2 = map (fun k -> mk_compnumeral k v) (8--15) in
341 let part1 = map (subst[mk_comb(BIT0_tm,v),mk_comb(BIT1_tm,v)])
343 and part0 = map (fun k -> mk_compnumeral k zero_tm) (0--15) in
344 part0 @ part1 @ part2 in
346 allpairs (fun mtm ntm ->
347 mk_comb(mk_comb(add_tm,mtm),ntm)) (bases m_tm) (bases n_tm) in
348 let BITS_INJ = (STANDARDIZE o prove)
349 (`(BIT0 m = BIT0 n <=> m = n) /\
350 (BIT1 m = BIT1 n <=> m = n)`,
351 REWRITE_TAC[BIT0; BIT1] THEN
352 REWRITE_TAC[GSYM MULT_2] THEN
353 REWRITE_TAC[SUC_INJ; EQ_MULT_LCANCEL; ARITH_EQ]) in
354 let ARITH_0 = (STANDARDIZE o MESON[NUMERAL; ADD_CLAUSES])
355 `m + _0 = m /\ _0 + n = n` in
356 let patadj = subst[`SUC(m + _0)`,`SUC m`; `SUC(_0 + n)`,`SUC n`] in
357 let mkclauses sucflag t =
358 let tm = if sucflag then mk_comb(suc_tm,t) else t in
359 let th1 = PURE_REWRITE_CONV[ARITH_ADD; ARITH_SUC; ARITH_0] tm in
360 let tm1 = patadj(rand(concl th1)) in
361 if not(free_in add_tm tm1) then th1,
362 (if free_in m_tm tm1 then 0 else 1) else
363 let ptm = rand(rand(rand(rand tm1))) in
364 let tmc = mk_eq(mk_eq(ptm,p_tm),mk_eq(tm,subst[p_tm,ptm] tm1)) in
365 EQT_ELIM(REWRITE_CONV[ARITH_ADD; ARITH_SUC; ARITH_0; BITS_INJ] tmc),
366 (if free_in suc_tm tm1 then 3 else 2) in
367 let add_clauses,add_flags =
368 let l1,l2 = unzip(map (mkclauses false) starts) in
369 Array.of_list(map STANDARDIZE l1),Array.of_list l2 in
370 let adc_clauses,adc_flags =
371 let l1,l2 = unzip(map (mkclauses true) starts) in
372 Array.of_list(map STANDARDIZE l1),Array.of_list l2 in
373 let rec NUM_ADD_RULE mtm ntm =
374 let m_lo,m_hi = topsplit mtm
375 and n_lo,n_hi = topsplit ntm in
376 let m_ind = if m_hi = zero_tm then m_lo else m_lo + 16
377 and n_ind = if n_hi = zero_tm then n_lo else n_lo + 16 in
378 let ind = 32 * m_ind + n_ind in
379 let th1 = Array.get add_clauses ind
380 and fl = Array.get add_flags ind in
382 0 -> INST [m_hi,m_tm] th1
383 | 1 -> INST [n_hi,n_tm] th1
384 | 2 -> let th2 = NUM_ADD_RULE m_hi n_hi in
385 (match concl th2 with Comb(_,ptm) ->
386 let th3 = INST [m_hi,m_tm; n_hi,n_tm;ptm,p_tm] th1 in
388 | 3 -> let th2 = NUM_ADC_RULE m_hi n_hi in
389 (match concl th2 with Comb(_,ptm) ->
390 let th3 = INST [m_hi,m_tm; n_hi,n_tm;ptm,p_tm] th1 in
392 and NUM_ADC_RULE mtm ntm =
393 let m_lo,m_hi = topsplit mtm
394 and n_lo,n_hi = topsplit ntm in
395 let m_ind = if m_hi = zero_tm then m_lo else m_lo + 16
396 and n_ind = if n_hi = zero_tm then n_lo else n_lo + 16 in
397 let ind = 32 * m_ind + n_ind in
398 let th1 = Array.get adc_clauses ind
399 and fl = Array.get adc_flags ind in
401 0 -> INST [m_hi,m_tm] th1
402 | 1 -> INST [n_hi,n_tm] th1
403 | 2 -> let th2 = NUM_ADD_RULE m_hi n_hi in
404 (match concl th2 with Comb(_,ptm) ->
405 let th3 = INST [m_hi,m_tm; n_hi,n_tm;ptm,p_tm] th1 in
407 | 3 -> let th2 = NUM_ADC_RULE m_hi n_hi in
408 (match concl th2 with Comb(_,ptm) ->
409 let th3 = INST [m_hi,m_tm; n_hi,n_tm;ptm,p_tm] th1 in
411 NUM_ADD_RULE,NUM_ADC_RULE in
413 let pth_0 = (STANDARDIZE o prove)
414 (`(n = a + p * b <=> BIT0 n = BIT0 a + BIT0 p * b)`,
415 REWRITE_TAC[BIT0; BIT1] THEN
416 REWRITE_TAC[GSYM MULT_2; GSYM MULT_ASSOC; GSYM LEFT_ADD_DISTRIB] THEN
417 REWRITE_TAC[EQ_MULT_LCANCEL; ARITH_EQ])
418 and pth_z = (STANDARDIZE o prove)
419 (`n = _0 + p * b <=> BIT0 n = _0 + BIT0 p * b`,
420 SUBST1_TAC(SYM(SPEC `_0` NUMERAL)) THEN
421 REWRITE_TAC[BIT1; BIT0] THEN
422 REWRITE_TAC[ADD_CLAUSES; GSYM MULT_2] THEN
423 REWRITE_TAC[GSYM MULT_ASSOC; EQ_MULT_LCANCEL; ARITH_EQ])
424 and pth_1 = (STANDARDIZE o prove)
425 (`(n = a + p * b <=> BIT1 n = BIT1 a + BIT0 p * b)`,
426 REWRITE_TAC[BIT0; BIT1] THEN
427 REWRITE_TAC[GSYM MULT_2; GSYM MULT_ASSOC; GSYM LEFT_ADD_DISTRIB;
428 ADD_CLAUSES; SUC_INJ] THEN
429 REWRITE_TAC[EQ_MULT_LCANCEL; ARITH_EQ])
430 and pth_base = (STANDARDIZE o prove)
431 (`n = _0 + BIT1 _0 * n`,
432 MESON_TAC[ADD_CLAUSES; MULT_CLAUSES; NUMERAL])
433 and pth_triv = (STANDARDIZE o prove)
434 (`_0 = a + p * b <=> _0 = a + BIT0 p * b`,
435 CONV_TAC(BINOP_CONV SYM_CONV) THEN
436 SUBST1_TAC(SYM(SPEC `_0` NUMERAL)) THEN
437 REWRITE_TAC[ADD_EQ_0; MULT_EQ_0; BIT0])
438 and pths_1 = (Array.of_list o CONJUNCTS o STANDARDIZE o prove)
440 BIT0(BIT0(BIT0(BIT0 n))) =
441 BIT0(BIT0(BIT0(BIT0 a))) + BIT0(BIT0(BIT0(BIT0 p))) * b) /\
443 BIT1(BIT0(BIT0(BIT0 n))) =
444 BIT1(BIT0(BIT0(BIT0 a))) + BIT0(BIT0(BIT0(BIT0 p))) * b) /\
446 BIT0(BIT1(BIT0(BIT0 n))) =
447 BIT0(BIT1(BIT0(BIT0 a))) + BIT0(BIT0(BIT0(BIT0 p))) * b) /\
449 BIT1(BIT1(BIT0(BIT0 n))) =
450 BIT1(BIT1(BIT0(BIT0 a))) + BIT0(BIT0(BIT0(BIT0 p))) * b) /\
452 BIT0(BIT0(BIT1(BIT0 n))) =
453 BIT0(BIT0(BIT1(BIT0 a))) + BIT0(BIT0(BIT0(BIT0 p))) * b) /\
455 BIT1(BIT0(BIT1(BIT0 n))) =
456 BIT1(BIT0(BIT1(BIT0 a))) + BIT0(BIT0(BIT0(BIT0 p))) * b) /\
458 BIT0(BIT1(BIT1(BIT0 n))) =
459 BIT0(BIT1(BIT1(BIT0 a))) + BIT0(BIT0(BIT0(BIT0 p))) * b) /\
461 BIT1(BIT1(BIT1(BIT0 n))) =
462 BIT1(BIT1(BIT1(BIT0 a))) + BIT0(BIT0(BIT0(BIT0 p))) * b) /\
464 BIT0(BIT0(BIT0(BIT1 n))) =
465 BIT0(BIT0(BIT0(BIT1 a))) + BIT0(BIT0(BIT0(BIT0 p))) * b) /\
467 BIT1(BIT0(BIT0(BIT1 n))) =
468 BIT1(BIT0(BIT0(BIT1 a))) + BIT0(BIT0(BIT0(BIT0 p))) * b) /\
470 BIT0(BIT1(BIT0(BIT1 n))) =
471 BIT0(BIT1(BIT0(BIT1 a))) + BIT0(BIT0(BIT0(BIT0 p))) * b) /\
473 BIT1(BIT1(BIT0(BIT1 n))) =
474 BIT1(BIT1(BIT0(BIT1 a))) + BIT0(BIT0(BIT0(BIT0 p))) * b) /\
476 BIT0(BIT0(BIT1(BIT1 n))) =
477 BIT0(BIT0(BIT1(BIT1 a))) + BIT0(BIT0(BIT0(BIT0 p))) * b) /\
479 BIT1(BIT0(BIT1(BIT1 n))) =
480 BIT1(BIT0(BIT1(BIT1 a))) + BIT0(BIT0(BIT0(BIT0 p))) * b) /\
482 BIT0(BIT1(BIT1(BIT1 n))) =
483 BIT0(BIT1(BIT1(BIT1 a))) + BIT0(BIT0(BIT0(BIT0 p))) * b) /\
485 BIT1(BIT1(BIT1(BIT1 n))) =
486 BIT1(BIT1(BIT1(BIT1 a))) + BIT0(BIT0(BIT0(BIT0 p))) * b)`,
487 MP_TAC(REWRITE_RULE[GSYM MULT_2] BIT0) THEN
488 MP_TAC(REWRITE_RULE[GSYM MULT_2] BIT1) THEN
489 ABBREV_TAC `two = 2` THEN
490 DISCH_THEN(fun th -> REWRITE_TAC[th]) THEN
491 DISCH_THEN(fun th -> REWRITE_TAC[th]) THEN
492 FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN
493 REWRITE_TAC[ADD_CLAUSES; SUC_INJ; EQ_MULT_LCANCEL; ARITH_EQ;
494 GSYM LEFT_ADD_DISTRIB; GSYM MULT_ASSOC])
495 and pths_0 = (Array.of_list o CONJUNCTS o STANDARDIZE o prove)
496 (`(n = _0 + p * b <=>
497 BIT0(BIT0(BIT0(BIT0 n))) =
498 _0 + BIT0(BIT0(BIT0(BIT0 p))) * b) /\
500 BIT1(BIT0(BIT0(BIT0 n))) =
501 BIT1 _0 + BIT0(BIT0(BIT0(BIT0 p))) * b) /\
503 BIT0(BIT1(BIT0(BIT0 n))) =
504 BIT0(BIT1 _0) + BIT0(BIT0(BIT0(BIT0 p))) * b) /\
506 BIT1(BIT1(BIT0(BIT0 n))) =
507 BIT1(BIT1 _0) + BIT0(BIT0(BIT0(BIT0 p))) * b) /\
509 BIT0(BIT0(BIT1(BIT0 n))) =
510 BIT0(BIT0(BIT1 _0)) + BIT0(BIT0(BIT0(BIT0 p))) * b) /\
512 BIT1(BIT0(BIT1(BIT0 n))) =
513 BIT1(BIT0(BIT1 _0)) + BIT0(BIT0(BIT0(BIT0 p))) * b) /\
515 BIT0(BIT1(BIT1(BIT0 n))) =
516 BIT0(BIT1(BIT1 _0)) + BIT0(BIT0(BIT0(BIT0 p))) * b) /\
518 BIT1(BIT1(BIT1(BIT0 n))) =
519 BIT1(BIT1(BIT1 _0)) + BIT0(BIT0(BIT0(BIT0 p))) * b) /\
521 BIT0(BIT0(BIT0(BIT1 n))) =
522 BIT0(BIT0(BIT0(BIT1 _0))) + BIT0(BIT0(BIT0(BIT0 p))) * b) /\
524 BIT1(BIT0(BIT0(BIT1 n))) =
525 BIT1(BIT0(BIT0(BIT1 _0))) + BIT0(BIT0(BIT0(BIT0 p))) * b) /\
527 BIT0(BIT1(BIT0(BIT1 n))) =
528 BIT0(BIT1(BIT0(BIT1 _0))) + BIT0(BIT0(BIT0(BIT0 p))) * b) /\
530 BIT1(BIT1(BIT0(BIT1 n))) =
531 BIT1(BIT1(BIT0(BIT1 _0))) + BIT0(BIT0(BIT0(BIT0 p))) * b) /\
533 BIT0(BIT0(BIT1(BIT1 n))) =
534 BIT0(BIT0(BIT1(BIT1 _0))) + BIT0(BIT0(BIT0(BIT0 p))) * b) /\
536 BIT1(BIT0(BIT1(BIT1 n))) =
537 BIT1(BIT0(BIT1(BIT1 _0))) + BIT0(BIT0(BIT0(BIT0 p))) * b) /\
539 BIT0(BIT1(BIT1(BIT1 n))) =
540 BIT0(BIT1(BIT1(BIT1 _0))) + BIT0(BIT0(BIT0(BIT0 p))) * b) /\
542 BIT1(BIT1(BIT1(BIT1 n))) =
543 BIT1(BIT1(BIT1(BIT1 _0))) + BIT0(BIT0(BIT0(BIT0 p))) * b)`,
544 SUBST1_TAC(MESON[NUMERAL] `_0 = 0`) THEN
545 MP_TAC(REWRITE_RULE[GSYM MULT_2] BIT0) THEN
546 MP_TAC(REWRITE_RULE[GSYM MULT_2] BIT1) THEN
547 ABBREV_TAC `two = 2` THEN
548 DISCH_THEN(fun th -> REWRITE_TAC[th]) THEN
549 DISCH_THEN(fun th -> REWRITE_TAC[th]) THEN
550 FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN
551 REWRITE_TAC[ADD_CLAUSES; SUC_INJ; EQ_MULT_LCANCEL; ARITH_EQ;
552 GSYM LEFT_ADD_DISTRIB; GSYM MULT_ASSOC]) in
553 let rec NUM_SHIFT_CONV k tm =
554 if k <= 0 then INST [tm,n_tm] pth_base else
556 Comb(_,Comb(_,Comb(_,Comb(_,_)))) when k >= 4 ->
557 let i,ntm = topsplit tm in
558 let th1 = NUM_SHIFT_CONV (k - 4) ntm in
559 (match concl th1 with
560 Comb(_,Comb(Comb(_,Const("_0",_)),Comb(Comb(_,ptm),btm))) ->
561 let th2 = Array.get pths_0 i in
562 let th3 = INST [ntm,n_tm; btm,b_tm; ptm,p_tm] th2 in
564 | Comb(_,Comb(Comb(_,atm),Comb(Comb(_,ptm),btm))) ->
565 let th2 = Array.get pths_1 i in
566 let th3 = INST[ntm,n_tm; atm,a_tm; btm,b_tm; ptm,p_tm] th2 in
568 | Comb(Const("BIT0",_),ntm) ->
569 let th1 = NUM_SHIFT_CONV (k - 1) ntm in
570 (match concl th1 with
571 Comb(_,Comb(Comb(_,Const("_0",_)),Comb(Comb(_,ptm),btm))) ->
572 EQ_MP (INST [ntm,n_tm; btm,b_tm; ptm,p_tm] pth_z) th1
573 | Comb(_,Comb(Comb(_,atm),Comb(Comb(_,ptm),btm))) ->
575 (INST[ntm,n_tm; atm,a_tm; btm,b_tm; ptm,p_tm] pth_0) th1)
576 | Comb(Const("BIT1",_),ntm) ->
577 let th1 = NUM_SHIFT_CONV (k - 1) ntm in
578 (match concl th1 with
579 Comb(_,Comb(Comb(_,atm),Comb(Comb(_,ptm),btm))) ->
581 (INST [ntm,n_tm; atm,a_tm; btm,b_tm; ptm,p_tm] pth_1) th1)
583 let th1 = NUM_SHIFT_CONV (k - 1) tm in
584 (match concl th1 with
585 Comb(_,Comb(Comb(_,atm),Comb(Comb(_,ptm),btm))) ->
586 EQ_MP (INST [atm,a_tm; btm,b_tm; ptm,p_tm] pth_triv)
588 | _ -> failwith "malformed numeral" in
590 let NUM_UNSHIFT_CONV =
591 let pth_triv = (STANDARDIZE o prove)
593 SUBST1_TAC(SYM(SPEC `_0` NUMERAL)) THEN
594 REWRITE_TAC[MULT_CLAUSES; ADD_CLAUSES])
595 and pth_base = (STANDARDIZE o prove)
596 (`a + BIT1 _0 * b = a + b`,
597 SUBST1_TAC(SYM(SPEC `BIT1 _0` NUMERAL)) THEN
598 REWRITE_TAC[MULT_CLAUSES; ADD_CLAUSES])
599 and pth_0 = (STANDARDIZE o prove)
600 (`BIT0 a + BIT0 p * b = BIT0(a + p * b)`,
601 REWRITE_TAC[BIT0] THEN REWRITE_TAC[GSYM MULT_2] THEN
602 REWRITE_TAC[GSYM MULT_ASSOC; GSYM LEFT_ADD_DISTRIB])
603 and pth_1 = (STANDARDIZE o prove)
604 (`BIT1 a + BIT0 p * b = BIT1(a + p * b)`,
605 REWRITE_TAC[BIT0; BIT1] THEN REWRITE_TAC[GSYM MULT_2] THEN
606 REWRITE_TAC[ADD_CLAUSES; SUC_INJ] THEN
607 REWRITE_TAC[GSYM MULT_ASSOC; GSYM LEFT_ADD_DISTRIB] THEN
608 REWRITE_TAC[EQ_MULT_LCANCEL; ARITH_EQ])
609 and pth_z = (STANDARDIZE o prove)
610 (`_0 + BIT0 p * b = BIT0(_0 + p * b)`,
611 SUBST1_TAC(SYM(SPEC `_0` NUMERAL)) THEN
612 REWRITE_TAC[BIT1; BIT0] THEN REWRITE_TAC[ADD_CLAUSES] THEN
613 REWRITE_TAC[RIGHT_ADD_DISTRIB])
614 and puths_1 = (Array.of_list o CONJUNCTS o STANDARDIZE o prove)
616 BIT0(BIT0(BIT0(BIT0 a))) + BIT0(BIT0(BIT0(BIT0 p))) * b =
617 BIT0(BIT0(BIT0(BIT0 n)))) /\
619 BIT1(BIT0(BIT0(BIT0 a))) + BIT0(BIT0(BIT0(BIT0 p))) * b =
620 BIT1(BIT0(BIT0(BIT0 n)))) /\
622 BIT0(BIT1(BIT0(BIT0 a))) + BIT0(BIT0(BIT0(BIT0 p))) * b =
623 BIT0(BIT1(BIT0(BIT0 n)))) /\
625 BIT1(BIT1(BIT0(BIT0 a))) + BIT0(BIT0(BIT0(BIT0 p))) * b =
626 BIT1(BIT1(BIT0(BIT0 n)))) /\
628 BIT0(BIT0(BIT1(BIT0 a))) + BIT0(BIT0(BIT0(BIT0 p))) * b =
629 BIT0(BIT0(BIT1(BIT0 n)))) /\
631 BIT1(BIT0(BIT1(BIT0 a))) + BIT0(BIT0(BIT0(BIT0 p))) * b =
632 BIT1(BIT0(BIT1(BIT0 n)))) /\
634 BIT0(BIT1(BIT1(BIT0 a))) + BIT0(BIT0(BIT0(BIT0 p))) * b =
635 BIT0(BIT1(BIT1(BIT0 n)))) /\
637 BIT1(BIT1(BIT1(BIT0 a))) + BIT0(BIT0(BIT0(BIT0 p))) * b =
638 BIT1(BIT1(BIT1(BIT0 n)))) /\
640 BIT0(BIT0(BIT0(BIT1 a))) + BIT0(BIT0(BIT0(BIT0 p))) * b =
641 BIT0(BIT0(BIT0(BIT1 n)))) /\
643 BIT1(BIT0(BIT0(BIT1 a))) + BIT0(BIT0(BIT0(BIT0 p))) * b =
644 BIT1(BIT0(BIT0(BIT1 n)))) /\
646 BIT0(BIT1(BIT0(BIT1 a))) + BIT0(BIT0(BIT0(BIT0 p))) * b =
647 BIT0(BIT1(BIT0(BIT1 n)))) /\
649 BIT1(BIT1(BIT0(BIT1 a))) + BIT0(BIT0(BIT0(BIT0 p))) * b =
650 BIT1(BIT1(BIT0(BIT1 n)))) /\
652 BIT0(BIT0(BIT1(BIT1 a))) + BIT0(BIT0(BIT0(BIT0 p))) * b =
653 BIT0(BIT0(BIT1(BIT1 n)))) /\
655 BIT1(BIT0(BIT1(BIT1 a))) + BIT0(BIT0(BIT0(BIT0 p))) * b =
656 BIT1(BIT0(BIT1(BIT1 n)))) /\
658 BIT0(BIT1(BIT1(BIT1 a))) + BIT0(BIT0(BIT0(BIT0 p))) * b =
659 BIT0(BIT1(BIT1(BIT1 n)))) /\
661 BIT1(BIT1(BIT1(BIT1 a))) + BIT0(BIT0(BIT0(BIT0 p))) * b =
662 BIT1(BIT1(BIT1(BIT1 n))))`,
663 SUBST1_TAC(MESON[NUMERAL] `_0 = 0`) THEN
664 MP_TAC(REWRITE_RULE[GSYM MULT_2] BIT0) THEN
665 MP_TAC(REWRITE_RULE[GSYM MULT_2] BIT1) THEN
666 ABBREV_TAC `two = 2` THEN
667 DISCH_THEN(fun th -> REWRITE_TAC[th]) THEN
668 DISCH_THEN(fun th -> REWRITE_TAC[th]) THEN
669 FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN
670 REWRITE_TAC[ADD_CLAUSES; SUC_INJ; EQ_MULT_LCANCEL; ARITH_EQ;
671 GSYM LEFT_ADD_DISTRIB; GSYM MULT_ASSOC]) in
672 let puths_2 = Array.of_list
673 (map (fun i -> let th1 = Array.get puths_1 (i mod 16)
674 and th2 = Array.get puths_1 (i / 16) in
675 let th3 = GEN_REWRITE_RULE RAND_CONV [th1] th2 in
676 STANDARDIZE th3) (0--255)) in
677 let rec NUM_UNSHIFT_CONV tm =
679 Comb(Comb(Const("+",_),atm),Comb(Comb(Const("*",_),ptm),btm)) ->
680 (match (atm,ptm,btm) with
681 (_,_,Const("_0",_)) ->
682 INST [atm,a_tm; ptm,p_tm] pth_triv
683 | (_,Comb(Const("BIT1",_),Const("_0",_)),_) ->
684 let th1 = INST [atm,a_tm; btm,b_tm] pth_base in
685 let Comb(_,Comb(Comb(_,mtm),ntm)) = concl th1 in
686 TRANS th1 (NUM_ADD_RULE mtm ntm)
687 | (Comb(_,Comb(_,Comb(_,Comb(_,atm')))),
688 Comb(_,Comb(_,Comb(_,Comb(_,(Comb(_,_) as ptm'))))),_) ->
689 let i,_ = topsplit atm in
690 (match (atm',ptm') with
691 (Comb(_,Comb(_,Comb(_,Comb(_,atm'')))),
692 Comb(_,Comb(_,Comb(_,Comb(_,(Comb(_,_) as ptm'')))))) ->
693 let j,_ = topsplit atm' in
694 let tm' = mk_comb(mk_comb(add_tm,atm''),
695 mk_comb(mk_comb(mul_tm,ptm''),btm)) in
696 let th1 = NUM_UNSHIFT_CONV tm' in
697 let th2 = INST [atm'',a_tm; ptm'',p_tm; btm,b_tm;
698 rand(concl th1),n_tm]
699 (Array.get puths_2 (16 * j + i)) in
702 let tm' = mk_comb(mk_comb(add_tm,atm'),
703 mk_comb(mk_comb(mul_tm,ptm'),btm)) in
704 let th1 = NUM_UNSHIFT_CONV tm' in
705 let th2 = INST [atm',a_tm; ptm',p_tm; btm,b_tm;
706 rand(concl th1),n_tm]
707 (Array.get puths_1 i) in
709 | (Const("_0",_),Comb(Const("BIT0",_),qtm),_) ->
710 let th1 = INST [btm,b_tm; qtm,p_tm] pth_z in
711 CONV_RULE(RAND_CONV(RAND_CONV NUM_UNSHIFT_CONV)) th1
712 | (Comb(Const("BIT0",_),ctm),Comb(Const("BIT0",_),qtm),_) ->
713 let th1 = INST [ctm,a_tm; btm,b_tm; qtm,p_tm] pth_0 in
714 CONV_RULE(RAND_CONV(RAND_CONV NUM_UNSHIFT_CONV)) th1
715 | (Comb(Const("BIT1",_),ctm),Comb(Const("BIT0",_),qtm),_) ->
716 let th1 = INST [ctm,a_tm; btm,b_tm; qtm,p_tm] pth_1 in
717 CONV_RULE(RAND_CONV(RAND_CONV NUM_UNSHIFT_CONV)) th1
718 | _ -> failwith "malformed numeral")
719 | _ -> failwith "malformed numeral" in
721 let NUM_SQUARE_RULE =
722 let pth_0 = (STANDARDIZE o prove)
724 MESON_TAC[NUMERAL; REWRITE_CONV[ARITH] `0 EXP 2`])
725 and pth_1 = (STANDARDIZE o prove)
726 (`(BIT1 _0) EXP 2 = BIT1 _0`,
727 MESON_TAC[NUMERAL; REWRITE_CONV[ARITH] `1 EXP 2`])
728 and pth_even = (STANDARDIZE o prove)
729 (`m EXP 2 = n <=> (BIT0 m) EXP 2 = BIT0(BIT0 n)`,
730 ABBREV_TAC `two = 2` THEN
731 REWRITE_TAC[BIT0] THEN EXPAND_TAC "two" THEN
732 REWRITE_TAC[GSYM MULT_2] THEN REWRITE_TAC[EXP_2] THEN
733 REWRITE_TAC[AC MULT_AC `(2 * m) * (2 * n) = 2 * 2 * m * n`] THEN
734 REWRITE_TAC[EQ_MULT_LCANCEL; ARITH_EQ])
735 and pth_odd = (STANDARDIZE o prove)
736 (`m EXP 2 = n <=> (BIT1 m) EXP 2 = BIT1(BIT0(m + n))`,
737 ABBREV_TAC `two = 2` THEN
738 REWRITE_TAC[NUMERAL; BIT0; BIT1] THEN
739 EXPAND_TAC "two" THEN REWRITE_TAC[GSYM MULT_2] THEN
740 REWRITE_TAC[EXP_2; MULT_CLAUSES; ADD_CLAUSES] THEN
741 REWRITE_TAC[SUC_INJ; GSYM MULT_ASSOC; GSYM LEFT_ADD_DISTRIB] THEN
742 REWRITE_TAC[AC ADD_AC `(m + m * 2 * m) + m = m * 2 * m + m + m`] THEN
743 REWRITE_TAC[GSYM MULT_2; AC MULT_AC `m * 2 * m = 2 * m * m`] THEN
744 REWRITE_TAC[GSYM MULT_ASSOC; GSYM LEFT_ADD_DISTRIB] THEN
745 REWRITE_TAC[EQ_MULT_LCANCEL; ARITH_EQ] THEN
746 GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [ADD_SYM] THEN
747 REWRITE_TAC[EQ_ADD_RCANCEL])
748 and pth_qstep = (UNDISCH o STANDARDIZE o prove)
752 ==> (BIT1(BIT1(BIT1 n))) EXP 2 = BIT1(BIT0(BIT0(BIT0 a)))`,
753 ABBREV_TAC `two = 2` THEN
754 SUBST1_TAC(MESON[NUMERAL] `_0 = 0`) THEN
755 REWRITE_TAC[BIT1; BIT0] THEN EXPAND_TAC "two" THEN
756 REWRITE_TAC[GSYM MULT_2] THEN
757 REWRITE_TAC[ADD1; LEFT_ADD_DISTRIB; GSYM ADD_ASSOC] THEN
758 REWRITE_TAC[MULT_ASSOC] THEN REWRITE_TAC[ARITH] THEN
759 REWRITE_TAC[IMP_CONJ] THEN
760 DISCH_THEN(SUBST1_TAC o SYM) THEN
761 DISCH_THEN(SUBST1_TAC o SYM) THEN DISCH_TAC THEN
762 MATCH_MP_TAC(MESON[EQ_ADD_LCANCEL]
763 `!m:num. m + n = m + p ==> n = p`) THEN
764 EXISTS_TAC `16 * (n + 1)` THEN
765 ASM_REWRITE_TAC[ADD_ASSOC; GSYM LEFT_ADD_DISTRIB] THEN
766 EXPAND_TAC "two" THEN REWRITE_TAC[EXP_2] THEN
767 REWRITE_TAC[LEFT_ADD_DISTRIB; RIGHT_ADD_DISTRIB] THEN
768 REWRITE_TAC[MULT_CLAUSES; MULT_ASSOC] THEN
769 REWRITE_TAC[AC MULT_AC `(8 * n) * NUMERAL p = (8 * NUMERAL p) * n`] THEN
770 REWRITE_TAC[ARITH] THEN
771 REWRITE_TAC[AC ADD_AC
772 `(n + 16) + p + q + 49 = (n + p + q) + (16 + 49)`] THEN
773 REWRITE_TAC[GSYM ADD_ASSOC] THEN REWRITE_TAC[ARITH] THEN
774 REWRITE_TAC[ADD_ASSOC; EQ_ADD_RCANCEL] THEN
775 REWRITE_TAC[GSYM ADD_ASSOC; GSYM MULT_2; MULT_ASSOC] THEN
776 ONCE_REWRITE_TAC[AC ADD_AC `a + b + c:num = b + a + c`] THEN
777 REWRITE_TAC[GSYM RIGHT_ADD_DISTRIB] THEN
779 and pth_rec = (UNDISCH o STANDARDIZE o prove)
787 ==> n EXP 2 = c + p * (b + p * a)`,
788 REWRITE_TAC[IMP_CONJ] THEN
789 DISCH_THEN SUBST1_TAC THEN
790 REPLICATE_TAC 5 (DISCH_THEN(SUBST1_TAC o SYM)) THEN
791 REWRITE_TAC[EXP_2; LEFT_ADD_DISTRIB; RIGHT_ADD_DISTRIB] THEN
792 REWRITE_TAC[MULT_AC] THEN CONV_TAC(BINOP_CONV NUM_CANCEL_CONV) THEN
793 DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[RIGHT_ADD_DISTRIB] THEN
794 REWRITE_TAC[MULT_AC] THEN REWRITE_TAC[ADD_AC])
795 and pth_toom3 = (STANDARDIZE o prove)
798 (l + BIT1 _0 * (m + BIT1 _0 * h)) EXP 2 =
799 a + BIT1 _0 * (b + BIT1 _0 * (c + BIT1 _0 * (d + BIT1 _0 * e))) /\
800 (l + BIT0(BIT1 _0) * (m + BIT0(BIT1 _0) * h)) EXP 2 =
801 a + BIT0(BIT1 _0) * (b + BIT0(BIT1 _0) *
802 (c + BIT0(BIT1 _0) * (d + BIT0(BIT1 _0) * e))) /\
803 (h + BIT0(BIT1 _0) * (m + BIT0(BIT1 _0) * l)) EXP 2 =
804 e + BIT0(BIT1 _0) * (d + BIT0(BIT1 _0) *
805 (c + BIT0(BIT1 _0) * (b + BIT0(BIT1 _0) * a)))
806 ==> (l + p * (m + p * h)) EXP 2 =
807 a + p * (b + p * (c + p * (d + p * e)))`,
808 ABBREV_TAC `two = 2` THEN
809 SUBST1_TAC(MESON[NUMERAL] `_0 = 0`) THEN
810 REWRITE_TAC[BIT1; BIT0] THEN
811 EXPAND_TAC "two" THEN REWRITE_TAC[GSYM MULT_2] THEN
812 REWRITE_TAC[ARITH] THEN
814 `!p x y z. (x + p * (y + p * z)) EXP 2 =
815 x * x + p * (2 * x * y + p * ((2 * x * z + y * y) +
816 p * (2 * y * z + p * z * z)))`
817 (fun th -> REWRITE_TAC[th])
819 [REWRITE_TAC[EXP_2; MULT_2; LEFT_ADD_DISTRIB; RIGHT_ADD_DISTRIB] THEN
820 REWRITE_TAC[MULT_AC] THEN REWRITE_TAC[ADD_AC];
821 REWRITE_TAC[EXP_2]] THEN
823 [`a':num = l * l`; `b' = 2 * l * m`; `c' = 2 * l * h + m * m`;
824 `d' = 2 * m * h`; `e':num = h * h`] THEN
825 SUBST1_TAC(AC MULT_AC `2 * m * l = 2 * l * m`) THEN
826 SUBST1_TAC(AC MULT_AC `2 * h * l = 2 * l * h`) THEN
827 SUBST1_TAC(AC MULT_AC `2 * h * m = 2 * m * h`) THEN
828 ASM_REWRITE_TAC[] THEN EXPAND_TAC "two" THEN
829 POP_ASSUM_LIST(K ALL_TAC) THEN
830 ASM_CASES_TAC `a':num = a` THEN ASM_REWRITE_TAC[] THEN
831 ASM_CASES_TAC `e':num = e` THEN ASM_REWRITE_TAC[] THEN
832 POP_ASSUM_LIST(K ALL_TAC) THEN
833 REWRITE_TAC[EQ_ADD_LCANCEL; EQ_MULT_LCANCEL] THEN
834 REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC] THEN
835 REWRITE_TAC[ARITH] THEN
836 REWRITE_TAC[MULT_CLAUSES; EQ_ADD_LCANCEL] THEN
837 REWRITE_TAC[ADD_ASSOC; EQ_ADD_RCANCEL] THEN
838 REWRITE_TAC[GSYM ADD_ASSOC] THEN DISCH_TAC THEN
839 FIRST_ASSUM(MP_TAC o MATCH_MP (MESON[]
840 `b = b' /\ c = c' /\ d = d'
841 ==> 5 * b + c' + d' = 5 * b' + c + d`)) THEN
842 REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC] THEN
843 REWRITE_TAC(map (fun k ->
844 SYM(REWRITE_CONV[ARITH_SUC]
845 (mk_comb(suc_tm,mk_small_numeral(k - 1)))))
847 REWRITE_TAC[MULT_CLAUSES; ADD_CLAUSES] THEN
848 CONV_TAC(LAND_CONV NUM_CANCEL_CONV) THEN DISCH_THEN SUBST_ALL_TAC THEN
849 FIRST_ASSUM(MP_TAC o MATCH_MP (MESON[]
850 `b = b' /\ c = c' /\ d = d'
851 ==> b + d':num = b' + d /\ 4 * b + d' = 4 * b' + d`)) THEN
852 REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC] THEN
853 REWRITE_TAC(map (fun k ->
854 SYM(REWRITE_CONV[ARITH_SUC]
855 (mk_comb(suc_tm,mk_small_numeral(k - 1)))))
857 REWRITE_TAC[MULT_CLAUSES; ADD_CLAUSES] THEN
858 CONV_TAC(LAND_CONV(BINOP_CONV NUM_CANCEL_CONV)) THEN
859 REWRITE_TAC[GSYM MULT_2] THEN ONCE_REWRITE_TAC[ADD_SYM] THEN
860 REWRITE_TAC[GSYM(el 4 (CONJUNCTS MULT_CLAUSES))] THEN
861 SIMP_TAC[EQ_MULT_LCANCEL; NOT_SUC])
862 and pth_even3 = (STANDARDIZE o prove)
864 (BIT0(BIT0(BIT0 m))) EXP 2 = BIT0(BIT0(BIT0(BIT0(BIT0(BIT0 n)))))`,
865 ABBREV_TAC `two = 2` THEN
866 REWRITE_TAC[BIT0] THEN REWRITE_TAC[GSYM MULT_2] THEN
867 EXPAND_TAC "two" THEN REWRITE_TAC[EXP_2] THEN
868 REWRITE_TAC[AC MULT_AC
869 `(2 * 2 * 2 * m) * 2 * 2 * 2 * m = 2 * 2 * 2 * 2 * 2 * 2 * m * m`] THEN
870 REWRITE_TAC[EQ_MULT_LCANCEL; ARITH_EQ]) in
871 let NUM_UNSHIFT2_CONV =
872 RAND_CONV(RAND_CONV NUM_UNSHIFT_CONV) THENC NUM_UNSHIFT_CONV in
873 let NUM_UNSHIFT3_CONV =
874 RAND_CONV(RAND_CONV NUM_UNSHIFT2_CONV) THENC NUM_UNSHIFT_CONV in
875 let NUM_UNSHIFT4_CONV =
876 RAND_CONV(RAND_CONV NUM_UNSHIFT3_CONV) THENC NUM_UNSHIFT_CONV in
877 let BINOP2_CONV conv1 conv2 = COMB2_CONV (RAND_CONV conv1) conv2 in
878 let TOOM3_CONV = BINOP2_CONV
879 (LAND_CONV NUM_UNSHIFT2_CONV) NUM_UNSHIFT4_CONV in
880 let rec GEN_NUM_SQUARE_RULE w z tm =
882 Const("_0",_) -> pth_0
883 | Comb(Const("BIT0",_),mtm) ->
885 Comb(Const("BIT0",_),Comb(Const("BIT0",_),ptm)) ->
886 let th1 = GEN_NUM_SQUARE_RULE w (z - 3) ptm in
887 let ntm = rand(concl th1) in
888 EQ_MP (INST [ptm,m_tm; ntm,n_tm] pth_even3) th1
890 let th1 = GEN_NUM_SQUARE_RULE w (z - 1) mtm in
891 let ntm = rand(concl th1) in
892 EQ_MP (INST [mtm,m_tm; ntm,n_tm] pth_even) th1)
893 | Comb(Const("BIT1",_),mtm) ->
894 if mtm = zero_tm then pth_1 else
895 if (w < 100 or z < 20) & w + z < 150 then
897 Comb(Const("BIT1",_),Comb(Const("BIT1",_),ntm)) ->
898 let th1 = NUM_ADD_RULE ntm one_tm in
899 let mtm = rand(concl th1) in
900 let th2 = NUM_SQUARE_RULE mtm in
901 let ptm = rand(concl th2) in
903 (mk_comb(BIT0_tm,mk_comb(BIT0_tm,ptm))) mtm in
904 let th3 = NUM_ADD_RULE mtm atm in
906 [atm,a_tm; mtm,m_tm; ntm,n_tm; ptm,p_tm] pth_qstep in
907 QUICK_PROVE_HYP (CONJ th1 (CONJ th2 th3)) th4
909 let th1 = GEN_NUM_SQUARE_RULE (w - 1) z mtm in
910 let ntm = rand(concl th1) in
911 let th2 = EQ_MP (INST [mtm,m_tm; ntm,n_tm] pth_odd) th1 in
912 (match concl th2 with
913 Comb(_,Comb(_,Comb(_,Comb(Comb(_,ptm),qtm)))) ->
914 let th3 = NUM_ADD_RULE ptm qtm in
915 TRANS th2 (AP_BIT1 (AP_BIT0 th3)))
916 else if w + z < 800 then
917 let k2 = (w + z) / 2 in
918 let th1 = NUM_SHIFT_CONV k2 tm in
919 let Comb(Comb(_,ltm),Comb(Comb(_,ptm),htm)) = rand(concl th1) in
920 let th2 = NUM_ADD_RULE htm ltm in
921 let mtm = rand(concl th2) in
922 let th3 = NUM_SQUARE_RULE htm
923 and th4 = NUM_SQUARE_RULE ltm
924 and th5 = NUM_SQUARE_RULE mtm in
925 let atm = rand(concl th3)
926 and ctm = rand(concl th4)
927 and dtm = rand(concl th5) in
928 let th6 = NUM_ADD_RULE atm ctm in
929 let etm = rand(concl th6) in
930 let btm = subbn dtm etm in
931 let th7 = NUM_ADD_RULE etm btm in
932 let dtm = rand(concl th7) in
933 let th8 = INST [atm,a_tm; btm,b_tm; ctm,c_tm; dtm,d_tm; etm,e_tm;
934 htm,h_tm; ltm,l_tm; mtm,m_tm; tm,n_tm; ptm,p_tm]
936 let th9 = QUICK_PROVE_HYP (end_itlist CONJ
937 [th1;th2;th3;th4;th5;th6;th7]) th8 in
938 CONV_RULE(RAND_CONV(RAND_CONV(RAND_CONV NUM_UNSHIFT_CONV) THENC
939 NUM_UNSHIFT_CONV)) th9
941 let k3 = (w + z) / 3 in
942 let th0 = (NUM_SHIFT_CONV k3 THENC
943 RAND_CONV(RAND_CONV(NUM_SHIFT_CONV k3))) tm in
944 let Comb(Comb(_,ltm),Comb(Comb(_,ptm),
945 Comb(Comb(_,mtm),Comb(Comb(_,_),htm)))) = rand(concl th0) in
946 let th1 = NUM_SQUARE_RULE htm
947 and th2 = NUM_SQUARE_RULE ltm in
948 let atm = rand(concl th2) and etm = rand(concl th1) in
949 let lnum = dest_raw_numeral ltm
950 and mnum = dest_raw_numeral mtm
951 and hnum = dest_raw_numeral htm in
952 let btm = rand(mk_numeral(num_2 */ lnum */ mnum))
953 and ctm = rand(mk_numeral(mnum */ mnum +/ num_2 */ lnum */ hnum))
954 and dtm = rand(mk_numeral(num_2 */ hnum */ mnum)) in
956 [atm,a_tm; btm,b_tm; ctm,c_tm; dtm,d_tm; etm,e_tm;
957 htm,h_tm; mtm,m_tm; ltm,l_tm; ptm,p_tm] pth_toom3 in
961 (BINOP2_CONV TOOM3_CONV (BINOP2_CONV TOOM3_CONV TOOM3_CONV))))
963 let [tm3;tm4;tm5] = conjuncts(rand(rand(lhand(concl th')))) in
964 let th3 = NUM_SQUARE_RULE (lhand(lhand tm3))
965 and th4 = NUM_SQUARE_RULE (lhand(lhand tm4))
966 and th5 = NUM_SQUARE_RULE (lhand(lhand tm5)) in
967 MP th' (end_itlist CONJ [th1;th2;th3;th4;th5])
968 and NUM_SQUARE_RULE tm =
969 let w,z = bitcounts tm in GEN_NUM_SQUARE_RULE w z tm in
972 let QUICK_PROVE_HYP ath bth =
973 EQ_MP (DEDUCT_ANTISYM_RULE ath bth) ath
974 and pth_0l,pth_0r = (CONJ_PAIR o STANDARDIZE o prove)
975 (`_0 * n = _0 /\ m * _0 = _0`,
976 MESON_TAC[NUMERAL; MULT_CLAUSES])
977 and pth_1l,pth_1r = (CONJ_PAIR o STANDARDIZE o prove)
978 (`(BIT1 _0) * n = n /\ m * (BIT1 _0) = m`,
979 MESON_TAC[NUMERAL; MULT_CLAUSES])
980 and pth_evenl,pth_evenr = (CONJ_PAIR o STANDARDIZE o prove)
981 (`(m * n = p <=> (BIT0 m) * n = BIT0 p) /\
982 (m * n = p <=> m * BIT0 n = BIT0 p)`,
983 REWRITE_TAC[BIT0] THEN REWRITE_TAC[GSYM MULT_2] THEN
984 REWRITE_TAC[AC MULT_AC `m * 2 * n = 2 * m * n`] THEN
985 REWRITE_TAC[GSYM MULT_ASSOC; EQ_MULT_LCANCEL; ARITH_EQ])
986 and pth_oddl,pth_oddr = (CONJ_PAIR o STANDARDIZE o prove)
987 (`(m * n = p <=> BIT1 m * n = BIT0 p + n) /\
988 (m * n = p <=> m * BIT1 n = BIT0 p + m)`,
989 REWRITE_TAC[BIT0; BIT1] THEN REWRITE_TAC[GSYM MULT_2] THEN
990 REWRITE_TAC[MULT_CLAUSES] THEN
991 REWRITE_TAC[MESON[MULT_AC; ADD_SYM] `m + m * 2 * n = 2 * m * n + m`] THEN
992 REWRITE_TAC[GSYM MULT_ASSOC; EQ_MULT_LCANCEL; EQ_ADD_RCANCEL] THEN
993 REWRITE_TAC[ARITH_EQ]) in
994 let pth_oo1 = (UNDISCH_ALL o STANDARDIZE o prove)
995 (`n + p = m /\ SUC(m + n) = a /\ p EXP 2 = b /\ a EXP 2 = c /\ b + d = c
996 ==> ((BIT1 m) * (BIT1 n) = d)`,
997 ABBREV_TAC `two = 2` THEN REWRITE_TAC[BIT1; IMP_CONJ] THEN
998 FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN
999 REWRITE_TAC[EXP_2; GSYM MULT_2] THEN
1000 REPLICATE_TAC 4 (DISCH_THEN(SUBST1_TAC o SYM)) THEN
1001 REWRITE_TAC[ADD1; AC ADD_AC `((n + p) + n) + 1 = (p + (n + n)) + 1`] THEN
1002 REWRITE_TAC[GSYM MULT_2] THEN
1003 REWRITE_TAC[LEFT_ADD_DISTRIB; RIGHT_ADD_DISTRIB] THEN
1004 REWRITE_TAC[GSYM ADD_ASSOC; MULT_CLAUSES; EQ_ADD_LCANCEL] THEN
1005 DISCH_THEN SUBST1_TAC THEN
1006 REWRITE_TAC[MULT_2; LEFT_ADD_DISTRIB; RIGHT_ADD_DISTRIB] THEN
1007 REWRITE_TAC[MULT_AC] THEN REWRITE_TAC[ADD_AC]) in
1008 let pth_oo2 = PURE_ONCE_REWRITE_RULE[MULT_SYM]
1009 (INST [n_tm,m_tm; m_tm,n_tm] pth_oo1) in
1010 let pth_recodel = (UNDISCH_ALL o STANDARDIZE o prove)
1011 (`SUC(_0 + m) = p ==> (p * n = a + n <=> m * n = a)`,
1012 SUBST1_TAC(MESON[NUMERAL] `_0 = 0`) THEN
1013 DISCH_THEN(SUBST1_TAC o SYM) THEN
1014 REWRITE_TAC[ADD_CLAUSES; MULT_CLAUSES; EQ_ADD_RCANCEL])
1015 and pth_recoder = (UNDISCH_ALL o STANDARDIZE o prove)
1016 (`SUC(_0 + n) = p ==> (m * p = a + m <=> m * n = a)`,
1017 ONCE_REWRITE_TAC[MULT_SYM] THEN
1018 SUBST1_TAC(MESON[NUMERAL] `_0 = 0`) THEN
1019 DISCH_THEN(SUBST1_TAC o SYM) THEN
1020 REWRITE_TAC[ADD_CLAUSES; MULT_CLAUSES; EQ_ADD_RCANCEL]) in
1021 let rec NUM_MUL_RULE k l tm tm' =
1023 (Const("_0",_),_) -> INST [tm',n_tm] pth_0l
1024 | (_,Const("_0",_)) -> INST [tm,m_tm] pth_0r
1025 | (Comb(Const("BIT1",_),Const("_0",_)),_) -> INST [tm',n_tm] pth_1l
1026 | (_,Comb(Const("BIT1",_),Const("_0",_))) -> INST [tm,m_tm] pth_1r
1027 | (Comb(Const("BIT0",_),mtm),_) ->
1028 let th0 = NUM_MUL_RULE (k - 1) l mtm tm' in
1030 [mtm,m_tm; tm',n_tm; rand(concl th0),p_tm] pth_evenl in
1032 | (_,Comb(Const("BIT0",_),ntm)) ->
1033 let th0 = NUM_MUL_RULE k (l - 1) tm ntm in
1035 [tm,m_tm; ntm,n_tm; rand(concl th0),p_tm] pth_evenr in
1037 | (Comb(Const("BIT1",_),mtm),Comb(Const("BIT1",_),ntm)) ->
1038 if k <= 50 or l <= 50 or
1039 Int k */ Int k <=/ Int l or
1040 Int l */ Int l <= Int k then
1041 match (mtm,ntm) with
1042 (Comb(Const("BIT1",_),Comb(Const("BIT1",_),_)),_) ->
1043 let th1 = NUM_ADC_RULE zero_tm tm in
1044 let ptm = rand(concl th1) in
1045 let th2 = NUM_MUL_RULE k l ptm tm' in
1046 let atm = subbn (rand(concl th2)) tm' in
1047 let th3 = INST [tm,m_tm; tm',n_tm; ptm,p_tm; atm,a_tm]
1049 let th4 = PROVE_HYP th1 th3 in
1050 EQ_MP th4 (TRANS th2 (SYM(NUM_ADD_RULE atm tm')))
1051 | (_,Comb(Const("BIT1",_),Comb(Const("BIT1",_),_))) ->
1052 let th1 = NUM_ADC_RULE zero_tm tm' in
1053 let ptm = rand(concl th1) in
1054 let th2 = NUM_MUL_RULE k l tm ptm in
1055 let atm = subbn (rand(concl th2)) tm in
1056 let th3 = INST [tm,m_tm; tm',n_tm; ptm,p_tm; atm,a_tm]
1058 let th4 = PROVE_HYP th1 th3 in
1059 EQ_MP th4 (TRANS th2 (SYM(NUM_ADD_RULE atm tm)))
1062 let th0 = NUM_MUL_RULE (k - 1) l mtm tm' in
1063 let ptm = rand(concl th0) in
1065 EQ_MP (INST [mtm,m_tm; tm',n_tm; ptm,p_tm] pth_oddl) th0 in
1066 let tm1 = lhand(rand(concl th1)) in
1067 TRANS th1 (NUM_ADD_RULE tm1 tm')
1069 let th0 = NUM_MUL_RULE k (l - 1) tm ntm in
1070 let ptm = rand(concl th0) in
1072 EQ_MP (INST [tm,m_tm; ntm,n_tm; ptm,p_tm] pth_oddr) th0 in
1073 let tm1 = lhand(rand(concl th1)) in
1074 TRANS th1 (NUM_ADD_RULE tm1 tm)
1076 let mval = dest_raw_numeral mtm
1077 and nval = dest_raw_numeral ntm in
1078 if nval <=/ mval then
1079 let ptm = rand(mk_numeral(mval -/ nval)) in
1080 let th2 = NUM_ADD_RULE ntm ptm
1081 and th3 = NUM_ADC_RULE mtm ntm in
1082 let atm = rand(concl th3) in
1083 let th4 = NUM_SQUARE_RULE ptm in
1084 let btm = rand(concl th4) in
1085 let th5 = NUM_SQUARE_RULE atm in
1086 let ctm = rand(concl th5) in
1087 let dtm = subbn ctm btm in
1088 let th6 = NUM_ADD_RULE btm dtm in
1089 let th1 = INST [atm,a_tm; btm,b_tm; ctm,c_tm; dtm,d_tm;
1090 mtm,m_tm; ntm,n_tm; ptm,p_tm] pth_oo1 in
1091 QUICK_PROVE_HYP (end_itlist CONJ
1092 [th2;th3;th4;th5;th6]) th1
1094 let ptm = rand(mk_numeral(nval -/ mval)) in
1095 let th2 = NUM_ADD_RULE mtm ptm
1096 and th3 = NUM_ADC_RULE ntm mtm in
1097 let atm = rand(concl th3) in
1098 let th4 = NUM_SQUARE_RULE ptm in
1099 let btm = rand(concl th4) in
1100 let th5 = NUM_SQUARE_RULE atm in
1101 let ctm = rand(concl th5) in
1102 let dtm = subbn ctm btm in
1103 let th6 = NUM_ADD_RULE btm dtm in
1104 let th1 = INST [atm,a_tm; btm,b_tm; ctm,c_tm; dtm,d_tm;
1105 mtm,m_tm; ntm,n_tm; ptm,p_tm] pth_oo2 in
1106 QUICK_PROVE_HYP (end_itlist CONJ
1107 [th2;th3;th4;th5;th6]) th1
1108 | _ -> failwith "NUM_MUL_RULE" in
1110 let NUM_MULT_CONV' =
1111 let pth_refl = (STANDARDIZE o MESON[EXP_2])
1112 `m EXP 2 = p <=> m * m = p` in
1115 Comb(Comb(Const("*",_),mtm),ntm) ->
1116 if Pervasives.compare mtm ntm = 0 then
1117 let th1 = NUM_SQUARE_RULE mtm in
1118 let ptm = rand(concl th1) in
1119 EQ_MP (INST [mtm,m_tm;ptm,p_tm] pth_refl) th1
1121 let w1,z1 = bitcounts mtm and w2,z2 = bitcounts ntm in
1122 NUM_MUL_RULE (w1+z1) (w2+z2) mtm ntm
1123 | _ -> failwith "NUM_MULT_CONV'" in
1125 let pth = (STANDARDIZE o prove)
1126 (`SUC(_0 + m) = n <=> SUC(NUMERAL m) = NUMERAL n`,
1127 BINOP_TAC THEN MESON_TAC[NUMERAL; ADD_CLAUSES]) in
1130 Comb(Const("SUC",_),Comb(Const("NUMERAL",_),mtm))
1131 when wellformed mtm ->
1132 let th1 = NUM_ADC_RULE zero_tm mtm in
1133 let ntm = rand(concl th1) in
1134 EQ_MP(INST [mtm,m_tm; ntm,n_tm] pth) th1
1135 | _ -> failwith "NUM_SUC_CONV" in
1137 let topthm_add = (STANDARDIZE o MESON[NUMERAL])
1138 `m + n = p <=> NUMERAL m + NUMERAL n = NUMERAL p` in
1141 Comb(Comb(Const("+",_),Comb(Const("NUMERAL",_),mtm)),
1142 Comb(Const("NUMERAL",_),ntm))
1143 when wellformed mtm & wellformed ntm ->
1144 let th1 = NUM_ADD_RULE mtm ntm in
1145 let ptm = rand(concl th1) in
1146 let th2 = INST [mtm,m_tm; ntm,n_tm; ptm,p_tm] topthm_add in
1148 | _ -> failwith "NUM_ADD_CONV" in
1150 let topthm_mul = (STANDARDIZE o MESON[NUMERAL])
1151 `m * n = p <=> NUMERAL m * NUMERAL n = NUMERAL p`
1152 and pth_refl = (STANDARDIZE o MESON[NUMERAL; EXP_2])
1153 `m EXP 2 = p <=> NUMERAL m * NUMERAL m = NUMERAL p` in
1156 Comb(Comb(Const("*",_),Comb(Const("NUMERAL",_),mtm)),
1157 Comb(Const("NUMERAL",_),ntm)) ->
1158 if Pervasives.compare mtm ntm = 0 then
1159 let th1 = NUM_SQUARE_RULE mtm in
1160 let ptm = rand(concl th1) in
1161 EQ_MP (INST [mtm,m_tm;ptm,p_tm] pth_refl) th1
1163 let w1,z1 = bitcounts mtm and w2,z2 = bitcounts ntm in
1164 let th1 = NUM_MUL_RULE (w1+z1) (w2+z2) mtm ntm in
1165 let ptm = rand(concl th1) in
1166 let th2 = INST [mtm,m_tm; ntm,n_tm; ptm,p_tm] topthm_mul in
1168 | _ -> failwith "NUM_MULT_CONV" in
1170 let pth0 = (STANDARDIZE o prove)
1171 (`(m EXP n = p) ==> (p * p = a) ==> (m EXP (BIT0 n) = a)`,
1172 REPEAT(DISCH_THEN(SUBST1_TAC o SYM)) THEN
1173 REWRITE_TAC[BIT0; EXP_ADD])
1174 and pth1 = (STANDARDIZE o prove)
1175 (`(m EXP n = p) ==> (p * p = b) ==> (m * b = a) ==> (m EXP (BIT1 n) = a)`,
1176 REPEAT(DISCH_THEN(SUBST1_TAC o SYM)) THEN
1177 REWRITE_TAC[BIT1; EXP_ADD; EXP])
1178 and pth = (STANDARDIZE o prove)
1179 (`m EXP _0 = BIT1 _0`,
1180 MP_TAC (CONJUNCT1 EXP) THEN REWRITE_TAC[NUMERAL; BIT1] THEN
1181 DISCH_THEN MATCH_ACCEPT_TAC)
1182 and tth = (STANDARDIZE o prove)
1183 (`(NUMERAL m) EXP (NUMERAL n) = m EXP n`,
1184 REWRITE_TAC[NUMERAL])
1185 and fth = (STANDARDIZE o prove)
1187 REWRITE_TAC[NUMERAL]) in
1188 let tconv = GEN_REWRITE_CONV I [tth] in
1189 let rec NUM_EXP_CONV l r =
1190 if r = zero_tm then INST [l,m_tm] pth else
1191 let b,r' = dest_comb r in
1193 let th1 = NUM_EXP_CONV l r' in
1194 let tm1 = rand(concl th1) in
1195 let th2 = NUM_MULT_CONV' (mk_binop mul_tm tm1 tm1) in
1196 let tm2 = rand(concl th2) in
1197 MP (MP (INST [l,m_tm; r',n_tm; tm1,p_tm; tm2,a_tm] pth0) th1) th2
1199 let th1 = NUM_EXP_CONV l r' in
1200 let tm1 = rand(concl th1) in
1201 let th2 = NUM_MULT_CONV' (mk_binop mul_tm tm1 tm1) in
1202 let tm2 = rand(concl th2) in
1203 let th3 = NUM_MULT_CONV' (mk_binop mul_tm l tm2) in
1204 let tm3 = rand(concl th3) in
1205 MP (MP (MP (INST [l,m_tm; r',n_tm; tm1,p_tm; tm2,b_tm; tm3,a_tm]
1206 pth1) th1) th2) th3 in
1207 fun tm -> try let th = tconv tm in
1208 let lop,r = dest_comb (rand(concl th)) in
1209 let _,l = dest_comb lop in
1210 if not (wellformed l & wellformed r) then failwith "" else
1211 let th' = NUM_EXP_CONV l r in
1212 let tm' = rand(concl th') in
1213 TRANS (TRANS th th') (INST [tm',m_tm] fth)
1214 with Failure _ -> failwith "NUM_EXP_CONV" in
1216 let pth = (UNDISCH o STANDARDIZE o prove)
1217 (`SUC(m + n) = p ==> ((NUMERAL n < NUMERAL p) <=> T)`,
1218 REWRITE_TAC[NUMERAL; LT_EXISTS; ADD_CLAUSES] THEN
1220 and qth = (UNDISCH o STANDARDIZE o prove)
1221 (`m + p = n ==> (NUMERAL n < NUMERAL p <=> F)`,
1222 DISCH_THEN(SUBST1_TAC o SYM) THEN
1223 REWRITE_TAC[NOT_LT; NUMERAL] THEN
1224 MESON_TAC[LE_ADD; ADD_SYM])
1225 and rth = (STANDARDIZE o prove)
1226 (`NUMERAL n < NUMERAL n <=> F`,
1227 MESON_TAC[LT_REFL]) in
1230 Comb(Comb(Const("<",_),Comb(Const("NUMERAL",_),mtm)),
1231 Comb(Const("NUMERAL",_),ntm)) ->
1232 let rel = orderrelation mtm ntm in
1233 if rel = 0 then INST[ntm,n_tm] rth
1234 else if rel < 0 then
1235 let dtm = sbcbn ntm mtm in
1236 let th = NUM_ADC_RULE dtm mtm in
1237 QUICK_PROVE_HYP th (INST [dtm,m_tm; mtm,n_tm; ntm,p_tm] pth)
1239 let dtm = subbn mtm ntm in
1240 let th = NUM_ADD_RULE dtm ntm in
1241 QUICK_PROVE_HYP th (INST [dtm,m_tm; mtm,n_tm; ntm,p_tm] qth)
1242 | _ -> failwith "NUM_LT_CONV"
1244 let pth = (UNDISCH o STANDARDIZE o prove)
1245 (`m + n = p ==> ((NUMERAL n <= NUMERAL p) <=> T)`,
1246 DISCH_THEN(SUBST1_TAC o SYM) THEN
1247 REWRITE_TAC[NUMERAL] THEN
1248 MESON_TAC[LE_ADD; ADD_SYM])
1249 and qth = (UNDISCH o STANDARDIZE o prove)
1250 (`SUC(m + p) = n ==> (NUMERAL n <= NUMERAL p <=> F)`,
1251 DISCH_THEN(SUBST1_TAC o SYM) THEN
1252 REWRITE_TAC[NUMERAL; NOT_LE; ADD_CLAUSES; LT_EXISTS] THEN
1254 and rth = (STANDARDIZE o prove)
1255 (`NUMERAL n <= NUMERAL n <=> T`,
1256 REWRITE_TAC[LE_REFL]) in
1259 Comb(Comb(Const("<=",_),Comb(Const("NUMERAL",_),mtm)),
1260 Comb(Const("NUMERAL",_),ntm)) ->
1261 let rel = orderrelation mtm ntm in
1262 if rel = 0 then INST[ntm,n_tm] rth
1263 else if rel < 0 then
1264 let dtm = subbn ntm mtm in
1265 let th = NUM_ADD_RULE dtm mtm in
1266 QUICK_PROVE_HYP th (INST [dtm,m_tm; mtm,n_tm; ntm,p_tm] pth)
1268 let dtm = sbcbn mtm ntm in
1269 let th = NUM_ADC_RULE dtm ntm in
1270 QUICK_PROVE_HYP th (INST [dtm,m_tm; mtm,n_tm; ntm,p_tm] qth)
1271 | _ -> failwith "NUM_LE_CONV"
1273 let pth = (UNDISCH o STANDARDIZE o prove)
1274 (`SUC(m + n) = p ==> ((NUMERAL n = NUMERAL p) <=> F)`,
1275 DISCH_THEN(SUBST1_TAC o SYM) THEN
1276 REWRITE_TAC[NUMERAL; GSYM LE_ANTISYM; DE_MORGAN_THM] THEN
1277 REWRITE_TAC[NOT_LE; LT_EXISTS; ADD_CLAUSES] THEN
1279 and qth = (UNDISCH o STANDARDIZE o prove)
1280 (`SUC(m + p) = n ==> ((NUMERAL n = NUMERAL p) <=> F)`,
1281 DISCH_THEN(SUBST1_TAC o SYM) THEN
1282 REWRITE_TAC[NUMERAL; GSYM LE_ANTISYM; DE_MORGAN_THM] THEN
1283 REWRITE_TAC[NOT_LE; LT_EXISTS; ADD_CLAUSES] THEN
1285 and rth = (STANDARDIZE o prove)
1286 (`(NUMERAL n = NUMERAL n) <=> T`,
1290 Comb(Comb(Const("=",_),Comb(Const("NUMERAL",_),mtm)),
1291 Comb(Const("NUMERAL",_),ntm)) ->
1292 let rel = orderrelation mtm ntm in
1293 if rel = 0 then INST [ntm,n_tm] rth
1294 else if rel < 0 then
1295 let dtm = sbcbn ntm mtm in
1296 let th = NUM_ADC_RULE dtm mtm in
1297 QUICK_PROVE_HYP th (INST [dtm,m_tm; mtm,n_tm; ntm,p_tm] pth)
1299 let dtm = sbcbn mtm ntm in
1300 let th = NUM_ADC_RULE dtm ntm in
1301 QUICK_PROVE_HYP th (INST [dtm,m_tm; mtm,n_tm; ntm,p_tm] qth)
1302 | _ -> failwith "NUM_EQ_CONV" in
1303 NUM_SUC_CONV,NUM_ADD_CONV,NUM_MULT_CONV,NUM_EXP_CONV,
1304 NUM_LT_CONV,NUM_LE_CONV,NUM_EQ_CONV;;
1306 let NUM_GT_CONV = GEN_REWRITE_CONV I [GT] THENC NUM_LT_CONV;;
1308 let NUM_GE_CONV = GEN_REWRITE_CONV I [GE] THENC NUM_LE_CONV;;
1313 REWRITE_TAC[PRE]) in
1315 (`(SUC m = n) ==> (PRE n = m)`,
1316 DISCH_THEN(SUBST1_TAC o SYM) THEN REWRITE_TAC[PRE])
1317 and m = `m:num` and n = `n:num` in
1320 fun tm -> try let l,r = dest_comb tm in
1321 if not (l = pre) then fail() else
1322 let x = dest_numeral r in
1323 if x =/ Int 0 then tth else
1324 let tm' = mk_numeral (x -/ Int 1) in
1325 let th1 = NUM_SUC_CONV (mk_comb(suc,tm')) in
1326 MP (INST [tm',m; r,n] pth) th1
1327 with Failure _ -> failwith "NUM_PRE_CONV";;
1331 (`p <= n ==> (p - n = 0)`,
1332 REWRITE_TAC[SUB_EQ_0])
1334 (`(m + n = p) ==> (p - n = m)`,
1335 DISCH_THEN(SUBST1_TAC o SYM) THEN
1336 REWRITE_TAC[ADD_SUB])
1337 and m = `m:num` and n = `n:num` and p = `p:num`
1341 fun tm -> try let l,r = dest_binop minus tm in
1342 let ln = dest_numeral l
1343 and rn = dest_numeral r in
1345 let pth = INST [l,p; r,n] pth0
1346 and th0 = EQT_ELIM(NUM_LE_CONV (mk_binop le l r)) in
1349 let kn = ln -/ rn in
1350 let k = mk_numeral kn in
1351 let pth = INST [k,m; l,p; r,n] pth1
1352 and th0 = NUM_ADD_CONV (mk_binop plus k r) in
1354 with Failure _ -> failwith "NUM_SUB_CONV";;
1356 let NUM_DIV_CONV,NUM_MOD_CONV =
1358 (`(q * n + r = m) ==> r < n ==> (m DIV n = q) /\ (m MOD n = r)`,
1359 MESON_TAC[DIVMOD_UNIQ])
1360 and m = `m:num` and n = `n:num` and q = `q:num` and r = `r:num`
1361 and dtm = `(DIV)` and mtm = `(MOD)` in
1362 let NUM_DIVMOD_CONV x y =
1364 and l = mod_num x y in
1365 let th0 = INST [mk_numeral x,m; mk_numeral y,n;
1366 mk_numeral k,q; mk_numeral l,r] pth in
1367 let tm0 = lhand(lhand(concl th0)) in
1368 let th1 = (LAND_CONV NUM_MULT_CONV THENC NUM_ADD_CONV) tm0 in
1369 let th2 = MP th0 th1 in
1370 let tm2 = lhand(concl th2) in
1371 MP th2 (EQT_ELIM(NUM_LT_CONV tm2)) in
1372 (fun tm -> try let xt,yt = dest_binop dtm tm in
1373 CONJUNCT1(NUM_DIVMOD_CONV (dest_numeral xt) (dest_numeral yt))
1374 with Failure _ -> failwith "NUM_DIV_CONV"),
1375 (fun tm -> try let xt,yt = dest_binop mtm tm in
1376 CONJUNCT2(NUM_DIVMOD_CONV (dest_numeral xt) (dest_numeral yt))
1377 with Failure _ -> failwith "NUM_MOD_CONV");;
1386 (`(SUC x = y) ==> (FACT x = w) ==> (y * w = z) ==> (FACT y = z)`,
1387 REPEAT (DISCH_THEN(SUBST1_TAC o SYM)) THEN
1389 and w = `w:num` and x = `x:num` and y = `y:num` and z = `z:num` in
1391 let n' = n -/ (Int 1) in
1392 NUM_SUC_CONV (mk_comb(suc,mk_numeral n')) in
1393 let rec NUM_FACT_CONV n =
1394 if n =/ Int 0 then pth_0 else
1395 let th0 = mksuc n in
1396 let tmx = rand(lhand(concl th0)) in
1397 let tm0 = rand(concl th0) in
1398 let th1 = NUM_FACT_CONV (n -/ Int 1) in
1399 let tm1 = rand(concl th1) in
1400 let th2 = NUM_MULT_CONV (mk_binop mul tm0 tm1) in
1401 let tm2 = rand(concl th2) in
1402 let pth = INST [tmx,x; tm0, y; tm1,w; tm2,z] pth_suc in
1403 MP (MP (MP pth th0) th1) th2 in
1405 try let l,r = dest_comb tm in
1406 if fst(dest_const l) = "FACT"
1407 then NUM_FACT_CONV (dest_numeral r)
1409 with Failure _ -> failwith "NUM_FACT_CONV";;
1413 RATOR_CONV(RATOR_CONV(RAND_CONV NUM_LE_CONV)) THENC
1414 GEN_REWRITE_CONV I [COND_CLAUSES];;
1418 RATOR_CONV(RATOR_CONV(RAND_CONV NUM_LE_CONV)) THENC
1419 GEN_REWRITE_CONV I [COND_CLAUSES];;
1421 (* ------------------------------------------------------------------------- *)
1422 (* Final hack-together. *)
1423 (* ------------------------------------------------------------------------- *)
1426 let gconv_net = itlist (uncurry net_of_conv)
1427 [`NUMERAL m < NUMERAL n`,NUM_LT_CONV;
1428 `NUMERAL m <= NUMERAL n`,NUM_LE_CONV;
1429 `NUMERAL m > NUMERAL n`,NUM_GT_CONV;
1430 `NUMERAL m >= NUMERAL n`,NUM_GE_CONV;
1431 `NUMERAL m = NUMERAL n`,NUM_EQ_CONV]
1433 REWRITES_CONV gconv_net;;
1436 let gconv_net = itlist (uncurry net_of_conv)
1437 [`SUC(NUMERAL n)`,NUM_SUC_CONV;
1438 `PRE(NUMERAL n)`,NUM_PRE_CONV;
1439 `FACT(NUMERAL n)`,NUM_FACT_CONV;
1440 `NUMERAL m < NUMERAL n`,NUM_LT_CONV;
1441 `NUMERAL m <= NUMERAL n`,NUM_LE_CONV;
1442 `NUMERAL m > NUMERAL n`,NUM_GT_CONV;
1443 `NUMERAL m >= NUMERAL n`,NUM_GE_CONV;
1444 `NUMERAL m = NUMERAL n`,NUM_EQ_CONV;
1445 `EVEN(NUMERAL n)`,NUM_EVEN_CONV;
1446 `ODD(NUMERAL n)`,NUM_ODD_CONV;
1447 `NUMERAL m + NUMERAL n`,NUM_ADD_CONV;
1448 `NUMERAL m - NUMERAL n`,NUM_SUB_CONV;
1449 `NUMERAL m * NUMERAL n`,NUM_MULT_CONV;
1450 `(NUMERAL m) EXP (NUMERAL n)`,NUM_EXP_CONV;
1451 `(NUMERAL m) DIV (NUMERAL n)`,NUM_DIV_CONV;
1452 `(NUMERAL m) MOD (NUMERAL n)`,NUM_MOD_CONV;
1453 `MAX (NUMERAL m) (NUMERAL n)`,NUM_MAX_CONV;
1454 `MIN (NUMERAL m) (NUMERAL n)`,NUM_MIN_CONV]
1456 REWRITES_CONV gconv_net;;
1458 let NUM_REDUCE_CONV = DEPTH_CONV NUM_RED_CONV;;
1460 let NUM_REDUCE_TAC = CONV_TAC NUM_REDUCE_CONV;;
1462 (* ------------------------------------------------------------------------- *)
1463 (* I do like this after all... *)
1464 (* ------------------------------------------------------------------------- *)
1467 let SUC_tm = `SUC` in
1469 let n = dest_numeral tm -/ Int 1 in
1470 if n </ Int 0 then failwith "num_CONV" else
1471 let tm' = mk_numeral n in
1472 SYM(NUM_SUC_CONV (mk_comb(SUC_tm,tm')));;
1474 (* ------------------------------------------------------------------------- *)
1475 (* Expands "!n. n < numeral-constant ==> P(n)" into all the cases. *)
1476 (* ------------------------------------------------------------------------- *)
1478 let EXPAND_CASES_CONV =
1479 let pth_base = prove
1480 (`(!n. n < 0 ==> P n) <=> T`,
1482 and pth_step = prove
1483 (`(!n. n < SUC k ==> P n) <=> (!n. n < k ==> P n) /\ P k`,
1484 REWRITE_TAC[LT] THEN MESON_TAC[]) in
1485 let base_CONV = GEN_REWRITE_CONV I [pth_base]
1487 BINDER_CONV(LAND_CONV(RAND_CONV num_CONV)) THENC
1488 GEN_REWRITE_CONV I [pth_step] in
1490 (base_CONV ORELSEC (step_CONV THENC LAND_CONV conv)) tm in
1491 conv THENC (REWRITE_CONV[GSYM CONJ_ASSOC]);;