|
1
|
(*
|
|
2
|
* ENIAM_LCGparser, a parser for Logical Categorial Grammar formalism
|
|
3
4
5
|
* Copyright (C) 2016 Wojciech Jaworski <wjaworski atSPAMfree mimuw dot edu dot pl>
* Copyright (C) 2016 Institute of Computer Science Polish Academy of Sciences
*
|
|
6
7
|
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
|
|
8
9
10
|
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
|
|
11
|
* This library is distributed in the hope that it will be useful,
|
|
12
13
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
* GNU Lesser General Public License for more details.
|
|
15
|
*
|
|
16
|
* You should have received a copy of the GNU Lesser General Public License
|
|
17
18
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*)
|
|
19
|
|
|
20
|
open ENIAM_LCGtypes
|
|
21
22
|
open Xstd
open Printf
|
|
23
|
|
|
24
25
26
27
|
let type_term s = "\\text{" ^ s ^ "}"
let rec first_digit_index v n i =
if i = n then n else
|
|
28
|
if String.get v i >= '0' && String.get v i <= '9' then i
|
|
29
30
31
32
33
34
|
else first_digit_index v n (i+1)
let variable v =
let n = String.length v in
let i = first_digit_index v n 0 in
if n = i then v else
|
|
35
|
String.sub v 0 i ^ "_{" ^ String.sub v i (n-i) ^ "}"
|
|
36
37
38
39
|
let pred_name = function
"name_token" -> "name\\_token"
| s -> s
|
|
40
|
|
|
41
42
43
|
let rec linear_term c = function
Var v -> variable v
| Tuple l ->
|
|
44
45
46
47
|
let l = Xlist.map l (linear_term 2) in
let n = Xlist.fold l 0 (fun n s -> String.length s + n) in
let s =
if n < 100 then String.concat "\\otimes " l else
|
|
48
|
let s = String.concat "\\otimes\\\\ {}" l in
|
|
49
|
"\\begin{array}{l}" ^ s ^ "\\end{array}" in
|
|
50
51
|
if c > 1 then "(" ^ s ^ ")" else s
(* | LetIn(l,s,t) -> "{\\bf let } " ^ String.concat "\\otimes " (Xlist.map l variable) ^ " = " ^ (linear_term 0 s) ^ " \\text{ {\\bf in }} " ^ (linear_term 0 t) *)
|
|
52
53
|
| Variant(e,l) -> "\\langle " ^ String.concat ","(*"$,\\\\$"*) (Xlist.map l (fun (i,t) -> e^i^": "^linear_term 0 t)) ^ "\\rangle"
| VariantVar(v,t) -> "\\langle " ^ linear_term 0 t ^ "\\rangle_\\text{" ^ v ^ "}"
|
|
54
|
(* | Proj(n,t) -> "\\pi_" ^ (string_of_int n) ^ (linear_term c t) *)
|
|
55
56
57
58
|
| ProjVar(v,t) -> "\\pi_{" ^ variable v ^ "}" ^ (linear_term c t)
| SubstVar v -> variable v
| Subst(s,v,t) -> "{\\bf subst}(" ^ (linear_term 0 s) ^ "," ^ variable v ^ "," ^ (linear_term 0 t) ^ ")"
| Inj(n,t) -> "{\\bf inj}_{" ^ (string_of_int n) ^ "}" ^ (linear_term c t)
|
|
59
|
| Case(t,l) -> "{\\bf case}\\; " ^ (linear_term 0 t) ^ " \\;{\\bf of}\\; " ^
|
|
60
|
(String.concat " | " (Xlist.map l (fun (v,t) -> variable v ^ " \\to " ^ (linear_term 0 t))))
|
|
61
62
|
| Lambda(v,t) -> "\\lambda " ^ variable v ^ "." ^ (linear_term c t)
| LambdaSet(l,t) -> "\\lambda " ^ (String.concat "," (Xlist.map l variable)) ^ "." ^ (linear_term c t)
|
|
63
|
| LambdaRot(n,t) -> "{\\bf rot}_{" ^ (string_of_int n) ^ "}" ^ (linear_term c t)
|
|
64
65
|
| App(s,t) -> "\\big((" ^ (linear_term 0 s) ^ ")(" ^ (linear_term 0 t) ^ ")\\big)"
| Dot -> "\\bullet"
|
|
66
67
|
| Val s -> "\\text{" ^ Xlatex.escape_string s ^ "}"
| SetAttr(e,s,t) -> "{\\bf setattr}(\\text{{\\sc " ^ Xlatex.escape_string e ^ "}}," ^ linear_term 0 s ^ "," ^ linear_term 0 t ^ ")"
|
|
68
69
70
71
|
| Fix(s,t) -> "{\\bf fix}(" ^ linear_term 0 s ^ "," ^ linear_term 0 t ^ ")"
| Empty t -> "{\\bf empty}(" ^ linear_term 0 t ^ ")"
| Apply t -> "{\\bf apply}(" ^ linear_term 0 t ^ ")"
| Insert(s,t) -> "{\\bf insert}(" ^ linear_term 0 s ^ "," ^ linear_term 0 t ^ ")"
|
|
72
|
| Node t ->
|
|
73
|
"{\\left[\\begin{array}{ll}" ^
|
|
74
|
(String.concat "\\\\ " (Xlist.map (["ORTH",Val t.orth;"LEMMA",Val t.lemma;"POS",Val t.pos;"ID",Val (string_of_int t.id);
|
|
75
76
77
78
79
|
"WEIGHT",Val (string_of_float t.weight);"SYMBOL",t.symbol;
"ARG_SYMBOL",t.arg_symbol;"ARGS",t.args] @ t.attrs) (fun (e,t) ->
"\\text{" ^ (Xlatex.escape_string e) ^ "} & " ^ (linear_term 0 t)))) ^ "\\end{array}\\right]}"
(* | Morf m -> "\\text{" ^ Xlatex.escape_string (ENIAMwalStringOf.morf m) ^ "}"
| Gf s -> "\\text{" ^ Xlatex.escape_string (ENIAMwalStringOf.gf s) ^ "}" *)
|
|
80
81
|
| Ref i -> "{\\bf ref}\\; " ^ string_of_int i
| Cut t -> "{\\bf cut}(" ^ linear_term 0 t ^ ")"
|
|
82
|
(* | Choice choices -> "{\\bf choice}(" ^ String.concat ";" (StringMap.fold choices [] (fun l ei t -> (sprintf "%s: %s" ei (linear_term 0 t)) :: l)) ^ ")"
|
|
83
|
| Concept c ->
|
|
84
85
86
87
88
89
|
"{\\left[\\begin{array}{ll}" ^
(String.concat "\\\\ " (Xlist.map ([
"SENSE",c.c_sense;"NAME",c.c_name;
"VARIABLE",Val (fst c.c_variable ^ "_" ^ snd c.c_variable);"POS",Val (string_of_int c.c_pos);
"QUANT",c.c_quant;"LOCAL-QUANT",if c.c_local_quant then Val "+" else Val "-";"RELATIONS",c.c_relations]) (fun (e,t) ->
"\\text{" ^ (Xlatex.escape_string e) ^ "} & " ^ (linear_term 0 t)))) ^ "\\end{array}\\right]}"
|
|
90
|
| Context c ->
|
|
91
92
93
94
95
96
|
"{\\left[\\begin{array}{ll}" ^
(String.concat "\\\\ " (Xlist.map ([
"SENSE",c.cx_sense;
"VARIABLE",Val (fst c.cx_variable ^ "_" ^ snd c.cx_variable);"POS",Val (string_of_int c.cx_pos);
"RELATIONS",c.cx_relations;"CONTENTS",c.cx_contents]) (fun (e,t) ->
"\\text{" ^ (Xlatex.escape_string e) ^ "} & " ^ (linear_term 0 t)))) ^ "\\end{array}\\right]}"
|
|
97
98
99
100
101
|
| Relation(r,a,c) -> "{\\bf relation}(" ^ linear_term 0 r ^ "," ^ linear_term 0 a ^ "," ^ linear_term 0 c ^ ")"
| RevRelation(r,a,c) -> "{\\bf revrelation}(" ^ linear_term 0 r ^ "," ^ linear_term 0 a ^ "," ^ linear_term 0 c ^ ")"
| SingleRelation r -> "{\\bf singlerelation}(" ^ linear_term 0 r ^ ")"
| AddRelation(t,r,a,s) -> "{\\bf addrelation}(" ^ linear_term 0 t ^ "," ^ r ^ "," ^ a ^ "," ^ linear_term 0 s ^ ")"
| RemoveRelation r -> "{\\bf removerelation}(" ^ linear_term 0 r ^ ")"
|
|
102
|
| SetContextName(s,t) -> "{\\bf setcontextname}(" ^ s ^ "," ^ linear_term 0 t ^ ")" *)
|
|
103
104
105
|
let rec linear_term_simple c = function
Var v -> variable v
|
|
106
|
| Tuple l ->
|
|
107
108
109
110
|
let s = String.concat "\\otimes " (Xlist.map l (linear_term_simple 2)) in
if c > 1 then "(" ^ s ^ ")" else s
(* | LetIn(l,s,t) -> "\\;$\\\\\n${\\bf let } " ^ String.concat "\\otimes " (Xlist.map l variable) ^ " = " ^ (linear_term_simple 0 s) ^ " \\text{ {\\bf in }} " ^ (linear_term_simple 0 t) *)
(* | Triple(t1,t2,t3) -> "\\{" ^ linear_term_simple 0 t1 ^ "," ^ linear_term_simple 0 t2 ^ "," ^ linear_term_simple 0 t3 ^ "\\}" *)
|
|
111
112
|
| Variant(e,l) -> "\\langle " ^ String.concat "," (Xlist.map l (fun (i,t) -> e^i^": "^linear_term_simple 0 t)) ^ "\\rangle"
| VariantVar(v,t) -> "\\langle " ^ linear_term_simple 0 t ^ "\\rangle_\\text{" ^ v ^ "}"
|
|
113
|
(* | Proj(n,t) -> "\\pi_" ^ (string_of_int n) ^ (linear_term_simple c t) *)
|
|
114
115
116
117
|
| ProjVar(v,t) -> "\\pi_{" ^ variable v ^ "}" ^ (linear_term_simple c t)
| SubstVar v -> variable v
| Subst(s,v,t) -> "{\\bf subst}(" ^ (linear_term_simple 0 s) ^ "," ^ variable v ^ "," ^ (linear_term_simple 0 t) ^ ")"
| Inj(n,t) -> "{\\bf inj}_" ^ (string_of_int n) ^ (linear_term_simple c t)
|
|
118
|
| Case(t,l) -> "{\\bf case}\\; " ^ (linear_term_simple 0 t) ^ " \\;{\\bf of}\\; " ^
|
|
119
|
(String.concat " | " (Xlist.map l (fun (v,t) -> variable v ^ " \\to " ^ (linear_term_simple 0 t))))
|
|
120
121
|
| Lambda(v,t) -> "\\lambda " ^ variable v ^ "." ^ (linear_term_simple c t)
| LambdaSet(l,t) -> "\\lambda " ^ (String.concat "," (Xlist.map l variable)) ^ "." ^ (linear_term_simple c t)
|
|
122
|
| LambdaRot(n,t) -> "{\\bf rot}_{" ^ (string_of_int n) ^ "}" ^ (linear_term_simple c t)
|
|
123
124
|
| App(s,t) -> "\\big((" ^ (linear_term_simple 0 s) ^ ")(" ^ (linear_term_simple 0 t) ^ ")\\big)"
| Dot -> "\\bullet"
|
|
125
126
|
| Val s -> "\\text{" ^ Xlatex.escape_string s ^ "}"
| SetAttr(e,s,t) -> "{\\bf setattr}(\\text{{\\sc " ^ Xlatex.escape_string e ^ "}}," ^ linear_term_simple 0 s ^ "," ^ linear_term_simple 0 t ^ ")"
|
|
127
128
129
130
131
|
| Fix(s,t) -> "{\\bf fix}(" ^ linear_term_simple 0 s ^ "," ^ linear_term_simple 0 t ^ ")"
| Empty t -> "{\\bf empty}(" ^ linear_term_simple 0 t ^ ")"
| Apply t -> "{\\bf apply}(" ^ linear_term_simple 0 t ^ ")"
| Insert(s,t) -> "{\\bf insert}(" ^ linear_term_simple 0 s ^ "," ^ linear_term_simple 0 t ^ ")"
| Node _ -> "node"
|
|
132
133
|
(* | Morf m -> "\\text{" ^ Xlatex.escape_string (ENIAMwalStringOf.morf m) ^ "}"
| Gf s -> "\\text{" ^ Xlatex.escape_string (ENIAMwalStringOf.gf s) ^ "}" *)
|
|
134
135
|
| Ref i -> "{\\bf ref}\\; " ^ string_of_int i
| Cut t -> "{\\bf cut}(" ^ linear_term_simple 0 t ^ ")"
|
|
136
|
(* | Choice choices -> "{\\bf choice}(" ^ String.concat ";" (StringMap.fold choices [] (fun l ei t -> (sprintf "%s: %s" ei (linear_term_simple 0 t)) :: l)) ^ ")"
|
|
137
|
| Concept c ->
|
|
138
139
140
141
142
143
|
"{\\left[\\begin{array}{ll}" ^
(String.concat "\\\\ " (Xlist.map ([
"SENSE",c.c_sense;"NAME",c.c_name;
"VARIABLE",Val (fst c.c_variable ^ "_" ^ snd c.c_variable);"POS",Val (string_of_int c.c_pos);
"QUANT",c.c_quant;"LOCAL-QUANT",if c.c_local_quant then Val "+" else Val "-";"RELATIONS",c.c_relations]) (fun (e,t) ->
"\\text{" ^ (Xlatex.escape_string e) ^ "} & " ^ (linear_term_simple 0 t)))) ^ "\\end{array}\\right]}"
|
|
144
|
| Context c ->
|
|
145
146
147
148
149
150
|
"{\\left[\\begin{array}{ll}" ^
(String.concat "\\\\ " (Xlist.map ([
"SENSE",c.cx_sense;
"VARIABLE",Val (fst c.cx_variable ^ "_" ^ snd c.cx_variable);"POS",Val (string_of_int c.cx_pos);
"RELATIONS",c.cx_relations;"CONTENTS",c.cx_contents]) (fun (e,t) ->
"\\text{" ^ (Xlatex.escape_string e) ^ "} & " ^ (linear_term_simple 0 t)))) ^ "\\end{array}\\right]}"
|
|
151
152
153
154
155
|
| Relation(r,a,c) -> "{\\bf relation}(" ^ linear_term_simple 0 r ^ "," ^ linear_term_simple 0 a ^ "," ^ linear_term_simple 0 c ^ ")"
| RevRelation(r,a,c) -> "{\\bf revrelation}(" ^ linear_term_simple 0 r ^ "," ^ linear_term_simple 0 a ^ "," ^ linear_term_simple 0 c ^ ")"
| SingleRelation r -> "{\\bf singlerelation}(" ^ linear_term_simple 0 r ^ ")"
| AddRelation(t,r,a,s) -> "{\\bf addrelation}(" ^ linear_term_simple 0 t ^ "," ^ r ^ "," ^ a ^ "," ^ linear_term_simple 0 s ^ ")"
| RemoveRelation r -> "{\\bf removerelation}(" ^ linear_term_simple 0 r ^ ")"
|
|
156
|
| SetContextName(s,t) -> "{\\bf setcontextname}(" ^ s ^ "," ^ linear_term_simple 0 t ^ ")" *)
|
|
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
|
let direction = function
Forward -> "/"
| Backward -> "\\backslash"
| Both -> "|"
let atom = function
"m1" -> "\\text{m}_1"
| "m2" -> "\\text{m}_2"
| "m3" -> "\\text{m}_3"
| "n1" -> "\\text{n}_1"
| "n2" -> "\\text{n}_2"
| "f" -> "\\text{f}"
| "p1" -> "\\text{p}_1"
| "p2" -> "\\text{p}_2"
| "p3" -> "\\text{p}_3"
|
|
173
|
| s -> "\\text{" ^ Xlatex.escape_string s ^ "}"
|
|
174
|
|
|
175
176
177
|
let rec internal_grammar_symbol c = function
Atom x -> atom x
| AVar x -> " " ^ x
|
|
178
|
| With l ->
|
|
179
180
|
let s = String.concat "\\with" (Xlist.map l (internal_grammar_symbol 2)) in
if c > 1 then "(" ^ s ^ ")" else s
|
|
181
182
183
184
|
| Zero -> "0"
| Top -> "\\top"
let rec grammar_symbol c = function
|
|
185
|
Tensor l ->
|
|
186
187
|
let s = String.concat "\\otimes" (Xlist.map l (internal_grammar_symbol 2)) in
if c > 1 then "(" ^ s ^ ")" else s
|
|
188
|
| Plus l ->
|
|
189
190
|
let s = String.concat "\\oplus" (Xlist.map l (grammar_symbol 2)) in
if c > 1 then "(" ^ s ^ ")" else s
|
|
191
192
|
| Imp(s,d,t) -> "(" ^ (grammar_symbol 2 s) ^ "\\\\ \\hspace{1cm}" ^ direction d ^ (grammar_symbol 2 t) ^ ")"
| One -> "1"
|
|
193
|
| ImpSet(s,l) ->
|
|
194
195
|
let s = (grammar_symbol 1 s) ^ "\\{" ^ String.concat "\n," (Xlist.map l (fun (d,a) -> "\\\\ \\hspace{1cm}" ^ direction d ^ grammar_symbol 1 a)) ^ "\\}" in
if c > 0 then "(" ^ s ^ ")" else s
|
|
196
|
| WithVar(v,s,e,t) -> "\\bigwith_{" ^ e ^ ":" ^ v ^ ":=" ^ (internal_grammar_symbol 2 s) ^ "} \\\\ " ^ (grammar_symbol 2 t)
|
|
197
|
| Star s -> grammar_symbol 2 s ^ "^\\star"
|
|
198
|
| Bracket(lf,rf,s) -> "\\langle " ^ (if lf then "\\langle " else "") ^ (grammar_symbol 0 s) ^ "\\rangle" ^ (if rf then "\\rangle " else "")
|
|
199
200
201
|
| BracketSet d -> "{\\bf BracketSet}(" ^ direction d ^ ")"
| Maybe s -> "?" ^ grammar_symbol 2 s
|
|
202
|
let chart page g =
|
|
203
204
205
206
207
208
|
let layers = ENIAM_LCGchart.fold g IntMap.empty (fun layers (symbol,node1,node2,sem,layer) ->
let nodes = try IntMap.find layers layer with Not_found -> IntMap.empty in
let content = node2, grammar_symbol 0 symbol, linear_term 0 sem in
(* let nodes = IntMap.add_inc nodes node1 (node2,[content]) (fun (n,l) -> if n <> node2 then failwith "to_latex" else n, content :: l) in *)
let nodes = IntMap.add_inc nodes node1 [content] (fun l -> content :: l) in
IntMap.add layers layer nodes) in
|
|
209
|
let n = match page with "a4" -> "10" | "a1" -> "40" | _ -> "20" in
|
|
210
|
"\\begin{longtable}{|l|l|l|p{" ^ n ^ "cm}|}\n\\hline\n" ^
|
|
211
|
String.concat "" (List.rev (IntMap.fold layers [] (fun l layer nodes ->
|
|
212
213
214
|
IntMap.fold nodes l (fun l node1 contents ->
Xlist.fold contents l (fun l (node2,symbol,sem) ->
(Printf.sprintf "%d & %d--%d & $\\begin{array}{l}%s\\end{array}$ & $%s$\\\\\n\\hline\n" layer node1 node2 symbol sem) :: l))))) ^
|
|
215
|
"\\end{longtable}"
|
|
216
|
|
|
217
218
219
220
221
222
|
let print_chart path name page g =
Xlatex.latex_file_out path name page false (fun file ->
Printf.fprintf file "%s\n" (chart page g));
Xlatex.latex_compile_and_clean path name
|
|
223
|
let table_entries_of_symbol_term_list l =
|
|
224
|
String.concat "" (Xlist.rev_map l (fun (symbol,sem) ->
|
|
225
226
227
|
let symbol = grammar_symbol 0 symbol in
let sem = linear_term 0 sem in
Printf.sprintf "$\\begin{array}{l}%s\\end{array}$ & $%s$\\\\\n\\hline\n" symbol sem))
|
|
228
229
230
|
let parsed_dep_chart l =
if l = [] then "empty" else
|
|
231
232
233
|
"\\begin{longtable}{|l|p{20cm}|}\n\\hline\n" ^
table_entries_of_symbol_term_list l ^
"\\end{longtable}"
|
|
234
235
|
let not_parsed_dep_chart (id,left,l,right) =
|
|
236
|
Printf.sprintf "conll\\_id=%d\\\\" id ^
|
|
237
238
239
240
241
242
|
"\\begin{longtable}{|l|p{20cm}|}\n\\hline\n" ^
String.concat "\\hline\n" (Xlist.map left table_entries_of_symbol_term_list) ^
"\\hline\n\\hline\n\\hline\n" ^
table_entries_of_symbol_term_list l ^
"\\hline\n\\hline\n\\hline\n" ^
String.concat "\\hline\n" (Xlist.map right table_entries_of_symbol_term_list) ^
|
|
243
244
|
"\\end{longtable}"
|
|
245
|
let rec dep_chart_rec (DepNode(id,left,l,right)) =
|
|
246
|
(* printf "dep_chart_rec: %d\n" id; *)
|
|
247
|
String.concat "" (Xlist.map left dep_chart_rec) ^
|
|
248
|
String.concat "" (Xlist.rev_map l (fun (symbol,sem) ->
|
|
249
250
251
|
let symbol = grammar_symbol 0 symbol in
let sem = linear_term 0 sem in
Printf.sprintf "%d & $\\begin{array}{l}%s\\end{array}$ & $%s$\\\\\n\\hline\n" id symbol sem)) ^
|
|
252
|
String.concat "" (Xlist.map right dep_chart_rec)
|
|
253
|
|
|
254
|
let dep_chart graph =
|
|
255
|
"\\begin{longtable}{|l|l|p{20cm}|}\n\\hline\n" ^
|
|
256
|
dep_chart_rec graph ^
|
|
257
258
|
"\\end{longtable}"
|
|
259
260
|
let print_dependency_tree path name page dependency_tree =
Xlatex.latex_file_out path name page false (fun file ->
|
|
261
262
263
|
Int.iter 0 (Array.length dependency_tree - 1) (fun i ->
if dependency_tree.(i) <> Dot then Printf.fprintf file "{\\bf %d} $%s$\\\\\n" i (linear_term 0 dependency_tree.(i))));
Xlatex.latex_compile_and_clean path name
|
|
264
|
|
|
265
266
|
let print_references path name page references =
Xlatex.latex_file_out path name page false (fun file ->
|
|
267
268
269
|
Int.iter 0 (ExtArray.size references - 1) (fun i ->
if ExtArray.get references i <> Dot then Printf.fprintf file "{\\bf %d} $%s$\\\\\n" i (linear_term 0 (ExtArray.get references i))));
Xlatex.latex_compile_and_clean path name
|