]> matita.cs.unibo.it Git - helm.git/blob - helm/software/helena/src/basic_rg/brgLP.ml
- multi-file exportation for teyjus
[helm.git] / helm / software / helena / src / basic_rg / brgLP.ml
1 (*
2     ||M||  This file is part of HELM, an Hypertextual, Electronic        
3     ||A||  Library of Mathematics, developed at the Computer Science     
4     ||T||  Department, University of Bologna, Italy.                     
5     ||I||                                                                
6     ||T||  HELM is free software; you can redistribute it and/or         
7     ||A||  modify it under the terms of the GNU General Public License   
8     \   /  version 2 or (at your option) any later version.              
9      \ /   This software is distributed as is, NO WARRANTY.              
10       V_______________________________________________________________ *)
11
12 module KF = Filename
13 module KP = Printf
14
15 module U  = NUri
16 module C  = Cps
17 module G  = Options
18 module N  = Layer
19 module E  = Entity
20 module R  = Alpha
21 module B  = Brg
22
23 IFDEF MANAGER THEN
24
25 (* Internal functions *******************************************************)
26
27 let ok = ref true
28
29 let uris = ref []
30
31 let chunk = ref 0
32
33 let sub_och = ref stdout
34
35 let top_age = 7000
36
37 let size = 250
38
39 let base = "lp"
40
41 let ext_lp = ".elpi"
42 let ext_tj = ".mod"
43 let ext_tj_sig = ".sig"
44
45 let reserved = ["pi"; "sigma"; "nil"; "delay"; "in"; "with"; "resume"; "context"]
46
47 let alpha n =
48    if List.mem n reserved then !G.alpha ^ n else n
49
50 let out_preamble och =
51    let ich = open_in !G.preamble in
52    let rec aux () = KP.fprintf och "%s\n" (input_line ich); aux () in
53    try aux () with End_of_file -> close_in ich
54
55 let out_top_comment och msg =
56    KP.fprintf och "%% %s\n\n" msg
57
58 let out_comment och msg =
59    KP.fprintf och "%% %s\n" msg 
60
61 let out_clause och msg =
62    KP.fprintf och "%s\n\n" msg 
63
64 let out_uri och u =
65    let str = U.string_of_uri u in
66    let rec aux i =
67      let c = str.[i] in
68      if c = '.' then () else begin 
69         output_char och (if c = '/' then '_' else c);
70         aux (succ i)
71      end
72    in
73    let rec strip i n = 
74       if n <= 0 then succ i else
75       strip (String.index_from str (succ i) '/') (pred n)
76    in
77    aux (strip 0 3)
78
79 let out_name och a =
80    let f n = function 
81       | true  -> KP.fprintf och "%s" (alpha n)
82       | false -> KP.fprintf och "_"
83    in
84    let err () = f "" false in
85    E.name err f a
86
87 let rec out_term st e och = function
88    | B.Sort k                        ->
89       let sort = if k = 0 then "k+set" else if k = 1 then "k+prop" else assert false in
90       KP.fprintf och "(sort %s)" sort
91    | B.LRef (_, i)                   ->
92       let _, _, _, y, b = B.get e i in
93       KP.fprintf och "%a" out_name y
94    | B.GRef (_, s)                   ->
95       KP.fprintf och "%a" out_uri s
96    | B.Cast (u, t)                   ->
97       KP.fprintf och "(cast %a %a)" (out_term st e) u (out_term st e) t 
98    | B.Appl (x, v, t)                ->
99       let c = if x then "appx" else "appr" in
100       KP.fprintf och "(%s %a %a)" c (out_term st e) v (out_term st e) t
101    | B.Bind (y, B.Abst (r, n, w), t) ->
102       let y = R.alpha B.mem e y in
103       let ee = B.push e B.empty E.empty_node y (B.abst r n w) in
104       let c = if r then "prod" else "abst" in
105       let l = match N.to_string st n with
106          | "1" -> "l+1"
107          | "2" -> "l+2"
108          | _   -> ok := false; "?"
109       in
110       KP.fprintf och "(%s %s %a %a\\ %a)"
111          c l (out_term st e) w out_name y (out_term st ee) t
112    | B.Bind (y, B.Abbr v, t)         ->
113       let y = R.alpha B.mem e y in
114       let ee = B.push e B.empty E.empty_node y (B.abbr v) in
115       KP.fprintf och "(abbr %a %a\\ %a)"
116           (out_term st e) v out_name y (out_term st ee) t
117    | B.Bind (_, B.Void, _)           -> C.err ()
118
119 (* elpi variant 1 ***********************************************************)
120
121 let output_entity_lp1 och st (_, na, u, b) =
122    if na.E.n_apix <= !G.last then begin
123    match b with
124       | E.Abbr v ->
125          KP.fprintf och "(gdef+1 c+%u %a\n %a\\\n" na.E.n_apix (out_term st B.empty) v out_uri u;
126          uris := (true, u) :: !uris; !ok
127       | E.Abst w ->
128          KP.fprintf och "(gdec+1 c+%u %a\n%a\\\n" na.E.n_apix (out_term st B.empty) w out_uri u;
129          uris := (false, u) :: !uris; !ok
130       | E.Void   -> C.err ()
131    end else !ok
132
133 let close_out_lp1 och () =
134    let aux_sep _ = KP.fprintf och "%s" ")" in
135    KP.fprintf och "%s" "gtop";   
136    List.iter aux_sep !uris;
137    out_clause och "\n\n.";
138    close_out och
139
140 (* elpi variant 2 ***********************************************************)
141
142 let output_entity_lp2 och st (_, na, u, b) =
143    if na.E.n_apix <= !G.last then begin
144    match b with
145       | E.Abbr v ->
146          KP.fprintf och "g+line %a c+%u\n       %a\n.\n\n"
147             out_uri u na.E.n_apix (out_term st B.empty) v;
148          uris := (true, u) :: !uris; !ok
149       | E.Abst w ->
150          KP.fprintf och "g+line %a c+%u\n       %a\n.\n\n"
151             out_uri u na.E.n_apix (out_term st B.empty) w;
152          uris := (false, u) :: !uris; !ok
153       | E.Void   -> C.err ()
154    end else !ok
155
156 let close_out_lp2 och () =
157    let aux_name (b, s) =
158       let gde = if b then "gdef+2" else "gdec+2" in 
159       KP.fprintf och "(%s %a\n" gde out_uri s
160    in
161    let aux_sep _ = KP.fprintf och "%s" ")" in
162    if !G.first > 0 then begin
163       let s = KP.sprintf "tv+c C T :- $lt C c+%u, !." !G.first in
164       out_clause och s;
165       out_clause och "tv+c C T :- tv+ T."
166    end;
167    out_clause och "main :- grundlagen.";
168    out_clause och "grundlagen :- gv+";
169    List.iter aux_name (List.rev !uris);
170    KP.fprintf och "%s" "gtop";
171    List.iter aux_sep !uris;
172    out_clause och "\n\n.";
173    close_out och
174
175 (* teyjus variant 2 *************************************************)
176
177 let append_out name = 
178    open_out_gen [Open_append; Open_creat; Open_text] 0o666 name
179
180 let sub_close () = if !sub_och <> stdout then close_out !sub_och
181
182 let mk_name chunk =
183    let dir = KF.concat !G.manager_dir base in
184    let name = KP.sprintf "grundlagen%02u" chunk in
185    dir, name
186
187 let output_entity_tj2 och st (_, na, u, b) =
188    if na.E.n_apix <= !G.last then begin
189    if pred na.E.n_apix mod size = 0 then begin
190       sub_close ();
191       incr chunk;
192       let dir, name = mk_name !chunk in
193       let soch = open_out (KF.concat dir name ^ ext_tj_sig) in
194       out_preamble soch;
195       out_top_comment soch (KP.sprintf "This file was generated by %s: do not edit" G.version_string);
196       out_clause soch (KP.sprintf "sig %s." name);
197       out_clause soch "accum_sig grundlagen.";
198       out_clause soch (KP.sprintf "type line+%02u t -> int -> t -> o." !chunk);
199       close_out soch;
200       let soch = open_out (KF.concat dir name ^ ext_tj) in
201       out_preamble soch;
202       out_top_comment soch (KP.sprintf "This file was generated by %s: do not edit" G.version_string);
203       out_clause soch (KP.sprintf "module %s." name);
204       sub_och := soch
205    end;
206    out_comment !sub_och (KP.sprintf "constant %u" na.E.n_apix); 
207    match b with
208       | E.Abbr v ->
209          KP.fprintf !sub_och "line+%02u %a %u\n        %a\n.\n\n"
210             !chunk out_uri u (top_age - na.E.n_apix) (out_term st B.empty) v;
211          uris := (true, u) :: !uris; !ok
212       | E.Abst w ->
213          KP.fprintf !sub_och "line+%02u %a %u\n        %a\n.\n\n"
214             !chunk out_uri u (top_age - na.E.n_apix) (out_term st B.empty) w;
215          uris := (false, u) :: !uris; !ok
216       | E.Void   -> C.err ()
217    end else !ok
218
219 let close_out_tj2 och () =
220    let out_name och (b, u) =
221       let gde = if b then "gdef+2" else "gdec+2" in 
222       KP.fprintf och "(%s %a\n" gde out_uri u
223    in
224    let rec out_pars och p =
225       if p > 0 then begin KP.fprintf och "%s" ")"; out_pars och (pred p) end
226    in
227    let rec out_list chunk pars first items uris = match first, items, uris with
228       | true, _, _         ->
229          let dir, name = mk_name chunk in
230          let soch = append_out (KF.concat dir name ^ ext_tj) in
231          out_clause soch (KP.sprintf "g+line R C T :- line+%02u R C T, !." chunk);
232          KP.fprintf soch "g+list %u\n" chunk;
233          sub_och := soch;
234          out_list (succ chunk) pars false items uris
235       | false, _, []       ->
236          KP.fprintf !sub_och "gtop%a.\n\n" out_pars pars;
237          sub_close ()
238       | false, 0, _        ->
239          KP.fprintf !sub_och "(genv %u)%a.\n\n" chunk out_pars pars;
240          sub_close ();
241          out_list chunk 0 true size uris
242       | false, _, hd :: tl ->
243          out_name !sub_och hd; out_list chunk (succ pars) false (pred items) tl
244    in
245    let rec out_accumulate c =
246       if !chunk < c then KP.fprintf och "\n" else begin
247          let _, name = mk_name c in
248          KP.fprintf och "accumulate %s.\n" name;
249          out_accumulate (succ c)
250       end
251    in
252    sub_close ();
253    out_list 1 0 true size (List.rev !uris);
254    KP.fprintf och "accumulate helena.\n";
255    out_accumulate 1;
256    out_clause och "main :- grundlagen.";
257    out_clause och "grundlagen :- gv+ (genv 1).";
258    close_out och
259
260 (* teyjus variant 3 *************************************************)
261
262 let output_entity_tj3 och st (_, na, u, b) =
263    if na.E.n_apix <= !G.last then begin
264       out_comment och (KP.sprintf "constant %u" na.E.n_apix);
265       let age = top_age - na.E.n_apix in
266       match b with
267          | E.Abbr v ->
268             KP.fprintf och "g+line %a %u\n       %a\n.\n\n"
269                out_uri u age (out_term st B.empty) v;
270             KP.fprintf och "tv+ %a.\n\n" out_uri u;
271             KP.fprintf och "r+exp %a M C E M V :- g+line %a C V.\n\n"
272                out_uri u out_uri u;
273             uris := (true, u) :: !uris; !ok
274          | E.Abst w ->
275             KP.fprintf och "g+line %a %u\n       %a\n.\n\n"
276                out_uri u age (out_term st B.empty) w;
277             KP.fprintf och "tv+ %a.\n\n" out_uri u;
278             KP.fprintf och "r+exp %a M1 C E M2 W :- m+pred M1 M2, g+line %a C W.\n\n"
279                out_uri u out_uri u;
280             uris := (false, u) :: !uris; !ok
281          | E.Void   -> C.err ()
282    end else !ok
283
284 let close_out_tj3 och () =
285    let out_name (_, u) =
286       KP.fprintf och "gv+3 %a,\n" out_uri u
287    in
288    let rec out_list och chunk first items uris = match first, items, uris with
289       | true, _, _         ->
290          KP.fprintf och "chunk %u :-\n" chunk;
291          out_list och (succ chunk) false items uris
292       | false, _, []       -> KP.fprintf och "!.\n\n"; chunk
293       | false, 0, _        ->
294          KP.fprintf och "!.\n\n";
295          out_list och chunk true size uris
296       | false, _, hd :: tl ->
297          out_name hd; out_list och chunk false (pred items) tl
298    in
299    let rec out_chunks och chunks c =
300       if chunks < c then out_clause och "!." else begin
301          KP.fprintf och "chunk %u,\n" c; out_chunks och chunks (succ c)
302       end
303    in
304    let chunks = out_list och 1 true size (List.rev !uris) in
305    out_clause och "main :- grundlagen.";
306    KP.fprintf och "grundlagen :-\n";
307    out_chunks och (pred chunks) 1;
308    close_out och
309
310 (* Interface functions ******************************************************)
311
312 let open_out_lp1 fname =
313    let dir = KF.concat !G.manager_dir base in 
314    let path = KF.concat dir fname in
315    let och = open_out (path ^ "1" ^ ext_lp) in
316    out_preamble och;
317    out_top_comment och (KP.sprintf "This file was generated by %s: do not edit" G.version_string);
318    out_clause och "main :- grundlagen.";
319    out_clause och "grundlagen :- gv+";
320    output_entity_lp1 och, close_out_lp1 och
321
322 let open_out_lp2 fname =
323    let dir = KF.concat !G.manager_dir base in 
324    let path = KF.concat dir fname in
325    let och = open_out (path ^ "2" ^ ext_lp) in
326    out_preamble och;
327    out_top_comment och (KP.sprintf "This file was generated by %s: do not edit" G.version_string);
328    output_entity_lp2 och, close_out_lp2 och
329
330 let open_out_tj2 fname =
331    let dir = KF.concat !G.manager_dir base in
332    let path = KF.concat dir fname ^ "2" in
333    let och = open_out (path ^ ext_tj) in
334    out_preamble och;
335    out_top_comment och (KP.sprintf "This file was generated by %s: do not edit" G.version_string);
336    out_clause och "module grundlagen.";
337    output_entity_tj2 och, close_out_tj2 och
338
339 let open_out_tj3 fname =
340    let dir = KF.concat !G.manager_dir base in 
341    let path = KF.concat dir fname in
342    let och = open_out (path ^ "3" ^ ext_tj) in
343    out_preamble och;
344    out_top_comment och (KP.sprintf "This file was generated by %s: do not edit" G.version_string);
345    out_clause och "module grundlagen.";
346    out_clause och "accumulate helena.";
347    output_entity_tj3 och, close_out_tj3 och
348
349 END