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