1 (* Copyright (C) 2003-2005, HELM Team.
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.
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.
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.
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,
22 * For details, see the HELM World-Wide-Web page,
23 * http://cs.unibo.it/helm/.
26 (***************************************************************************)
30 (* Andrea Asperti <asperti@cs.unibo.it> *)
33 (***************************************************************************)
37 module P = Mpresentation
41 let p_mtr a b = Mpresentation.Mtr(a,b)
42 let p_mtd a b = Mpresentation.Mtd(a,b)
43 let p_mtable a b = Mpresentation.Mtable(a,b)
44 let p_mtext a b = Mpresentation.Mtext(a,b)
45 let p_mi a b = Mpresentation.Mi(a,b)
46 let p_mo a b = Mpresentation.Mo(a,b)
47 let p_mrow a b = Mpresentation.Mrow(a,b)
48 let p_mphantom a b = Mpresentation.Mphantom(a,b)
49 let b_ink a = Box.Ink a
54 split (n-1) (List.tl l) in
57 let get_xref = function
59 | `Hypothesis d -> d.Con.dec_id
60 | `Proof p -> p.Con.proof_id
61 | `Definition d -> d.Con.def_id
62 | `Joint jo -> jo.Con.joint_id
65 RenderingAttrs.spacing_attributes `BoxML
66 @ RenderingAttrs.indent_attributes `BoxML
68 let make_row items concl =
69 B.b_hv hv_attrs (items @ [ concl ])
72 B.b_v attrs [B.b_h [] items; B.b_indent concl]
74 B.b_h attrs (items@[B.b_space; concl]) *)
76 let make_concl ?(attrs=[]) verb concl =
77 B.b_hv (hv_attrs @ attrs) [ B.b_kw verb; concl ]
80 B.b_v attrs [ B.b_kw verb; B.b_indent concl]
82 B.b_h attrs [ B.b_kw verb; B.b_space; concl ] *)
84 let make_args_for_apply term2pres args =
85 let make_arg_for_apply is_first arg row =
88 Con.Aux n -> assert false
91 (match prem.Con.premise_binder with
94 (B.b_object (P.Mi ([], name)))::row
97 Some "helm", "xref", lemma.Con.lemma_id;
98 Some "xlink", "href", lemma.Con.lemma_uri ]
100 (B.b_object (P.Mi(lemma_attrs,lemma.Con.lemma_name)))::row
102 if is_first || (not b) then
104 else (B.b_object (P.Mi([],"?")))::row
107 (B.b_object (P.Mi([],"?")))::row
109 if is_first then res else B.skip::res
113 make_arg_for_apply true hd
114 (List.fold_right (make_arg_for_apply false) tl [])
117 let get_name ?(default="_") = function
121 let add_xref id = function
122 | B.Text (attrs, t) -> B.Text (((Some "helm", "xref", id) :: attrs), t)
123 | _ -> assert false (* TODO, add_xref is meaningful for all boxes *)
125 let rec justification ~for_rewriting_step ~ignore_atoms term2pres p =
126 if p.Con.proof_conclude.Con.conclude_method = "Exact" &&
131 (p.Con.proof_conclude.Con.conclude_method = "Exact" && not ignore_atoms) ||
132 (p.Con.proof_context = [] &&
133 p.Con.proof_apply_context = [] &&
134 p.Con.proof_conclude.Con.conclude_method = "Apply")
137 make_args_for_apply term2pres p.Con.proof_conclude.Con.conclude_args
140 (*(if for_rewriting_step then (B.b_kw "exact") else (B.b_kw "by"))::*)
143 B.Text([],"(")::pres_args@[B.Text([],")")])], None
146 if for_rewriting_step then
149 [B.b_kw "by"; B.b_space; B.b_kw "proof"]
151 Some (B.b_toggle [B.b_kw "proof";B.indent (proof2pres true term2pres p)])
153 and proof2pres0 term2pres ?skip_initial_lambdas_internal is_top_down p in_bu_conversion =
158 | `Hypothesis _ -> true
160 ((List.filter is_decl p.Con.proof_context) != []) in
161 let omit_conclusion = (not indent) && (p.Con.proof_context != []) in
163 (match p.Con.proof_conclude.Con.conclude_conclusion with
165 | Some t -> Some (term2pres t)) in
168 conclude2pres term2pres
169 ?skip_initial_lambdas_internal:
170 (match skip_initial_lambdas_internal with
171 Some (`Later s) -> Some (`Now s)
173 is_top_down p.Con.proof_name p.Con.proof_conclude indent
174 omit_conclusion in_bu_conversion in
176 acontext2pres term2pres
177 (if p.Con.proof_conclude.Con.conclude_method = "BU_Conversion" then
181 p.Con.proof_apply_context
183 (p.Con.proof_conclude.Con.conclude_method = "BU_Conversion")
185 context2pres term2pres
186 (match skip_initial_lambdas_internal with
187 Some (`Now n) -> snd (HExtlib.split_nth n p.Con.proof_context)
188 | _ -> p.Con.proof_context)
189 ~continuation:presacontext
192 let body = B.V([],[B.b_kw ("(*<<" ^ p.Con.proof_conclude.Con.conclude_method ^ (if is_top_down then "(TD)" else "(NTD)") ^ "*)"); body; B.b_kw "(*>>*)"]) in
194 match p.Con.proof_name with
202 make_concl ~attrs:[ Some "helm", "xref", p.Con.proof_id ]
204 B.b_toggle [ B.H ([], [concl; B.skip ; B.Text([],"(");
205 B.Object ([], P.Mi ([],name));
206 B.Text([],")") ]) ; body ]
210 and context2pres term2pres c ~continuation =
211 (* we generate a subtable for each context element, for selection
213 The table generated by the head-element does not have an xref;
214 the whole context-proof is already selectable *)
220 (fun ce continuation ->
221 let xref = get_xref ce in
222 B.V([Some "helm", "xref", xref ],
223 [B.H([Some "helm", "xref", "ce_"^xref],
224 [ce2pres_in_proof_context_element term2pres ce]);
225 continuation])) tl continuation in
226 let hd_xref= get_xref hd in
228 [B.H([Some "helm", "xref", "ce_"^hd_xref],
229 [ce2pres_in_proof_context_element term2pres hd]);
232 and ce2pres_in_joint_context_element term2pres = function
233 | `Inductive _ -> assert false (* TODO *)
237 | (`Definition _) as x -> ce2pres term2pres x
239 and ce2pres_in_proof_context_element term2pres = function
241 B.H ([],(List.map (ce2pres_in_joint_context_element term2pres) ho.Content.joint_defs))
245 | (`Definition _) as x -> ce2pres term2pres x
247 and ce2pres term2pres =
250 let ty = term2pres d.Con.dec_type in
254 B.Object ([], P.Mi([],get_name d.Con.dec_name));
259 let ty = term2pres h.Con.dec_type in
266 B.Object ([], P.Mi ([],get_name h.Con.dec_name));
270 proof2pres0 term2pres false p false
272 let term = term2pres d.Con.def_term in
274 [ B.b_kw "let"; B.b_space;
275 B.Object ([], P.Mi([],get_name d.Con.def_name));
276 B.Text([],Utf8Macro.unicode_of_tex "\\def");
279 and acontext2pres term2pres is_top_down ac continuation indent in_bu_conversion =
284 let continuation = aux tl in
285 (* Applicative context get flattened and the "body" of a BU_Conversion
286 is put in the applicative context. Thus two different situations
288 {method = "BU_Conversion"; applicative_context=[p1; ...; pn]}
289 {method = xxx; applicative_context =
290 [ p1; ...; pn; {method="BU_Conversion"} ; p_{n+1}; ... ; pm ]}
291 In both situations only pn must be processed in in_bu_conversion
294 let in_bu_conversion =
296 [] -> in_bu_conversion
297 | p::_ -> p.Con.proof_conclude.Con.conclude_method = "BU_Conversion"
299 let hd = proof2pres0 term2pres is_top_down p in_bu_conversion in
300 let hd = if indent then B.indent hd else hd in
301 B.V([Some "helm","xref",p.Con.proof_id],
302 [B.H([Some "helm","xref","ace_"^p.Con.proof_id],[hd]);
306 and conclude2pres term2pres ?skip_initial_lambdas_internal is_top_down name conclude indent omit_conclusion in_bu_conversion =
308 match conclude.Con.conclude_conclusion with
309 Some t (*when not omit_conclusion or
310 (* CSC: I ignore the omit_conclusion flag in this case. *)
311 (* CSC: Is this the correct behaviour? In the stylesheets *)
312 (* CSC: we simply generated nothing (i.e. the output type *)
313 (* CSC: of the function should become an option. *)
314 conclude.Con.conclude_method = "BU_Conversion" *) ->
315 let concl = term2pres t in
316 if conclude.Con.conclude_method = "BU_Conversion" then
318 (make_concl "that is equivalent to" concl ::
319 if is_top_down then [B.b_space ; B.b_kw "done";
320 B.Text([],".")] else [B.Text([],".")])
321 else if conclude.Con.conclude_method = "FalseInd" then
322 (* false ind is in charge to add the conclusion *)
323 falseind term2pres conclude
328 conclude.Con.conclude_method = "Intros+LetTac"
330 let name = get_name name in
334 (match conclude.Con.conclude_conclusion with
335 None -> B.Text([],"NO EXPECTED!!!")
336 | Some c -> term2pres c)
338 [make_concl "we need to prove" expected;
341 B.Object ([], P.Mi ([],name));
348 conclude_aux term2pres ?skip_initial_lambdas_internal is_top_down conclude in
350 if conclude.Con.conclude_method = "Intros+LetTac"
351 || conclude.Con.conclude_method = "ByInduction"
352 || conclude.Con.conclude_method = "TD_Conversion"
353 || conclude.Con.conclude_method = "Eq_chain"
356 else if omit_conclusion then
357 B.H([], [B.b_kw "done" ; B.Text([],".") ])
360 ((if not is_top_down || in_bu_conversion then
361 (make_concl "we proved" concl) ::
362 if not is_top_down then
363 let name = get_name ~default:"previous" name in
364 [B.b_space; B.Text([],"(" ^ name ^ ")")]
367 ) @ if not in_bu_conversion then [B.Text([],".")] else [])
369 B.V ([], prequel @ [conclude_body; ann_concl])
370 | _ -> conclude_aux term2pres ?skip_initial_lambdas_internal is_top_down conclude
373 B.indent (B.H ([Some "helm", "xref", conclude.Con.conclude_id],
376 B.H ([Some "helm", "xref", conclude.Con.conclude_id],[tconclude_body])
378 and conclude_aux term2pres ?skip_initial_lambdas_internal is_top_down conclude =
379 if conclude.Con.conclude_method = "TD_Conversion" then
381 (match conclude.Con.conclude_conclusion with
382 None -> B.Text([],"NO EXPECTED!!!")
383 | Some c -> term2pres c) in
385 (match conclude.Con.conclude_args with
386 [Con.ArgProof p] -> p
387 | _ -> assert false) in
389 (match subproof.Con.proof_conclude.Con.conclude_conclusion with
390 None -> B.Text([],"NO SYNTH!!!")
391 | Some c -> (term2pres c)) in
394 [make_concl "we need to prove" expected;
395 B.H ([],[make_concl "or equivalently" synth; B.Text([],".")]);
396 proof2pres0 term2pres true subproof false])
397 else if conclude.Con.conclude_method = "BU_Conversion" then
399 else if conclude.Con.conclude_method = "Exact" then
401 (match conclude.Con.conclude_args with
402 [Con.Term (b,t)] -> assert (not b);term2pres t
404 (match p.Con.premise_binder with
405 | None -> assert false; (* unnamed hypothesis ??? *)
406 | Some s -> B.Text([],s))
407 | err -> assert false) in
408 (match conclude.Con.conclude_conclusion with
410 B.b_h [] [B.b_kw "by"; B.b_space; arg]
412 B.b_h [] [B.b_kw "by"; B.b_space; arg]
414 else if conclude.Con.conclude_method = "Intros+LetTac" then
415 (match conclude.Con.conclude_args with
417 (match conclude.Con.conclude_args with
419 proof2pres0 term2pres ?skip_initial_lambdas_internal true p false
424 (match conclude.Con.conclude_conclusion with
425 None -> B.Text([],"NO Conclusion!!!")
426 | Some c -> term2pres c) in
427 (match conclude.Con.conclude_args with
430 ([None,"align","baseline 1"; None,"equalrows","false";
431 None,"columnalign","left"],
432 [B.H([],[B.Object([],proof2pres p term2pres false)]);
434 (make_concl "we proved 1" conclusion))])]);
437 else if (conclude.Con.conclude_method = "Case") then
438 case term2pres conclude
439 else if (conclude.Con.conclude_method = "ByInduction") then
440 byinduction term2pres conclude
441 else if (conclude.Con.conclude_method = "Exists") then
442 exists term2pres conclude
443 else if (conclude.Con.conclude_method = "AndInd") then
444 andind term2pres conclude
445 else if (conclude.Con.conclude_method = "FalseInd") then
446 falseind term2pres conclude
447 else if conclude.Con.conclude_method = "RewriteLR"
448 || conclude.Con.conclude_method = "RewriteRL" then
449 let justif1,justif2 =
450 (match (List.nth conclude.Con.conclude_args 6) with
452 justification ~for_rewriting_step:true ~ignore_atoms:true
454 | _ -> assert false) in
460 let index_term1, index_term2 =
461 if conclude.Con.conclude_method = "RewriteLR" then 2,5 else 5,2
464 (match List.nth conclude.Con.conclude_args index_term1 with
465 Con.Term (_,t) -> term2pres t
466 | _ -> assert false) in
468 (match List.nth conclude.Con.conclude_args index_term2 with
469 Con.Term (_,t) -> term2pres t
470 | _ -> assert false) in
477 [B.b_kw "we proved (" ;
480 term2; B.b_kw ") (equality)."])]
487 B.b_space; (B.b_kw "with");
489 B.b_space; justif1])::
490 match justif2 with None -> [] | Some j -> [B.indent j])
492 B.V([], justif @ [B.b_kw "by _"])
493 else if conclude.Con.conclude_method = "Eq_chain" then
494 let justification p =
496 justification ~for_rewriting_step:true ~ignore_atoms:false term2pres p
498 j1, match j2 with Some j -> [j] | None -> []
503 | (Con.ArgProof p)::(Con.Term (_,t))::tl ->
504 let justif1,justif2 = justification p in
505 B.HOV(RenderingAttrs.indent_attributes `BoxML,([B.b_kw
506 "=";B.b_space;term2pres t;B.b_space]@justif1@
507 (if tl <> [] then [B.Text ([],".")] else [B.b_space; B.b_kw "done" ; B.Text([],".")])@
512 match List.hd conclude.Con.conclude_args with
513 | Con.Term (_,t) -> t
518 [B.b_kw "conclude";B.b_space;term2pres hd;
519 B.V ([],aux (List.tl conclude.Con.conclude_args))])
522 [B.b_kw "obtain";B.b_space;B.b_kw "FIXMEXX"; B.b_space;term2pres hd;
523 B.V ([],aux (List.tl conclude.Con.conclude_args))])
524 else if conclude.Con.conclude_method = "Apply" then
526 make_args_for_apply term2pres conclude.Con.conclude_args in
530 B.Text([],"(")::pres_args@[B.Text([],")")])
533 B.b_kw ("Apply method" ^ conclude.Con.conclude_method ^ " to");
534 (B.indent (B.V ([], args2pres term2pres conclude.Con.conclude_args)))])
536 and args2pres term2pres l = List.map (arg2pres term2pres) l
538 and arg2pres term2pres =
540 Con.Aux n -> B.b_kw ("aux " ^ n)
541 | Con.Premise prem -> B.b_kw "premise"
542 | Con.Lemma lemma -> B.b_kw "lemma"
543 | Con.Term (_,t) -> term2pres t
544 | Con.ArgProof p -> proof2pres0 term2pres true p false
545 | Con.ArgMethod s -> B.b_kw "method"
547 and case term2pres conclude =
548 let proof_conclusion =
549 (match conclude.Con.conclude_conclusion with
550 None -> B.b_kw "No conclusion???"
551 | Some t -> term2pres t) in
552 let arg,args_for_cases =
553 (match conclude.Con.conclude_args with
554 Con.Aux(_)::Con.Aux(_)::Con.Term(_)::arg::tl ->
556 | _ -> assert false) in
560 Con.Aux n -> B.b_kw "an aux???"
561 | Con.Premise prem ->
562 (match prem.Con.premise_binder with
563 None -> B.b_kw "previous"
564 | Some n -> B.Object ([], P.Mi([],n)))
565 | Con.Lemma lemma -> B.Object ([], P.Mi([],lemma.Con.lemma_name))
568 | Con.ArgProof p -> B.b_kw "a proof???"
569 | Con.ArgMethod s -> B.b_kw "a method???")
571 (make_concl "we proceed by cases on" case_arg) in
573 (make_concl "to prove" proof_conclusion) in
574 B.V ([], case_on::to_prove::(make_cases term2pres args_for_cases))
576 and byinduction term2pres conclude =
577 let proof_conclusion =
578 (match conclude.Con.conclude_conclusion with
579 None -> B.b_kw "No conclusion???"
580 | Some t -> term2pres t) in
581 let inductive_arg,args_for_cases =
582 (match conclude.Con.conclude_args with
584 let l1,l2 = split (int_of_string n) tl in
585 let last_pos = (List.length l2)-1 in
586 List.nth l2 last_pos,l1
587 | _ -> assert false) in
590 (match inductive_arg with
591 Con.Aux n -> B.b_kw "an aux???"
592 | Con.Premise prem ->
593 (match prem.Con.premise_binder with
594 None -> B.b_kw "previous"
595 | Some n -> B.Object ([], P.Mi([],n)))
596 | Con.Lemma lemma -> B.Object ([], P.Mi([],lemma.Con.lemma_name))
599 | Con.ArgProof p -> B.b_kw "a proof???"
600 | Con.ArgMethod s -> B.b_kw "a method???") in
601 (make_concl "we proceed by induction on" arg) in
603 B.H ([], [make_concl "to prove" proof_conclusion ; B.Text([],".")]) in
604 B.V ([], induction_on::to_prove::(make_cases term2pres args_for_cases))
606 and make_cases term2pres l = List.map (make_case term2pres) l
608 and make_case term2pres =
612 (match p.Con.proof_name with
613 None -> B.b_kw "no name for case!!"
614 | Some n -> B.Object ([], P.Mi([],n))) in
618 `Hypothesis h -> h.Con.dec_inductive
619 | _ -> false) p.Con.proof_context in
627 let name = get_name h.Con.dec_name in
630 B.Object ([], P.Mi ([],name));
632 (term2pres h.Con.dec_type);
634 | _ -> assert false (*[B.Text ([],"???")]*)) in
638 (B.b_kw "case"::B.b_space::name::pattern_aux)@
642 (match p.Con.proof_conclude.Con.conclude_conclusion with
643 None -> B.b_kw "No conclusion!!!"
644 | Some t -> term2pres t) in
645 let asubconcl = B.indent (make_concl "the thesis becomes" subconcl) in
646 let induction_hypothesis =
650 let text = B.indent (B.b_kw "by induction hypothesis we know") in
655 (match h.Con.dec_name with
659 [term2pres h.Con.dec_type;
662 B.Object ([], P.Mi ([],name));
665 | _ -> assert false in
666 let hyps = List.map make_hyp indhyps in
669 conclude2pres term2pres true p.Con.proof_name p.Con.proof_conclude true true false in
672 match p.Con.proof_apply_context with
673 [] -> p.Con.proof_conclude.Con.conclude_id
674 | {Con.proof_id = id}::_ -> id
676 B.Action([None,"type","toggle"],
677 [ B.indent (add_xref acontext_id (B.b_kw "Proof"));
678 acontext2pres term2pres
679 (p.Con.proof_conclude.Con.conclude_method = "BU_Conversion")
680 p.Con.proof_apply_context body true
681 (p.Con.proof_conclude.Con.conclude_method = "BU_Conversion")
683 B.V ([], pattern::induction_hypothesis@[B.H ([],[asubconcl;B.Text([],".")]);presacontext])
686 and falseind term2pres conclude =
687 let proof_conclusion =
688 (match conclude.Con.conclude_conclusion with
689 None -> B.b_kw "No conclusion???"
690 | Some t -> term2pres t) in
692 (match conclude.Con.conclude_args with
693 [Con.Aux(n);_;case_arg] -> case_arg
696 List.map (ContentPp.parg 0) conclude.Con.conclude_args;
700 Con.Aux n -> assert false
701 | Con.Premise prem ->
702 (match prem.Con.premise_binder with
703 None -> [B.b_kw "Contradiction, hence"]
705 [ B.Object ([],P.Mi([],n)); B.skip;
706 B.b_kw "is contradictory, hence"])
708 [ B.Object ([], P.Mi([],lemma.Con.lemma_name)); B.skip;
709 B.b_kw "is contradictory, hence" ]
710 | _ -> assert false) in
711 make_row arg proof_conclusion
713 and andind term2pres conclude =
715 (match conclude.Con.conclude_args with
716 [Con.Aux(n);_;Con.ArgProof proof;case_arg] -> proof,case_arg
719 List.map (ContentPp.parg 0) conclude.Con.conclude_args;
723 Con.Aux n -> assert false
724 | Con.Premise prem ->
725 (match prem.Con.premise_binder with
727 | Some n -> [(B.b_kw "by"); B.b_space; B.Object([], P.Mi([],n))])
729 [(B.b_kw "by");B.skip;
730 B.Object([], P.Mi([],lemma.Con.lemma_name))]
731 | _ -> assert false) in
732 match proof.Con.proof_context with
733 `Hypothesis hyp1::`Hypothesis hyp2::tl ->
737 B.Object ([], P.Mi([],get_name hyp1.Con.dec_name));
740 term2pres hyp1.Con.dec_type]) in
744 B.Object ([], P.Mi([],get_name hyp2.Con.dec_name));
747 term2pres hyp2.Con.dec_type]) in
749 conclude2pres term2pres false proof.Con.proof_name proof.Con.proof_conclude
752 acontext2pres term2pres false proof.Con.proof_apply_context body false false
756 [B.H ([],arg@[B.skip; B.b_kw "we have"]);
763 and exists term2pres conclude =
765 (match conclude.Con.conclude_args with
766 [Con.Aux(n);_;Con.ArgProof proof;_] -> proof
769 List.map (ContentPp.parg 0) conclude.Con.conclude_args;
771 match proof.Con.proof_context with
772 `Declaration decl::`Hypothesis hyp::tl
773 | `Hypothesis decl::`Hypothesis hyp::tl ->
778 B.Object ([], P.Mi([],get_name decl.Con.dec_name));
779 B.Text([],":"); term2pres decl.Con.dec_type]) in
782 [(B.b_kw "such that");
785 B.Object ([], P.Mi([],get_name hyp.Con.dec_name));
788 term2pres hyp.Con.dec_type]) in
790 conclude2pres term2pres false proof.Con.proof_name proof.Con.proof_conclude
793 acontext2pres term2pres false proof.Con.proof_apply_context body false false
802 and proof2pres ?skip_initial_lambdas is_top_down term2pres p =
803 proof2pres0 term2pres
804 ?skip_initial_lambdas_internal:
805 (match skip_initial_lambdas with
806 None -> Some (`Later 0) (* we already printed theorem: *)
807 | Some n -> Some (`Later n))
814 let conjecture2pres term2pres (id, n, context, ty) =
816 (B.b_hv [Some "helm", "xref", id]
818 B.b_h [] [B.b_text [] "{...}"; B.b_space];
819 B.b_hv [] (HExtlib.list_concat ~sep:[B.b_text [] ";"; B.b_space]
820 (List.map (fun x -> [x])
825 [ B.b_object (p_mi [] "_") ;
826 B.b_object (p_mo [] ":?") ;
827 B.b_object (p_mi [] "_")]
828 | Some (`Declaration d)
829 | Some (`Hypothesis d) ->
830 let { Content.dec_name =
831 dec_name ; Content.dec_type = ty } = d
839 B.b_text [] ":"; B.b_space;
841 | Some (`Definition d) ->
843 { Content.def_name = def_name ;
844 Content.def_term = bo } = d
847 [ B.b_object (p_mi []
851 B.b_text [] (Utf8Macro.unicode_of_tex "\\Assign");
855 let proof_name = p.Content.proof_name in
857 [ B.b_object (p_mi []
858 (match proof_name with
861 B.b_text [] (Utf8Macro.unicode_of_tex "\\Assign");
863 proof2pres true term2pres p])
864 (List.rev context)))) ] ::
867 B.b_text [] (Utf8Macro.unicode_of_tex "\\vdash");
869 B.b_object (p_mi [] (string_of_int n)) ;
874 let metasenv2pres term2pres = function
877 (* Conjectures are in their own table to make *)
878 (* diffing the DOM trees easier. *)
880 ((B.b_kw ("Conjectures:" ^
881 (let _ = incr counter; in (string_of_int !counter)))) ::
882 (List.map (conjecture2pres term2pres) metasenv'))]
884 let inductive2pres term2pres ind =
885 let constructor2pres decl =
887 B.b_text [] ("| " ^ get_name decl.Content.dec_name ^ ":");
889 term2pres decl.Content.dec_type
894 B.b_kw (ind.Content.inductive_name ^ " of arity");
896 term2pres ind.Content.inductive_type ]
897 :: List.map constructor2pres ind.Content.inductive_constructors)
899 let definition2pres ?recno term2pres d =
900 let name = match d.Content.def_name with Some x -> x|_->assert false in
901 let rno = match recno with None -> -1 (* cofix *) | Some x -> x in
902 let ty = d.Content.def_type in
903 let module P = NotationPt in
904 let rec split_pi i t =
905 (* dummy case for corecursive defs *)
906 if i = ~-1 then [], P.UserInput, t
909 | P.Binder ((`Pi|`Forall),(var,_ as v),t)
910 | P.AttributedTerm (_,P.Binder ((`Pi|`Forall),(var,_ as v),t)) ->
915 | P.Binder ((`Pi|`Forall), var ,ty)
916 | P.AttributedTerm (_, P.Binder ((`Pi|`Forall), var ,ty)) ->
917 let l, r, t = split_pi (i-1) ty in
921 let params, rec_param, ty = split_pi rno ty in
922 let body = d.Content.def_term in
927 B.b_h [] [B.b_text [] "("; term2pres name; B.b_text [] " : ";
928 B.b_space; term2pres ty; B.b_text [] ")"; B.b_space]
929 | (name,None) -> B.b_h [] [term2pres name;B.b_space])
933 [B.b_hov (RenderingAttrs.indent_attributes `BoxML)
934 ( [B.b_hov (RenderingAttrs.indent_attributes `BoxML) ([ B.b_space; B.b_text [] name ] @
936 [B.indent(B.b_hov (RenderingAttrs.indent_attributes `BoxML) (params))]
940 [B.b_kw "on";B.b_space;term2pres rec_param] else [])
941 @ [ B.b_space; B.b_text [] ":";]) ]
942 @[ B.indent(term2pres ty)]);
944 B.b_h [] [B.b_space;term2pres body] ]
947 let njoint_def2pres ?recno term2pres def =
949 | `Inductive ind -> inductive2pres term2pres ind
950 | `Definition def -> definition2pres ?recno term2pres def
954 let njoint_def2pres term2pres joint_kind defs =
955 match joint_kind with
956 | `Recursive recnos ->
957 B.b_hv [] (B.b_kw "nlet rec " ::
959 (HExtlib.list_mapi (fun x i ->
960 if i > 0 then [B.b_kw " and ";x] else [x])
961 (List.map2 (fun a b -> njoint_def2pres ~recno:a term2pres b)
964 B.b_hv [] (B.b_kw "nlet corec " ::
966 (HExtlib.list_mapi (fun x i ->
967 if i > 0 then [B.b_kw " and ";x] else [x])
968 (List.map (njoint_def2pres term2pres) defs)))
970 B.b_hv [] (B.b_kw "ninductive " ::
972 (HExtlib.list_mapi (fun x i ->
973 if i > 0 then [B.b_kw " and ";x] else [x])
974 (List.map (njoint_def2pres term2pres) defs)))
976 B.b_hv [] (B.b_kw "ncoinductive " ::
978 (HExtlib.list_mapi (fun x i ->
979 if i > 0 then [B.b_kw " and ";x] else [x])
980 (List.map (njoint_def2pres term2pres) defs)))
984 ?skip_initial_lambdas ?(skip_thm_and_qed=false) term2pres
985 (id,metasenv,obj : NotationPt.term Content.cobj)
988 | `Def (Content.Const, thesis, `Proof p) ->
989 let name = get_name p.Content.proof_name in
990 let proof = proof2pres true ?skip_initial_lambdas term2pres p in
991 if skip_thm_and_qed then
995 [Some "helm","xref","id"]
996 ([ B.b_h [] (B.b_kw ("ntheorem " ^ name) ::
998 B.H ([],[B.indent (term2pres thesis) ; B.b_kw "." ])] @
999 metasenv2pres term2pres metasenv @
1000 [proof ; B.b_kw "qed."])
1001 | `Def (_, ty, `Definition body) ->
1002 let name = get_name body.Content.def_name in
1004 [Some "helm","xref","id"]
1006 (B.b_kw ("ndefinition " ^ name) :: [B.b_kw ":"]);
1007 B.indent (term2pres ty)] @
1008 metasenv2pres term2pres metasenv @
1010 B.indent (term2pres body.Content.def_term);
1012 | `Decl (_, `Declaration decl)
1013 | `Decl (_, `Hypothesis decl) ->
1014 let name = get_name decl.Content.dec_name in
1016 [Some "helm","xref","id"]
1017 ([B.b_h [] (B.b_kw ("naxiom " ^ name) :: []);
1019 B.indent (term2pres decl.Content.dec_type)] @
1020 metasenv2pres term2pres metasenv)
1023 [njoint_def2pres term2pres
1024 joint.Content.joint_kind joint.Content.joint_defs]
1027 let nterm2pres status ~ids_to_nrefs =
1030 let nref = Hashtbl.find ids_to_nrefs id in
1031 Some (NReference.string_of_reference nref)
1032 with Not_found -> None
1034 fun ?(prec=90) ast ->
1035 CicNotationPres.box_of_mpres
1036 (CicNotationPres.render status ~lookup_uri ~prec
1037 (TermContentPres.pp_ast status ast))
1039 let nobj2pres status ~ids_to_nrefs =
1040 nobj2pres0 ?skip_initial_lambdas:None ?skip_thm_and_qed:None
1041 (nterm2pres status ~ids_to_nrefs)
1043 let nconjlist2pres0 term2pres context =
1047 | None::tl -> aux accum tl
1048 | (Some (`Declaration d))::tl ->
1050 { Con.dec_name = dec_name ;
1051 Con.dec_id = dec_id ;
1052 Con.dec_type = ty } = d in
1054 Box.b_hv [Some "helm", "xref", dec_id]
1056 [ Box.b_object (p_mi []
1057 (match dec_name with
1060 Box.b_space; Box.b_text [] ":"; ];
1061 Box.indent (term2pres ty)] in
1063 | (Some (`Definition d))::tl ->
1065 { Con.def_name = def_name ;
1066 Con.def_id = def_id ;
1067 Con.def_term = bo } = d in
1069 Box.b_hov [Some "helm", "xref", def_id]
1070 [ Box.b_object (p_mi []
1071 (match def_name with
1073 | Some n -> n)) ; Box.b_space ;
1074 Box.b_text [] (Utf8Macro.unicode_of_tex "\\def") ;
1075 Box.indent (term2pres bo)] in
1077 | _::_ -> assert false
1079 if context <> [] then [Box.b_v [] (aux [] context)] else []
1081 let sequent2pres0 term2pres (_,_,context,ty) =
1082 let pres_context = nconjlist2pres0 term2pres context in
1083 let pres_goal = term2pres ty in
1089 b_ink [None,"width","4cm"; None,"height","2px"]; (* sequent line *)
1093 let ncontext2pres status ~ids_to_nrefs ctx =
1094 let ctx = HExtlib.filter_map (fun x -> x) ctx in
1095 context2pres (nterm2pres status ~ids_to_nrefs) ~continuation:Box.smallskip
1096 (ctx:>NotationPt.term Con.in_proof_context_element list)
1098 let nsequent2pres status ~ids_to_nrefs =
1099 sequent2pres0 (nterm2pres status ~ids_to_nrefs)