Update from HH
[Flyspeck/.git] / legacy / inequalities / ocaml_to_sml.ml
1
2 (* -------------------------------------------------------------------------- *)
3 (*  Signature                                                                 *)
4 (* -------------------------------------------------------------------------- *)
5
6 module type Ocaml_sml =
7 sig
8
9   type const_name = | Dodec_slope
10                     | Dd_31
11                     | Dd_32
12                     | Dd_33
13                     | Dd_41
14                     | Dd_42
15                     | Dd_51
16                     | Doct
17                     | Dodec_trunc
18                     | Pi
19                     | Ppa1
20                     | Ppa2
21                     | Ppd0
22                     | Ppm
23                     | Ppb
24                     | Ppa
25                     | Ppbc
26                     | Ppc
27                     | Ppd
28                     | Ppsolt0
29                     | Pt
30                     | Ss_5
31                     | Sqrt2
32                     | Sqrt8
33                     | Square_2t0
34                     | Sqrt_2t0
35                     | Square_4t0
36                     | Tt_0
37                     | Tt_5
38                     | Two_dodec_trunc
39                     | Two_dodec_trunc_sq
40                     | Two_t0
41                     | Xi_gamma
42                     | Xi'_gamma
43                     | Xiv
44                     | Zz_32
45                     | Zz_33
46                     | Zz_41
47                     | Zz_42
48
49   type func_name = | Anc
50                    | Arclength
51                    | Beta
52                    | Chi_x
53                    | Cross_diag_x
54                    | Crown
55                    | Delta_x
56                    | Dih_x
57                    | Dih2_x
58                    | Dih3_x
59                    | Dihr
60                    | Eta_x
61                    | Gamma_x
62                    | Kappa
63                    | Kx
64                    | Mu_flat_x
65                    | Mu_flipped_x
66                    | Mu_upright_x
67                    | Nu_gamma_x
68                    | Nu_x
69                    | Octa_x
70                    | Octavor0_x
71                    | Octavor_analytic_x
72                    | Omega_x
73                    | Overlap_f
74                    | Quo_x
75                    | Rad2_x
76                    | Sigma1_qrtet_x
77                    | Sigma32_qrtet_x
78                    | Sigma_qrtet_x
79                    | Sigmahat_x
80                    | Sol_x
81                    | Squander_x
82                    | Taua_x
83                    | Tauc0_x
84                    | Tauvt_x
85                    | Tau_0_x
86                    | Tau_analytic_x
87                    | Tau_sigma_x
88                    | Tauhat_x
89                    | Tauhatpi_x
90                    | Taumu_flat_x
91                    | Taunu_x
92                    | Truncated_volume_x
93                    | U_x
94                    | V0x
95                    | V1x
96                    | Volume_x
97                    | Vora_x
98                    | Vorc0_x
99                    | Vorc_x
100                    | Vor_0_x
101                    | Vor_0_x_flipped
102                    | Vor_analytic_x
103                    | Vor_analytic_x_flipped
104                    | Vort_x
105
106   type const = | Decimal of int * int
107                | Int of int
108                | Named of const_name
109                | Sqr of const
110                | Sqrt of const
111                | Cos of const
112                | Acos of const
113                | Copp of const
114                | Cplus of const * const
115                | Cmul of const * const
116                | Cdiv of const * const
117
118   type expr = | Const of const
119               | Funcall of func_name * expr list
120               | Var of string
121               | Varsqrt of string
122               | Opp of expr
123               | Mul of expr * expr
124               | Div of expr * expr
125               | Pow of expr * int
126               | One
127
128   type monom = const * expr
129
130   type lcomb = monom list
131
132   type bounds = {lo : const;
133                  hi : const}
134
135   type ineq = {name : string;
136                vars : (string * bounds) list;
137                rels : lcomb list}
138
139   (* 
140      put the hales inequalities in a normal form 
141
142      !x_1 ... x_n. ineq [lower_1,x_1,upper_1;
143                          ...;
144                          lower_n,x_n,upper_n]
145                         c_1_1 f_1 + ... + c_1_m f_m < &0 \/
146                         ... \/
147                         c_k_1 f_k + ... + c_k_m f_m < &0
148    *)
149   val normalize : Term.term -> Term.term
150
151
152   (* Translate HOL Light term to OCaml datatype *)
153   val translate : string * Term.term -> ineq
154
155   val translate_list : ignore : string list -> 
156                        terms : (string * Term.term) list -> ineq list
157
158   (* Print Ocaml datatype as an SML datatype *)
159   val ineq_to_sml : ineq -> unit
160
161   val ineqs_to_sml : file:string -> ineqs:ineq list -> unit
162
163 end
164
165 (* -------------------------------------------------------------------------- *)
166 (*  Structure                                                                 *)
167 (* -------------------------------------------------------------------------- *)
168
169 module Ocaml_sml (* : Ocaml_sml *) = 
170 struct 
171
172   type const_name = | Dodec_slope
173                     | Dd_31
174                     | Dd_32
175                     | Dd_33
176                     | Dd_41
177                     | Dd_42
178                     | Dd_51
179                     | Doct
180                     | Dodec_trunc
181                     | Pi
182                     | Ppa1
183                     | Ppa2
184                     | Ppd0
185                     | Ppm
186                     | Ppb
187                     | Ppa
188                     | Ppbc
189                     | Ppc
190                     | Ppd
191                     | Ppsolt0
192                     | Pt
193                     | Ss_5
194                     | Sqrt2
195                     | Sqrt8
196                     | Square_2t0
197                     | Sqrt_2t0
198                     | Square_4t0
199                     | Tt_0
200                     | Tt_5
201                     | Two_dodec_trunc
202                     | Two_dodec_trunc_sq
203                     | Two_t0
204                     | Xi_gamma
205                     | Xi'_gamma
206                     | Xiv
207                     | Zz_32
208                     | Zz_33
209                     | Zz_41
210                     | Zz_42
211
212   type func_name = | Anc
213                    | Arclength
214                    | Beta
215                    | Chi_x
216                    | Cross_diag_x
217                    | Crown
218                    | Delta_x
219                    | Dih_x
220                    | Dih2_x
221                    | Dih3_x
222                    | Dihr
223                    | Eta_x
224                    | Gamma_x
225                    | Kappa
226                    | Kx
227                    | Mu_flat_x
228                    | Mu_flipped_x
229                    | Mu_upright_x
230                    | Nu_gamma_x
231                    | Nu_x
232                    | Octa_x
233                    | Octavor0_x
234                    | Octavor_analytic_x
235                    | Omega_x
236                    | Overlap_f
237                    | Quo_x
238                    | Rad2_x
239                    | Sigma1_qrtet_x
240                    | Sigma32_qrtet_x
241                    | Sigma_qrtet_x
242                    | Sigmahat_x
243                    | Sol_x
244                    | Squander_x
245                    | Taua_x
246                    | Tauc0_x
247                    | Tauvt_x
248                    | Tau_0_x
249                    | Tau_analytic_x
250                    | Tau_sigma_x
251                    | Tauhat_x
252                    | Tauhatpi_x
253                    | Taumu_flat_x
254                    | Taunu_x
255                    | Truncated_volume_x
256                    | U_x
257                    | V0x
258                    | V1x
259                    | Volume_x
260                    | Vora_x
261                    | Vorc0_x
262                    | Vorc_x
263                    | Vor_0_x
264                    | Vor_0_x_flipped
265                    | Vor_analytic_x
266                    | Vor_analytic_x_flipped
267                    | Vort_x
268
269   type const = | Decimal of int * int
270                | Int of int
271                | Named of const_name
272                | Sqr of const
273                | Sqrt of const
274                | Cos of const
275                | Acos of const
276                | Copp of const
277                | Cplus of const * const
278                | Cmul of const * const
279                | Cdiv of const * const
280
281   type expr = | Const of const
282               | Funcall of func_name * expr list
283               | Var of string
284               | Varsqrt of string
285               | Opp of expr
286               | Mul of expr * expr
287               | Div of expr * expr
288               | Pow of expr * int
289               | One
290
291   type monom = const * expr
292
293   type lcomb = monom list
294
295   type bounds = {lo : const;
296                  hi : const}
297
298   type ineq = {name : string;
299                vars : (string * bounds) list;
300                rels : lcomb list}
301
302   (* -------------------------------------------------------------------------- *)
303   (*  Util                                                                      *)
304   (* -------------------------------------------------------------------------- *)
305
306   (* remove "kepler'" from the front of a name *)
307   let unkepler s = 
308     try
309       let kep = String.sub s 0 7 in
310         if kep = "kepler'" then String.sub s 7 (String.length s - 7)
311         else s
312     with Invalid_argument _ -> s
313
314   let const_of_string const = match const with
315     | "D31" -> Dd_31
316     | "D32" -> Dd_32
317     | "D33" -> Dd_33
318     | "D41" -> Dd_41
319     | "D42" -> Dd_42
320     | "D51" -> Dd_51
321     | "dodecSlope" -> Dodec_slope
322     | "dodecTrunc" -> Dodec_trunc
323     | "Z32" -> Zz_32
324     | "Z33" -> Zz_33
325     | "Z41" -> Zz_41
326     | "Z42" -> Zz_42
327     | "doct" -> Doct
328     | "pi" -> Pi
329     | "pp_a1" -> Ppa1
330     | "pp_a2" -> Ppa2
331     | "pp_d0" -> Ppd0
332     | "pp_m" -> Ppm
333     | "pp_b" -> Ppb
334     | "pp_a" -> Ppa
335     | "pp_bc" -> Ppbc
336     | "pp_c" -> Ppc
337     | "pp_d" -> Ppd
338     | "pp_solt0" -> Ppsolt0
339     | "pt" -> Pt
340     | "s5" -> Ss_5
341     | "sqrt2" -> Sqrt2
342     | "sqrt8" -> Sqrt8
343     | "sqrt_2t0" -> Sqrt_2t0
344     | "square_2t0" -> Square_2t0
345     | "square_4t0" -> Square_4t0
346     | "t0" -> Tt_0
347     | "t5" -> Tt_5
348     | "two_t0" -> Two_t0
349     | "twoDodecTrunc" -> Two_dodec_trunc
350     | "twoDodecTruncSq" -> Two_dodec_trunc_sq
351     | "xi_gamma" -> Xi_gamma
352     | "xi'_gamma" -> Xi'_gamma
353     | "xiV" -> Xiv
354     | _ -> failwith ("not a constant: " ^ const)
355
356   let const_of_string = const_of_string o unkepler 
357
358   let const_to_string const = match const with
359     | Dd_31 -> "D31"
360     | Dd_32 -> "D32"
361     | Dd_33 -> "D33"
362     | Dd_41 -> "D41"
363     | Dd_42 -> "D42"
364     | Dd_51 -> "D51"
365     | Dodec_slope -> "DodecSlope"
366     | Dodec_trunc -> "DodecTrunc"
367     | Zz_32 -> "Z32"
368     | Zz_33 -> "Z33"
369     | Zz_41 -> "Z41"
370     | Zz_42 -> "Z42"
371     | Doct -> "Doct"
372     | Pi -> "Pi"
373     | Ppa1 -> "Ppa1" 
374     | Ppa2 -> "Ppa2" 
375     | Ppd0 -> "Ppd0" 
376     | Ppm -> "Ppm" 
377     | Ppb -> "Ppb" 
378     | Ppa -> "Ppa" 
379     | Ppbc -> "Ppbc" 
380     | Ppc -> "Ppc" 
381     | Ppd -> "Ppd" 
382     | Ppsolt0 -> "Ppsolt0" 
383     | Pt -> "Pt"
384     | Ss_5 -> "S5"
385     | Sqrt2 -> "Sqrt2"
386     | Sqrt8 -> "Sqrt8"
387     | Sqrt_2t0 -> "Sqrt2t0"
388     | Square_2t0 -> "Square2t0"
389     | Square_4t0 -> "Square4t0"
390     | Tt_0 -> "T0"
391     | Tt_5 -> "T5"
392     | Two_dodec_trunc -> "TwoDodecTrunc"
393     | Two_dodec_trunc_sq -> "TwoDodecTruncSq"
394     | Two_t0 -> "TwoT0"
395     | Xi_gamma -> "XiGamma"
396     | Xi'_gamma -> "Xi'Gamma"
397     | XiV -> "XiV"
398
399   let func_of_string func = match func with
400     | "anc" -> Anc
401     | "arclength" -> Arclength
402     | "beta" -> Beta
403     | "chi_x" -> Chi_x
404     | "cross_diag_x" -> Cross_diag_x
405     | "crown" -> Crown
406     | "delta_x" -> Delta_x
407     | "dih2_x" -> Dih2_x
408     | "dih3_x" -> Dih3_x
409     | "dihR" -> Dihr
410     | "dih_x" -> Dih_x
411     | "eta_x" -> Eta_x
412     | "gamma_x" -> Gamma_x
413     | "kappa" -> Kappa
414     | "KX" -> Kx
415     | "mu_flat_x" -> Mu_flat_x
416     | "mu_flipped_x" -> Mu_flipped_x
417     | "mu_upright_x" -> Mu_upright_x
418     | "nu_gamma_x" -> Nu_gamma_x
419     | "nu_x" -> Nu_x
420     | "octa_x" -> Octa_x
421     | "octavor0_x" -> Octavor0_x
422     | "octavor_analytic_x" -> Octavor_analytic_x
423     | "omega_x" -> Omega_x
424     | "overlap_f" -> Overlap_f
425     | "quo_x" -> Quo_x
426     | "rad2_x" -> Rad2_x
427     | "sigma1_qrtet_x" -> Sigma1_qrtet_x
428     | "sigma32_qrtet_x" -> Sigma32_qrtet_x
429     | "sigma_qrtet_x" -> Sigma_qrtet_x
430     | "sigmahat_x" -> Sigmahat_x
431     | "sol_x" -> Sol_x
432     | "squander_x" -> Squander_x
433     | "tauA_x" -> Taua_x
434     | "tauC0_x" -> Tauc0_x
435     | "tauVt_x" -> Tauvt_x
436     | "tau_0_x" -> Tau_0_x
437     | "tau_analytic_x" -> Tau_analytic_x
438     | "tau_sigma_x" -> Tau_sigma_x
439     | "tauhat_x" -> Tauhat_x
440     | "tauhatpi_x" -> Tauhatpi_x
441     | "taumu_flat_x" -> Taumu_flat_x
442     | "taunu_x" -> Taunu_x
443     | "truncated_volume_x" -> Truncated_volume_x
444     | "u_x" -> U_x
445     | "v0x" -> V0x
446     | "v1x" -> V1x
447     | "volume_x" -> Volume_x
448     | "vorA_x" -> Vora_x
449     | "vorC0_x" -> Vorc0_x
450     | "vorC_x" -> Vorc_x
451     | "vor_0_x" -> Vor_0_x
452     | "vor_0_x_flipped" -> Vor_0_x_flipped
453     | "vor_analytic_x" -> Vor_analytic_x
454     | "vor_analytic_x_flipped" -> Vor_analytic_x_flipped
455     | "vort_x" -> Vort_x
456     | _ -> failwith ("no such const: " ^ func) 
457
458   let func_of_string = func_of_string o unkepler
459
460   let func_to_string func = match func with
461     | Anc -> "Anc" 
462     | Arclength -> "Arclength"
463     | Beta -> "Beta"
464     | Chi_x -> "ChiX"
465     | Cross_diag_x -> "CrossDiagX"
466     | Crown -> "Crown"
467     | Delta_x -> "DeltaX"
468     | Dih2_x -> "Dih2X"
469     | Dih3_x -> "Dih3X"
470     | Dihr -> "Dihr"
471     | Dih_x -> "DihX"
472     | Eta_x -> "EtaX"
473     | Gamma_x -> "GammaX"
474     | Kappa -> "Kappa"
475     | Kx -> "Kx"
476     | Mu_flat_x -> "MuFlatX"
477     | Mu_flipped_x -> "MuFlippedX"
478     | Mu_upright_x -> "MuUprightX"
479     | Nu_gamma_x -> "NuGammaX"
480     | Nu_x -> "NuX"
481     | Octa_x -> "OctaX"
482     | Octavor0_x -> "Octavor0X"
483     | Octavor_analytic_x -> "OctavorAnalyticX"
484     | Omega_x -> "OmegaX"
485     | Overlap_f -> "OverlapF"
486     | Quo_x -> "QuoX"
487     | Rad2_x -> "Rad2X"
488     | Sigma1_qrtet_x -> "Sigma1QrtetX"
489     | Sigma32_qrtet_x -> "Sigma32QrtetX"
490     | Sigma_qrtet_x -> "SigmaQrtetX"
491     | Sigmahat_x -> "SigmahatX"
492     | Sol_x -> "SolX"
493     | Squander_x -> "SquanderX"
494     | Taua_x -> "TauaX"
495     | Tauc0_x -> "Tauc0X"
496     | Tauvt_x -> "TauvtX"
497     | Tau_0_x -> "Tau0X"
498     | Tau_analytic_x -> "TauAnalyticX"
499     | Tau_sigma_x -> "TauSigmaX"
500     | Tauhat_x -> "TauhatX"
501     | Tauhatpi_x -> "TauhatpiX"
502     | Taumu_flat_x -> "TaumuFlatX"
503     | Taunu_x -> "TaunuX"
504     | Truncated_volume_x -> "TruncatedVolumeX"
505     | U_x -> "UX"
506     | V0x -> "V0x"
507     | V1x -> "V1x"
508     | Volume_x -> "VolumeX"
509     | Vora_x -> "VoraX"
510     | Vorc0_x -> "Vorc0X"
511     | Vorc_x -> "VorcX"
512     | Vor_0_x -> "Vor0X"
513     | Vor_0_x_flipped -> "Vor0XFlipped"
514     | Vor_analytic_x -> "VorAnalyticX"
515     | Vor_analytic_x_flipped -> "VorAnalyticXFlipped"
516     | Vort_x -> "VortX"
517
518   let var_to_string v = fst (dest_var v)
519   let dest_add t = try Some (dest_binop `(+.)` t) with _ -> None
520   let dest_sub t = try Some (dest_binop `(-.)` t) with _ -> None
521   let dest_mul t = try Some (dest_binop `( *. )` t) with _ -> None
522   let dest_div t = try Some (dest_binop `( / )` t) with _ -> None
523
524   (* -------------------------------------------------------------------------- *)
525   (*  Translation                                                               *)
526   (* -------------------------------------------------------------------------- *)
527
528   (* `#1.35` *)
529   let translate_decimal t : const option =
530     try
531       let dec,numden = strip_comb t in
532       let num,den = match numden with [num;den] -> num,den | _ -> failwith "" in
533       if dec = `DECIMAL` then
534         match dest_numeral num,dest_numeral den with
535             Num.Int num', Num.Int den' -> Some (Decimal (num',den'))
536           | _ -> failwith ""
537       else None
538     with _ -> None
539
540   (* `&5` *)  
541   let translate_rint t : const option = 
542     try
543       let amp,n = dest_comb t in
544         if amp = `&.` then 
545           match dest_numeral n with
546               Num.Int n' -> Some (Int n')
547             | _ -> None 
548         else None 
549     with _ -> None 
550
551   (*  `5` *)
552   let translate_int t : int option = 
553     try
554       match dest_numeral t with
555           Num.Int n' -> Some n'
556         | _ -> None 
557     with _ -> None 
558
559   (* `square_2t0` *)
560   let translate_named t : const option =
561     try
562       let c,_ = dest_const t in
563         Some (Named (const_of_string c))
564     with _ -> None
565
566   let rec translate_const t : const option =  
567     match translate_decimal t with
568         Some _ as c -> c
569       | None ->
570     match translate_rint t with
571         Some _ as c -> c
572       | None ->
573     match translate_named t with
574         Some _ as c -> c
575       | None ->
576     match translate_cos t with
577         Some _ as c -> c
578       | None ->
579     match translate_acos t with
580         Some _ as c -> c
581       | None ->
582     match translate_sqr t with
583         Some _ as c -> c
584       | None ->
585     match translate_sqrt t with
586         Some _ as c -> c
587       | None ->
588     match translate_copp t with
589         Some _ as c -> c
590       | None ->
591     match translate_cplus t with
592         Some _ as c -> c
593       | None ->
594     match translate_cmul t with
595         Some _ as c -> c
596       | None ->
597     match translate_cdiv t with
598         Some _ as c -> c
599       | None -> None 
600
601   and translate_unop p con t : const option = 
602     try
603       let p',c = dest_comb t in
604         if p = p' then
605         match translate_const c with
606             Some c -> Some (con c)
607           | None -> None 
608         else
609           None
610     with _ -> None 
611
612   and translate_binop p con t : const option = 
613     try
614       let l,r = dest_binop p t in
615       match translate_const l,translate_const r with
616           Some l', Some r' -> Some (con(l',r'))
617         | _ -> None 
618     with _ -> None 
619
620   and translate_cos t = translate_unop `cos` (fun x -> Cos x) t
621   and translate_acos t = translate_unop `acs` (fun x -> Acos x) t
622   and translate_sqr t = translate_unop `square` (fun x -> Sqr x) t
623   and translate_sqrt t = translate_unop `sqrt` (fun x -> Sqrt x) t
624   and translate_copp t = translate_unop `(--.)` (fun x -> Copp x) t
625   and translate_cplus t = translate_binop `(+.)` (fun x,y -> Cplus (x,y)) t
626   and translate_cmul t = translate_binop `( *. )` (fun x,y -> Cmul (x,y)) t
627   and translate_cdiv t = translate_binop `( / )` (fun x,y -> Cdiv (x,y)) t
628
629   let translate_var t = 
630     if is_var t then Some (Var (fst (dest_var t))) else None 
631
632   let translate_varsqrt t = 
633     try
634       let sqrt,x = dest_comb t in
635       if sqrt = `sqrt` && is_var x then
636         Some (Varsqrt (fst (dest_var x))) 
637       else None 
638     with _ -> None 
639
640   let rec translate_expr t : expr option = 
641     match translate_const t with
642         Some c -> Some (Const c)
643       | None ->
644     match translate_funcall t with
645         Some _ as c -> c
646       | None ->
647     match translate_varsqrt t with
648         Some _ as c -> c
649       | None ->
650     match translate_var t with
651         Some _ as c -> c
652       | None ->
653     match translate_opp t with
654         Some _ as c -> c
655       | None ->
656     match translate_mul t with
657         Some _ as c -> c
658       | None ->
659     match translate_div t with
660         Some _ as c -> c
661       | None ->
662     match translate_pow t with
663         Some _ as c -> c
664       | None -> failwith "translate_expr"
665
666   and translate_funcall t =
667     try
668       let f,xs = strip_comb t in
669       let func_str,_ = dest_const f in
670       let func = func_of_string func_str in
671       let xs' = map (fun x -> match translate_expr x with Some e -> e | None -> failwith "") xs in
672         Some (Funcall(func,xs'))
673     with _ -> None 
674
675   and translate_unop p con t : expr option = 
676     try
677       let p',c = dest_comb t in
678         if p = p' then
679         match translate_expr c with
680             Some c -> Some (con c)
681           | None -> None 
682         else
683           None
684     with _ -> None 
685
686   and translate_binop p con t : expr option = 
687     try
688       let l,r = dest_binop p t in
689       match translate_expr l,translate_expr r with
690           Some l', Some r' -> Some (con(l',r'))
691         | _ -> None 
692     with _ -> None 
693
694   and translate_opp t = translate_unop `(--.)` (fun x -> Opp x) t
695   and translate_mul t = translate_binop `( *. )` (fun x,y -> Mul (x,y)) t
696   and translate_div t = translate_binop `( / )` (fun x,y -> Div (x,y)) t
697   and translate_pow t = 
698     try
699       let f,[x;n] = strip_comb t in
700       if not(f = `((pow):real->num->real)`) then None else
701       let Some x' = translate_expr x in
702       let Some n' = translate_int n in
703         Some (Pow(x',n'))
704     with _ -> None 
705
706   let translate_monom t : monom option = 
707     match translate_const t with
708         Some x -> Some (x,One)
709       | None -> 
710     match dest_mul t with
711         Some (c,e) -> 
712           (match translate_const c, translate_expr e with
713                Some c', Some e' -> Some (c',e')
714              | _ -> match translate_expr t with
715                    Some e -> Some (Int 1,e)
716                  | None -> None)
717       | None ->
718           match translate_expr t with
719               Some e -> Some (Int 1,e)
720             | None -> None;;
721
722   let rec translate_lcomb t = 
723     match dest_add t with
724         Some (l,r) ->
725           (match translate_lcomb l ,translate_lcomb r with
726               Some l', Some r' -> Some (l' @ r')
727              | _ -> None)
728       | None -> 
729           match translate_monom t with
730               Some m -> Some [m]
731             | None -> None
732
733   let translate_rel t =
734     try
735       let lcomb,zero = dest_binop `(<.)` t in
736       let _ = if zero <> `(&0)` then failwith "not zero" else () in
737         translate_lcomb lcomb 
738     with _ -> failwith "translate_rel"
739
740   let translate_ineq t =
741     try
742       let _,body = strip_forall t in
743       let ineq_tm,bounds_rel = strip_comb body in
744       let bounds,rel = match bounds_rel with [bounds;rel] -> bounds,rel | _ -> failwith "" in
745       let ineqs = disjuncts rel in
746       let map_fn q = match translate_rel q with Some l -> l | None -> failwith "" in
747       let ineqs = map map_fn ineqs in
748       let dest_trip xyz =
749         let x,yz = dest_pair xyz in
750         let x = match translate_const x with Some x -> x | None -> failwith "" in
751         let y,z = dest_pair yz in
752         let y,_ = dest_var y in
753         let z = match translate_const z with Some x -> x | None -> failwith "" in     
754           y,{lo = x; hi = z} in
755       let bounds' = map dest_trip (dest_list bounds) in
756         (bounds',ineqs)
757     with _ -> failwith "translate_ineq"
758
759   (* -------------------------------------------------------------------------- *)
760   (*  Normalize                                                                 *)
761   (* -------------------------------------------------------------------------- *)
762
763   let normalize =
764     let thms = [
765                  REAL_ARITH `x *. (y + z) = x * y + x * z`;
766                  REAL_ARITH `(x +. y) * z = z * x + z * y`;
767                  REAL_ARITH `&0 *. x = &0`;
768                  REAL_ARITH `x * -- y = -- x * y`;
769                  REAL_ARITH `(x -. y) = x + (-- y)`;
770                  REAL_ARITH `(x +. y) + z = x + y + z`;
771                  REAL_ARITH `--. (x * y) = (--. x) * y`;
772                  REAL_ARITH `-- #0.0 = &0`;
773                  REAL_ARITH `-- &0 = &0`;
774                  REAL_ARITH `x + &0 = x`;
775                  REAL_ARITH `&0 + x = x`;
776                  REAL_ARITH `--. (x + y) = (--. x) + (-- y)`;
777                  REAL_ARITH `--. (-- x) = x`;
778                  REAL_ARITH `!f:real->real->real->real->real->real->real. (-- (f x1 x2 x3 x4 x5 x6)) = (-- (&1) *. (f x1 x2 x3 x4 x5 x6))`;
779                  MESON [] `(a \/ (b \/ c)) = (a \/ b \/ c)`;
780                  pi_prime_tau;
781                  pi_prime_sigma;
782                  LET_DEF;
783                  LET_END_DEF;
784                ] in
785     let once_thms = [
786                       REAL_ARITH `!x y z:real. (x < y) = x - y < &0`;
787                       REAL_ARITH `!x y z:real. (x > y) = y - x < &0`;
788                     ] in
789       fun x -> 
790         snd (dest_eq (concl (
791                               (DEPTH_CONV BETA_CONV THENC
792                                ONCE_REWRITE_CONV once_thms THENC
793                                REWRITE_CONV thms THENC
794                                NUM_REDUCE_CONV) x)))
795
796   let translate (name,q) =
797     let _ = print_endline ("translating ineq: " ^ name) in
798     let bounds,rels = translate_ineq (normalize q) in
799       {name = name;
800        vars = bounds;
801        rels = rels}
802
803   let translate_list ~ignore ~terms = 
804     map translate (List.filter (fun x,_ -> not (mem x ignore)) terms)
805
806   (* -------------------------------------------------------------------------- *)
807   (*  Pretty Printing                                                           *)
808   (* -------------------------------------------------------------------------- *)
809
810   open Format
811
812   let pp_int n = 
813     begin 
814       open_hbox ();
815       print_string (string_of_int n);
816       close_box ();
817     end
818
819   let pp_pair f (l,r) = 
820     begin 
821       open_hbox();
822       print_string "(";f l;print_string ",";f r;print_string ")";
823       close_box();
824     end
825
826   let separate = 
827     let rec separate x l str = match l with 
828       | [] ->  List.rev str
829       | [h] ->  List.rev (h::str)
830       | h::h'::t -> separate x (h'::t) (x::h::str) in
831       fun x l -> separate x l []
832
833   let rec iter_butlast f l = match l with
834     | [] | [_] -> ()
835     | h::t -> (f h;iter_butlast f t)
836
837   let rec last l = match l with
838     | [] -> failwith ""
839     | [h] -> h
840     | _::t -> last t
841
842   let pp_list_horiz f l = if l = [] then print_string "[]" else
843     begin 
844       open_hbox();
845       print_string "[";
846       iter_butlast (fun x -> (f x; print_string ", ")) l;
847       f (last l);
848       print_string "]";
849       close_box();
850     end
851
852   let pp_list_vert f l = if l = [] then print_string "[]" else
853     begin 
854       open_vbox 1;
855       print_string "[";
856       iter_butlast (fun x -> (f x; print_string ",";print_cut())) l;
857       f (last l);
858       print_string "]";
859       close_box();
860     end
861
862   let pp_unop p s c = 
863     begin
864       open_hbox();
865       print_string s;
866       print_string "(";
867       p c;
868       print_string ")";    
869       close_box();
870     end
871
872   let pp_binop p1 p2 s c1 c2 = 
873     begin
874       open_hbox();
875       print_string s;
876       print_string "(";
877       p1 c1;
878       print_string ",";
879       p2 c2;
880       print_string ")";    
881       close_box();
882     end
883
884   let pp_decimal (x,y) = 
885     begin 
886       open_hbox();
887       print_string "Decimal";
888       pp_pair pp_int (x,y);
889       close_box();
890     end
891
892   let pp_named n = print_string (const_to_string n)
893
894   let rec pp_const c = match c with
895     | Decimal (x,y) -> pp_decimal(x,y)
896     | Int n -> (print_string "Int "; pp_int n)
897     | Named n -> (print_string "Named ";pp_named n)
898     | Cos c -> pp_cos c
899     | Acos c -> pp_acos c
900     | Sqr c -> pp_sqr c
901     | Sqrt c -> pp_sqrt c
902     | Copp c -> pp_copp c
903     | Cplus (x,y) -> pp_cplus x y
904     | Cmul (x,y) -> pp_cmul x y
905     | Cdiv (x,y) -> pp_cdiv x y
906
907   and pp_cos c = pp_unop pp_const "Cos" c
908   and pp_acos c = pp_unop pp_const "Acos" c
909   and pp_sqr c = pp_unop pp_const "Sqr" c
910   and pp_sqrt c = pp_unop pp_const "Sqrt" c
911   and pp_copp c = pp_unop pp_const "Copp" c
912   and pp_cplus c1 c2 = pp_binop pp_const pp_const "Cplus" c1 c2
913   and pp_cmul c1 c2 = pp_binop pp_const pp_const "Cmul" c1 c2
914   and pp_cdiv c1 c2 = pp_binop pp_const pp_const "Cdiv" c1 c2
915
916   let rec pp_expr e = match e with
917     | Const c -> (print_string "Const (";pp_const c;print_string ")")
918     | Funcall (f,xs) -> pp_funcall f xs
919     | Var v -> pp_var v
920     | Varsqrt v -> pp_varsqrt v
921     | Opp e -> pp_opp e
922     | Mul(x,y) -> pp_mul x y
923     | Div(x,y) -> pp_div x y
924     | Pow(x,n) -> pp_pow x n
925     | One -> print_string "One"
926
927   and pp_funcall f xs = 
928     begin 
929       open_hbox();
930       print_string "Funcall(";
931       print_string (func_to_string f);
932       print_string ", ";
933       pp_list_horiz pp_expr xs;
934       print_string ")";    
935       close_box();
936     end
937
938   and pp_var v = print_string ("Var \"" ^ v ^ "\"")
939   and pp_varsqrt v = print_string ("Varsqrt \"" ^ v ^ "\"")
940   and pp_opp e = pp_unop pp_expr "Opp" e 
941   and pp_mul e1 e2 = pp_binop pp_expr pp_expr "Mul" e1 e2
942   and pp_div e1 e2 = pp_binop pp_expr pp_expr "Div" e1 e2
943   and pp_pow e1 e2 = pp_binop pp_expr pp_int "Pow" e1 e2
944
945   let pp_monom (c,e) = 
946     begin 
947       open_hbox();
948       print_string "(";
949       pp_const c;
950       print_string ",";
951       pp_expr e;
952       print_string ")";
953       close_box();
954     end
955
956   let pp_lcomb l = pp_list_horiz pp_monom l
957
958   let pp_bounds (v, {lo=lo;hi=hi}) =
959     begin 
960       open_vbox 1;
961       print_string ("(\"" ^ v ^ "\",");
962       print_cut();
963        open_hbox();
964        print_string "{lo = ";
965        pp_const lo;
966        close_box();
967        print_string ",";
968        print_cut();
969        open_hbox();
970        print_string " hi = ";
971        pp_const hi;
972        print_string "})";
973        close_box();
974       close_box(); 
975     end
976
977   let ineq_to_sml q = 
978     begin
979       open_vbox 1;
980       print_string "{";
981       print_string "name = \"";
982       print_string q.name;
983       print_string "\",";
984       print_cut();
985       print_cut();
986       print_string "vars = ";
987        pp_list_vert pp_bounds q.vars;
988        print_string ",";
989       print_cut();
990       print_cut();
991       print_string "rels = ";
992        pp_list_vert pp_lcomb q.rels;
993        print_string "}";
994       close_box();
995     end
996
997   let ineqs_to_sml qs =
998     let doit q = 
999       begin
1000         ineq_to_sml q;
1001         print_string ",";
1002         print_cut();
1003         print_cut();
1004       end in
1005     begin
1006       open_vbox 4;
1007       print_cut();
1008       iter_butlast doit qs;
1009       ineq_to_sml (last qs);
1010       close_box();
1011     end
1012
1013   let header univ = 
1014 "
1015 (*============================================================================*)
1016 (* THIS FILE IS AUTOGENERATED.  DO NOT EDIT!!!                                *)
1017 (*============================================================================*)
1018
1019 structure " ^ univ ^ "InequalitySyntaxBase:> INEQUALITY_SYNTAX_BASE =
1020 struct 
1021
1022 open FunctionUtil
1023 open InequalityUtil
1024
1025 val unexpandedIneqs = [
1026 "
1027
1028   let footer = 
1029 "
1030 ]
1031
1032 end" 
1033
1034   let ineqs_to_sml ~file ~ineqs ~univ = 
1035     let chan = open_out file in
1036       try
1037         set_formatter_out_channel chan;
1038         print_string (header univ);
1039         ineqs_to_sml ineqs;
1040         print_string footer;
1041         set_formatter_out_channel stdout;        
1042         close_out chan;
1043       with exn -> 
1044         set_formatter_out_channel stdout;
1045         close_out chan;        
1046         raise exn
1047
1048 end
1049
1050 (* 
1051
1052 needs "Examples/analysis.ml";;
1053 needs "Examples/transc.ml";;
1054 needs "Jordan/lib_ext.ml";;
1055 needs "Jordan/parse_ext_override_interface.ml";;
1056 unambiguous_interface();;
1057
1058 #use "../../kepler/sml/inequalities/holl/definitions_kepler.ml";;
1059 #use "../../kepler/sml/inequalities/holl/kep_inequalities.ml";;
1060 #use "../../kepler/sml/inequalities/holl/ineq_names.ml";;
1061 #use "../../kepler/sml/inequalities/holl/ocaml_to_sml.ml";;
1062 let ocaml_ineqs = Ocaml_sml.translate_list ~ignore:Ineq_names.ignore ~terms:Ineq_names.ineqs;;
1063
1064 Ocaml_sml.ineqs_to_sml 
1065    ~file:"/Users/seanmcl/save/versioned/projects/kepler/sml/inequalities/inequality-syntax.sml" 
1066    ~ineqs:ocaml_ineqs;;
1067
1068 let file = "/Users/seanmcl/save/versioned/projects/kepler/sml/inequalities/inequality-syntax.sml"
1069
1070 let q = List.nth ocaml_ineqs 0;;
1071 (print_endline ""; Ocaml_sml.ineq_to_sml q; print_endline "";)
1072
1073    let t = Ocaml_sml.normalize x;;
1074    Ocaml_sml.translate_ineq t
1075
1076
1077    #trace Ocaml_sml.;;
1078    #trace Ocaml_sml.normalize;;
1079    #trace Ocaml_sml.translate_const;;
1080    #trace Ocaml_sml.translate_cdiv;;
1081    #trace Ocaml_sml.translate_expr;;
1082    #trace Ocaml_sml.translate_funcall;;
1083    #trace Ocaml_sml.translate_div;;
1084    #trace Ocaml_sml.translate_monom;;
1085    #trace Ocaml_sml.translate_lcomb;;
1086    #trace Ocaml_sml.translate_rel;;
1087    #trace Ocaml_sml.translate_ineq;;
1088    #trace Ocaml_sml.translate_pow;;
1089    #trace Ocaml_sml.translate;;
1090
1091    #untrace_all;;
1092
1093    let x = I_327474205_1
1094    Ocaml_sml.translate_ineq (Ocaml_sml.normalize x)
1095    Ocaml_sml.normalize I_327474205_1
1096
1097    translate_ineq I_867513567_13
1098    let t = `tau_sigma_x x1 x2 x3 x4 x5 x6 -. #0.2529 *. dih_x x1 x2 x3 x4 x5 x6 >.
1099    --. #0.3442`
1100
1101
1102  *)