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