]> matita.cs.unibo.it Git - helm.git/blob - components/content_pres/content2Procedural.ml
Procedural: some improvements
[helm.git] / components / content_pres / content2Procedural.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 module H = HExtlib
27 module C = Content
28 module G = GrafiteAst
29 module N = CicNotationPt
30
31 (* functions to be moved ****************************************************)
32
33 let rec list_split n l =
34    if n = 0 then [],l else 
35    let l1, l2 = list_split (pred n) (List.tl l) in
36    List.hd l :: l1, l2
37
38 (****************************************************************************)
39
40 type name  = string
41 type what  = Cic.annterm
42 type using = Cic.annterm
43 type count = int
44 type note  = string
45
46 type step = Note of note 
47           | Theorem of name * what * note
48           | Qed of note
49           | Intros of count option * name list * note
50           | Elim of what * using option * note
51           | Exact of what * note
52           | Branch of step list list * note
53
54 (* level 2 transformation ***************************************************)
55
56 let mk_name = function
57    | Some name -> name
58    | None      -> "_"
59
60 let mk_intros_arg = function
61    | `Declaration {C.dec_name = name}
62    | `Hypothesis {C.dec_name = name}
63    | `Definition {C.def_name = name}  -> mk_name name 
64    | `Joint _                         -> assert false
65    | `Proof _                         -> assert false
66
67 let mk_intros_args pc = List.map mk_intros_arg pc
68
69 let split_inductive n tl =
70    let l1, l2 = list_split (int_of_string n) tl in
71    List.hd (List.rev l2), l1
72
73 let mk_what rpac = function
74    | C.Premise {C.premise_n = Some i; C.premise_binder = Some b} -> 
75       Cic.ARel ("", "", i, b)
76    | C.Premise {C.premise_n = None; C.premise_binder = None} -> 
77       Cic.ARel ("", "", 1, "COMPOUND")
78    | C.Term t -> t
79    | C.Premise _   -> assert false
80    | C.ArgMethod _ -> assert false
81    | C.ArgProof _  -> assert false
82    | C.Lemma _     -> assert false
83    | C.Aux _       -> assert false
84
85 let rec mk_proof p =
86    let names = mk_intros_args p.C.proof_context in
87    let count = List.length names in
88    if count > 0 then Intros (Some count, names, "") :: mk_proof_body p
89    else mk_proof_body p
90    
91 and mk_proof_body p = 
92    let cmethod = p.C.proof_conclude.C.conclude_method in
93    let cargs = p.C.proof_conclude.C.conclude_args in
94    let capply = p.C.proof_apply_context in
95    match cmethod, cargs with
96       | "Intros+LetTac", [C.ArgProof p] -> mk_proof p 
97       | "ByInduction", C.Aux n :: C.Term (Cic.AAppl (_, using :: _)) :: tl ->
98          let rpac = List.rev capply in
99          let whatm, ms = split_inductive n tl in (* actual rx params here *)
100          let what, qs = mk_what rpac whatm, List.map mk_subproof ms in
101          [Elim (what, Some using, ""); Branch (qs, "")] 
102       | _ ->  
103          [Note (Printf.sprintf "%s %u" cmethod (List.length cargs))] 
104
105 and mk_subproof = function
106    | C.ArgProof ({C.proof_name = Some n} as p) -> Note n :: mk_proof p
107    | C.ArgProof ({C.proof_name = None} as p)   -> Note "" :: mk_proof p
108    | _                                         -> assert false
109
110 let mk_obj ids_to_inner_sorts prefix (_, params, xmenv, obj) =
111    if List.length params > 0 || xmenv <> None then assert false;
112    match obj with
113       | `Def (C.Const, t, `Proof ({C.proof_name = Some name} as p)) ->
114            Theorem (name, t, "") :: mk_proof p @ [Qed ""]
115       | _ -> assert false 
116
117 (* grafite ast constructors *************************************************)
118
119 let floc = H.dummy_floc
120
121 let mk_note str = G.Comment (floc, G.Note (floc, str))
122
123 let mk_theorem name t = 
124    let obj = N.Theorem (`Theorem, name, t, None) in
125    G.Executable (floc, G.Command (floc, G.Obj (floc, obj)))
126
127 let mk_qed =
128    G.Executable (floc, G.Command (floc, G.Qed floc))
129
130 let mk_tactic tactic =
131    G.Executable (floc, G.Tactical (floc, G.Tactic (floc, tactic), None))
132
133 let mk_intros xi ids =
134    let tactic = G.Intros (floc, xi, ids) in
135    mk_tactic tactic
136
137 let mk_elim what using =
138    let tactic = G.Elim (floc, what, using, Some 0, []) in
139    mk_tactic tactic
140
141 let mk_exact t =
142    let tactic = G.Exact (floc, t) in
143    mk_tactic tactic
144
145 let mk_dot = G.Executable (floc, G.Tactical (floc, G.Dot floc, None))
146
147 let mk_sc = G.Executable (floc, G.Tactical (floc, G.Semicolon floc, None))
148
149 let mk_ob = G.Executable (floc, G.Tactical (floc, G.Branch floc, None))
150
151 let mk_cb = G.Executable (floc, G.Tactical (floc, G.Merge floc, None))
152
153 let mk_vb = G.Executable (floc, G.Tactical (floc, G.Shift floc, None))
154
155 (* rendering ****************************************************************)
156
157 let cont sep a = match sep with 
158    | None     -> a
159    | Some sep -> sep :: a
160
161 let list_rev_map_concat map sep a l =
162    let rec aux a = function
163       | []          -> a
164       | [x]         -> map a x
165       | x :: y :: l -> aux (sep :: map a x) (y :: l)  
166    in
167    aux a l
168
169 let rec render_step sep a = function
170    | Note s            -> mk_note s :: a
171    | Theorem (n, t, s) -> mk_note s :: mk_theorem n t :: a 
172    | Qed s             -> mk_note s :: mk_qed :: a
173    | Intros (c, ns, s) -> mk_note s :: cont sep (mk_intros c ns :: a)
174    | Elim (t, xu, s)   -> mk_note s :: cont sep (mk_elim t xu :: a)
175    | Exact (t, s)      -> mk_note s :: cont sep (mk_exact t :: a)
176 (*   | Branch ([], s)    -> mk_note s :: cont sep a
177    | Branch ([ps], s)  -> mk_note s :: cont sep (render_steps a ps)
178 *)   | Branch (pss, s)   ->
179       let a =  mk_ob :: a in
180       let body = mk_cb :: list_rev_map_concat render_steps mk_vb a pss in
181       mk_note s :: cont sep body
182
183 and render_steps a = function
184    | []                                      -> a
185    | [p]                                     -> render_step None a p
186    | (Note _ | Theorem _ | Qed _ as p) :: ps ->
187       render_steps (render_step None a p) ps 
188    | p :: ((Branch _ :: _) as ps)            ->
189       render_steps (render_step (Some mk_sc) a p) ps
190    | p :: ps                                 ->
191       render_steps (render_step (Some mk_dot) a p) ps
192
193 (* interface functions ******************************************************)
194
195 let content2procedural ~ids_to_inner_sorts prefix cobj = 
196    prerr_endline "Phase 2 transformation";
197    let steps = mk_obj ids_to_inner_sorts prefix cobj in
198    prerr_endline "grafite rendering";
199    List.rev (render_steps [] steps)