]> matita.cs.unibo.it Git - helm.git/blob - helm/ocaml/cic_transformations/content2pres.ml
fixed Whelp stuff
[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 -> assert false (*
308         B.H ([],
309         (B.Text ([],"JOINT ")
310         :: List.map ce2pres ho.Content.joint_defs)) *)
311
312   and acontext2pres ac continuation indent =
313     let module Con = Content in
314     List.fold_right
315       (fun p continuation ->
316          let hd = 
317            if indent then
318              B.indent (proof2pres p)
319            else 
320              proof2pres p in
321          B.V([Some "helm","xref",p.Con.proof_id],
322            [B.H([Some "helm","xref","ace_"^p.Con.proof_id],[hd]);
323             continuation])) ac continuation 
324
325   and conclude2pres conclude indent omit_conclusion =
326     let module Con = Content in
327     let module P = Mpresentation in
328     let tconclude_body = 
329       match conclude.Con.conclude_conclusion with
330         Some t when
331          not omit_conclusion or
332          (* CSC: I ignore the omit_conclusion flag in this case.   *)
333          (* CSC: Is this the correct behaviour? In the stylesheets *)
334          (* CSC: we simply generated nothing (i.e. the output type *)
335          (* CSC: of the function should become an option.          *)
336          conclude.Con.conclude_method = "BU_Conversion" ->
337           let concl = (term2pres t) in 
338           if conclude.Con.conclude_method = "BU_Conversion" then
339             make_concl "that is equivalent to" concl
340           else if conclude.Con.conclude_method = "FalseInd" then
341            (* false ind is in charge to add the conclusion *)
342            falseind conclude
343           else  
344             let conclude_body = conclude_aux conclude in
345             let ann_concl = 
346               if conclude.Con.conclude_method = "TD_Conversion" then
347                  make_concl "that is equivalent to" concl 
348               else make_concl "we conclude" concl in
349             B.V ([], [conclude_body; ann_concl])
350       | _ -> conclude_aux conclude in
351     if indent then 
352       B.indent (B.H ([Some "helm", "xref", conclude.Con.conclude_id],
353                     [tconclude_body]))
354     else 
355       B.H ([Some "helm", "xref", conclude.Con.conclude_id],[tconclude_body])
356
357
358   and conclude_aux conclude =
359     let module Con = Content in
360     let module P = Mpresentation in
361     if conclude.Con.conclude_method = "TD_Conversion" then
362       let expected = 
363         (match conclude.Con.conclude_conclusion with 
364            None -> B.Text([],"NO EXPECTED!!!")
365          | Some c -> term2pres c) in
366       let subproof = 
367         (match conclude.Con.conclude_args with
368           [Con.ArgProof p] -> p
369          | _ -> assert false) in
370       let synth = 
371         (match subproof.Con.proof_conclude.Con.conclude_conclusion with
372            None -> B.Text([],"NO SYNTH!!!")
373          | Some c -> (term2pres c)) in
374       B.V 
375         ([],
376         [make_concl "we must prove" expected;
377          make_concl "or equivalently" synth;
378          proof2pres subproof])
379     else if conclude.Con.conclude_method = "BU_Conversion" then
380       assert false
381     else if conclude.Con.conclude_method = "Exact" then
382       let arg = 
383         (match conclude.Con.conclude_args with 
384            [Con.Term t] -> term2pres t
385          | [Con.Premise p] -> 
386              (match p.Con.premise_binder with
387              | None -> assert false; (* unnamed hypothesis ??? *)
388              | Some s -> B.Text([],s))
389          | err -> assert false) in
390       (match conclude.Con.conclude_conclusion with 
391          None ->
392           B.b_h [] [B.b_kw "Consider"; B.b_space; arg]
393        | Some c -> let conclusion = term2pres c in
394           make_row 
395             [arg; B.b_space; B.Text([],"proves")]
396             conclusion
397        )
398     else if conclude.Con.conclude_method = "Intros+LetTac" then
399       (match conclude.Con.conclude_args with
400          [Con.ArgProof p] -> proof2pres p
401        | _ -> assert false)
402 (* OLD CODE 
403       let conclusion = 
404       (match conclude.Con.conclude_conclusion with 
405          None -> B.Text([],"NO Conclusion!!!")
406        | Some c -> term2pres c) in
407       (match conclude.Con.conclude_args with
408          [Con.ArgProof p] -> 
409            B.V 
410             ([None,"align","baseline 1"; None,"equalrows","false";
411               None,"columnalign","left"],
412               [B.H([],[B.Object([],proof2pres p)]);
413                B.H([],[B.Object([],
414                 (make_concl "we proved 1" conclusion))])]);
415        | _ -> assert false)
416 *)
417     else if (conclude.Con.conclude_method = "Case") then
418       case conclude
419     else if (conclude.Con.conclude_method = "ByInduction") then
420       byinduction conclude
421     else if (conclude.Con.conclude_method = "Exists") then
422       exists conclude
423     else if (conclude.Con.conclude_method = "AndInd") then
424       andind conclude
425     else if (conclude.Con.conclude_method = "FalseInd") then
426       falseind conclude
427     else if (conclude.Con.conclude_method = "Rewrite") then
428       let justif = 
429         (match (List.nth conclude.Con.conclude_args 6) with
430            Con.ArgProof p -> justification term2pres p
431          | _ -> assert false) in
432       let term1 = 
433         (match List.nth conclude.Con.conclude_args 2 with
434            Con.Term t -> term2pres t
435          | _ -> assert false) in 
436       let term2 = 
437         (match List.nth conclude.Con.conclude_args 5 with
438            Con.Term t -> term2pres t
439          | _ -> assert false) in
440       B.V ([], 
441          [B.H ([],[
442           (B.b_kw "rewrite");
443           B.b_space; term1;
444           B.b_space; (B.b_kw "with");
445           B.b_space; term2;
446           B.indent justif])])
447     else if conclude.Con.conclude_method = "Apply" then
448       let pres_args = 
449         make_args_for_apply term2pres conclude.Con.conclude_args in
450       B.H([],
451         (B.b_kw "by")::
452         B.b_space::
453         B.Text([],"(")::pres_args@[B.Text([],")")])
454     else 
455       B.V 
456         ([],
457          [B.Text([],"Apply method" ^ conclude.Con.conclude_method ^ " to");
458           (B.indent 
459              (B.V 
460                 ([],
461                  args2pres conclude.Con.conclude_args)))]) 
462
463   and args2pres l = List.map arg2pres l
464
465   and arg2pres =
466     let module Con = Content in
467     function
468         Con.Aux n -> 
469           B.Text ([],"aux " ^ n)
470       | Con.Premise prem -> 
471           B.Text ([],"premise")
472       | Con.Lemma lemma ->
473           B.Text ([],"lemma")
474       | Con.Term t -> 
475           term2pres t
476       | Con.ArgProof p ->
477         proof2pres p 
478       | Con.ArgMethod s -> 
479          B.Text ([],"method") 
480  
481    and case conclude =
482      let module Con = Content in
483      let proof_conclusion = 
484        (match conclude.Con.conclude_conclusion with
485           None -> B.Text([],"No conclusion???")
486         | Some t -> term2pres t) in
487      let arg,args_for_cases = 
488        (match conclude.Con.conclude_args with
489            Con.Aux(_)::Con.Aux(_)::Con.Term(_)::arg::tl ->
490              arg,tl
491          | _ -> assert false) in
492      let case_on =
493        let case_arg = 
494          (match arg with
495             Con.Aux n -> 
496               B.Text ([],"an aux???")
497            | Con.Premise prem ->
498               (match prem.Con.premise_binder with
499                  None -> B.Text ([],"the previous result")
500                | Some n -> B.Object ([], P.Mi([],n)))
501            | Con.Lemma lemma -> B.Object ([], P.Mi([],lemma.Con.lemma_name))
502            | Con.Term t -> 
503                term2pres t
504            | Con.ArgProof p ->
505                B.Text ([],"a proof???")
506            | Con.ArgMethod s -> 
507                B.Text ([],"a method???")) in
508         (make_concl "we proceede by cases on" case_arg) in
509      let to_prove =
510         (make_concl "to prove" proof_conclusion) in
511      B.V 
512        ([],
513           case_on::to_prove::(make_cases args_for_cases))
514
515    and byinduction conclude =
516      let module Con = Content in
517      let proof_conclusion = 
518        (match conclude.Con.conclude_conclusion with
519           None -> B.Text([],"No conclusion???")
520         | Some t -> term2pres t) in
521      let inductive_arg,args_for_cases = 
522        (match conclude.Con.conclude_args with
523            Con.Aux(n)::_::tl ->
524              let l1,l2 = split (int_of_string n) tl in
525              let last_pos = (List.length l2)-1 in
526              List.nth l2 last_pos,l1
527          | _ -> assert false) in
528      let induction_on =
529        let arg = 
530          (match inductive_arg with
531             Con.Aux n -> 
532               B.Text ([],"an aux???")
533            | Con.Premise prem ->
534               (match prem.Con.premise_binder with
535                  None -> B.Text ([],"the previous result")
536                | Some n -> B.Object ([], P.Mi([],n)))
537            | Con.Lemma lemma -> B.Object ([], P.Mi([],lemma.Con.lemma_name))
538            | Con.Term t -> 
539                term2pres t
540            | Con.ArgProof p ->
541                B.Text ([],"a proof???")
542            | Con.ArgMethod s -> 
543                B.Text ([],"a method???")) in
544         (make_concl "we proceede by induction on" arg) in
545      let to_prove =
546         (make_concl "to prove" proof_conclusion) in
547      B.V 
548        ([],
549           induction_on::to_prove::
550           (make_cases args_for_cases))
551
552     and make_cases l = List.map make_case l
553
554     and make_case =  
555       let module Con = Content in
556       function 
557         Con.ArgProof p ->
558           let name =
559             (match p.Con.proof_name with
560                None -> B.Text([],"no name for case!!")
561              | Some n -> B.Object ([], P.Mi([],n))) in
562           let indhyps,args =
563              List.partition 
564                (function
565                    `Hypothesis h -> h.Con.dec_inductive
566                  | _ -> false) p.Con.proof_context in
567           let pattern_aux =
568              List.fold_right
569                (fun e p -> 
570                   let dec  = 
571                     (match e with 
572                        `Declaration h 
573                      | `Hypothesis h -> 
574                          let name = 
575                            (match h.Con.dec_name with
576                               None -> "NO NAME???"
577                            | Some n ->n) in
578                          [B.b_space;
579                           B.Object ([], P.Mi ([],name));
580                           B.Text([],":");
581                           (term2pres h.Con.dec_type)]
582                      | _ -> [B.Text ([],"???")]) in
583                   dec@p) args [] in
584           let pattern = 
585             B.H ([],
586                (B.Text([],"Case")::B.b_space::name::pattern_aux)@
587                 [B.b_space;
588                  B.Text([],"->")]) in
589           let subconcl = 
590             (match p.Con.proof_conclude.Con.conclude_conclusion with
591                None -> B.Text([],"No conclusion!!!") 
592              | Some t -> term2pres t) in
593           let asubconcl = B.indent (make_concl "the thesis becomes" subconcl) in
594           let induction_hypothesis = 
595             (match indhyps with
596               [] -> []
597             | _ -> 
598                let text =
599                  B.indent (B.Text([],"by induction hypothesis we know:")) in
600                let make_hyp =
601                  function 
602                    `Hypothesis h ->
603                      let name = 
604                        (match h.Con.dec_name with
605                           None -> "no name"
606                         | Some s -> s) in
607                      B.indent (B.H ([],
608                        [B.Text([],"(");
609                         B.Object ([], P.Mi ([],name));
610                         B.Text([],")");
611                         B.b_space;
612                         term2pres h.Con.dec_type]))
613                    | _ -> assert false in
614                let hyps = List.map make_hyp indhyps in
615                text::hyps) in          
616           (* let acontext = 
617                acontext2pres_old p.Con.proof_apply_context true in *)
618           let body = conclude2pres p.Con.proof_conclude true false in
619           let presacontext = 
620            let acontext_id =
621             match p.Con.proof_apply_context with
622                [] -> p.Con.proof_conclude.Con.conclude_id
623              | {Con.proof_id = id}::_ -> id
624            in
625             B.Action([None,"type","toggle"],
626               [B.indent
627                (B.Text
628                  ([None,"color","red" ;
629                    Some "helm", "xref", acontext_id],"Proof")) ;
630                acontext2pres p.Con.proof_apply_context body true]) in
631           B.V ([], pattern::asubconcl::induction_hypothesis@[presacontext])
632        | _ -> assert false 
633
634      and falseind conclude =
635        let module P = Mpresentation in
636        let module Con = Content in
637        let proof_conclusion = 
638          (match conclude.Con.conclude_conclusion with
639             None -> B.Text([],"No conclusion???")
640           | Some t -> term2pres t) in
641        let case_arg = 
642          (match conclude.Con.conclude_args with
643              [Con.Aux(n);_;case_arg] -> case_arg
644            | _ -> assert false;
645              (* 
646              List.map (ContentPp.parg 0) conclude.Con.conclude_args;
647              assert false *)) in
648        let arg = 
649          (match case_arg with
650              Con.Aux n -> assert false
651            | Con.Premise prem ->
652               (match prem.Con.premise_binder with
653                  None -> [B.Text([],"Contradiction, hence")]
654                | Some n -> 
655                   [B.Object ([],P.Mi([],n)); B.skip;B.Text([],"is contradictory, hence")])
656            | Con.Lemma lemma -> 
657                [B.Object ([], P.Mi([],lemma.Con.lemma_name)); B.skip; B.Text([],"is contradictory, hence")]
658            | _ -> assert false) in
659             (* let body = proof2pres {proof with Con.proof_context = tl} in *)
660        make_row arg proof_conclusion
661
662      and andind conclude =
663        let module P = Mpresentation in
664        let module Con = Content in
665        let proof_conclusion = 
666          (match conclude.Con.conclude_conclusion with
667             None -> B.Text([],"No conclusion???")
668           | Some t -> term2pres t) in
669        let proof,case_arg = 
670          (match conclude.Con.conclude_args with
671              [Con.Aux(n);_;Con.ArgProof proof;case_arg] -> proof,case_arg
672            | _ -> assert false;
673              (* 
674              List.map (ContentPp.parg 0) conclude.Con.conclude_args;
675              assert false *)) in
676        let arg = 
677          (match case_arg with
678              Con.Aux n -> assert false
679            | Con.Premise prem ->
680               (match prem.Con.premise_binder with
681                  None -> []
682                | Some n -> [(B.b_kw "by"); B.b_space; B.Object([], P.Mi([],n))])
683            | Con.Lemma lemma -> 
684                [(B.b_kw "by");B.skip; B.Object([], P.Mi([],lemma.Con.lemma_name))]
685            | _ -> assert false) in
686        match proof.Con.proof_context with
687          `Hypothesis hyp1::`Hypothesis hyp2::tl ->
688             let get_name hyp =
689               (match hyp.Con.dec_name with
690                 None -> "_"
691               | Some s -> s) in
692             let preshyp1 = 
693               B.H ([],
694                [B.Text([],"(");
695                 B.Object ([], P.Mi([],get_name hyp1));
696                 B.Text([],")");
697                 B.skip;
698                 term2pres hyp1.Con.dec_type]) in
699             let preshyp2 = 
700               B.H ([],
701                [B.Text([],"(");
702                 B.Object ([], P.Mi([],get_name hyp2));
703                 B.Text([],")");
704                 B.skip;
705                 term2pres hyp2.Con.dec_type]) in
706             (* let body = proof2pres {proof with Con.proof_context = tl} in *)
707             let body = conclude2pres proof.Con.proof_conclude false true in
708             let presacontext = 
709               acontext2pres proof.Con.proof_apply_context body false in
710             B.V 
711               ([],
712                [B.H ([],arg@[B.skip; B.Text([],"we have")]);
713                 preshyp1;
714                 B.Text([],"and");
715                 preshyp2;
716                 presacontext]);
717          | _ -> assert false
718
719      and exists conclude =
720        let module P = Mpresentation in
721        let module Con = Content in
722        let proof_conclusion = 
723          (match conclude.Con.conclude_conclusion with
724             None -> B.Text([],"No conclusion???")
725           | Some t -> term2pres t) in
726        let proof = 
727          (match conclude.Con.conclude_args with
728              [Con.Aux(n);_;Con.ArgProof proof;_] -> proof
729            | _ -> assert false;
730              (* 
731              List.map (ContentPp.parg 0) conclude.Con.conclude_args;
732              assert false *)) in
733        match proof.Con.proof_context with
734            `Declaration decl::`Hypothesis hyp::tl
735          | `Hypothesis decl::`Hypothesis hyp::tl ->
736            let get_name decl =
737              (match decl.Con.dec_name with
738                 None -> "_"
739               | Some s -> s) in
740            let presdecl = 
741              B.H ([],
742                [(B.b_kw "let");
743                 B.skip;
744                 B.Object ([], P.Mi([],get_name decl));
745                 B.Text([],":"); term2pres decl.Con.dec_type]) in
746            let suchthat =
747              B.H ([],
748                [(B.b_kw "such that");
749                 B.skip;
750                 B.Text([],"(");
751                 B.Object ([], P.Mi([],get_name hyp));
752                 B.Text([],")");
753                 B.skip;
754                 term2pres hyp.Con.dec_type]) in
755             (* let body = proof2pres {proof with Con.proof_context = tl} in *)
756             let body = conclude2pres proof.Con.proof_conclude false true in
757             let presacontext = 
758               acontext2pres proof.Con.proof_apply_context body false in
759             B.V 
760               ([],
761                [presdecl;
762                 suchthat;
763                 presacontext]);
764          | _ -> assert false in
765
766 proof2pres p
767 ;;
768
769 exception ToDo;;
770
771 let counter = ref 0
772
773 let conjecture2pres term2pres (id, n, context, ty) =
774   (B.b_h [Some "helm", "xref", id]
775      (((List.map
776           (function
777              | None ->
778                  B.b_h []
779                    [ B.b_object (p_mi [] "_") ;
780                      B.b_object (p_mo [] ":?") ;
781                      B.b_object (p_mi [] "_")]
782              | Some (`Declaration d)
783              | Some (`Hypothesis d) ->
784                  let { Content.dec_name =
785                      dec_name ; Content.dec_type = ty } = d
786                  in
787                    B.b_h []
788                      [ B.b_object
789                          (p_mi []
790                             (match dec_name with
791                                  None -> "_"
792                                | Some n -> n));
793                        B.b_text [] ":";
794                        term2pres ty ]
795              | Some (`Definition d) ->
796                  let
797                      { Content.def_name = def_name ;
798                        Content.def_term = bo } = d
799                  in
800                    B.b_h []
801                      [ B.b_object (p_mi []
802                                      (match def_name with
803                                           None -> "_"
804                                         | Some n -> n)) ;
805                        B.b_text [] ":=" ;
806                        term2pres bo]
807              | Some (`Proof p) ->
808                  let proof_name = p.Content.proof_name in
809                    B.b_h []
810                      [ B.b_object (p_mi []
811                                      (match proof_name with
812                                           None -> "_"
813                                         | Some n -> n)) ;
814                        B.b_text [] ":=" ;
815                        proof2pres term2pres p])
816           (List.rev context)) @
817          [ B.b_text [] "|-" ;
818            B.b_object (p_mi [] (string_of_int n)) ;
819            B.b_text [] ":" ;
820            term2pres ty ])))
821
822 let metasenv2pres term2pres = function
823   | None -> []
824   | Some metasenv' ->
825       (* Conjectures are in their own table to make *)
826       (* diffing the DOM trees easier.              *)
827       [B.b_v []
828         ((B.b_text []
829             ("Conjectures:" ^
830              (let _ = incr counter; in (string_of_int !counter)))) ::
831          (List.map (conjecture2pres term2pres) metasenv'))]
832
833 let params2pres params =
834   let param2pres uri =
835     B.b_text [Some "xlink", "href", UriManager.string_of_uri uri]
836       (UriManager.name_of_uri uri)
837   in
838   let rec spatiate = function
839     | [] -> []
840     | hd :: [] -> [hd]
841     | hd :: tl -> hd :: B.b_text [] ", " :: spatiate tl
842   in
843   match params with
844   | [] -> []
845   | p ->
846       let params = spatiate (List.map param2pres p) in
847       [B.b_space;
848        B.b_h [] (B.b_text [] "[" :: params @ [ B.b_text [] "]" ])]
849
850 let recursion_kind2pres params kind =
851   let kind =
852     match kind with
853     | `Recursive _ -> "Recursive definition"
854     | `CoRecursive -> "CoRecursive definition"
855     | `Inductive _ -> "Inductive definition"
856     | `CoInductive _ -> "CoInductive definition"
857   in
858   B.b_h [] (B.b_text [] kind :: params2pres params)
859
860 let inductive2pres term2pres ind =
861   let constructor2pres decl =
862     B.b_h [] [
863       B.b_text [] ("| " ^ get_name decl.Content.dec_name ^ ":");
864       B.b_space;
865       term2pres decl.Content.dec_type
866     ]
867   in
868   B.b_v []
869     (B.b_h [] [
870       B.b_text [] (ind.Content.inductive_name ^ " of arity ");
871       term2pres ind.Content.inductive_type ]
872     :: List.map constructor2pres ind.Content.inductive_constructors)
873
874 let joint_def2pres term2pres def =
875   match def with
876   | `Inductive ind -> inductive2pres term2pres ind
877   | _ -> assert false (* ZACK or raise ToDo? *)
878
879 let content2pres term2pres (id,params,metasenv,obj) =
880   match obj with
881   | `Def (Content.Const, thesis, `Proof p) ->
882       let name = get_name p.Content.proof_name in
883       B.b_v
884         [Some "helm","xref","id"]
885         ([ B.b_h [] (B.b_text [] ("Proof " ^ name) :: params2pres params);
886            B.b_text [] "Thesis:";
887            B.indent (term2pres thesis) ] @
888          metasenv2pres term2pres metasenv @
889          [proof2pres term2pres p])
890   | `Def (_, ty, `Definition body) ->
891       let name = get_name body.Content.def_name in
892       B.b_v
893         [Some "helm","xref","id"]
894         ([B.b_h [] (B.b_text [] ("Definition " ^ name) :: params2pres params);
895           B.b_text [] "Type:";
896           B.indent (term2pres ty)] @
897           metasenv2pres term2pres metasenv @
898           [term2pres body.Content.def_term])
899   | `Decl (_, `Declaration decl)
900   | `Decl (_, `Hypothesis decl) ->
901       let name = get_name decl.Content.dec_name in
902       B.b_v
903         [Some "helm","xref","id"]
904         ([B.b_h [] (B.b_text [] ("Axiom " ^ name) :: params2pres params);
905           B.b_text [] "Type:";
906           B.indent (term2pres decl.Content.dec_type)] @
907           metasenv2pres term2pres metasenv)
908   | `Joint joint ->
909       B.b_v []
910         (recursion_kind2pres params joint.Content.joint_kind
911         :: List.map (joint_def2pres term2pres) joint.Content.joint_defs)
912   | _ -> raise ToDo
913 ;;
914
915 (*
916 let content2pres ~ids_to_inner_sorts =
917  content2pres 
918   (function p -> 
919      (Cexpr2pres.cexpr2pres_charcount 
920                     (Content_expressions.acic2cexpr ids_to_inner_sorts p)))
921 ;;
922 *)
923
924 let content2pres ~ids_to_inner_sorts =
925   content2pres
926     (fun annterm ->
927       let (ast, ids_to_uris) as arg =
928         Acic2Ast.ast_of_acic ids_to_inner_sorts annterm
929       in
930       let astBox = Ast2pres.ast2astBox arg in
931       Box.map (fun ast -> Ast2pres.ast2mpres (ast, ids_to_uris)) astBox)
932