-
Notifications
You must be signed in to change notification settings - Fork 0
/
toLatex.ml
149 lines (140 loc) · 4.27 KB
/
toLatex.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
(* translation of constraints to latex *)
module C = FixConstraint
module Su = Ast.Subst
open Misc.Ops
(* print linebreak after each connective in constraint *)
let c_linebreak = ref true
let q_mathit = Printf.sprintf "\\mathit{%s}"
let sort_to_latex s = Ast.Sort.to_string s |> q_mathit
let symbol_to_latex s =
Ast.Symbol.to_string s
|> Str.global_replace (Str.regexp "_") "\\_"
|> Str.global_replace (Str.regexp "#") "\\#" |> q_mathit
let constant_to_latex = Ast.Constant.to_string
let bop_to_latex = function
| Ast.Plus -> "+"
| Ast.Minus -> "-"
| Ast.Times -> ""
| Ast.Div -> "/"
let brel_to_latex = function
| Ast.Eq -> "="
| Ast.Ne -> "!="
| Ast.Gt -> ">"
| Ast.Ge -> "\\geq"
| Ast.Lt -> "<"
| Ast.Le -> "\\leq"
let bind_to_latex (s, t) =
Printf.sprintf "%s:%s" (symbol_to_latex s) (sort_to_latex t)
let rec expr_to_latex (e, _) =
match e with
| Ast.Con c -> constant_to_latex c
| Ast.Var s -> symbol_to_latex s
| Ast.App (s, es) ->
Printf.sprintf "%s([%s])"
(symbol_to_latex s) (List.map expr_to_latex es |> String.concat " ")
| Ast.Bin (e1, op, e2) ->
Printf.sprintf "(%s %s %s)"
(expr_to_latex e1) (bop_to_latex op) (expr_to_latex e2)
| Ast.Ite (ip, te, ee) ->
Printf.sprintf "%s ? %s : %s"
(pred_to_latex ip) (expr_to_latex te) (expr_to_latex ee)
| Ast.Fld (s, e) ->
Printf.sprintf "%s.%s" (expr_to_latex e) (symbol_to_latex s)
and pred_to_latex (p, _) =
match p with
| Ast.True -> "\\ltrue"
| Ast.False -> "\\lfalse"
| Ast.Bexp e -> expr_to_latex e
| Ast.Not p -> Printf.sprintf "\\neg (%s)" (pred_to_latex p)
| Ast.Imp (p1, p2) ->
Printf.sprintf "(%s \\limp %s)" (pred_to_latex p1) (pred_to_latex p2)
| Ast.And ps ->
if ps = [] then "\\ltrue" else
List.map pred_to_latex ps |> String.concat " \\land "
| Ast.Or ps ->
if ps = [] then "\\lfalse" else
List.map pred_to_latex ps |> String.concat " \\lor "
| Ast.Atom (e1, r, e2) ->
Printf.sprintf "(%s %s %s)"
(expr_to_latex e1) (brel_to_latex r) (expr_to_latex e2)
| Ast.Forall (qs,p) ->
Printf.sprintf "\\forall %s: %s"
(List.map bind_to_latex qs |> String.concat ", ") (pred_to_latex p)
let subst_to_latex (s, e) =
Printf.sprintf "[%s/%s]" (expr_to_latex e) (symbol_to_latex s)
let refa_to_latex refa =
match refa with
| C.Conc pred -> pred_to_latex pred
| C.Kvar (subs, sym) ->
Printf.sprintf "%s%s"
(symbol_to_latex sym)
(List.map subst_to_latex (Su.to_list subs) |> String.concat "")
let reft_to_latex (v, b, r) =
Printf.sprintf "\\{ %s:%s \\mid %s \\}"
(symbol_to_latex v) (sort_to_latex b)
(if r = [] then "\\ltrue" else
(List.map refa_to_latex r |> String.concat " \\land "))
let envt_to_latex envt =
if Ast.Symbol.SMap.is_empty envt then
"\\ltrue;\\ "
else
Ast.Symbol.SMap.fold
(fun sym reft sofar ->
Printf.sprintf "%s:%s;%s%s"
(symbol_to_latex sym) (reft_to_latex reft)
(if !c_linebreak then "\\\\\n" else "\\ ")
sofar) envt ""
let c_to_latex out c =
Printf.fprintf out
"\\begin{footnotesize}
\\begin{verbatim}
%s
\\end{verbatim}
\\end{footnotesize}
" (C.to_string c);
Printf.fprintf out
"\\begin{displaymath}
\\begin{array}[t]{l}
%s %s\\ \\deriv\\\\ %s\\ <:\\\\ %s\\qquad %s
\\end{array}
\\end{displaymath}
\\hrule
"
(C.env_of_t c |> envt_to_latex)
(C.grd_of_t c |> pred_to_latex)
(C.lhs_of_t c |> reft_to_latex)
(C.rhs_of_t c |> reft_to_latex)
(try string_of_int (C.id_of_t c) with _ -> "")
let wf_to_latex out wf =
Printf.fprintf out
"\\begin{displaymath}
\\begin{array}[t]{l}
%s\\ \\deriv\\ %s\\qquad %s
\\end{array}
\\end{displaymath}
\\hrule
"
(C.env_of_wf wf |> envt_to_latex)
(C.reft_of_wf wf |> reft_to_latex)
(try string_of_int (C.id_of_wf wf) with _ -> "")
let to_latex out cs ws =
print_endline "Translating to LaTeX.";
Printf.fprintf out
"\\documentclass[10pt]{llncs}
\\pagestyle{plain}
\\usepackage{amsmath}
\\newcommand{\\ltrue}{\\mathit{true}}
\\newcommand{\\lfalse}{\\mathit{false}}
\\newcommand{\\limp}{\\rightarrow}
\\newcommand{\\deriv}{\\vdash}
\\begin{document}
";
List.iter (c_to_latex out) cs;
List.iter (wf_to_latex out) ws;
Printf.fprintf out
"\\end{document}
%%%%%% Local Variables:
%%%%%% mode: latex
%%%%%% TeX-master: t
%%%%%% End:
"