1structure acl2encodeLib :> acl2encodeLib =
2struct
3
4(*****************************************************************************)
5(* Used to encode functions from HOL to ACL2                                 *)
6(*****************************************************************************)
7
8open Lib Parse Type Term Drule Thm Tactical bossLib
9open Rewrite polytypicLib encodeLib functionEncodeLib
10open translateTheory extendTranslateTheory wordsLib intLib
11
12(*
13app load ["intLib","wordsLib","extendTranslateTheory","functionEncodeLib", "fmap_encodeTheory"];
14*)
15
16(*****************************************************************************)
17(* Abbreviations for types to avoid parsing later...                         *)
18(*****************************************************************************)
19
20val num = ``:num``;
21val int = ``:int``;
22val rat = ``:rat``;
23val com = ``:complex_rational``;
24val bool = ``:bool``;
25val char = ``:char``;
26val string = ``:string``;
27val pair = ``:'a # 'b``;
28val list = ``:'a list``;
29val sexp = ``:sexp``;
30val fcp = ``:'a ** 'b``;
31val word = ``:'a word``;
32
33infix &&&;
34fun (a &&& b) = a andalso b;
35
36(*****************************************************************************)
37(* A rule to generate the theorem: |- X o I = X   for some X                 *)
38(*****************************************************************************)
39
40fun simple_encode_map_encode tm = CONJUNCT2 (ISPEC tm combinTheory.I_o_ID);
41
42fun simple_map_compose t =
43    CONJUNCT1 (ISPEC (mk_const("I",t --> t)) combinTheory.I_o_ID);
44
45(*****************************************************************************)
46(* Some required theorems and functions for which the whole package is       *)
47(* uneccessary.                                                              *)
48(*****************************************************************************)
49
50val GSYM = Conv.GSYM;
51val I_THM = combinTheory.I_THM;
52val K_THM = combinTheory.K_THM;
53
54(*****************************************************************************)
55(* Keeping track of whats in ..                                              *)
56(*****************************************************************************)
57
58exception ExistsAlready;
59
60val performed = ref ([]:string list);
61
62fun perform string =
63    if Lib.mem string (!performed) then raise ExistsAlready
64       else (performed := string :: (!performed));
65
66fun tryperform string =
67    if Lib.mem string (!performed) then raise ExistsAlready else ();
68
69(*****************************************************************************)
70(* Add the type-translation theorems for natural numbers                     *)
71(*****************************************************************************)
72
73fun add_num_translations () =
74let val _ = perform "add_num_translations"
75    val _ = add_translation sexp num
76    val _ = add_coding_function sexp num "encode"
77        {const = ``nat``,definition = sexpTheory.nat_def,induction = NONE};
78    val _ = add_coding_function sexp num "decode"
79        {const = ``sexp_to_nat``,definition = translateTheory.sexp_to_nat_def,
80         induction = NONE};
81    val _ = add_coding_function sexp num "detect"
82        {const = ``sexp_to_bool o natp``,
83         definition = hol_defaxiomsTheory.natp_def,
84         induction = NONE};
85
86    val _ = add_source_function num "map"
87        {const = ``I``,definition = I_THM,induction = NONE};
88    val _ = add_source_function num "all"
89        {const = ``K T``,definition = K_THM,induction = NONE};
90    val _ = add_coding_function sexp num "fix"
91        {const = ``nfix``,definition = hol_defaxiomsTheory.nfix_def,
92         induction = NONE};
93
94    val _ = add_coding_theorem sexp num "encode_decode_map"
95            translateTheory.ENCDECMAP_NAT;
96    val _ = add_coding_theorem sexp num "encode_detect_all"
97            translateTheory.ENCDETALL_NAT;
98    val _ = add_coding_theorem sexp num "decode_encode_fix"
99            translateTheory.DECENCFIX_NAT;
100    val _ = add_coding_theorem sexp num "encode_map_encode"
101            (simple_encode_map_encode ``nat``)
102    val _ = add_coding_theorem sexp num "fix_id"
103            translateTheory.FIXID_NAT;
104    val _ = add_source_theorem sexp "map_compose" (simple_map_compose sexp);
105    val _ = add_source_theorem num "map_compose" (simple_map_compose num);
106
107    val _ = add_coding_theorem sexp num "detect_dead"
108            translateTheory.DETDEAD_NAT;
109    val _ = add_coding_theorem sexp num "general_detect"
110            (DECIDE ``!x. (sexp_to_bool o natp) x ==>
111                          (sexp_to_bool o natp) x``)
112in
113    ()
114end handle ExistsAlready => ()
115
116(*****************************************************************************)
117(* Add the type-translation theorems for integers                            *)
118(*****************************************************************************)
119
120fun add_int_translations () =
121let val _ = perform "add_int_translations"
122    val _ = add_translation sexp int
123    val _ = add_coding_function sexp int "encode"
124        {const = ``int``,definition = sexpTheory.int_def,induction = NONE};
125    val _ = add_coding_function sexp int "decode"
126        {const = ``sexp_to_int``,definition = translateTheory.sexp_to_int_def,
127         induction = NONE};
128    val _ = add_coding_function sexp int "detect"
129        {const = ``sexp_to_bool o integerp``,
130         definition = sexpTheory.integerp_def,
131         induction = NONE};
132
133    val _ = add_source_function int "map"
134        {const = ``I``,definition = I_THM,induction = NONE};
135    val _ = add_source_function int "all"
136        {const = ``K T``,definition = K_THM,induction = NONE};
137    val _ = add_coding_function sexp int "fix"
138        {const = ``ifix``,definition = hol_defaxiomsTheory.ifix_def,
139         induction = NONE};
140
141    val _ = add_coding_theorem sexp int "encode_decode_map"
142            translateTheory.ENCDECMAP_INT;
143    val _ = add_coding_theorem sexp int "encode_detect_all"
144            translateTheory.ENCDETALL_INT;
145    val _ = add_coding_theorem sexp int "decode_encode_fix"
146            translateTheory.DECENCFIX_INT;
147    val _ = add_coding_theorem sexp int "encode_map_encode"
148            (simple_encode_map_encode ``int``)
149    val _ = add_coding_theorem sexp int "fix_id"
150            translateTheory.FIXID_INT;
151    val _ = add_source_theorem int "map_compose" (simple_map_compose int);
152
153    val _ = add_coding_theorem sexp int "detect_dead"
154            translateTheory.DETDEAD_INT;
155    val _ = add_coding_theorem sexp int "general_detect"
156            (DECIDE ``!x. (sexp_to_bool o integerp) x ==>
157                          (sexp_to_bool o integerp) x``)
158    val _ = set_bottom_value int ``0i``
159in
160    ()
161end handle ExistsAlready => ()
162
163(*****************************************************************************)
164(* Add the type-translation theorems for booleans                            *)
165(*****************************************************************************)
166
167fun add_bool_translations () =
168let val _ = perform "add_bool_translations"
169    val _ = add_translation sexp bool
170    val _ = add_coding_function sexp bool "encode"
171        {const = ``bool``,definition = translateTheory.bool_def,
172         induction = NONE};
173    val _ = add_coding_function sexp bool "decode"
174        {const = ``sexp_to_bool``,definition = translateTheory.sexp_to_bool_def,
175         induction = NONE};
176    val _ = add_coding_function sexp bool "detect"
177        {const = ``sexp_to_bool o booleanp``,
178         definition = hol_defaxiomsTheory.booleanp_def,
179         induction = NONE};
180
181    val _ = add_source_function bool "map"
182        {const = ``I``,definition = I_THM,induction = NONE};
183    val _ = add_source_function bool "all"
184        {const = ``K T``,definition = K_THM,induction = NONE};
185    val _ = add_coding_function sexp bool "fix"
186        {const = ``fix_bool``,definition = translateTheory.fix_bool_def,
187         induction = NONE};
188
189    val _ = add_coding_theorem sexp bool "encode_decode_map"
190            translateTheory.ENCDECMAP_BOOL;
191    val _ = add_coding_theorem sexp bool "encode_detect_all"
192            translateTheory.ENCDETALL_BOOL;
193    val _ = add_coding_theorem sexp bool "decode_encode_fix"
194            translateTheory.DECENCFIX_BOOL;
195    val _ = add_coding_theorem sexp bool "encode_map_encode"
196            (simple_encode_map_encode ``bool``)
197    val _ = add_coding_theorem sexp bool "fix_id"
198            translateTheory.FIXID_BOOL;
199    val _ = add_source_theorem bool "map_compose" (simple_map_compose bool);
200
201    val _ = add_coding_theorem sexp bool "detect_dead"
202            translateTheory.DETDEAD_BOOL;
203    val _ = add_coding_theorem sexp bool "general_detect"
204            (DECIDE ``!x. (sexp_to_bool o booleanp) x ==>
205                          (sexp_to_bool o booleanp) x``)
206in
207    ()
208end handle ExistsAlready => ()
209
210(*****************************************************************************)
211(* Add the type-translation theorems for strings                             *)
212(*****************************************************************************)
213
214fun add_string_translations () =
215let val _ = perform "add_string_translations"
216    val _ = add_translation_precise sexp string
217    val _ = add_coding_function_precise sexp string "encode"
218        {const = ``str``,definition = combinTheory.I_THM, induction = NONE};
219    val _ = add_coding_function_precise sexp string "decode"
220        {const = ``sexp_to_string``,definition = translateTheory.sexp_to_string_def,
221         induction = NONE};
222    val _ = add_coding_function_precise sexp string "detect"
223        {const = ``sexp_to_bool o stringp``,
224         definition = sexpTheory.stringp_def,
225         induction = NONE};
226
227    val _ = add_source_function_precise string "map"
228        {const = ``I``,definition = I_THM,induction = NONE};
229    val _ = add_source_function_precise string "all"
230        {const = ``K T``,definition = K_THM,induction = NONE};
231    val _ = add_coding_function_precise sexp string "fix"
232        {const = ``fix_string``,definition = translateTheory.fix_string_def,
233         induction = NONE};
234
235    val _ = add_coding_theorem_precise sexp string "encode_decode_map"
236            translateTheory.ENCDECMAP_STRING;
237    val _ = add_coding_theorem_precise sexp string "encode_detect_all"
238            translateTheory.ENCDETALL_STRING;
239    val _ = add_coding_theorem_precise sexp string "decode_encode_fix"
240            translateTheory.DECENCFIX_STRING;
241    val _ = add_coding_theorem_precise sexp string "encode_map_encode"
242            (simple_encode_map_encode ``str``)
243    val _ = add_coding_theorem_precise sexp string "fix_id"
244            translateTheory.FIXID_STRING;
245    val _ = add_source_theorem_precise string "map_compose" (simple_map_compose string);
246
247    val _ = add_coding_theorem_precise sexp string "detect_dead"
248            translateTheory.DETDEAD_STRING;
249    val _ = add_coding_theorem_precise sexp string "general_detect"
250            (DECIDE ``!x. (sexp_to_bool o stringp) x ==>
251                          (sexp_to_bool o stringp) x``)
252
253    val _ = functionEncodeLib.add_terminal
254            ("str ?", op&&& o (equal ``str`` ## stringSyntax.is_string_literal) o dest_comb);
255in
256    ()
257end handle ExistsAlready => ()
258
259(*****************************************************************************)
260(* Add the type-translation theorems for chars                             *)
261(*****************************************************************************)
262
263fun add_char_translations () =
264let val _ = perform "add_char_translations"
265    val _ = add_translation_precise sexp char
266    val _ = add_coding_function_precise sexp char "encode"
267        {const = ``chr``,definition = combinTheory.I_THM, induction = NONE};
268    val _ = add_coding_function_precise sexp char "decode"
269        {const = ``sexp_to_char``,definition = translateTheory.sexp_to_char_def,
270         induction = NONE};
271    val _ = add_coding_function_precise sexp char "detect"
272        {const = ``sexp_to_bool o characterp``,
273         definition = sexpTheory.characterp_def,
274         induction = NONE};
275
276    val _ = add_source_function_precise char "map"
277        {const = ``I``,definition = I_THM,induction = NONE};
278    val _ = add_source_function_precise char "all"
279        {const = ``K T``,definition = K_THM,induction = NONE};
280    val _ = add_coding_function_precise sexp char "fix"
281        {const = ``fix_char``,definition = translateTheory.fix_char_def,
282         induction = NONE};
283
284    val _ = add_coding_theorem_precise sexp char "encode_decode_map"
285            translateTheory.ENCDECMAP_CHAR;
286    val _ = add_coding_theorem_precise sexp char "encode_detect_all"
287            translateTheory.ENCDETALL_CHAR;
288    val _ = add_coding_theorem_precise sexp char "decode_encode_fix"
289            translateTheory.DECENCFIX_CHAR;
290    val _ = add_coding_theorem_precise sexp char "encode_map_encode"
291            (simple_encode_map_encode ``chr``)
292    val _ = add_coding_theorem_precise sexp char "fix_id"
293            translateTheory.FIXID_CHAR;
294    val _ = add_source_theorem_precise char "map_compose" (simple_map_compose char);
295
296    val _ = add_coding_theorem_precise sexp char "detect_dead"
297            translateTheory.DETDEAD_CHAR;
298    val _ = add_coding_theorem_precise sexp char "general_detect"
299            (DECIDE ``!x. (sexp_to_bool o characterp) x ==>
300                          (sexp_to_bool o characterp) x``)
301in
302    ()
303end handle ExistsAlready => ()
304
305(*****************************************************************************)
306(* Add the type-translation theorems for rational numbers                    *)
307(*****************************************************************************)
308
309fun add_rat_translations () =
310let val _ = perform "add_rat_translations"
311    val _ = add_translation sexp rat
312    val _ = add_coding_function sexp rat "encode"
313        {const = ``rat``,definition = sexpTheory.rat_def,induction = NONE};
314    val _ = add_coding_function sexp rat "decode"
315        {const = ``sexp_to_rat``,definition = translateTheory.sexp_to_rat_def,
316         induction = NONE};
317    val _ = add_coding_function sexp rat "detect"
318        {const = ``sexp_to_bool o rationalp``,
319         definition = sexpTheory.rationalp_def,
320         induction = NONE};
321
322    val _ = add_source_function rat "map"
323        {const = ``I``,definition = I_THM,induction = NONE};
324    val _ = add_source_function rat "all"
325        {const = ``K T``,definition = K_THM,induction = NONE};
326    val _ = add_coding_function sexp rat "fix"
327        {const = ``fix_rat``,definition = translateTheory.fix_rat_def,
328         induction = NONE};
329
330    val _ = add_coding_theorem sexp rat "encode_decode_map"
331            translateTheory.ENCDECMAP_RAT;
332    val _ = add_coding_theorem sexp rat "encode_detect_all"
333            translateTheory.ENCDETALL_RAT;
334    val _ = add_coding_theorem sexp rat "decode_encode_fix"
335            translateTheory.DECENCFIX_RAT;
336    val _ = add_coding_theorem sexp rat "encode_map_encode"
337            (simple_encode_map_encode ``rat``)
338    val _ = add_coding_theorem sexp rat "fix_id"
339            translateTheory.FIXID_RAT;
340    val _ = add_source_theorem rat "map_compose" (simple_map_compose rat);
341
342    val _ = add_coding_theorem sexp rat "detect_dead"
343            translateTheory.DETDEAD_RAT;
344    val _ = add_coding_theorem sexp rat "general_detect"
345            (DECIDE ``!x. (sexp_to_bool o rationalp) x ==>
346                          (sexp_to_bool o rationalp) x``)
347in
348    ()
349end handle ExistsAlready => ()
350
351(*****************************************************************************)
352(* Add the type-translation theorems for products                            *)
353(*****************************************************************************)
354
355fun add_product_translations () =
356let val _ = perform "add_product_translations"
357    val _ = add_translation sexp pair
358    val _ = add_coding_function sexp pair "encode"
359                {const = ``pair``,
360                 definition = translateTheory.pair_thm,
361                 induction = NONE};
362    val _ = add_coding_function sexp pair "decode"
363                {const = ``sexp_to_pair``,
364                 definition = translateTheory.sexp_to_pair_def,
365                 induction = NONE};
366    val _ = add_coding_function sexp pair "detect"
367                {const = ``pairp``,
368                 definition = translateTheory.pairp_def,
369                 induction = NONE};
370    val _ = add_source_function pair "map"
371                {const = ``$##``,
372                 definition = pairTheory.PAIR_MAP_THM,
373                 induction = NONE};
374    val _ = add_source_function pair "all"
375              {const = ``all_pair``,
376               definition = translateTheory.all_pair_def,
377               induction = NONE};
378    val _ = add_coding_function sexp pair "fix"
379              {const = ``fix_pair``,definition = translateTheory.fix_pair_def,
380               induction = NONE};
381
382    val _ = add_coding_theorem sexp pair "encode_decode_map"
383            translateTheory.ENCDECMAP_PAIR;
384    val _ = add_coding_theorem sexp pair "encode_detect_all"
385            translateTheory.ENCDETALL_PAIR;
386    val _ = add_coding_theorem sexp pair "decode_encode_fix"
387            translateTheory.DECENCFIX_PAIR;
388    val _ = add_coding_theorem sexp pair "encode_map_encode"
389            translateTheory.ENCMAPENC_PAIR;
390
391    val _ = add_coding_theorem sexp pair "fix_id"
392            translateTheory.FIXID_PAIR;
393    val _ = add_source_theorem pair "map_id"
394            quotient_pairTheory.PAIR_MAP_I;
395    val _ = add_source_theorem pair "all_id"
396            translateTheory.ALLID_PAIR;
397
398    val _ = add_source_theorem pair "map_compose"
399            (prove(``(a ## b) o (c ## d) = ((a o c) ## (b o d))``,
400                 REWRITE_TAC [boolTheory.FUN_EQ_THM] THEN Cases THEN
401                 REWRITE_TAC [pairTheory.PAIR_MAP_THM,combinTheory.o_THM]));
402
403    val _ = add_coding_theorem sexp pair "detect_dead"
404            translateTheory.DETDEAD_PAIR;
405    val _ = add_coding_theorem sexp pair "general_detect"
406            translateTheory.GENERAL_DETECT_PAIR;
407in
408    ()
409end handle ExistsAlready => ()
410
411(*****************************************************************************)
412(* Add the type translations for lists.                                      *)
413(*****************************************************************************)
414
415val list_ind = translateTheory.sexp_list_ind;
416
417val decode_list_ind =
418    (list_ind,[(``P0:sexp -> bool``,(``sexp_to_list f``,list)),
419               (``P1:sexp -> bool``,(``sexp_to_pair f (sexp_to_list f)``,
420                                                    ``:'a # 'a list``))]);
421val detect_list_ind =
422    (list_ind,[(``P0:sexp -> bool``,(``listp f``,list)),
423               (``P1:sexp -> bool``,(``pairp f (listp f)``,
424                                               ``:'a # 'a list``))]);
425val fix_list_ind =
426    (list_ind,[(``P0:sexp -> bool``,(``fix_list f``,list)),
427               (``P1:sexp -> bool``,(``fix_pair f (fix_list f)``,
428                                                ``:'a # 'a list``))]);
429
430val encode_list_ind =
431    (TypeBase.induction_of list,
432    [(``P:'a list -> bool``,(``list f``,list))]);
433val map_list_ind =
434    (TypeBase.induction_of list,
435    [(``P:'a list -> bool``,(``MAP f``,list))]);
436val every_list_ind =
437    (TypeBase.induction_of list,
438    [(``P:'a list -> bool``,(``EVERY f``,list))]);
439
440fun add_list_translations () =
441let val _ = perform "add_list_translations"
442    val _ = add_translation sexp list
443    val _ = add_coding_function sexp list "encode"
444                {const = ``list``,
445                 definition = translateTheory.list_thm,
446                 induction = SOME encode_list_ind};
447    val _ = add_coding_function sexp list "decode"
448                {const = ``sexp_to_list``,
449                 definition = translateTheory.sexp_to_list_thm,
450                 induction = SOME decode_list_ind};
451    val _ = add_coding_function sexp list "detect"
452                {const = ``listp``,
453                 definition = translateTheory.listp_thm,
454                 induction = SOME detect_list_ind};
455    val _ = add_source_function list "map"
456                {const = ``MAP``,
457                 definition = listTheory.MAP,
458                 induction = SOME map_list_ind};
459    val _ = add_source_function list "all"
460              {const = ``EVERY``,
461               definition = listTheory.EVERY_DEF,
462               induction = SOME every_list_ind};
463    val _ = add_coding_function sexp list "fix"
464              {const = ``fix_list``,
465               definition = translateTheory.fix_list_thm,
466               induction = SOME fix_list_ind};
467
468    val _ = add_coding_theorem sexp list "encode_decode_map"
469            translateTheory.ENCDECMAP_LIST;
470    val _ = add_coding_theorem sexp list "encode_detect_all"
471            translateTheory.ENCDETALL_LIST;
472    val _ = add_coding_theorem sexp list "decode_encode_fix"
473            translateTheory.DECENCFIX_LIST;
474    val _ = add_coding_theorem sexp list "encode_map_encode"
475            translateTheory.ENCMAPENC_LIST;
476
477    val _ = add_coding_theorem sexp list "fix_id"
478            translateTheory.FIXID_LIST;
479    val _ = add_source_theorem list "map_id"
480            quotient_listTheory.LIST_MAP_I;
481    val _ = add_source_theorem list "all_id"
482            translateTheory.ALLID_LIST;
483
484    val _ = add_source_theorem list "map_compose"
485            (GSYM rich_listTheory.MAP_o);
486
487    val _ = add_coding_theorem sexp list "detect_dead"
488            translateTheory.DETDEAD_LIST;
489    val _ = add_coding_theorem sexp list "general_detect"
490            translateTheory.GENERAL_DETECT_LIST;
491in
492    ()
493end handle ExistsAlready => ()
494
495(*****************************************************************************)
496(* Add the translations for FCPs                                             *)
497(*****************************************************************************)
498
499fun add_fcp_translations () =
500let val _ = perform "add_fcp_translations"
501    val _ = add_translation sexp fcp
502    val _ = add_coding_function sexp fcp "encode"
503        {const = ``fcp_encode``,
504         definition = extendTranslateTheory.fcp_encode_def,
505         induction = NONE};
506    val _ = add_coding_function sexp fcp "decode"
507        {const = ``fcp_decode``,
508         definition = extendTranslateTheory.fcp_decode_def,
509         induction = NONE};
510    val _ = add_coding_function sexp fcp "detect"
511        {const = ``fcp_detect : (sexp -> bool) -> 'b itself -> sexp -> bool``,
512         definition = extendTranslateTheory.fcp_detect_def,
513         induction = NONE};
514
515    val _ = add_source_function fcp "map"
516        {const = ``FCP_MAP : ('a -> 'c) -> 'a ** 'b -> 'c ** 'b``,
517         definition = fcpTheory.FCP_MAP,induction = NONE};
518    val _ = add_source_function fcp "all"
519        {const = ``FCP_EVERY : ('a -> bool) -> 'a ** 'b -> bool``,
520         definition = fcpTheory.FCP_EVERY,induction = NONE};
521    val _ = add_coding_function sexp fcp "fix"
522        {const = ``fcp_fix : (sexp -> sexp) -> 'b itself -> sexp -> sexp``,
523         definition = extendTranslateTheory.fcp_fix_def,
524         induction = NONE};
525
526    val _ = add_coding_theorem sexp fcp "encode_decode_map"
527            extendTranslateTheory.ENCDECMAP_FCP;
528    val _ = add_coding_theorem sexp fcp "encode_detect_all"
529            extendTranslateTheory.ENCDETALL_FCP;
530    val _ = add_coding_theorem sexp fcp "decode_encode_fix"
531            extendTranslateTheory.DECENCFIX_FCP;
532    val _ = add_coding_theorem sexp fcp "encode_map_encode"
533            extendTranslateTheory.ENCMAPENC_FCP;
534    val _ = add_coding_theorem sexp fcp "fix_id"
535            extendTranslateTheory.FIXID_FCP;
536    val _ = add_source_theorem fcp "map_compose"
537            extendTranslateTheory.MAP_COMPOSE_FCP;
538    val _ = add_source_theorem fcp "map_id"
539            extendTranslateTheory.MAPID_FCP;
540    val _ = add_source_theorem fcp "all_id"
541            extendTranslateTheory.ALLID_FCP;
542
543
544    val _ = add_coding_theorem sexp fcp "detect_dead"
545            extendTranslateTheory.DETDEAD_FCP;
546    val _ = add_coding_theorem sexp fcp "general_detect"
547            extendTranslateTheory.GENERAL_DETECT_FCP;
548
549    val _ = set_bottom_value ``:'a word`` ``\a. FCP i. a``;
550in
551    ()
552end handle ExistsAlready => ()
553
554(*****************************************************************************)
555(* Add the translations for words                                            *)
556(*****************************************************************************)
557
558fun add_word_translations () =
559let val _ = perform "add_word_translations"
560    val _ = add_translation_precise sexp word handle _ => ()
561    val _ = add_coding_function_precise sexp word "encode"
562        {const = ``word_encode``,
563         definition = extendTranslateTheory.word_encode_def,
564         induction = NONE};
565    val _ = add_coding_function_precise sexp word "decode"
566        {const = ``word_decode``,
567         definition = extendTranslateTheory.word_decode_def,
568         induction = NONE};
569    val _ = add_coding_function_precise sexp word "detect"
570        {const = ``word_detect``,
571         definition = extendTranslateTheory.word_detect_def,
572         induction = NONE};
573
574    val _ = add_source_function_precise word "map"
575        {const = ``I``,definition = I_THM,induction = NONE};
576    val _ = add_source_function_precise word "all"
577        {const = ``K T``,definition = K_THM,induction = NONE};
578    val _ = add_coding_function_precise sexp word "fix"
579        {const = ``word_fix``,
580         definition = extendTranslateTheory.word_fix_def,
581         induction = NONE};
582
583    val _ = add_coding_theorem_precise sexp word "encode_decode_map"
584            extendTranslateTheory.ENCDECMAP_WORD;
585    val _ = add_coding_theorem_precise sexp word "encode_detect_all"
586            extendTranslateTheory.ENCDETALL_WORD;
587    val _ = add_coding_theorem_precise sexp word "decode_encode_fix"
588            extendTranslateTheory.DECENCFIX_WORD;
589    val _ = add_coding_theorem_precise sexp word "encode_map_encode"
590            (simple_encode_map_encode ``word_encode (:'a)``)
591    val _ = add_coding_theorem_precise sexp word "fix_id"
592            extendTranslateTheory.FIXID_WORD;
593    val _ = add_source_theorem_precise word "map_compose"
594            (simple_map_compose word);
595
596    val _ = add_coding_theorem_precise sexp word "detect_dead"
597            extendTranslateTheory.DETDEAD_WORD;
598    val _ = add_coding_theorem_precise sexp word "general_detect"
599            (DECIDE ``!x. word_detect (:'b) x ==>
600                          word_detect (:'b) x``)
601    val _ = add_source_theorem_precise ``:'a word`` "map_id"
602            (REFL ``I:'a word -> 'a word``);
603
604    val _ = set_bottom_value ``:'a word`` ``0w``;
605in
606    ()
607end handle ExistsAlready => ()
608
609(*****************************************************************************)
610(* Initialise the type encoding system for s-expressions                     *)
611(*****************************************************************************)
612
613fun initialise_sexp() =
614let val _ = perform "initialise_sexp"
615    val _ = add_translation_scheme sexp
616                translateTheory.SEXP_REDUCE
617                translateTheory.SEXP_TERMINAL;
618    val _ = add_product_translations();
619    val _ = add_translation sexp sexp
620    val _ = add_coding_theorem sexp sexp "decode_encode_fix"
621            (prove(``I o I = I:sexp -> sexp``,
622                   REWRITE_TAC [combinTheory.I_o_ID]));
623    val _ = add_coding_theorem sexp sexp "fix_id"
624            (prove(``!x. (K T) x ==> (I x = x)``,
625                   REWRITE_TAC [combinTheory.I_THM,combinTheory.K_THM]));
626    val _ = add_source_function ``:sexp`` "map"
627            {const = ``I:sexp -> sexp``,
628             definition = combinTheory.I_THM,
629             induction = NONE};
630    val _ = add_source_function ``:sexp`` "all"
631            {const = ``(K T):sexp -> bool``,
632             definition = combinTheory.K_THM,
633             induction = NONE};
634
635    val _ = initialise_source_function_generators ();
636    val _ = initialise_coding_function_generators sexp;
637    val _ = initialise_coding_theorem_generators sexp;
638in
639    ()
640end handle ExistsAlready => ()
641
642(*****************************************************************************)
643(* Functions specialised for encoding to sexp                                *)
644(*                                                                           *)
645(* initialise_type : hol_type -> unit                                        *)
646(*      Fully initialises the encoding of a type, encoding the type and      *)
647(*      creating the standard rewriting functions                            *)
648(*                                                                           *)
649(* translate_simple_function                                                 *)
650(*        : (term * string) list -> thm -> thm                               *)
651(*    Translates a function which requires no additional theorems for the    *)
652(*    function to encode.                                                    *)
653(* translate_conditional_function                                            *)
654(*        : (term * string) list -> thm list -> thm -> thm                   *)
655(*    Translates a function which relies upon conditional propagation        *)
656(*    theorems in a non-trivial way. The list of theorems supplied is given  *)
657(*    to the forward and backward-chaining resolution mechanisms to solve    *)
658(*    this. Eg. the following term and propagation theorem:                  *)
659(*          nat (if ~(a = 0) then b DIV a else 0)                            *)
660(*          |- 0 < a ==> nat (b DIV a) = ...                                 *)
661(*    Require the theorem: |- 0 < a ==> ~(a = 0) to be added to the set.     *)
662(* translate_limit_function                                                  *)
663(*      : (term * string) list ->                                            *)
664(*        (term * term list) list -> thm list -> thm -> thm                  *)
665(*    Translates a function that has specific limits that must be placed     *)
666(*    upon a valid translation, eg. the function LOG:                        *)
667(*        translate_limit_function [(``LOG``,"translated_log")]              *)
668(*                                 [(``LOG``,[``\a b. 1 < a /\ 0 < b``])]    *)
669(*                                 [|- 1 < a ==> 0 < a]                      *)
670(*              |- 1 < a ==> (LOG a b = if b < a then 1 else LOG a (b DIV a) *)
671(*                                                                           *)
672(*****************************************************************************)
673
674fun set_destructors thms =
675    (functionEncodeLib.set_destructors sexp thms)
676    handle e => wrapException "set_destructors" e
677
678fun initialise_type t =
679    (encode_type sexp t ;
680     add_standard_coding_rewrites sexp t)
681    handle e => wrapException "initialise_type" e
682
683fun translate_simple_function names thm =
684    convert_definition sexp names [] [] thm
685    handle e => wrapException "translate_simple_function" e
686
687fun translate_conditional_function names extras thm =
688    convert_definition sexp names [] extras thm
689    handle e => wrapException "translate_conditional_function" e
690
691fun translate_limit_function names limits extras thm =
692    convert_definition sexp names limits extras thm
693    handle e => wrapException "translate_limits_function" e
694
695fun flatten_recognizers namef t =
696    functionEncodeLib.flatten_recognizers namef sexp t
697    handle e => wrapException "flatten_recognizers" e;
698
699(*****************************************************************************)
700(* Polymorphic functions specialised for encoding to sexp                    *)
701(*                                                                           *)
702(* translate_simple_polymorphic_function                                     *)
703(*        : (term * string) list -> (term * thm) list -> thm -> thm          *)
704(* translate_conditional_polymorphic_function                                *)
705(*        : (term * string) list -> (term * thm) list ->                     *)
706(*                                  thm list -> thm -> thm                   *)
707(* translate_limit_polymorphic_function                                      *)
708(*      : (term * string) list -> (term * term list) list ->                 *)
709(*                        (term * thm) list -> thm list -> thm -> thm        *)
710(*                                                                           *)
711(*****************************************************************************)
712
713fun translate_simple_polymorphic_function names map_thms thm =
714    convert_polymorphic_definition sexp names [] map_thms [] thm
715    handle e => wrapException "translate_simple_polymorphic_function" e
716
717fun translate_conditional_polymorphic_function names map_thms extras thm =
718    convert_polymorphic_definition sexp names [] map_thms extras thm
719    handle e => wrapException "translate_conditional_polymorphic_function" e
720
721fun translate_limit_polymorphic_function names map_thms limits extras thm =
722    convert_polymorphic_definition sexp names limits map_thms extras thm
723    handle e => wrapException "translate_limits_polymorphic_function" e
724
725(*****************************************************************************)
726(* Translations specialised for s-expressions and FCPs                       *)
727(*                                                                           *)
728(* translate_simple_fcp_function                                             *)
729(*        : string -> thm -> thm                                             *)
730(* translate_conditional_fcp_function                                        *)
731(*        : string -> thm list -> thm -> thm                                 *)
732(* translate_limit_fcp_function                                              *)
733(*        : string -> term list -> thm list -> thm -> thm                    *)
734(* translate_recursive_fcp_function                                          *)
735(*        : string -> term list -> thm list -> thm ->                        *)
736(*          thm list -> tactic -> (thm -> thm -> tactic) -> thm              *)
737(*                                                                           *)
738(* flatten_fcp_recognizers                                                   *)
739(*       : (hol_type -> string) -> hol_type -> thm list                      *)
740(*                                                                           *)
741(*****************************************************************************)
742
743fun translate_simple_fcp_function names thm =
744    convert_abstracted_nonrec_definition
745    (can (match_term ``dimindex (:'a)``))
746    sexp names [] [] thm
747    handle e => wrapException "translate_simple_fcp_function" e
748
749fun translate_conditional_fcp_function names extras thm =
750    convert_abstracted_nonrec_definition
751    (can (match_term ``dimindex (:'a)``))
752    sexp names [] extras thm
753    handle e => wrapException "translate_conditional_fcp_function" e
754
755fun translate_limit_fcp_function names limits extras thm =
756    convert_abstracted_nonrec_definition
757    (can (match_term ``dimindex (:'a)``))
758    sexp names limits extras thm
759    handle e => wrapException "translate_limit_fcp_function" e
760
761fun translate_recursive_fcp_function names limits extras thm
762        rewrites tactic1 tactic2 =
763    convert_abstracted_definition
764    (can (match_term ``dimindex (:'a)``))
765    sexp names limits extras thm rewrites tactic1 tactic2
766    handle e => wrapException "translate_recursive_fcp_function" e
767
768fun flatten_fcp_recognizers namef t =
769    flatten_abstract_recognizers
770    namef (can (match_term ``dimindex (:'a)``)) sexp t
771    handle e => wrapException "flatten_fcp_recognizers" e;
772
773(*****************************************************************************)
774(* Tactics which may, or may not, be useful in proving full definitions.     *)
775(*****************************************************************************)
776
777open Psyntax boolSyntax Tactic;
778
779fun ENCODE_WF_REL_TAC R (a,g) =
780let val RR = Parse.parse_in_context (g::a) R
781    val r = fst (dest_exists g)
782    val rtypes = pairSyntax.strip_prod (hd (fst (strip_fun (type_of r))))
783    val ftypes = pairSyntax.strip_prod (hd (fst (strip_fun (type_of RR))))
784    fun ftype t = type_subst (map (fn v => v |-> sexp) (type_vars t)) t
785
786    val decoders = map (get_decode_function sexp o ftype) ftypes
787    val func = foldr pairLib.mk_pair_map (last decoders) (butlast decoders)
788
789    val at = gen_tyvar();
790    val bt = gen_tyvar();
791    val inv_image =
792        mk_const("inv_image",
793            (at --> at --> bool) --> (bt --> at) --> bt --> bt --> bool);
794
795    val RRR = list_imk_comb(inv_image,[RR,func]);
796in
797    (EXISTS_TAC RRR THEN
798    CONJ_TAC THENL [MATCH_MP_TAC (relationTheory.WF_inv_image),ALL_TAC] THEN
799    REWRITE_TAC [relationTheory.inv_image_def,prim_recTheory.WF_measure] THEN
800    pairLib.GEN_BETA_TAC THEN
801    REWRITE_TAC [pairTheory.PAIR_MAP_THM,prim_recTheory.measure_thm,
802        combinTheory.o_THM,pairTheory.FST,pairTheory.SND] THEN
803    REPEAT STRIP_TAC) (a,g)
804end
805
806local
807fun pop_tac ([],g) = ALL_TAC ([],g)
808  | pop_tac (a::b,g) =
809    (POP_ASSUM (SUBST_ALL_TAC o GSYM) THEN
810    markerLib.ABBREV_TAC
811    (mk_eq(variant (free_varsl (g::a::b))
812              (mk_var(fst (dest_var (rhs a)),type_of (rand (lhs a)))),
813           rand (lhs a)))) (a::b,g);
814in
815fun FULL_CHOOSE_DETECT_TAC (a,g) =
816let val types = mapfilter (get_detect_type o rator) a
817    val thms = map (FULL_DECODE_ENCODE_THM sexp) types
818    val rewrites1 = map (FULL_ENCODE_DECODE_THM sexp) types
819    val rewrites2 = map (FULL_ENCODE_DETECT_THM sexp) types
820in
821    (MAP_EVERY IMP_RES_TAC thms THEN
822     TRY (NTAC (length thms) pop_tac) THEN
823     REWRITE_TAC (rewrites1 @ rewrites2) THEN
824     RULE_ASSUM_TAC (REWRITE_RULE (rewrites1 @ rewrites2))) (a,g)
825end
826end;
827
828(*****************************************************************************)
829(* Add rewrites for natural number functions.                                *)
830(*****************************************************************************)
831
832local
833val tm = ``nat a``
834in
835fun is_encoded_num term =
836    can (match_term tm) term
837    andalso numLib.is_numeral (rand term)
838end
839
840fun add_num_rewrites () =
841let val _ = tryperform "add_num_rewrites"
842    val _ = add_standard_rewrite 1 "num =0" translateTheory.NAT_EQUAL_0;
843    val _ = add_standard_rewrite 1 "num 0="
844            (prove(``bool (0 = a) = zp (nat a)``,
845             REWRITE_TAC [GSYM translateTheory.NAT_EQUAL_0,
846                          translateTheory.BOOL_CONG] THEN
847             DECIDE_TAC))
848    val _ = add_standard_rewrite 1 "num 0 <" translateTheory.NAT_0_LT;
849    val _ = add_standard_rewrite 0 "num <" translateTheory.NAT_LT;
850    val _ = add_standard_rewrite 0 "num <=" translateTheory.NAT_LE;
851    val _ = add_standard_rewrite 0 "num >=" translateTheory.NAT_GE;
852    val _ = add_standard_rewrite 0 "num >" translateTheory.NAT_GT;
853    val _ = add_standard_rewrite 0 "num +" translateTheory.NAT_ADD;
854    val _ = add_standard_rewrite 0 "SUC" translateTheory.NAT_SUC;
855    val _ = add_standard_rewrite 1 "SUC-PRE" translateTheory.NAT_SUC_PRE;
856    val _ = add_standard_rewrite 0 "PRE" translateTheory.NAT_PRE;
857    val _ = add_standard_rewrite 0 "num *" translateTheory.NAT_MULT;
858    val _ = add_standard_rewrite 0 "num -fix" translateTheory.NAT_SUB;
859    val _ = add_standard_rewrite 1 "num -" translateTheory.NAT_SUB_COND;
860    val _ = add_standard_rewrite 0 "num encdec" translateTheory.DECENC_NAT;
861    val _ = add_standard_rewrite 0 "natp" translateTheory.FLATTEN_NAT;
862    val _ = add_standard_rewrite 0 "is SUC" translateTheory.NUM_CONSTRUCT;
863    val _ = add_standard_rewrite 0 "num case" translateTheory.NUM_CASE;
864    val _ = add_terminal ("nat ?",is_encoded_num);
865    val _ = set_destructors [CONJUNCT2 (prim_recTheory.PRE)];
866    val _ = add_standard_rewrite 0 "Num" translateTheory.NAT_NUM;
867
868    val _ = add_standard_rewrite 0 "DIV" extendTranslateTheory.NAT_DIV;
869    val _ = add_standard_rewrite 0 "MOD" extendTranslateTheory.NAT_MOD;
870    val _ = add_standard_rewrite 0 "num **" extendTranslateTheory.NAT_EXPT;
871    val _ = add_standard_rewrite 1 "num <<" extendTranslateTheory.NAT_ASH;
872    val _ = add_standard_rewrite 0 "MAX" extendTranslateTheory.NAT_MAX;
873    val _ = add_standard_rewrite 0 "MIN" extendTranslateTheory.NAT_MIN;
874
875    val _ = add_standard_rewrite 0 "BIT" extendTranslateTheory.NAT_BIT;
876    val _ = perform "add_num_rewrites"
877in
878    ()
879end handle ExistsAlready => ()
880
881(*****************************************************************************)
882(* Add rewrites for boolean functions.                                       *)
883(*****************************************************************************)
884
885fun add_bool_rewrites () =
886let val _ = tryperform "add_bool_rewrites"
887    val _ = add_standard_rewrite 0 "booleanp" translateTheory.FLATTEN_BOOL;
888    val _ = add_conditional_rewrite 0 "if" translateTheory.COND_REWRITE;
889    val _ = add_standard_rewrite 1 "if T" translateTheory.COND_T;
890    val _ = add_standard_rewrite 1 "if F" translateTheory.COND_F;
891    val _ = add_conditional_rewrite 1 "/\\-left" translateTheory.BOOL_LEFT_AND;
892    val _ = add_conditional_rewrite 0 "/\\-right"
893            translateTheory.BOOL_RIGHT_AND;
894    val _ = add_conditional_rewrite 1 "\\/-left" translateTheory.BOOL_LEFT_OR;
895    val _ = add_conditional_rewrite 0 "\\/-right" translateTheory.BOOL_RIGHT_OR;
896    val _ = add_conditional_rewrite 0 "==>implies" translateTheory.BOOL_IMPLIES;
897    val _ = add_standard_rewrite 0 "bool ~" translateTheory.BOOL_NOT;
898    val _ = add_standard_rewrite 0 "T" translateTheory.BOOL_T;
899    val _ = add_standard_rewrite 0 "F" translateTheory.BOOL_F;
900
901    val _ = add_standard_rewrite 0 "|= consp" translateTheory.BOOL_PAIR;
902    val _ = add_standard_rewrite 0 "K T" translateTheory.BOOL_KT;
903    val _ = perform "add_bool_rewrites"
904in
905    ()
906end handle ExistsAlready => ()
907
908(*****************************************************************************)
909(* Add rewrites for list functions.                                          *)
910(*****************************************************************************)
911
912fun add_list_rewrites() =
913let val _ = tryperform "add_list_rewrites"
914    val _ = add_standard_rewrite 0 "HD" translateTheory.LIST_HD;
915    val _ = add_standard_rewrite 0 "TL" translateTheory.LIST_TL;
916    val _ = add_standard_rewrite 0 "NULL" translateTheory.LIST_NULL;
917    val _ = add_standard_rewrite 0 "LENGTH" translateTheory.LIST_LENGTH;
918    val _ = add_standard_rewrite 0 "list case" translateTheory.LIST_CASE;
919    val _ = add_standard_rewrite 1 "is []" translateTheory.LIST_CONSTRUCT1;
920    val _ = add_standard_rewrite 1 "is Cons" translateTheory.LIST_CONSTRUCT2;
921    val _ = set_destructors [listTheory.HD,listTheory.TL];
922    val _ = add_standard_coding_rewrites sexp list;
923    val _ = perform "add_list_rewrites"
924in
925    ()
926end handle ExistsAlready => ()
927
928(*****************************************************************************)
929(* Add rewrites for product functions.                                       *)
930(*****************************************************************************)
931
932fun add_pair_rewrites() =
933let val _ = perform "add_pair_rewrites"
934    val _ = set_destructors [pairTheory.FST,pairTheory.SND];
935    val _ = add_standard_coding_rewrites sexp pair;
936    val _ = add_standard_rewrite 0 "FST" translateTheory.PAIR_FST;
937    val _ = add_standard_rewrite 0 "SND" translateTheory.PAIR_SND;
938    val _ = add_standard_rewrite 0 "pair case" translateTheory.PAIR_CASE;
939in
940    ()
941end handle ExistsAlready => ()
942
943(*****************************************************************************)
944(* Add the polytypic rewrites                                                *)
945(*****************************************************************************)
946
947fun add_polytypic_rewrites() =
948let val _ = perform "add_polytypic_rewrites"
949    val _ = add_standard_conversion 0 "nesting"
950                                (nested_constructor_rewrite ``:sexp``);
951    val _ = add_standard_rewrite 0 "=" translateTheory.BOOL_EQUALITY;
952    val _ = add_polytypic_rewrite 0 "\\x." make_lambda_propagation_theorem;
953    val _ = add_polytypic_rewrite 0 "dec enc" polytypic_decodeencode;
954    val _ = add_polytypic_rewrite 0 "case" polytypic_casestatement;
955    val _ = add_polytypic_rewrite 0 "construct" polytypic_encodes;
956    val _ = add_polytypic_rewrite 0 "let" polytypic_let_conv
957    val _ = add_standard_conversion 0 "I var" (target_function_conv ``:sexp``)
958    val _ = add_standard_conversion 0 "I enc" (dummy_encoder_conv ``:sexp``);
959    val _ = add_polytypic_rewrite 0 "PRED" polytypic_recognizer;
960in
961    ()
962end handle ExistsAlready => ()
963
964(*****************************************************************************)
965(* Add the integer rewrites                                                  *)
966(*****************************************************************************)
967
968local
969val tm = ``int (a:int)``
970in
971fun is_encoded_int term =
972    can (match_term tm) term
973    andalso numLib.is_numeral (rand (rand term)) handle _ => false
974end;
975
976fun add_int_rewrites() =
977let val _ = perform "add_int_rewrites"
978    val _ = add_standard_rewrite 0 "integerp" translateTheory.FLATTEN_INT;
979
980    val _ = add_standard_rewrite 0 "int +" translateTheory.INT_ADD;
981    val _ = add_standard_rewrite 0 "int *" translateTheory.INT_MULT;
982    val _ = add_standard_rewrite 0 "int ~" translateTheory.INT_UNARY_MINUS;
983    val _ = add_standard_rewrite 0 "int <" translateTheory.INT_LT;
984    val _ = add_standard_rewrite 0 "int >" translateTheory.INT_GT;
985    val _ = add_standard_rewrite 0 "int <=" translateTheory.INT_LE;
986    val _ = add_standard_rewrite 0 "int >=" translateTheory.INT_GE;
987    val _ = add_standard_rewrite 0 "int -" translateTheory.INT_SUB;
988    val _ = add_standard_rewrite 0 "int &" (GSYM sexpTheory.nat_def);
989
990    val _ = add_standard_rewrite 0 "int **" extendTranslateTheory.INT_EXPT;
991    val _ = add_standard_rewrite 0 "int /" extendTranslateTheory.INT_DIV;
992    val _ = add_standard_rewrite 0 "quot" extendTranslateTheory.INT_QUOT;
993    val _ = add_standard_rewrite 0 "int %" extendTranslateTheory.INT_MOD;
994    val _ = add_standard_rewrite 0 "rem" extendTranslateTheory.INT_REM;
995    val _ = add_standard_rewrite 0 "SGN" extendTranslateTheory.INT_SGN;
996    val _ = add_standard_rewrite 1 "int <<" extendTranslateTheory.INT_ASH;
997    val _ = add_standard_rewrite 0 "max" extendTranslateTheory.INT_MAX;
998    val _ = add_standard_rewrite 0 "min" extendTranslateTheory.INT_MIN;
999    val _ = add_standard_rewrite 0 "ABS" extendTranslateTheory.INT_ABS;
1000
1001    val _ = add_terminal ("int ?",is_encoded_int);
1002in
1003    ()
1004end handle ExistsAlready => ()
1005
1006(*****************************************************************************)
1007(* Add the Rational rewrites                                                 *)
1008(*****************************************************************************)
1009
1010local
1011val tm = ``rat (a:rat)``
1012in
1013fun is_encoded_rat term =
1014    can (match_term tm) term
1015    andalso numLib.is_numeral (rand (rand term)) handle _ => false
1016end;
1017
1018fun add_rat_rewrites() =
1019let val _ = perform "add_rat_rewrites"
1020    val _ = add_standard_rewrite 0 "rationalp" translateTheory.FLATTEN_RAT;
1021
1022    val _ = add_standard_rewrite 0 "rat +" translateTheory.RAT_ADD;
1023    val _ = add_standard_rewrite 0 "rat *" translateTheory.RAT_MULT;
1024    val _ = add_standard_rewrite 0 "rat ~" translateTheory.RAT_UNARY_MINUS;
1025    val _ = add_standard_rewrite 0 "rat <" translateTheory.RAT_LT;
1026    val _ = add_standard_rewrite 0 "rat >" translateTheory.RAT_GT;
1027    val _ = add_standard_rewrite 0 "rat <=" translateTheory.RAT_LE;
1028    val _ = add_standard_rewrite 0 "rat >=" translateTheory.RAT_GE;
1029    val _ = add_standard_rewrite 0 "rat -" translateTheory.RAT_SUB;
1030    val _ = add_standard_rewrite 0 "rat -" translateTheory.RAT_DIV;
1031
1032    val _ = add_terminal ("rat ?",is_encoded_rat)
1033in
1034    ()
1035end handle ExistsAlready => ()
1036
1037(*****************************************************************************)
1038(* Add the FCP rewrites                                                      *)
1039(*****************************************************************************)
1040
1041fun add_fcp_rewrites() =
1042let val _ = perform "add_fcp_rewrites"
1043    val _ = add_conditional_rewrite 0 "%%" extendTranslateTheory.FCP_INDEX;
1044    val _ = add_standard_rewrite 0 ":+" extendTranslateTheory.FCP_UPDATE;
1045in
1046    ()
1047end handle ExistsAlready => ();
1048
1049(*****************************************************************************)
1050(* Add the word rewrites                                                     *)
1051(*****************************************************************************)
1052
1053fun add_word_rewrites() =
1054let val _ = perform "add_word_rewrites"
1055    val _ = add_standard_rewrite 0 "isword" extendTranslateTheory.WORD_FLATTEN;
1056
1057    val _ = add_standard_rewrite 0 "&&" extendTranslateTheory.WORD_AND;
1058    val _ = add_standard_rewrite 0 "!!" extendTranslateTheory.WORD_OR;
1059    val _ = add_standard_rewrite 0 "??" extendTranslateTheory.WORD_XOR;
1060    val _ = add_standard_rewrite 0 "w~" extendTranslateTheory.WORD_NOT;
1061    val _ = add_standard_rewrite 1 "~!!" extendTranslateTheory.WORD_ORC1;
1062    val _ = add_standard_rewrite 1 "!!~" extendTranslateTheory.WORD_ORC2;
1063    val _ = add_standard_rewrite 1 "~&&" extendTranslateTheory.WORD_ANDC1;
1064    val _ = add_standard_rewrite 1 "&&~" extendTranslateTheory.WORD_ANDC2;
1065    val _ = add_standard_rewrite 1 "~(&&)" extendTranslateTheory.WORD_NAND;
1066    val _ = add_standard_rewrite 1 "~(??)" extendTranslateTheory.WORD_NXOR;
1067    val _ = add_standard_rewrite 1 "~(!!)" extendTranslateTheory.WORD_NOR;
1068    val _ = add_standard_rewrite 1 "word %%" extendTranslateTheory.WORD_BIT;
1069    val _ = add_standard_rewrite 0 ">>" extendTranslateTheory.WORD_ASR;
1070    val _ = add_standard_rewrite 0 "<<" extendTranslateTheory.WORD_LSL;
1071    val _ = add_standard_rewrite 0 "word_msb" extendTranslateTheory.WORD_MSB;
1072
1073    val _ = add_standard_rewrite 0 "word +" extendTranslateTheory.WORD_ADD;
1074    val _ = add_standard_rewrite 0 "word -" extendTranslateTheory.WORD_SUB;
1075    val _ = add_standard_rewrite 0 "word *" extendTranslateTheory.WORD_MUL;
1076    val _ = add_standard_rewrite 0 "word $-" extendTranslateTheory.WORD_NEG;
1077    val _ = add_standard_rewrite 0 "word /" extendTranslateTheory.WORD_DIV;
1078    val _ = add_standard_rewrite 0 "word T" extendTranslateTheory.WORD_T;
1079    val _ = add_standard_rewrite 0 "word <" extendTranslateTheory.WORD_LT;
1080    val _ = add_standard_rewrite 0 "word >" extendTranslateTheory.WORD_GT;
1081    val _ = add_standard_rewrite 0 "word <=" extendTranslateTheory.WORD_LE;
1082    val _ = add_standard_rewrite 0 "word >=" extendTranslateTheory.WORD_GE;
1083
1084    val _ = add_standard_rewrite 0 "n2w" extendTranslateTheory.WORD_N2W;
1085    val _ = add_standard_rewrite 0 "w2n" extendTranslateTheory.NAT_W2N;
1086    val _ = add_standard_rewrite 0 "int sw2i"
1087                  (GSYM extendTranslateTheory.word_encode_def)
1088    val _ = add_standard_conversion 0 "index"
1089                  (Conv.RAND_CONV wordsLib.SIZES_CONV);
1090
1091    local
1092      open intLib integerTheory Tactic Tactical
1093      val i2n_lemma = prove(``0 <= (i + 1) rem 2 ** l - 1 + 2 ** l``,
1094        REWRITE_TAC [ARITH_PROVE ``0i <= a - 1 + b = ~a < b``] THEN
1095        MATCH_MP_TAC
1096          (ARITH_PROVE ``!a b c. a <= b /\ b < c ==> a < c:int``) THEN
1097        Q.EXISTS_TAC `ABS ((i + 1) rem 2 ** l)` THEN
1098        METIS_TAC [INT_REMQUOT,INT_ABS_NUM,INT_EXP,INT_EXP_EQ0,
1099          ARITH_PROVE ``~(2 = 0i)``,INT_ABS,INT_NOT_LT,INT_NEGNEG,INT_LE_REFL,
1100          INT_LE_NEGL]);
1101    in
1102       val i2n_thms = [INT_EXP_EQ0,ARITH_PROVE ``~(2 = 0i)``,
1103            REWRITE_CONV [integerTheory.INT_POS,integerTheory.INT_EXP]
1104                 ``0 <= 2 ** a``,
1105            prove(``~(b = 0) /\ 0i <= b ==> 0 <= a % b``,
1106                     METIS_TAC [INT_MOD_BOUNDS,INT_NOT_LT]),i2n_lemma]
1107    end;
1108
1109    val _ = translate_conditional_function
1110            [(``i2n``,"translated_i2n")]
1111            i2n_thms
1112            signedintTheory.i2n_def;
1113
1114    val _ = translate_simple_function
1115            [(``extend``,"translated_extend")]
1116            signedintTheory.extend_def;
1117in
1118    ()
1119end handle ExistsAlready => ();
1120
1121(*****************************************************************************)
1122(* Initialisation of finite map rewrites                                     *)
1123(*****************************************************************************)
1124
1125fun is_fmap t = ((curry op= "fmap" o fst o dest_type) t) handle _ => false
1126val fdom = hd o snd o dest_type;
1127val frng = hd o tl o snd o dest_type;
1128val fmap = mk_type("fmap", [alpha,beta])
1129
1130(*****************************************************************************)
1131(* ONEONE_DECENC_THM                                                         *)
1132(*****************************************************************************)
1133
1134fun ONEONE_DECENC_THM t =
1135let val _ = if type_vars t = [] then () else
1136               raise (polyExn (Standard, [], "Not a ground type: " ^ type_to_string t))
1137    val thm1 = generate_coding_theorem sexp "encode_decode_map" t
1138    val thm2 = generate_source_theorem "map_id" t
1139    val thm3 = Q.AP_TERM `ONE_ONE` (TRANS thm1 thm2);
1140in  EQ_MP (SYM thm3) (INST_TYPE [alpha |-> t] fmap_encodeTheory.ONE_ONE_I)
1141end handle e => wrapException "ONEONE_DECENC_THM" e
1142
1143fun ONEONE_ENC_THM t =
1144    MATCH_MP fmap_encodeTheory.ONE_ONE_RING (ONEONE_DECENC_THM t)
1145
1146local
1147(* Make a 11 term *)
1148fun mk11 term =
1149let val (t1,t2) = dom_rng (type_of term)
1150in  mk_comb(mk_const("ONE_ONE", (t1 --> t2) --> bool), term)
1151end;
1152
1153val find_terms = HolKernel.find_terms;
1154in
1155
1156(*****************************************************************************)
1157(* CODINGTHEOREM_FMAP: Replace the previous coding theorem generate with one *)
1158(*   that resolves ONE_ONE terms in the antecedent.                          *)
1159(*****************************************************************************)
1160
1161fun CODINGTHEOREM_FMAP s t =
1162let val cc = if exists_coding_theorem_conclusion sexp s
1163                then get_coding_theorem_conclusion sexp s t
1164                else get_source_theorem_conclusion s t
1165    val t1 = if exists_coding_theorem_conclusion sexp s
1166                then generate_coding_theorem sexp s (base_type t)
1167                else generate_source_theorem s (base_type t);
1168    val t2 = REWRITE_RULE [fmap_encodeTheory.ONE_ONE_I]
1169             (PART_MATCH (lhs o snd o strip_imp) (SPEC_ALL t1)
1170                         (lhs (snd (strip_imp (snd (strip_forall cc))))))
1171
1172    val thm1 = if null (type_vars (fdom t))
1173                  then ONEONE_DECENC_THM (fdom t)
1174                  else ASSUME (fst (dest_imp (concl t2)))
1175
1176    val matched = MATCH_MP t2 thm1 handle _ =>
1177                  MATCH_MP t2 (MATCH_MP fmap_encodeTheory.ONE_ONE_RING thm1) handle _ =>
1178                  t2
1179
1180
1181    val fthm = generate_coding_theorem sexp s (fdom t) handle _ =>
1182               generate_source_theorem s (fdom t)
1183    val tthm = generate_coding_theorem sexp s (frng t) handle _ =>
1184               generate_source_theorem s (frng t)
1185
1186    val rterm = repeat rator (rhs (snd (strip_imp (snd (strip_forall cc)))));
1187
1188in  GENL (fst (strip_forall cc)) (DISCH_ALL (TRANS matched (MK_COMB (AP_TERM rterm (SPEC_ALL fthm), tthm))))
1189end handle e => wrapException ("CODINGTHEOREM_FMAP(" ^ type_to_string t ^ ")") e
1190
1191(*****************************************************************************)
1192(* oneone_decenc_conclusion: Potentially adds a ONEONE (decode o encode) to  *)
1193(* the previous term.                                                        *)
1194(*****************************************************************************)
1195fun oneone_decenc_conclusion previous target t =
1196let val (vars,prev) = strip_forall (previous target t)
1197    val sub = type_subst (map (fn x => x |-> gen_tyvar()) (type_vars t))
1198    val enc = if is_fmap t then SOME (encodeLib.get_encode_function target (fdom t)) else NONE
1199    val terms = if is_fmap t then [combinSyntax.mk_o(valOf enc, encodeLib.get_decode_function target (fdom t)),
1200                                   combinSyntax.mk_o(encodeLib.get_decode_function target (sub (fdom t)), valOf enc)] else []
1201
1202    val sdec = if is_fmap t then map combinSyntax.dest_o (find_terms (fn a => exists (can (C match_term a)) terms) prev) else []
1203    val pdec = if is_fmap t then map snd (filter (curry op= (valOf enc) o fst) sdec) @ map fst (filter (curry op= (valOf enc) o snd) sdec) else []
1204
1205    val _ = if is_fmap t andalso null (find_terms (can (match_term (valOf enc))) prev)
1206               then raise (polyExn (Standard, [], "No encoder in conclusion of theorem"))
1207               else ()
1208    val pdecs = if is_fmap t andalso null pdec
1209                   then (find_terms (can (match_term (encodeLib.get_decode_function target (fdom t)))) prev @
1210                         [encodeLib.get_decode_function target (fdom t)])
1211                   else pdec
1212    val vars' = union vars (if is_fmap t then free_vars (hd pdecs) else [])
1213in
1214    list_mk_forall(vars', if not (is_fmap t) orelse null (type_vars (fdom t))
1215       then prev
1216       else mk_imp(mk11 (combinSyntax.mk_o(hd pdecs, valOf enc)), prev))
1217end handle e => wrapException ("oneone_decenc_conclusion(" ^ type_to_string t ^ ")") e
1218
1219(*****************************************************************************)
1220(* oneone_enc_conclusion: Potentially adds a ONEONE encode to the previous   *)
1221(* term.                                                                     *)
1222(*****************************************************************************)
1223fun oneone_enc_conclusion previous target t =
1224let val (vars,prev) = strip_forall (previous target t)
1225    val sub = type_subst (map (fn x => x |-> gen_tyvar()) (type_vars t))
1226    val enc = if is_fmap t then SOME (encodeLib.get_encode_function target (fdom t)) else NONE
1227in
1228    list_mk_forall(vars, if not (is_fmap t) orelse null (type_vars (fdom t))
1229       then prev
1230       else mk_imp(mk11 (valOf enc), prev))
1231end handle e => wrapException ("oneone_enc_conclusion(" ^ type_to_string t ^ ")") e
1232
1233(*****************************************************************************)
1234(* oneone_mapenc_conclusion: Potentially adds a ONEONE encode and a          *)
1235(* ONEONE map to the previous term.                                          *)
1236(*****************************************************************************)
1237fun oneone_mapenc_conclusion previous x =
1238let val (vars,prev) = strip_forall (previous x)
1239    val coders = find_terms (fn x => (is_fmap o fst o dom_rng o type_of) x handle _ => false) prev
1240    val pvars = filter is_var (mapfilter (rand o rator) coders)
1241    val imps = map mk11 (filter (C mem pvars) vars)
1242in
1243    list_mk_forall(vars,
1244         if null imps then prev else mk_imp(list_mk_conj imps, prev))
1245end
1246end
1247
1248local
1249open fmap_encodeTheory encodeLib
1250in
1251fun add_fmap_translations () =
1252let val _ = perform "add_fmap_translations"
1253    val _ = add_translation sexp fmap
1254
1255    val _ = add_rule_coding_theorem_generator "encode_decode_map" is_fmap
1256
1257    val _ = add_coding_theorem sexp fmap "encode_detect_all" ENCDETALL_FMAP;
1258    val _ = add_coding_theorem sexp fmap "decode_encode_fix" DECENCFIX_FMAP;
1259    val _ = add_coding_theorem sexp fmap "encode_decode_map" ENCDECMAP_FMAP;
1260
1261    val _ = add_coding_theorem sexp fmap "encode_map_encode" ENCMAPENC_FMAP;
1262
1263    val _ = add_coding_theorem sexp fmap "fix_id" FIXID_FMAP;
1264    val _ = add_source_theorem fmap "all_id" ALLID_FMAP;
1265    val _ = add_source_theorem fmap "map_id" MAPID_FMAP;
1266
1267    val _ = add_source_theorem fmap "map_compose" FMAP_MAP_COMPOSE;
1268
1269    val _ = add_coding_theorem sexp fmap "detect_dead" DETECTDEAD_FMAP;
1270    val _ = add_coding_theorem sexp fmap "general_detect" DETECT_GENERAL_FMAP
1271
1272    val _ = add_source_function fmap "map"
1273        {const = ``map_fmap``, definition = map_fmap_def, induction = NONE};
1274
1275    val _ = add_source_function fmap "all"
1276        {const = ``all_fmap``, definition = all_fmap_def, induction = NONE};
1277
1278    val _ = add_coding_function sexp fmap "encode"
1279        {const = ``encode_fmap``, definition = encode_fmap_def, induction = NONE};
1280
1281    val _ = add_coding_function sexp fmap "decode"
1282        {const = ``decode_fmap``, definition = decode_fmap_def, induction = NONE};
1283
1284    val _ = add_coding_function sexp fmap "detect"
1285        {const = ``detect_fmap``, definition = detect_fmap_def, induction = NONE};
1286
1287    val _ = add_coding_function sexp fmap "fix"
1288        {const = ``fix_fmap``, definition = fix_fmap_def, induction = NONE};
1289
1290    val _ = set_coding_theorem_conclusion sexp "encode_decode_map" (oneone_decenc_conclusion mk_encode_decode_map_conc sexp);
1291    val _ = add_rule_coding_theorem_generator "encode_decode_map" is_fmap (CODINGTHEOREM_FMAP "encode_decode_map") sexp;
1292
1293    val _ = set_coding_theorem_conclusion sexp "encode_detect_all" (oneone_enc_conclusion mk_encode_detect_all_conc sexp);
1294    val _ = add_rule_coding_theorem_generator "encode_detect_all" is_fmap (CODINGTHEOREM_FMAP "encode_detect_all") sexp;
1295
1296    val _ = set_coding_theorem_conclusion sexp "decode_encode_fix" (oneone_decenc_conclusion mk_decode_encode_fix_conc sexp);
1297    val _ = add_rule_coding_theorem_generator "decode_encode_fix" is_fmap (CODINGTHEOREM_FMAP "decode_encode_fix") sexp;
1298
1299    val _ = set_coding_theorem_conclusion sexp "encode_map_encode" (curry (oneone_mapenc_conclusion (uncurry mk_encode_map_encode_conc)) sexp);
1300    val _ = add_rule_coding_theorem_generator "encode_map_encode" is_fmap (CODINGTHEOREM_FMAP "encode_map_encode") sexp;
1301
1302    val _ = set_source_theorem_conclusion "map_compose" (oneone_mapenc_conclusion mk_map_compose_conc);
1303    val _ = add_rule_source_theorem_generator "map_compose" is_fmap (CODINGTHEOREM_FMAP "map_compose");
1304
1305in  ()
1306end
1307end;
1308
1309local
1310open fmap_encodeTheory
1311in
1312fun add_fmap_rewrites () =
1313let val _ = add_standard_rewrite 0 "fmap_p" sorted_car_rewrite;
1314    val _ = add_standard_rewrite 0 "FDOM" fdom_rewrite;
1315    val _ = add_standard_rewrite 0 "FAPPLY" apply_rewrite;
1316    val _ = add_standard_rewrite 0 "FUPDATE" fupdate_rewrite;
1317    val _ = add_standard_rewrite 0 "FEMPTY" fempty_rewrite;
1318in ()
1319end
1320end
1321
1322(*****************************************************************************)
1323(* Initialisation: run the above functions, checking for errors.             *)
1324(*****************************************************************************)
1325
1326val _ = Feedback.set_trace "functionEncodeLib.Trace" 1;
1327
1328val _ = (initialise_sexp() handle e =>
1329        Raise (mkStandardExn "initialise_sexp"
1330              ("Failed to add the translations for :sexp\n" ^
1331               ("Original exception: \n" ^ exn_to_string e))));
1332
1333fun add_translations f t =
1334    (trace 1 "Adding translations for the type: " ;
1335     trace 1 (type_to_string t) ; trace 1 "\n" ;
1336     f ()) handle e =>
1337        Raise (mkStandardExn "Initialisation"
1338              ("Failed to add the translations for " ^ type_to_string t ^
1339               ("\nOriginal exception: \n" ^ exn_to_string e)));
1340
1341val _ = add_translations add_num_translations num;
1342val _ = add_translations add_int_translations int;
1343val _ = add_translations add_rat_translations rat;
1344val _ = add_translations add_bool_translations bool;
1345val _ = add_translations add_string_translations string;
1346val _ = add_translations add_char_translations char;
1347val _ = add_translations add_list_translations list;
1348val _ = add_translations add_fcp_translations fcp;
1349val _ = add_translations add_word_translations word;
1350val _ = add_translations add_fmap_translations fmap;
1351
1352fun add_rewrites f t =
1353    (trace 1 "Adding rewrites for the type: " ;
1354     trace 1 (type_to_string t) ; trace 1 "\n" ;
1355     f ()) handle e =>
1356        Raise (mkStandardExn "Initialisation"
1357              ("Failed to add the rewrites for " ^ type_to_string t ^
1358               ("\nOriginal exception: \n" ^ exn_to_string e)));
1359
1360val _ = add_rewrites add_num_rewrites num;
1361val _ = add_rewrites add_bool_rewrites bool;
1362val _ = (trace 1 "Adding polytypic rewrites\n" ;
1363         add_polytypic_rewrites())
1364        handle e => Raise (mkStandardExn "Initialisation"
1365                    ("Failed to add polytypic rewrites"));
1366val _ = add_rewrites add_list_rewrites list;
1367val _ = add_rewrites add_pair_rewrites pair
1368val _ = add_rewrites add_int_rewrites int;
1369val _ = add_rewrites add_rat_rewrites rat;
1370val _ = add_rewrites add_fcp_rewrites fcp;
1371val _ = add_rewrites add_word_rewrites word;
1372val _ = add_rewrites add_fmap_rewrites fmap;
1373
1374
1375(*****************************************************************************)
1376(* Output of definitions                                                     *)
1377(*    - Doesn't yet work for mutually recursive definitions...               *)
1378(*****************************************************************************)
1379
1380open sexp;
1381
1382fun tryfilter f [] = []
1383  | tryfilter f (x::xs) =
1384  if (f x handle _ => false) then x::tryfilter f xs else tryfilter f xs;
1385
1386fun mapff f1 f2 [] = []
1387  | mapff f1 f2 (x::xs) = f1 x :: f2 x:: mapff f1 f2 xs;
1388
1389val GCONST = map (fst o strip_comb o lhs o snd o strip_forall)
1390             o strip_conj o concl
1391
1392fun order_defs [] = []
1393  | order_defs L =
1394let val (head,rest) =
1395        with_exn
1396        (pluck (fn x =>
1397             all (fn y => null (find_terms (C mem (GCONST x)) (concl y))
1398                          orelse (concl x = concl y)) L))
1399        L
1400        (mkStandardExn "order_defs"
1401               ("Could not order the function list: " ^
1402                xlist_to_string thm_to_string L ^
1403                "\n as it appears to contain cycles..."))
1404in  head::order_defs rest
1405end;
1406
1407fun acl2_var_map s = (implode o filter (not o curry op= #"'") o explode) s
1408
1409fun acl2_prime s = s ^ "p";
1410
1411fun acl2_variant vl v =
1412    if mem v vl then acl2_variant vl (acl2_prime v) else v;
1413
1414local
1415fun conv1 term =
1416let val var = fst (dest_var (fst (dest_abs term)))
1417    val vars = free_vars term
1418    val newvar = acl2_var_map var
1419    val variant = acl2_variant (map (fst o dest_var) vars) newvar
1420in
1421    if variant = var
1422       then NO_CONV term
1423       else RENAME_VARS_CONV [variant] term
1424end;
1425in
1426fun ACL2_BVARS_CONV term = REDEPTH_CONV conv1 term
1427    handle UNCHANGED => REFL term
1428         | e => wrapException "ACL2_BVARS_CONV" e
1429end
1430
1431fun mk_mlsexp_mbe_term body =
1432    mk_mlsexp_list
1433            [mksym "ACL2" "MUST-BE-EQUAL",
1434             term_to_mlsexp body,
1435             term_to_mlsexp (rand (rator body))]
1436
1437fun mk_mlsexp_guard body =
1438    mk_mlsexp_list
1439       [mksym "ACL2" "DECLARE",
1440        mk_mlsexp_list
1441           [mksym "ACL2" "XARGS",
1442            mksym "ACL2" ":GUARD",
1443            term_to_mlsexp (rand (rator (rator body)))]];
1444
1445fun def_to_mlsexp_mbe_defun thm =
1446let val (asl,concl) = dest_thm (SPEC_ALL thm)
1447    val _ = if null asl then ()
1448               else raise (mkStandardExn "def_to_mlsexp_mbe_defun"
1449                    ("The theorem supplied:\n" ^ thm_to_string thm ^
1450                     "\nhas a non-empty hypothesis set."))
1451    val (opr,args) = strip_comb (lhs concl)
1452in
1453    mk_mlsexp_list
1454       [mksym "COMMON-LISP" "DEFUN",
1455        string_to_mlsym(get_name opr),
1456        mk_mlsexp_list(map term_to_mlsexp args),
1457        mk_mlsexp_guard (rhs concl),
1458        mk_mlsexp_mbe_term (rhs concl)]
1459end;
1460
1461fun all_definitions (thm:thm) =
1462let val consts = GCONST thm
1463    val {Name,Thy,Ty} = dest_thy_const (hd consts)
1464    val consts = mk_set (find_terms (fn x => is_const x andalso
1465                                     (curry op= Thy o #Thy o dest_thy_const) x)
1466                            (concl thm))
1467    val all_defs = DB.definitions Thy
1468    val filtered1 = tryfilter (not o null o intersect consts o GCONST o snd)
1469                              all_defs
1470    val filtered2 = tryfilter (String.isPrefix "translated_" o fst) filtered1
1471
1472    val recursive = map all_definitions
1473                        (op_set_diff (fn a => fn b => concl a = concl b)
1474                                     (map snd filtered2) [thm]);
1475in
1476    op_mk_set (fn a => fn b => concl a = concl b)
1477              (thm::flatten recursive)
1478end;
1479
1480fun print_all_defs filename print convert thm =
1481let val ordered = order_defs (all_definitions thm)
1482    val rewritten = map (REWRITE_RULE [sexpTheory.andl_def] o
1483                         CONV_RULE ACL2_BVARS_CONV o GEN_ALL) ordered
1484    val preamble = mk_mlsexp_list
1485        [mksym "ACL2" "IN-PACKAGE",
1486         mlstr (!current_package)];
1487    fun post_def thm = mk_mlsexp_list
1488        [mksym "ACL2" "VERIFY-GUARDS",
1489         string_to_mlsym(get_name (hd (GCONST thm)))]
1490
1491    fun mprint out x = (print out x ; out "\n\n")
1492
1493    val outputs = preamble::mapff convert post_def (rev rewritten)
1494in
1495    print_lisp_file filename (fn out => map (mprint out) outputs)
1496end handle e => wrapException "print_all_defs" e
1497
1498fun print_all_defs_standard filename thm =
1499    print_all_defs filename print_mlsexp def_to_mlsexp_defun thm
1500                   handle e => wrapException "print_all_defs_standard" e
1501
1502fun can_mbe thm =
1503    can (C match_term (rhs (concl (SPEC_ALL thm)))) ``ite a b c`` andalso
1504    not (can (C match_term (rhs (concl (SPEC_ALL thm)))) ``ite (consp a) b c``);
1505
1506(*****************************************************************************)
1507(* Very nasty hack to allow the use of the :guard keyword... this will be    *)
1508(* replaced with the proper symbol, or better code, at a later date.         *)
1509(*****************************************************************************)
1510
1511fun print_allow_keyword (out:string->unit) (sym as mlsym(_,v))  =
1512     if String.isPrefix ":" v
1513        then out v
1514        else out (mlsym_to_string sym)
1515 | print_allow_keyword (out:string->unit) (mlstr s) =
1516     (out "\""; out s; out "\"")
1517 | print_allow_keyword (out:string->unit) (mlchr c) =
1518     (out "(code-char "; out(int_to_string(ord c)); out ")")
1519 | print_allow_keyword (out:string->unit) (mlnum(an,ad,bn,bd)) =
1520    if (bn = "0") andalso (bd = "1")
1521     then (out an; out "/"; out ad)
1522     else (out "(COMMON-LISP::COMPLEX ";
1523           out an; out "/"; out ad;
1524           out " ";
1525           out bn; out "/"; out bd;
1526           out ")")
1527 | print_allow_keyword (out:string->unit) (mlpair(p1,p2)) =
1528     (out "(";
1529      (if is_mlsexp_list p2
1530        then let val sl = dest_mlsexp_list p2
1531             in
1532              if null sl
1533               then print_allow_keyword out p1
1534               else (print_allow_keyword out p1;
1535                     map (fn p => (out " "; print_allow_keyword out p)) sl;
1536                     ())
1537             end
1538        else (print_allow_keyword out p1; out " . ";
1539              print_allow_keyword out p2));
1540      out ")");
1541
1542fun print_all_defs_mbe filename thm =
1543    print_all_defs filename print_allow_keyword
1544        (fn y => if can_mbe y then def_to_mlsexp_mbe_defun y else
1545                                          def_to_mlsexp_defun y) thm
1546    handle e => wrapException "print_all_defs_mbe" e;
1547
1548val Raise = polytypicLib.Raise;
1549
1550end