1 (* Copyright (C) 2000, 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 (**************************************************************************)
35 module P = Mpresentation;;
36 module CE = Content_expressions;;
38 let symbol_table = Hashtbl.create 503;;
39 let symbol_table_charcount = Hashtbl.create 503;;
43 let rec countterm current_size t =
44 if current_size > maxsize then current_size
46 CE.Symbol (_,name,None,_) -> current_size + (String.length name)
47 | CE.Symbol (_,name,Some subst,_) ->
48 let c1 = current_size + (String.length name) in
50 | CE.LocalVar (_,name) -> current_size + (String.length name)
51 | CE.Meta (_,name,l) ->
56 | Some t' -> countterm i t'
57 ) (current_size + String.length name) l
58 | CE.Num (_,value) -> current_size + (String.length value)
60 List.fold_left countterm current_size l
61 | CE.Binder (_, _,(n,s),body) ->
62 let cs = countterm (current_size + 2 + (String.length n)) s in
64 | CE.Letin (_,(n,s),body) ->
65 let cs = countterm (current_size + 3 + (String.length n)) s in
67 | CE.Letrec (_,defs,body) ->
70 (fun c (n,bo) -> countterm (c+(String.length n)) bo) current_size defs in
73 let cs = countterm (current_size + 4) a in
75 (fun c (n,bo) -> countterm (c+(String.length n)) bo) current_size np
78 countsubst subst current_size =
80 (fun current_size (uri,expr) ->
81 if (current_size > maxsize) then current_size
84 (current_size + (String.length (UriManager.name_of_uri uri))) in
85 (countterm c1 expr)) current_size subst
89 ((countterm 0 t) > maxsize)
92 let rec make_attributes l1 =
95 | None::tl -> make_attributes (List.tl l1) tl
97 let p,n = List.hd l1 in
98 (p,n,s)::(make_attributes (List.tl l1) tl)
101 let make_math_tail = List.map (fun s -> P.Mtext ([], s))
103 let rec cexpr2pres ?(priority = 0) ?(assoc = false) ?(tail = []) t =
104 let module CE = Content_expressions in
105 let module P = Mpresentation in
108 CE.Symbol (xref,name,None,uri) ->
111 [Some "helm","xref";Some "xlink","href"] [xref;uri] in
114 else P.Mrow([],P.Mi (attr,name)::(make_math_tail tail))
115 | CE.Symbol (xref,name,Some subst,uri) ->
118 [Some "helm","xref";Some "xlink","href"] [xref;uri] in
125 P.Mi([],UriManager.name_of_uri uri)]
129 P.Mi([],UriManager.name_of_uri uri)::
137 (P.Mtext([],"]")::(make_math_tail tail)))
138 | CE.LocalVar (xref,name) ->
139 let attr = make_attributes [Some "helm","xref"] [xref] in
142 else P.Mrow([],P.Mi (attr,name)::(make_math_tail tail))
143 | CE.Meta (xref,name,l) ->
144 let attr = make_attributes [Some "helm","xref"] [xref] in
149 | Some t -> cexpr2pres t
153 P.Mrow ([],P.Mi (attr,name) :: P.Mo ([],"[") :: l' @ [P.Mo ([],"]")])
156 ([],P.Mi (attr,name):: P.Mo ([],"[") :: l' @ [P.Mo ([],"]")] @ (make_math_tail tail))
157 | CE.Num (xref,value) ->
158 let attr = make_attributes [Some "helm","xref"] [xref] in
161 else P.Mrow([],P.Mn (attr,value)::(make_math_tail tail))
162 | CE.Appl (axref,CE.Symbol(sxref,n,subst,uri)::tl) ->
163 let aattr = make_attributes [Some "helm","xref"] [axref] in
164 let sattr = make_attributes [Some "helm","xref";Some "xlink","href"] [sxref;uri] in
166 (let f = Hashtbl.find symbol_table n in
167 f tl ~priority ~assoc ~tail aattr sattr)
170 P.Mo([],"(")::P.Mi(sattr,n)::(make_args tl)@(P.Mo([],")")::(make_math_tail tail))))
171 | CE.Appl (xref,l) as t ->
172 let attr = make_attributes [Some"helm","xref"] [xref] in
174 P.Mo([],"(")::(make_args l)@(P.Mo([],")")::(make_math_tail tail)))
175 | CE.Binder (xref, kind,(n,s),body) ->
176 let attr = make_attributes [Some "helm","xref"] [xref] in
178 if kind = "Lambda" then
179 Netconversion.ustring_of_uchar `Enc_utf8 0x03bb
180 else if kind = "Prod" then
181 Netconversion.ustring_of_uchar `Enc_utf8 0x03a0
182 else if kind = "Forall" then
183 Netconversion.ustring_of_uchar `Enc_utf8 0x2200
184 else if kind = "Exists" then
185 Netconversion.ustring_of_uchar `Enc_utf8 0x2203
188 P.Mtext([None,"mathcolor","Blue"],binder)::
189 P.Mtext([],n ^ ":")::
192 (aux body)::(make_math_tail tail))
193 | CE.Letin (xref,(n,s),body) ->
194 let attr = make_attributes [Some "helm","xref"] [xref] in
196 P.Mtext([],("let "))::
197 P.Mtext([],(n ^ "="))::
200 (aux body)::(make_math_tail tail))
201 | CE.Letrec (xref,defs,body) ->
202 let attr = make_attributes [Some "helm","xref"] [xref] in
207 [P.Mtext([],(n ^ "="));(aux body)]
209 P.Mtext([],(n ^ "="))::
210 (aux body)::P.Mtext([]," and")::(make_defs tl)) in
212 P.Mtext([],("let rec "))::
214 (P.Mtext([]," in ")::
215 (aux body)::(make_math_tail tail)))
216 | CE.Case (xref,a,np) ->
217 let attr = make_attributes [Some "helm","xref"] [xref] in
218 let rec make_patterns =
221 | [(n,p)] -> make_pattern n p
223 (make_pattern n p)@(P.smallskip::
224 P.Mtext([],"|")::P.smallskip::(make_patterns tl)))
225 and make_pattern n p =
226 let rec get_vars_and_body =
228 CE.Binder (_, "Lambda",(n,_),body) ->
229 let v,b = get_vars_and_body body in
232 let vars,body = get_vars_and_body p in
236 | l -> "(" ^ n ^" "^(String.concat " " l) ^ ")" ^ " -> " in
237 [P.Mtext([],lhs);P.smallskip;aux body] in
239 P.Mtext([],"match")::P.smallskip::
240 (aux a)::P.smallskip::
241 P.Mtext([],"with")::P.smallskip::
242 P.Mtext([],"[")::P.smallskip::
243 (make_patterns np)@(P.smallskip::P.Mtext([],("]"))::(make_math_tail tail))) in
248 make_args ?(priority = 0) ?(assoc = false) ?(tail = []) =
250 [] -> List.map (fun s -> P.Mtext ([], s)) tail
251 | a::tl -> P.smallskip::(cexpr2pres a)::(make_args ~tail:tail tl)
254 let make_box_tail = List.map (Box.b_text [])
257 let rec make_args_charcount ?(priority = 0) ?(assoc = false) ?(tail = []) =
260 | [a] -> [Box.indent (cexpr2pres_charcount ~tail:tail a)]
262 let c = List.fold_left countterm 0 l in
264 (Box.indent (cexpr2pres_charcount a))::
265 (make_args_charcount ~tail:tail tl)
267 [Box.indent (Box.b_object (P.Mrow ([], (make_args ~tail:tail l))))]
274 let c = List.fold_left countterm 0 tl in
276 P.Mtable ([("align","baseline 1");("equalrows","false");
277 ("columnalign","left")],
278 (make_args_charcount tl))
280 P.Mrow([], make_args tl) in
281 [P.Mtr([],[P.Mtd([],(cexpr2pres_charcount a))]);
282 P.Mtr([],[P.Mtd([],P.indented tlpres)])] *)
285 cexpr2pres_charcount ?(priority = 0) ?(assoc = false) ?(tail = []) t =
286 if not (is_big t) then
287 Box.b_object (cexpr2pres ~priority ~assoc ~tail t)
288 else let aux = cexpr2pres_charcount in
290 CE.Symbol (xref,name,None,uri) ->
293 [Some "helm","xref";Some "xlink","href"] [xref;uri] in
295 Box.b_object (P.Mi (attr,name))
297 Box.b_h [] (Box.b_object (P.Mi (attr,name)) :: (make_box_tail tail))
298 | CE.Symbol (xref,name,Some subst,uri) ->
301 [Some "helm","xref";Some "xlink","href"] [xref;uri] in
306 [Box.b_object (cexpr2pres a);
308 Box.b_object (P.Mi([],UriManager.name_of_uri uri))]
310 Box.b_object (cexpr2pres a) ::
312 Box.b_object (P.Mi([],UriManager.name_of_uri uri)) ::
313 Box.b_text [] "; " ::
317 Box.b_object (P.Mi (attr,name))::
320 (Box.b_text [] "]")::(make_box_tail tail) )
321 | CE.LocalVar (xref,name) ->
322 let attr = make_attributes [Some "helm","xref"] [xref] in
324 Box.b_object (P.Mi (attr,name))
326 Box.b_object (P.Mrow ([], P.Mi (attr,name)::(make_math_tail tail)))
327 | CE.Meta (xref,name,l) ->
328 let attr = make_attributes [Some "helm","xref"] [xref] in
333 | Some t -> cexpr2pres t
336 Box.b_object (P.Mrow ([],P.Mi (attr,name) :: P.Mo ([],"[") :: l' @ [P.Mo ([],"]")] @ (make_math_tail tail)))
337 | CE.Num (xref,value) ->
338 let attr = make_attributes [Some "helm","xref"] [xref] in
340 Box.b_object (P.Mn (attr,value))
342 Box.b_object (P.Mrow ([], P.Mn (attr,value)::(make_math_tail tail)))
343 | CE.Appl (axref,CE.Symbol(sxref,n,subst,uri)::tl) ->
344 let aattr = make_attributes [Some "helm","xref"] [axref] in
345 let sattr = make_attributes [Some "helm","xref";Some "xlink","href"] [sxref;uri] in
347 (let f = Hashtbl.find symbol_table_charcount n in
348 f tl ~priority ~assoc ~tail aattr sattr)
353 Box.b_object (cexpr2pres (CE.Symbol(sxref,n,subst,uri)))
355 make_args_charcount ~tail:(")"::tail) tl
357 | CE.Appl (xref,l) as t ->
358 let attr = make_attributes [Some "helm","xref"] [xref] in
362 cexpr2pres_charcount (List.hd l)
364 make_args_charcount ~tail:(")"::tail) (List.tl l)
366 | CE.Binder (xref, kind,(n,s),body) as t ->
367 let attr = make_attributes [Some "helm","xref"] [xref] in
369 if kind = "Lambda" then
370 Netconversion.ustring_of_uchar `Enc_utf8 0x03bb
371 else if kind = "Prod" then
372 Netconversion.ustring_of_uchar `Enc_utf8 0x03a0
373 else if kind = "Forall" then
374 Netconversion.ustring_of_uchar `Enc_utf8 0x2200
375 else if kind = "Exists" then
376 Netconversion.ustring_of_uchar `Enc_utf8 0x2203
380 Box.b_text [None,"color","blue"] binder;
381 Box.b_text [] (n ^ ":");
382 cexpr2pres_charcount s ~tail:["."]
384 Box.b_h [] [ Box.indent (cexpr2pres_charcount body ~tail:tail) ]
386 | CE.Letin (xref,(n,s),body) as t ->
387 let attr = make_attributes [Some "helm","xref"] [xref] in
392 Box.b_text [] (n ^ "=");
393 cexpr2pres_charcount s;
397 Box.indent (cexpr2pres_charcount body)
399 | CE.Letrec (xref,defs,body) ->
400 let attr = make_attributes [Some "helm","xref"] [xref] in
405 [Box.b_text [] (n ^ "="); (aux body)]
407 Box.b_text [] (n ^ "=")::
418 [ Box.smallskip; Box.b_kw "in"; Box.smallskip; aux body ]
420 | CE.Case (xref,a,np) ->
421 let attr = make_attributes [Some "helm","xref"] [xref] in
424 let tail = " with"::tail in (* LUCA: porcheria all'ennesima potenza, TODO ripensare il meccanismo del tail *)
425 [ Box.b_h [] [ Box.b_kw "match"; Box.smallskip ];
437 let rec make_patterns is_first ~tail =
441 let sep = if is_first then "[ " else "| " in
442 [ Box.b_h [] [make_pattern sep ~tail n p] ]
445 if is_first then "[ " else "| " in
446 [ Box.b_h [] ((make_pattern sep [] n p) :: (make_patterns false ~tail tl)) ]
447 and make_pattern sep ~tail n p =
448 let rec get_vars_and_body =
450 CE.Binder (_, "Lambda",(n,_),body) ->
451 let v,b = get_vars_and_body body in
454 let vars,body = get_vars_and_body p in
457 [] -> sep ^ n ^ " -> "
458 | l -> sep ^"(" ^n^" "^(String.concat " " l) ^ ")" ^ " -> " in
459 if (is_big body) then
462 Box.indent (aux ~tail body)
465 Box.b_h [] [ Box.b_text [] lhs; aux ~tail body ]
468 make_patterns true np ~tail:("]"::tail) in
469 Box.b_v attr (arg@patterns)