]> matita.cs.unibo.it Git - helm.git/blob - helm/ocaml/cic_transformations/ast2pres.ml
bumped changelog line to match upload date
[helm.git] / helm / ocaml / cic_transformations / ast2pres.ml
1 (* Copyright (C) 2000, 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 (*                             28/6/2003                                  *)
32 (*                                                                        *)
33 (**************************************************************************)
34
35 module A = CicAst;;
36 module P = Mpresentation;;
37
38 let symbol_table = Hashtbl.create 503;;
39 let symbol_table_charcount = Hashtbl.create 503;;
40
41 let maxsize = 25;;
42
43 let rec countvar current_size = function
44     (Cic.Anonymous, None) -> current_size + 1 (* underscore *)
45   | (Cic.Anonymous, Some ty) -> countterm current_size ty
46   | (Cic.Name s, None) -> current_size + String.length s
47   | (Cic.Name s, Some ty) -> current_size + countterm current_size ty
48
49 and countterm current_size t =
50   if current_size > maxsize then current_size 
51   else match t with
52       A.AttributedTerm (_,t) -> countterm current_size t
53     | A.Appl l -> 
54         List.fold_left countterm current_size l
55     | A.Binder (_,var,body) -> 
56         let varsize = countvar current_size var in
57         countterm (varsize + 1) body (* binder *)
58     | A.Case (arg, _, ty, pl) ->
59         let size1 = countterm (current_size+10) arg in (* match with *)
60         let size2 =
61           match ty with
62               None -> size1
63             | Some ty -> countterm size1 ty in
64         List.fold_left 
65           (fun c ((constr,vars),action) ->
66              let size3 =
67                List.fold_left countvar (c+String.length constr) vars in
68              countterm size3 action) size2 pl 
69     | A.LetIn (var,s,t) ->
70         let size1 = countvar current_size var in
71         let size2 = countterm size1 s in
72         countterm size2 t
73     | A.LetRec (_,l,t) ->
74         let size1 =
75           List.fold_left
76             (fun c (var,s,_) -> 
77                let size1 = countvar c var in
78                countterm size1 s) current_size l in
79           countterm size1 t
80     | A.Ident(s,None) -> current_size + (String.length s)
81     | A.Ident(s,Some l) ->
82         List.fold_left 
83           (fun c (v,t) -> countterm (c + (String.length v)) t) 
84           (current_size + (String.length s)) l
85     | A.Implicit -> current_size + 1 (* underscore *)
86     | A.Meta (_,l) ->
87         List.fold_left 
88           (fun c t -> 
89              match t with
90                  None -> c + 1 (* underscore *)
91                | Some t -> countterm c t)
92           (current_size + 1) l (* num *)
93     | A.Num (s, _) -> current_size + String.length s
94     | A.Sort _ -> current_size + 4 (* sort name *)
95     | A.Symbol (s,_) -> current_size + String.length s
96 ;;
97
98 let is_big t = 
99   ((countterm 0 t) > maxsize)
100 ;;
101
102 let rec make_attributes l1 =
103   function
104       [] -> []
105     | None::tl -> make_attributes (List.tl l1) tl
106     | (Some s)::tl ->
107        let p,n = List.hd l1 in
108         (p,n,s)::(make_attributes (List.tl l1) tl)
109 ;;
110
111 let map_tex unicode texcmd =
112   let default_map_tex = Printf.sprintf "\\%s " in
113   if unicode then
114     try
115       Utf8Macro.expand texcmd
116     with Utf8Macro.Macro_not_found _ -> default_map_tex texcmd
117   else
118     default_map_tex texcmd
119
120 let resolve_binder unicode = function
121   | `Lambda -> map_tex unicode "lambda"
122   | `Pi -> map_tex unicode "Pi"
123   | `Forall -> map_tex unicode "forall"
124   | `Exists -> map_tex unicode "exists"
125 ;;
126
127 let rec make_args f ~tail = function
128     | [] -> assert false
129     | [arg] -> [f ~tail arg]
130     | arg :: tl -> (f ~tail:[] arg) :: (make_args f ~tail tl)
131
132 let append_tail ~tail box =
133   match tail with
134   | [] -> box
135   | _ -> Box.H ([], box :: (List.map (fun t -> Box.Text ([], t)) tail))
136
137 let ast2astBox ?(unicode = true) ?(priority = 0) ?(assoc = false) ?(tail = [])
138   (t, ids_to_uris)
139 =
140   let lookup_uri = function
141     | None -> None
142     | Some id ->
143         (try
144           Some (Hashtbl.find ids_to_uris id)
145         with Not_found -> None)
146   in
147   let make_std_attributes xref =
148     let uri = lookup_uri xref in
149     make_attributes [Some "helm","xref"; Some "xlink","href"] [xref;uri]
150   in
151   let rec ast2box ?(priority = 0) ?(assoc = false) ?xref ~tail t =
152     if is_big t then 
153       bigast2box ~priority ~assoc ?xref ~tail t
154     else
155       let attrs = make_std_attributes xref in
156       append_tail ~tail (Box.Object (attrs, t))
157   and
158   bigast2box ?(priority = 0) ?(assoc = false) ?xref ~tail t =
159   match t with
160     | A.AttributedTerm (`Loc _, t) -> bigast2box ?xref ~tail t
161     | A.AttributedTerm (`IdRef xref, t) -> bigast2box ~xref ~tail t
162     | A.Appl [] -> assert false
163     | A.Appl ((hd::tl) as l) ->
164         let rec find_symbol idref = function
165           | A.AttributedTerm (`Loc _, t) -> find_symbol None t
166           | A.AttributedTerm (`IdRef id, t) -> find_symbol (Some id) t
167           | A.Symbol (name, _) ->
168               (match idref with
169               | None -> assert false
170               | Some idref -> `Symbol (name, idref))
171           | _ -> `None
172         in
173         let aattr = make_attributes [Some "helm","xref"] [xref] in
174         (match find_symbol None hd with
175         | `Symbol (name, sxref) ->
176             let sattr = make_std_attributes (Some sxref) in
177             (try 
178               (let f = Hashtbl.find symbol_table_charcount name in
179                f tl ~unicode ~priority ~assoc ~tail ~ids_to_uris aattr sattr)
180             with Not_found ->
181               Box.H 
182                 (make_attributes [Some "helm","xref"] [xref],
183                  [Box.Text([],"(");
184                   Box.V([],
185                     make_args (fun ~tail t -> ast2box ~tail t)
186                       ~tail:(")" :: tail) l);
187                   Box.Text([],")")]))
188         | `None ->
189             Box.H 
190               (make_attributes [Some "helm","xref"] [xref],
191                [Box.Text([],"(");
192                 Box.V([],
193                   make_args
194                     (fun ~tail t -> ast2box ~tail t)
195                     ~tail:(")" :: tail) l)]
196                 ))
197     | A.Binder (`Forall, (Cic.Anonymous, typ), body)
198     | A.Binder (`Pi, (Cic.Anonymous, typ), body) ->
199         Box.V(make_attributes [Some "helm","xref"] [xref],
200           [(match typ with
201             | None -> Box.Text([], "?")
202             | Some typ -> ast2box ~tail:[] typ);
203             Box.H([],
204               [Box.skip;
205                Box.Text([], map_tex unicode "to");
206                ast2box ~tail body])])
207     | A.Binder(kind, var, body) ->
208         Box.V(make_attributes [Some "helm","xref"] [xref],
209               [Box.H([],
210                 [Box.Text ([None,"color","blue"], resolve_binder unicode kind);
211                  make_var ~tail:("." :: tail) var]);
212                Box.indent (ast2box ~tail body)])
213     | A.Case(arg, _, ty, pl) ->
214         let make_rule ~tail sep ((constr,vars),rhs) =
215           if (is_big rhs) then
216             Box.V([],[Box.H([],[Box.Text([],sep);
217                                 Box.smallskip; 
218                                 make_pattern constr vars;
219                                 Box.smallskip; 
220                                 Box.Text([],map_tex unicode "Rightarrow")]);
221                       Box.indent (bigast2box ~tail rhs)])
222           else
223             Box.H([],[Box.Text([],sep);
224                       Box.smallskip; 
225                       make_pattern constr vars;
226                       Box.smallskip; 
227                       Box.Text([],map_tex unicode "Rightarrow");
228                       Box.smallskip; 
229                       Box.Object([],rhs)]) in
230         let plbox = match pl with
231             [] -> Box.Text([],"[]")
232           | r::tl -> 
233               Box.V([],
234                 (make_rule ~tail:[] "[" r) ::
235                 (make_args
236                   (fun ~tail pat -> make_rule ~tail:[] "|" pat)
237                   ~tail:("]" :: tail)
238                   tl))
239         in
240         let ty_box =
241           match ty with
242           | Some ty ->
243               [ Box.H([],[Box.Text([],"[");
244                          ast2box ~tail ty;
245                          Box.Text([],"]")]) ]
246           | None -> []
247         in
248         if is_big arg then
249           Box.V(make_attributes [Some "helm","xref"] [xref],
250                  ty_box @
251                  [Box.Text([],"match");
252                  Box.indent (Box.H([],[Box.skip; bigast2box ~tail arg]));
253                  Box.Text([],"with");
254                  Box.indent plbox])
255         else
256           Box.V(make_attributes [Some "helm","xref"] [xref],
257                 ty_box @
258                 [Box.H(make_attributes [Some "helm","xref"] [xref],
259                        [Box.Text([],"match");
260                         Box.smallskip;
261                         ast2box ~tail arg;
262                         Box.smallskip;
263                         Box.Text([],"with")]);
264                  Box.indent plbox])
265     | A.LetIn (var, s, t) ->
266         Box.V(make_attributes [Some "helm","xref"] [xref],
267               (make_def "let" var s "in")@[ast2box ~tail t])
268     | A.LetRec (_, vars, body) ->
269         let definitions =
270           let rec make_defs let_txt = function
271               [] -> []
272             | [(var,s,_)] -> 
273                 make_def let_txt var s "in"
274             | (var,s,_)::tl ->
275                 (make_def let_txt var s "")@(make_defs "and" tl) in
276           make_defs "let rec" vars in
277         Box.V(make_attributes [Some "helm","xref"] [xref],
278               definitions@[ast2box ~tail body])
279     | A.Ident (s, subst) ->
280         let subst =
281           let rec make_substs start_txt = 
282             function
283               [] -> []
284             | [(s,t)] -> 
285                 make_subst start_txt s t ""
286             | (s,t)::tl ->
287                 (make_subst start_txt s t ";")@(make_substs "" tl)
288           in
289           match subst with
290           | Some subst ->
291               Box.H([],
292                     [Box.Text(make_std_attributes xref,s);
293                      Box.Action([],
294                        [Box.Text([],"[...]");
295                         Box.H([], [Box.Text([], map_tex unicode "subst" ^ "[");
296                          Box.V([], make_substs "" subst);
297                          Box.Text([], "]")])])])
298           | None -> Box.Text(make_std_attributes xref, s)
299         in
300          subst
301         (*
302         Box.H([], (* attr here or on Vbox? *)
303               [Box.Text(make_std_attributes xref,s);
304                Box.Action([], [Box.Text([], "[_]"); Box.V([],subst)])])
305                (* Box.indent(Box.V([],subst))]) *)
306         *)
307     | A.Implicit -> 
308         Box.Text([],"_") (* big? *)
309     | A.Meta (n, l) ->
310         let local_context =
311           List.map 
312             (function t -> 
313                Box.H([],[aux_option ~tail t; Box.Text([],";")])) 
314             l in
315         Box.V(make_attributes [Some "helm","xref"] [xref],
316               [Box.Text([],"?"^(string_of_int n));
317                Box.H([],[Box.Text([],"[");
318                          Box.V([],local_context);
319                          Box.Text([],"]")])])
320     | A.Num (s, _) -> 
321          Box.Text([],s)
322     | A.Sort kind ->
323         (match kind with 
324              `Prop -> Box.Text([],"Prop")
325            | `Set -> Box.Text([],"Set")
326            | `Type -> Box.Text([],"Type")   
327            | `CProp -> Box.Text([],"CProp"))    
328     | A.Symbol (s, _) -> 
329         Box.Text([],s)
330
331   and aux_option ~tail = function
332       None  -> Box.Text([],"_")
333     | Some ast -> ast2box ~tail ast 
334
335   and make_var ~tail = function
336       (Cic.Anonymous, None) -> Box.Text([],"_:_")
337     | (Cic.Anonymous, Some t) -> 
338         Box.H([],[Box.Text([],"_:");ast2box ~tail t])
339     | (Cic.Name s, None) -> Box.Text([],s)
340     | (Cic.Name s, Some t) ->
341         if is_big t then
342           Box.V([],[Box.Text([],s^":");
343                     Box.indent(bigast2box ~tail t)])
344         else
345           Box.H([],[Box.Text([],s^":");Box.Object([],t)])
346
347   and make_pattern constr = 
348     function
349         [] -> Box.Text([],constr)
350       | vars -> 
351           let bvars =
352             List.fold_right 
353               (fun var acc -> 
354                  let bv = 
355                    match var with
356                        (* ignoring the type *)
357                        (Cic.Anonymous, _) -> Box.Text([],"_")
358                      | (Cic.Name s, _) -> Box.Text([],s) in
359                    Box.Text([]," ")::bv::acc) vars [Box.Text([],")")] in
360             Box.H([],Box.Text([],"(")::Box.Text([],constr)::bvars)
361       
362
363   and make_def let_txt var def end_txt =
364     let name = 
365       (match var with
366            (* ignoring the type *)
367            (Cic.Anonymous, _) -> Box.Text([],"_") 
368          | (Cic.Name s, _) -> Box.Text([],s)) in
369     pretty_append ~tail:[end_txt]
370       [Box.Text([],let_txt);
371        Box.smallskip;
372        name;
373        Box.smallskip;
374        Box.Text([],"=")
375       ]
376       def 
377
378   and make_subst start_txt varname body end_txt =
379     pretty_append ~tail:[end_txt]
380       ((if start_txt <> "" then [Box.Text([],start_txt)] else [])@
381        [Box.Text([],varname);
382         Box.smallskip;
383         Box.Text([],map_tex unicode "Assign")
384        ])
385       body
386             
387   and pretty_append ~tail l ast =
388     if is_big ast then
389       [Box.H([],l);
390        Box.H([],[Box.skip; bigast2box ~tail ast])]
391     else
392       [Box.H([],l@[Box.smallskip; (ast2box ~tail ast)])]
393
394 in
395 ast2box ~priority ~assoc ~tail t
396 ;;
397
398 let m_row_with_fences = P.row_with_brackets
399 let m_row = P.row_without_brackets
400 let m_open_fence = P.Mo([None, "stretchy", "false"], "(")
401 let m_close_fence = P.Mo([None, "stretchy", "false"], ")")
402
403 let ast2mpres ?(priority = 0) ?(assoc = false) (ast, ids_to_uris) =
404   let lookup_uri = function
405     | None -> None
406     | Some id ->
407         (try
408           Some (Hashtbl.find ids_to_uris id)
409         with Not_found -> None)
410   in
411   let make_std_attributes xref =
412     let uri = lookup_uri xref in
413     make_attributes [Some "helm","xref"; Some "xlink","href"] [xref;uri]
414   in
415   let rec aux ?xref =
416   function
417     | A.AttributedTerm (`Loc _, ast) -> aux ?xref ast
418     | A.AttributedTerm (`IdRef xref, ast) -> aux ~xref ast
419     | A.Symbol (name,_) -> 
420         let attr = make_std_attributes xref in
421         P.Mi (attr,name)
422     | A.Ident (name,subst) ->
423         let attr = make_std_attributes xref in
424         let rec make_subst =
425           (function 
426               [] -> []
427             | (n,a)::tl ->
428                 (aux a)::
429                 P.Mtext([],"/")::
430                 P.Mi([],n)::
431                 P.Mtext([],"; ")::
432                 P.smallskip::
433                 (make_subst tl)) in
434         let subst =
435           match subst with
436           | None -> []
437           | Some subst -> make_subst subst
438         in
439         (match subst with
440         | [] -> P.Mi (attr, name)
441         | _ ->
442             P.Mrow ([],
443               P.Mi (attr,name)::
444               P.Mtext([],"[")::
445               subst @
446               [(P.Mtext([],"]"))]))
447     | A.Meta (no,l) ->
448         let attr = make_attributes [Some "helm","xref"] [xref] in
449         let l' =
450          List.map
451           (function
452               None -> P.Mo([],"_")
453             | Some t -> aux t
454           ) l
455         in
456          P.Mrow ([],P.Mi (attr,"?" ^ string_of_int no) :: P.Mo ([],"[") ::
457            l' @ [P.Mo ([],"]")])
458     | A.Num (value, _) -> 
459         let attr = make_attributes [Some "helm","xref"] [xref] in
460         P.Mn (attr,value)
461     | A.Sort `Prop -> P.Mtext ([], "Prop")
462     | A.Sort `Set -> P.Mtext ([], "Set")
463     | A.Sort `Type -> P.Mtext ([], "Type")
464     | A.Sort `CProp -> P.Mtext ([], "CProp")
465     | A.Implicit -> P.Mtext([], "?")
466     | A.Appl [] -> assert false
467     | A.Appl ((hd::tl) as l) ->
468         let rec find_symbol idref = function
469           | A.AttributedTerm (`Loc _, t) -> find_symbol None t
470           | A.AttributedTerm (`IdRef id, t) -> find_symbol (Some id) t
471           | A.Symbol (name, _) ->
472               (match idref with
473               | None -> assert false
474               | Some idref -> `Symbol (name, idref))
475           | term ->
476               `None
477         in
478         let aattr = make_attributes [Some "helm","xref"] [xref] in
479         (match find_symbol None hd with
480         | `Symbol (name, sxref) ->
481             let sattr = make_std_attributes (Some sxref) in
482             (try 
483               (let f = Hashtbl.find symbol_table name in
484                f tl ~priority ~assoc ~ids_to_uris aattr sattr)
485             with Not_found ->
486               P.Mrow(aattr,
487               m_open_fence :: P.Mi(sattr,name)::(make_args tl) @
488               [m_close_fence]))
489         | `None ->
490             P.Mrow(aattr, m_open_fence :: (aux hd) :: (make_args tl) @
491             [m_close_fence]))
492     | A.Binder (`Pi, (Cic.Anonymous, Some ty), body)
493     | A.Binder (`Forall, (Cic.Anonymous, Some ty), body) ->
494         let attr = make_attributes [Some "helm","xref"] [xref] in
495         P.Mrow (attr, [
496           aux ty;
497           P.Mtext ([], map_tex true "to");
498           aux body])
499     | A.Binder (kind,var,body) ->
500         let attr = make_attributes [Some "helm","xref"] [xref] in
501         let binder = resolve_binder true kind in
502         let var = make_capture_variable var in
503         P.Mrow (attr, 
504            P.Mtext([None,"mathcolor","blue"],binder) :: var @ 
505            [P.Mo([],"."); aux body])
506     | A.LetIn (var,s,body) ->
507         let attr = make_attributes [Some "helm","xref"] [xref] in
508         P.Mrow (attr, 
509            P.Mtext([],("let ")) ::
510            (make_capture_variable var @
511            P.Mtext([],("="))::
512            (aux s)::
513            P.Mtext([]," in ")::
514            [aux body]))
515     | A.LetRec (_, defs, body) ->
516         let attr = make_attributes [Some "helm","xref"] [xref] in
517         let rec make_defs =
518           (function 
519                [] -> assert false
520              | [(var,body,_)] -> 
521                  make_capture_variable var @ [P.Mtext([],"=");(aux body)]
522              | (var,body,_)::tl -> 
523                  make_capture_variable var @
524                  (P.Mtext([],"=")::
525                   (aux body)::P.Mtext([]," and")::(make_defs tl))) in
526         P.Mrow (attr,  
527           P.Mtext([],("let rec "))::
528           (make_defs defs)@
529            (P.Mtext([]," in ")::
530            [aux body]))
531     | A.Case (arg,_,outtype,patterns) ->
532         (* TODO print outtype *)
533         let attr = make_attributes [Some "helm","xref"] [xref] in
534         let rec make_patterns =
535           (function 
536                [] -> []
537              | [(constr, vars),rhs] -> make_pattern constr vars rhs
538              | ((constr,vars), rhs)::tl -> 
539                  (make_pattern constr vars rhs)@(P.smallskip::
540                  P.Mtext([],"|")::P.smallskip::(make_patterns tl)))
541         and make_pattern constr vars rhs =           
542           let lhs = 
543             P.Mtext([], constr) ::
544               (List.concat
545                 (List.map (fun var -> P.smallskip :: make_capture_variable var)
546                   vars))
547           in
548           lhs @
549           [P.smallskip; P.Mtext([],map_tex true "to"); P.smallskip; aux rhs]
550         in
551         P.Mrow (attr,
552           P.Mtext([],"match")::P.smallskip::
553           (aux arg)::P.smallskip::
554           P.Mtext([],"with")::P.smallskip::
555           P.Mtext([],"[")::P.smallskip::
556           (make_patterns patterns)@(P.smallskip::[P.Mtext([],("]"))]))
557
558   and make_capture_variable (name, ty) =
559     let name =
560       match name with
561       | Cic.Anonymous -> [P.Mtext([], "_")]
562       | Cic.Name s -> [P.Mtext([], s)]
563     in
564     let ty =
565       match ty with
566       | None -> []
567       | Some ty -> [P.Mtext([],":"); aux ty]
568     in
569     name @ ty
570
571   and make_args ?(priority = 0) ?(assoc = false) =
572     function
573         [] -> []
574       | a::tl -> P.smallskip::(aux a)::(make_args tl)
575
576   in
577   aux ast
578 ;;
579
580 let box_prefix = "b";;
581
582 let add_xml_declaration stream =
583   [<
584     Xml.xml_cdata "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n" ;
585     Xml.xml_cdata "\n";
586     Xml.xml_nempty ~prefix:box_prefix "box"
587       [ Some "xmlns","m","http://www.w3.org/1998/Math/MathML" ;
588         Some "xmlns","b","http://helm.cs.unibo.it/2003/BoxML" ;
589         Some "xmlns","helm","http://www.cs.unibo.it/helm" ;
590         Some "xmlns","xlink","http://www.w3.org/1999/xlink"
591       ] stream
592   >]
593
594 let ast2mpresXml ((ast, ids_to_uris) as arg) =
595   let astBox = ast2astBox arg in
596   let smallAst2mpresXml ast =
597     P.print_mpres (ast2mpres (ast, ids_to_uris))
598   in
599   (Box.box2xml ~obj2xml:smallAst2mpresXml astBox)
600
601 let b_open_fence = Box.b_text [] "("
602 let b_close_fence = Box.b_text [] ")"
603 let b_v_with_fences attrs a b op =
604   Box.b_h attrs [
605     b_open_fence;
606     Box.b_v [] [
607       a;
608       Box.b_h [] [ op; b ]
609     ];
610     b_close_fence
611   ]
612 let b_v_without_fences attrs a b op =
613   Box.b_v attrs [
614     a;
615     Box.b_h [] [ op; b ]
616   ]
617
618 let _ = (** fill symbol_table *)
619   let binary f = function [a;b] -> f a b | _ -> assert false in
620   let unary f = function [a] -> f a | _ -> assert false in
621   let add_binary_op name threshold ?(assoc=`Left) symbol =
622     let assoc = match assoc with `Left -> true | `Right -> false in
623     Hashtbl.add symbol_table name (binary
624       (fun a b ~priority ~assoc ~ids_to_uris aattr sattr ->
625         let symbol =
626           match symbol with
627           | `Symbol name -> map_tex true name
628           | `Ascii s -> s
629         in
630          if (priority > threshold) || (priority = threshold && assoc) then
631            m_row_with_fences aattr
632              (ast2mpres ~priority:threshold ~assoc (a, ids_to_uris))
633              (ast2mpres ~priority:threshold ~assoc:(not assoc) (b, ids_to_uris))
634              (P.Mo(sattr,symbol))
635          else 
636            m_row aattr
637              (ast2mpres ~priority:threshold ~assoc (a, ids_to_uris))
638              (ast2mpres ~priority:threshold ~assoc:(not assoc) (b, ids_to_uris))
639              (P.Mo(sattr,symbol))));
640     Hashtbl.add symbol_table_charcount name (binary
641       (fun a b ~unicode ~priority ~assoc ~tail ~ids_to_uris aattr sattr ->
642         let symbol =
643           match symbol with
644           | `Symbol name -> map_tex unicode name
645           | `Ascii s -> s
646         in
647
648          if (priority > threshold) || (priority = threshold && assoc) then
649            b_v_with_fences aattr
650              (ast2astBox ~priority:threshold ~assoc ~tail:[] (a, ids_to_uris))
651              (ast2astBox ~priority:threshold ~assoc:(not assoc) ~tail
652               (b, ids_to_uris))
653              (Box.Text(sattr,symbol))
654          else 
655            b_v_without_fences aattr
656              (ast2astBox ~priority:threshold ~assoc ~tail:[] (a, ids_to_uris))
657              (ast2astBox ~priority:threshold ~assoc:(not assoc) ~tail
658               (b, ids_to_uris))
659              (Box.Text(sattr,symbol))))
660   in
661   Hashtbl.add symbol_table "not" (unary
662     (fun a ~priority ~assoc ~ids_to_uris attr sattr ->
663        (P.Mrow([], [
664          m_open_fence; P.Mo([],map_tex true "lnot");
665          ast2mpres (a, ids_to_uris); m_close_fence]))));
666   Hashtbl.add symbol_table "inv" (unary
667     (fun a ~priority ~assoc ~ids_to_uris attr sattr ->
668       P.Msup([],
669         P.Mrow([],[ m_open_fence; ast2mpres (a, ids_to_uris); m_close_fence]),
670         P.Mrow([],[ P.Mo([],"-"); P.Mn([],"1")]))));
671   Hashtbl.add symbol_table "opp" (unary
672     (fun a ~priority ~assoc ~ids_to_uris attr sattr ->
673       P.Mrow([],[
674         P.Mo([],"-");
675         m_open_fence;
676         ast2mpres (a, ids_to_uris);
677         m_close_fence])));
678   add_binary_op "arrow" 5 ~assoc:`Right (`Symbol "to");
679   add_binary_op "eq" 40 (`Ascii "=");
680   add_binary_op "and" 20 (`Symbol "land");
681   add_binary_op "or" 10 (`Symbol "lor");
682   add_binary_op "iff" 5 (`Symbol "iff");
683   add_binary_op "leq" 40 (`Symbol "leq");
684   add_binary_op "lt" 40 (`Symbol "lt");
685   add_binary_op "geq" 40 (`Symbol "geq");
686   add_binary_op "gt" 40 (`Symbol "gt");
687   add_binary_op "plus" 60 (`Ascii "+");
688   add_binary_op "times" 70 (`Ascii "*");
689   add_binary_op "minus" 60 (`Ascii "-");
690   add_binary_op "div" 60 (`Ascii "/");
691