]> matita.cs.unibo.it Git - helm.git/blob - helm/ocaml/cic_transformations/content2pres.ml
- implemented inductive type rendering
[helm.git] / helm / ocaml / cic_transformations / content2pres.ml
1 (* Copyright (C) 2000, HELM Team.
2  * 
3  * This file is part of HELM, an Hypertextual, Electronic
4  * Library of Mathematics, developed at the Computer Science
5  * Department, University of Bologna, Italy.
6  * 
7  * HELM is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  * 
12  * HELM is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with HELM; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20  * MA  02111-1307, USA.
21  * 
22  * For details, see the HELM World-Wide-Web page,
23  * http://cs.unibo.it/helm/.
24  *)
25
26 (***************************************************************************)
27 (*                                                                         *)
28 (*                            PROJECT HELM                                 *)
29 (*                                                                         *)
30 (*                Andrea Asperti <asperti@cs.unibo.it>                     *)
31 (*                              17/06/2003                                 *)
32 (*                                                                         *)
33 (***************************************************************************)
34
35 module P = Mpresentation
36 module B = Box
37
38 let p_mtr a b = Mpresentation.Mtr(a,b)
39 let p_mtd a b = Mpresentation.Mtd(a,b)
40 let p_mtable a b = Mpresentation.Mtable(a,b)
41 let p_mtext a b = Mpresentation.Mtext(a,b)
42 let p_mi a b = Mpresentation.Mi(a,b)
43 let p_mo a b = Mpresentation.Mo(a,b)
44 let p_mrow a b = Mpresentation.Mrow(a,b)
45 let p_mphantom a b = Mpresentation.Mphantom(a,b)
46
47 let rec split n l =
48   if n = 0 then [],l
49   else let l1,l2 = 
50     split (n-1) (List.tl l) in
51     (List.hd l)::l1,l2
52 ;;
53   
54
55 let is_big_general countterm p =
56   let maxsize = Ast2pres.maxsize in
57   let module Con = Content in
58   let rec countp current_size p =
59     if current_size > maxsize then current_size
60     else 
61       let c1 = (countcontext current_size p.Con.proof_context) in
62       if c1 > maxsize then c1
63     else 
64       let c2 = (countapplycontext c1 p.Con.proof_apply_context) in
65       if c2 > maxsize then c2
66     else 
67       countconclude c2 p.Con.proof_conclude
68
69   and 
70     countcontext current_size c =
71       List.fold_left countcontextitem current_size c
72   and
73     countcontextitem current_size e =
74       if current_size > maxsize then maxsize
75       else 
76         (match e with
77           `Declaration d -> 
78             (match d.Con.dec_name with
79                Some s -> current_size + 4 + (String.length s)
80              | None -> prerr_endline "NO NAME!!"; assert false)
81         | `Hypothesis h ->
82             (match h.Con.dec_name with
83                 Some s -> current_size + 4 + (String.length s)
84               | None -> prerr_endline "NO NAME!!"; assert false) 
85         | `Proof p -> countp current_size p
86         | `Definition d -> 
87             (match d.Con.def_name with
88                 Some s -> 
89                   let c1 = (current_size + 4 + (String.length s)) in
90                   (countterm c1 d.Con.def_term)
91               | None -> 
92                   prerr_endline "NO NAME!!"; assert false) 
93         | `Joint ho -> maxsize + 1) (* we assume is big *)
94   and 
95     countapplycontext current_size ac =
96       List.fold_left countp current_size ac
97   and 
98     countconclude current_size co =
99       if current_size > maxsize then current_size
100       else
101         let c1 = countargs current_size co.Con.conclude_args in
102         if c1 > maxsize then c1 
103       else 
104         (match co.Con.conclude_conclusion with
105            Some concl ->  countterm c1 concl
106         | None -> c1)
107   and 
108     countargs current_size args =
109       List.fold_left countarg current_size args
110   and
111     countarg current_size arg =
112       if current_size > maxsize then current_size
113       else 
114         (match arg with 
115            Con.Aux _ -> current_size
116          | Con.Premise prem -> 
117              (match prem.Con.premise_binder with
118                 Some s -> current_size + (String.length s)
119               | None -> current_size + 7) 
120          | Con.Lemma lemma -> 
121              current_size + (String.length lemma.Con.lemma_name)
122          | Con.Term t -> countterm current_size t
123          | Con.ArgProof p -> countp current_size p
124          | Con.ArgMethod s -> (maxsize + 1)) in
125   let size = (countp 0 p) in
126   (size > maxsize)
127 ;;
128
129 let is_big = is_big_general (Ast2pres.countterm)
130 ;;
131
132 let get_xref =
133     let module Con = Content in
134       function
135         `Declaration d  
136       | `Hypothesis d -> d.Con.dec_id
137       | `Proof p -> p.Con.proof_id
138       | `Definition d -> d.Con.def_id
139       | `Joint jo -> jo.Con.joint_id
140 ;;
141
142 let make_row ?(attrs=[]) items concl =
143   match concl with 
144       B.V _ -> (* big! *)
145         B.b_v attrs [B.b_h [] items; B.b_indent concl]
146     | _ ->  (* small *)
147         B.b_h attrs (items@[B.b_space; concl])
148 ;;
149
150 let make_concl ?(attrs=[]) verb concl =
151   match concl with 
152       B.V _ -> (* big! *)
153         B.b_v attrs [ B.b_kw verb; B.b_indent concl]
154     | _ ->  (* small *)
155         B.b_h attrs [ B.b_kw verb; B.b_space; concl ]
156 ;;
157
158 let make_args_for_apply term2pres args =
159  let module Con = Content in
160  let make_arg_for_apply is_first arg row = 
161   let res =
162    match arg with 
163       Con.Aux n -> assert false
164     | Con.Premise prem -> 
165         let name = 
166           (match prem.Con.premise_binder with
167              None -> "previous"
168            | Some s -> s) in
169         (B.b_object (P.Mi ([], name)))::row
170     | Con.Lemma lemma -> 
171         (B.b_object (P.Mi([],lemma.Con.lemma_name)))::row 
172     | Con.Term t -> 
173         if is_first then
174           (term2pres t)::row
175         else (B.b_object (P.Mi([],"_")))::row
176     | Con.ArgProof _ 
177     | Con.ArgMethod _ -> 
178         (B.b_object (P.Mi([],"_")))::row
179   in
180    if is_first then res else B.skip::res
181  in
182   match args with 
183     hd::tl -> 
184       make_arg_for_apply true hd 
185         (List.fold_right (make_arg_for_apply false) tl [])
186   | _ -> assert false
187 ;;
188
189 let get_name = function
190   | Some s -> s
191   | None -> "_"
192
193 let rec justification term2pres p = 
194   let module Con = Content in
195   let module P = Mpresentation in
196   if ((p.Con.proof_conclude.Con.conclude_method = "Exact") or
197      ((p.Con.proof_context = []) &
198       (p.Con.proof_apply_context = []) &
199       (p.Con.proof_conclude.Con.conclude_method = "Apply"))) then
200     let pres_args = 
201       make_args_for_apply term2pres p.Con.proof_conclude.Con.conclude_args in
202     B.H([],
203       (B.b_kw "by")::B.b_space::
204       B.Text([],"(")::pres_args@[B.Text([],")")]) 
205   else proof2pres term2pres p 
206      
207 and proof2pres term2pres p =
208   let rec proof2pres p =
209     let module Con = Content in
210       let indent = 
211         let is_decl e = 
212           (match e with 
213              `Declaration _
214            | `Hypothesis _ -> true
215            | _ -> false) in
216         ((List.filter is_decl p.Con.proof_context) != []) in 
217       let omit_conclusion = (not indent) && (p.Con.proof_context != []) in
218       let concl = 
219         (match p.Con.proof_conclude.Con.conclude_conclusion with
220            None -> None
221          | Some t -> Some (term2pres t)) in
222       let body =
223           let presconclude = 
224             conclude2pres p.Con.proof_conclude indent omit_conclusion in
225           let presacontext = 
226             acontext2pres p.Con.proof_apply_context presconclude indent in
227           context2pres p.Con.proof_context presacontext in
228       match p.Con.proof_name with
229         None -> body
230       | Some name ->
231           let action = 
232            match concl with
233               None -> body
234             | Some ac ->
235                B.Action
236                  ([None,"type","toggle"],
237                   [(make_concl ~attrs:[Some "helm", "xref", p.Con.proof_id]
238                      "proof of" ac); body])
239           in
240           B.V ([],
241             [B.Text ([],"(" ^ name ^ ")");
242              B.indent action])
243
244   and context2pres c continuation =
245     (* we generate a subtable for each context element, for selection
246        purposes 
247        The table generated by the head-element does not have an xref;
248        the whole context-proof is already selectable *)
249     match c with
250       [] -> continuation
251     | hd::tl -> 
252         let continuation' =
253           List.fold_right
254             (fun ce continuation ->
255               let xref = get_xref ce in
256               B.V([Some "helm", "xref", xref ],
257                 [B.H([Some "helm", "xref", "ce_"^xref],[ce2pres ce]);
258                  continuation])) tl continuation in
259          let hd_xref= get_xref hd in
260          B.V([],
261              [B.H([Some "helm", "xref", "ce_"^hd_xref],
262                [ce2pres hd]);
263              continuation'])
264          
265   and ce2pres =
266     let module Con = Content in
267       function
268         `Declaration d -> 
269           (match d.Con.dec_name with
270               Some s ->
271                 let ty = term2pres d.Con.dec_type in
272                 B.H ([],
273                   [(B.b_kw "Assume");
274                    B.b_space;
275                    B.Object ([], P.Mi([],s));
276                    B.Text([],":");
277                    ty])
278             | None -> 
279                 prerr_endline "NO NAME!!"; assert false)
280       | `Hypothesis h ->
281           (match h.Con.dec_name with
282               Some s ->
283                 let ty = term2pres h.Con.dec_type in
284                 B.H ([],
285                   [(B.b_kw "Suppose");
286                    B.b_space;
287                    B.Text([],"(");
288                    B.Object ([], P.Mi ([],s));
289                    B.Text([],")");
290                    B.b_space;
291                    ty])
292             | None -> 
293                 prerr_endline "NO NAME!!"; assert false) 
294       | `Proof p -> 
295            proof2pres p 
296       | `Definition d -> 
297            (match d.Con.def_name with
298               Some s ->
299                 let term = term2pres d.Con.def_term in
300                 B.H ([],
301                   [B.Text([],"Let ");
302                    B.Object ([], P.Mi([],s));
303                    B.Text([]," = ");
304                    term])
305             | None -> 
306                 prerr_endline "NO NAME!!"; assert false) 
307       | `Joint ho -> 
308             B.Text ([],"jointdef")
309
310   and acontext2pres ac continuation indent =
311     let module Con = Content in
312     List.fold_right
313       (fun p continuation ->
314          let hd = 
315            if indent then
316              B.indent (proof2pres p)
317            else 
318              proof2pres p in
319          B.V([Some "helm","xref",p.Con.proof_id],
320            [B.H([Some "helm","xref","ace_"^p.Con.proof_id],[hd]);
321             continuation])) ac continuation 
322
323   and conclude2pres conclude indent omit_conclusion =
324     let module Con = Content in
325     let module P = Mpresentation in
326     let tconclude_body = 
327       match conclude.Con.conclude_conclusion with
328         Some t when
329          not omit_conclusion or
330          (* CSC: I ignore the omit_conclusion flag in this case.   *)
331          (* CSC: Is this the correct behaviour? In the stylesheets *)
332          (* CSC: we simply generated nothing (i.e. the output type *)
333          (* CSC: of the function should become an option.          *)
334          conclude.Con.conclude_method = "BU_Conversion" ->
335           let concl = (term2pres t) in 
336           if conclude.Con.conclude_method = "BU_Conversion" then
337             make_concl "that is equivalent to" concl
338           else if conclude.Con.conclude_method = "FalseInd" then
339            (* false ind is in charge to add the conclusion *)
340            falseind conclude
341           else  
342             let conclude_body = conclude_aux conclude in
343             let ann_concl = 
344               if conclude.Con.conclude_method = "TD_Conversion" then
345                  make_concl "that is equivalent to" concl 
346               else make_concl "we conclude" concl in
347             B.V ([], [conclude_body; ann_concl])
348       | _ -> conclude_aux conclude in
349     if indent then 
350       B.indent (B.H ([Some "helm", "xref", conclude.Con.conclude_id],
351                     [tconclude_body]))
352     else 
353       B.H ([Some "helm", "xref", conclude.Con.conclude_id],[tconclude_body])
354
355
356   and conclude_aux conclude =
357     let module Con = Content in
358     let module P = Mpresentation in
359     if conclude.Con.conclude_method = "TD_Conversion" then
360       let expected = 
361         (match conclude.Con.conclude_conclusion with 
362            None -> B.Text([],"NO EXPECTED!!!")
363          | Some c -> term2pres c) in
364       let subproof = 
365         (match conclude.Con.conclude_args with
366           [Con.ArgProof p] -> p
367          | _ -> assert false) in
368       let synth = 
369         (match subproof.Con.proof_conclude.Con.conclude_conclusion with
370            None -> B.Text([],"NO SYNTH!!!")
371          | Some c -> (term2pres c)) in
372       B.V 
373         ([],
374         [make_concl "we must prove" expected;
375          make_concl "or equivalently" synth;
376          proof2pres subproof])
377     else if conclude.Con.conclude_method = "BU_Conversion" then
378       assert false
379     else if conclude.Con.conclude_method = "Exact" then
380       let arg = 
381         (match conclude.Con.conclude_args with 
382            [Con.Term t] -> term2pres t
383          | _ -> assert false) in
384       (match conclude.Con.conclude_conclusion with 
385          None ->
386           B.b_h [] [B.b_kw "Consider"; B.b_space; arg]
387        | Some c -> let conclusion = term2pres c in
388           make_row 
389             [arg; B.b_space; B.Text([],"proves")]
390             conclusion
391        )
392     else if conclude.Con.conclude_method = "Intros+LetTac" then
393       (match conclude.Con.conclude_args with
394          [Con.ArgProof p] -> proof2pres p
395        | _ -> assert false)
396 (* OLD CODE 
397       let conclusion = 
398       (match conclude.Con.conclude_conclusion with 
399          None -> B.Text([],"NO Conclusion!!!")
400        | Some c -> term2pres c) in
401       (match conclude.Con.conclude_args with
402          [Con.ArgProof p] -> 
403            B.V 
404             ([None,"align","baseline 1"; None,"equalrows","false";
405               None,"columnalign","left"],
406               [B.H([],[B.Object([],proof2pres p)]);
407                B.H([],[B.Object([],
408                 (make_concl "we proved 1" conclusion))])]);
409        | _ -> assert false)
410 *)
411     else if (conclude.Con.conclude_method = "Case") then
412       case conclude
413     else if (conclude.Con.conclude_method = "ByInduction") then
414       byinduction conclude
415     else if (conclude.Con.conclude_method = "Exists") then
416       exists conclude
417     else if (conclude.Con.conclude_method = "AndInd") then
418       andind conclude
419     else if (conclude.Con.conclude_method = "FalseInd") then
420       falseind conclude
421     else if (conclude.Con.conclude_method = "Rewrite") then
422       let justif = 
423         (match (List.nth conclude.Con.conclude_args 6) with
424            Con.ArgProof p -> justification term2pres p
425          | _ -> assert false) in
426       let term1 = 
427         (match List.nth conclude.Con.conclude_args 2 with
428            Con.Term t -> term2pres t
429          | _ -> assert false) in 
430       let term2 = 
431         (match List.nth conclude.Con.conclude_args 5 with
432            Con.Term t -> term2pres t
433          | _ -> assert false) in
434       B.V ([], 
435          [B.H ([],[
436           (B.b_kw "rewrite");
437           B.b_space; term1;
438           B.b_space; (B.b_kw "with");
439           B.b_space; term2;
440           B.indent justif])])
441     else if conclude.Con.conclude_method = "Apply" then
442       let pres_args = 
443         make_args_for_apply term2pres conclude.Con.conclude_args in
444       B.H([],
445         (B.b_kw "by")::
446         B.b_space::
447         B.Text([],"(")::pres_args@[B.Text([],")")])
448     else 
449       B.V 
450         ([],
451          [B.Text([],"Apply method" ^ conclude.Con.conclude_method ^ " to");
452           (B.indent 
453              (B.V 
454                 ([],
455                  args2pres conclude.Con.conclude_args)))]) 
456
457   and args2pres l = List.map arg2pres l
458
459   and arg2pres =
460     let module Con = Content in
461     function
462         Con.Aux n -> 
463           B.Text ([],"aux " ^ n)
464       | Con.Premise prem -> 
465           B.Text ([],"premise")
466       | Con.Lemma lemma ->
467           B.Text ([],"lemma")
468       | Con.Term t -> 
469           term2pres t
470       | Con.ArgProof p ->
471         proof2pres p 
472       | Con.ArgMethod s -> 
473          B.Text ([],"method") 
474  
475    and case conclude =
476      let module Con = Content in
477      let proof_conclusion = 
478        (match conclude.Con.conclude_conclusion with
479           None -> B.Text([],"No conclusion???")
480         | Some t -> term2pres t) in
481      let arg,args_for_cases = 
482        (match conclude.Con.conclude_args with
483            Con.Aux(_)::Con.Aux(_)::Con.Term(_)::arg::tl ->
484              arg,tl
485          | _ -> assert false) in
486      let case_on =
487        let case_arg = 
488          (match arg with
489             Con.Aux n -> 
490               B.Text ([],"an aux???")
491            | Con.Premise prem ->
492               (match prem.Con.premise_binder with
493                  None -> B.Text ([],"the previous result")
494                | Some n -> B.Object ([], P.Mi([],n)))
495            | Con.Lemma lemma -> B.Object ([], P.Mi([],lemma.Con.lemma_name))
496            | Con.Term t -> 
497                term2pres t
498            | Con.ArgProof p ->
499                B.Text ([],"a proof???")
500            | Con.ArgMethod s -> 
501                B.Text ([],"a method???")) in
502         (make_concl "we proceede by cases on" case_arg) in
503      let to_prove =
504         (make_concl "to prove" proof_conclusion) in
505      B.V 
506        ([],
507           case_on::to_prove::(make_cases args_for_cases))
508
509    and byinduction conclude =
510      let module Con = Content in
511      let proof_conclusion = 
512        (match conclude.Con.conclude_conclusion with
513           None -> B.Text([],"No conclusion???")
514         | Some t -> term2pres t) in
515      let inductive_arg,args_for_cases = 
516        (match conclude.Con.conclude_args with
517            Con.Aux(n)::_::tl ->
518              let l1,l2 = split (int_of_string n) tl in
519              let last_pos = (List.length l2)-1 in
520              List.nth l2 last_pos,l1
521          | _ -> assert false) in
522      let induction_on =
523        let arg = 
524          (match inductive_arg with
525             Con.Aux n -> 
526               B.Text ([],"an aux???")
527            | Con.Premise prem ->
528               (match prem.Con.premise_binder with
529                  None -> B.Text ([],"the previous result")
530                | Some n -> B.Object ([], P.Mi([],n)))
531            | Con.Lemma lemma -> B.Object ([], P.Mi([],lemma.Con.lemma_name))
532            | Con.Term t -> 
533                term2pres t
534            | Con.ArgProof p ->
535                B.Text ([],"a proof???")
536            | Con.ArgMethod s -> 
537                B.Text ([],"a method???")) in
538         (make_concl "we proceede by induction on" arg) in
539      let to_prove =
540         (make_concl "to prove" proof_conclusion) in
541      B.V 
542        ([],
543           induction_on::to_prove::
544           (make_cases args_for_cases))
545
546     and make_cases l = List.map make_case l
547
548     and make_case =  
549       let module Con = Content in
550       function 
551         Con.ArgProof p ->
552           let name =
553             (match p.Con.proof_name with
554                None -> B.Text([],"no name for case!!")
555              | Some n -> B.Object ([], P.Mi([],n))) in
556           let indhyps,args =
557              List.partition 
558                (function
559                    `Hypothesis h -> h.Con.dec_inductive
560                  | _ -> false) p.Con.proof_context in
561           let pattern_aux =
562              List.fold_right
563                (fun e p -> 
564                   let dec  = 
565                     (match e with 
566                        `Declaration h 
567                      | `Hypothesis h -> 
568                          let name = 
569                            (match h.Con.dec_name with
570                               None -> "NO NAME???"
571                            | Some n ->n) in
572                          [B.b_space;
573                           B.Object ([], P.Mi ([],name));
574                           B.Text([],":");
575                           (term2pres h.Con.dec_type)]
576                      | _ -> [B.Text ([],"???")]) in
577                   dec@p) args [] in
578           let pattern = 
579             B.H ([],
580                (B.Text([],"Case")::B.b_space::name::pattern_aux)@
581                 [B.b_space;
582                  B.Text([],"->")]) in
583           let subconcl = 
584             (match p.Con.proof_conclude.Con.conclude_conclusion with
585                None -> B.Text([],"No conclusion!!!") 
586              | Some t -> term2pres t) in
587           let asubconcl = B.indent (make_concl "the thesis becomes" subconcl) in
588           let induction_hypothesis = 
589             (match indhyps with
590               [] -> []
591             | _ -> 
592                let text =
593                  B.indent (B.Text([],"by induction hypothesis we know:")) in
594                let make_hyp =
595                  function 
596                    `Hypothesis h ->
597                      let name = 
598                        (match h.Con.dec_name with
599                           None -> "no name"
600                         | Some s -> s) in
601                      B.indent (B.H ([],
602                        [B.Text([],"(");
603                         B.Object ([], P.Mi ([],name));
604                         B.Text([],")");
605                         B.b_space;
606                         term2pres h.Con.dec_type]))
607                    | _ -> assert false in
608                let hyps = List.map make_hyp indhyps in
609                text::hyps) in          
610           (* let acontext = 
611                acontext2pres_old p.Con.proof_apply_context true in *)
612           let body = conclude2pres p.Con.proof_conclude true false in
613           let presacontext = 
614            let acontext_id =
615             match p.Con.proof_apply_context with
616                [] -> p.Con.proof_conclude.Con.conclude_id
617              | {Con.proof_id = id}::_ -> id
618            in
619             B.Action([None,"type","toggle"],
620               [B.indent
621                (B.Text
622                  ([None,"color","red" ;
623                    Some "helm", "xref", acontext_id],"Proof")) ;
624                acontext2pres p.Con.proof_apply_context body true]) in
625           B.V ([], pattern::asubconcl::induction_hypothesis@[presacontext])
626        | _ -> assert false 
627
628      and falseind conclude =
629        let module P = Mpresentation in
630        let module Con = Content in
631        let proof_conclusion = 
632          (match conclude.Con.conclude_conclusion with
633             None -> B.Text([],"No conclusion???")
634           | Some t -> term2pres t) in
635        let case_arg = 
636          (match conclude.Con.conclude_args with
637              [Con.Aux(n);_;case_arg] -> case_arg
638            | _ -> assert false;
639              (* 
640              List.map (ContentPp.parg 0) conclude.Con.conclude_args;
641              assert false *)) in
642        let arg = 
643          (match case_arg with
644              Con.Aux n -> assert false
645            | Con.Premise prem ->
646               (match prem.Con.premise_binder with
647                  None -> [B.Text([],"Contradiction, hence")]
648                | Some n -> 
649                   [B.Object ([],P.Mi([],n)); B.skip;B.Text([],"is contradictory, hence")])
650            | Con.Lemma lemma -> 
651                [B.Object ([], P.Mi([],lemma.Con.lemma_name)); B.skip; B.Text([],"is contradictory, hence")]
652            | _ -> assert false) in
653             (* let body = proof2pres {proof with Con.proof_context = tl} in *)
654        make_row arg proof_conclusion
655
656      and andind conclude =
657        let module P = Mpresentation in
658        let module Con = Content in
659        let proof_conclusion = 
660          (match conclude.Con.conclude_conclusion with
661             None -> B.Text([],"No conclusion???")
662           | Some t -> term2pres t) in
663        let proof,case_arg = 
664          (match conclude.Con.conclude_args with
665              [Con.Aux(n);_;Con.ArgProof proof;case_arg] -> proof,case_arg
666            | _ -> assert false;
667              (* 
668              List.map (ContentPp.parg 0) conclude.Con.conclude_args;
669              assert false *)) in
670        let arg = 
671          (match case_arg with
672              Con.Aux n -> assert false
673            | Con.Premise prem ->
674               (match prem.Con.premise_binder with
675                  None -> []
676                | Some n -> [(B.b_kw "by"); B.b_space; B.Object([], P.Mi([],n))])
677            | Con.Lemma lemma -> 
678                [(B.b_kw "by");B.skip; B.Object([], P.Mi([],lemma.Con.lemma_name))]
679            | _ -> assert false) in
680        match proof.Con.proof_context with
681          `Hypothesis hyp1::`Hypothesis hyp2::tl ->
682             let get_name hyp =
683               (match hyp.Con.dec_name with
684                 None -> "_"
685               | Some s -> s) in
686             let preshyp1 = 
687               B.H ([],
688                [B.Text([],"(");
689                 B.Object ([], P.Mi([],get_name hyp1));
690                 B.Text([],")");
691                 B.skip;
692                 term2pres hyp1.Con.dec_type]) in
693             let preshyp2 = 
694               B.H ([],
695                [B.Text([],"(");
696                 B.Object ([], P.Mi([],get_name hyp2));
697                 B.Text([],")");
698                 B.skip;
699                 term2pres hyp2.Con.dec_type]) in
700             (* let body = proof2pres {proof with Con.proof_context = tl} in *)
701             let body = conclude2pres proof.Con.proof_conclude false true in
702             let presacontext = 
703               acontext2pres proof.Con.proof_apply_context body false in
704             B.V 
705               ([],
706                [B.H ([],arg@[B.skip; B.Text([],"we have")]);
707                 preshyp1;
708                 B.Text([],"and");
709                 preshyp2;
710                 presacontext]);
711          | _ -> assert false
712
713      and exists conclude =
714        let module P = Mpresentation in
715        let module Con = Content in
716        let proof_conclusion = 
717          (match conclude.Con.conclude_conclusion with
718             None -> B.Text([],"No conclusion???")
719           | Some t -> term2pres t) in
720        let proof = 
721          (match conclude.Con.conclude_args with
722              [Con.Aux(n);_;Con.ArgProof proof;_] -> proof
723            | _ -> assert false;
724              (* 
725              List.map (ContentPp.parg 0) conclude.Con.conclude_args;
726              assert false *)) in
727        match proof.Con.proof_context with
728            `Declaration decl::`Hypothesis hyp::tl
729          | `Hypothesis decl::`Hypothesis hyp::tl ->
730            let get_name decl =
731              (match decl.Con.dec_name with
732                 None -> "_"
733               | Some s -> s) in
734            let presdecl = 
735              B.H ([],
736                [(B.b_kw "let");
737                 B.skip;
738                 B.Object ([], P.Mi([],get_name decl));
739                 B.Text([],":"); term2pres decl.Con.dec_type]) in
740            let suchthat =
741              B.H ([],
742                [(B.b_kw "such that");
743                 B.skip;
744                 B.Text([],"(");
745                 B.Object ([], P.Mi([],get_name hyp));
746                 B.Text([],")");
747                 B.skip;
748                 term2pres hyp.Con.dec_type]) in
749             (* let body = proof2pres {proof with Con.proof_context = tl} in *)
750             let body = conclude2pres proof.Con.proof_conclude false true in
751             let presacontext = 
752               acontext2pres proof.Con.proof_apply_context body false in
753             B.V 
754               ([],
755                [presdecl;
756                 suchthat;
757                 presacontext]);
758          | _ -> assert false in
759
760 proof2pres p
761 ;;
762
763 exception ToDo;;
764
765 let counter = ref 0
766
767 let conjecture2pres term2pres (id, n, context, ty) =
768   (B.b_h [Some "helm", "xref", id]
769      (((List.map
770           (function
771              | None ->
772                  B.b_h []
773                    [ B.b_object (p_mi [] "_") ;
774                      B.b_object (p_mo [] ":?") ;
775                      B.b_object (p_mi [] "_")]
776              | Some (`Declaration d)
777              | Some (`Hypothesis d) ->
778                  let { Content.dec_name =
779                      dec_name ; Content.dec_type = ty } = d
780                  in
781                    B.b_h []
782                      [ B.b_object
783                          (p_mi []
784                             (match dec_name with
785                                  None -> "_"
786                                | Some n -> n));
787                        B.b_text [] ":";
788                        term2pres ty ]
789              | Some (`Definition d) ->
790                  let
791                      { Content.def_name = def_name ;
792                        Content.def_term = bo } = d
793                  in
794                    B.b_h []
795                      [ B.b_object (p_mi []
796                                      (match def_name with
797                                           None -> "_"
798                                         | Some n -> n)) ;
799                        B.b_text [] ":=" ;
800                        term2pres bo]
801              | Some (`Proof p) ->
802                  let proof_name = p.Content.proof_name in
803                    B.b_h []
804                      [ B.b_object (p_mi []
805                                      (match proof_name with
806                                           None -> "_"
807                                         | Some n -> n)) ;
808                        B.b_text [] ":=" ;
809                        proof2pres term2pres p])
810           (List.rev context)) @
811          [ B.b_text [] "|-" ;
812            B.b_object (p_mi [] (string_of_int n)) ;
813            B.b_text [] ":" ;
814            term2pres ty ])))
815
816 let metasenv2pres term2pres = function
817   | None -> []
818   | Some metasenv' ->
819       (* Conjectures are in their own table to make *)
820       (* diffing the DOM trees easier.              *)
821       [B.b_v []
822         ((B.b_text []
823             ("Conjectures:" ^
824              (let _ = incr counter; in (string_of_int !counter)))) ::
825          (List.map (conjecture2pres term2pres) metasenv'))]
826
827 let params2pres params =
828   let param2pres uri =
829     B.b_text [Some "xlink", "href", UriManager.string_of_uri uri]
830       (UriManager.name_of_uri uri)
831   in
832   let rec spatiate = function
833     | [] -> []
834     | hd :: [] -> [hd]
835     | hd :: tl -> hd :: B.b_text [] ", " :: spatiate tl
836   in
837   match params with
838   | [] -> []
839   | p ->
840       let params = spatiate (List.map param2pres p) in
841       [B.b_space;
842        B.b_h [] (B.b_text [] "[" :: params @ [ B.b_text [] "]" ])]
843
844 let recursion_kind2pres params kind =
845   let kind =
846     match kind with
847     | `Recursive _ -> "Recursive definition"
848     | `CoRecursive -> "CoRecursive definition"
849     | `Inductive _ -> "Inductive definition"
850     | `CoInductive _ -> "CoInductive definition"
851   in
852   B.b_h [] (B.b_text [] kind :: params2pres params)
853
854 let inductive2pres term2pres ind =
855   let constructor2pres decl =
856     B.b_h [] [
857       B.b_text [] ("| " ^ get_name decl.Content.dec_name ^ ":");
858       B.b_space;
859       term2pres decl.Content.dec_type
860     ]
861   in
862   B.b_v []
863     (B.b_h [] [
864       B.b_text [] (ind.Content.inductive_name ^ " of arity ");
865       term2pres ind.Content.inductive_type ]
866     :: List.map constructor2pres ind.Content.inductive_constructors)
867
868 let joint_def2pres term2pres def =
869   match def with
870   | `Inductive ind -> inductive2pres term2pres ind
871   | _ -> assert false (* ZACK or raise ToDo? *)
872
873 let content2pres term2pres (id,params,metasenv,obj) =
874   match obj with
875   | `Def (Content.Const, thesis, `Proof p) ->
876       let name = get_name p.Content.proof_name in
877       B.b_v
878         [Some "helm","xref","id"]
879         ([ B.b_h [] (B.b_text [] ("Proof " ^ name) :: params2pres params);
880            B.b_text [] "Thesis:";
881            B.indent (term2pres thesis) ] @
882          metasenv2pres term2pres metasenv @
883          [proof2pres term2pres p])
884   | `Def (_, ty, `Definition body) ->
885       let name = get_name body.Content.def_name in
886       B.b_v
887         [Some "helm","xref","id"]
888         ([B.b_h [] (B.b_text [] ("Definition " ^ name) :: params2pres params);
889           B.b_text [] "Type:";
890           B.indent (term2pres ty)] @
891           metasenv2pres term2pres metasenv @
892           [term2pres body.Content.def_term])
893   | `Decl (_, `Declaration decl)
894   | `Decl (_, `Hypothesis decl) ->
895       let name = get_name decl.Content.dec_name in
896       B.b_v
897         [Some "helm","xref","id"]
898         ([B.b_h [] (B.b_text [] ("Axiom " ^ name) :: params2pres params);
899           B.b_text [] "Type:";
900           B.indent (term2pres decl.Content.dec_type)] @
901           metasenv2pres term2pres metasenv)
902   | `Joint joint ->
903       B.b_v []
904         (recursion_kind2pres params joint.Content.joint_kind
905         :: List.map (joint_def2pres term2pres) joint.Content.joint_defs)
906   | _ -> raise ToDo
907 ;;
908
909 (*
910 let content2pres ~ids_to_inner_sorts =
911  content2pres 
912   (function p -> 
913      (Cexpr2pres.cexpr2pres_charcount 
914                     (Content_expressions.acic2cexpr ids_to_inner_sorts p)))
915 ;;
916 *)
917
918 let content2pres ~ids_to_inner_sorts =
919   content2pres
920     (fun annterm ->
921       let (ast, ids_to_uris) as arg =
922         Acic2Ast.ast_of_acic ids_to_inner_sorts annterm
923       in
924       let astBox = Ast2pres.ast2astBox arg in
925       Box.map (fun ast -> Ast2pres.ast2mpres (ast, ids_to_uris)) astBox)
926