Skip to content

Commit e5a52de

Browse files
[aslspec] prose generation
1 parent 4ae8ec3 commit e5a52de

File tree

13 files changed

+486
-148
lines changed

13 files changed

+486
-148
lines changed

asllib/aslspec/builtins.spec

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
1-
operator cond_case[T](Bool, T) -> T
1+
operator cond_case[T](c: Bool, r: T) -> T
22
{
33
math_macro = \condcase,
44
custom = true,
5+
prose_application = "if {c} holds then {r}",
56
};
67

78
// TODO: add a custom rendering where all conditions
89
// and all values are properly aligned.
910
// Perhaps this can be achieved by adding a raw attribute to macros, which doesn't wrap them with braces.
1011
// TODO: add custom syntac for cases.
11-
variadic operator cond_op[T](list1(T)) -> T
12+
variadic operator cond_op[T](cases: list1(T)) -> T
1213
{
1314
math_macro = \condop,
1415
custom = true,
16+
prose_application = "{cases}",
1517
};
1618

17-
constant bot { "bottom", math_macro = \bot };
19+
constant bot { "the bottom value", math_macro = \bot };
1820

1921
constant None { "the empty \optionalterm{}" };
2022

@@ -74,39 +76,45 @@ operator some[T](T) -> option(T)
7476
operator assign[T](lhs: T, rhs: T) -> Bool
7577
{
7678
math_macro = \eqdef,
79+
prose_application = "define {lhs} as {rhs}",
7780
};
7881

7982
operator reverse_assign[T](lhs: T, rhs: T) -> Bool
8083
{
81-
math_macro = \eqname,
84+
math_macro = \reverseeqdef,
85+
prose_application = "{lhs} is {rhs}",
8286
};
8387

8488
operator equal[T](a: T, b: T) -> (c: Bool)
8589
{
8690
math_macro = \equal,
87-
prose_application = "equating {a} to {b} yields {c}",
91+
prose_application = "{a} is equal to {b}",
8892
};
8993

90-
operator not_equal[T](T, T) -> Bool
94+
operator not_equal[T](a: T, b: T) -> Bool
9195
{
9296
math_macro = \notequal,
97+
prose_application = "{a} is not equal to {b}",
9398
};
9499

95-
operator if_then_else[T](Bool, T, T) -> T
100+
operator if_then_else[T](c: Bool, r_true: T, r_false: T) -> T
96101
{
97102
math_macro = \ifthenelseop,
103+
prose_application = "if {c} then {r_true} else {r_false}"
98104
};
99105

100-
variadic operator and(list1(Bool)) -> Bool
106+
variadic operator and(conjuncts: list1(Bool)) -> Bool
101107
{
102108
associative = true,
103109
math_macro = \land,
110+
prose_application = "all of the following hold: {conjuncts}"
104111
};
105112

106-
variadic operator or(list1(Bool)) -> Bool
113+
variadic operator or(disjuncts: list1(Bool)) -> Bool
107114
{
108115
associative = true,
109116
math_macro = \lor,
117+
prose_application = "one of the following holds: {disjuncts}"
110118
};
111119

112120
operator list_and(list0(Bool)) -> Bool
@@ -119,16 +127,18 @@ operator list_or(list0(Bool)) -> Bool
119127
math_macro = \listor,
120128
};
121129

122-
operator not(Bool) -> Bool
130+
operator not(b: Bool) -> Bool
123131
{
124132
math_macro = \opnot,
133+
prose_application = "the logical negation of {b}",
125134
};
126135

127136
// This is negation, specialized to a single variable to allow
128137
// the macro to drop the parenthesis around the variable.
129-
operator not_single(Bool) -> Bool
138+
operator not_single(b: Bool) -> Bool
130139
{
131140
math_macro = \opnotvar,
141+
prose_application = "the logical negation of {b}",
132142
};
133143

134144
operator iff(Bool, Bool) -> Bool
@@ -141,15 +151,17 @@ operator implies(Bool, Bool) -> Bool
141151
math_macro = \implies,
142152
};
143153

144-
variadic operator num_plus[NumType](list1(NumType)) -> NumType
154+
variadic operator num_plus[NumType](addends: list1(NumType)) -> NumType
145155
{
146156
associative = true,
147157
math_macro = \numplus,
158+
prose_application = "the addition of {addends}"
148159
};
149160

150-
operator num_minus[NumType](NumType, NumType) -> NumType
161+
operator num_minus[NumType](a: NumType, b: NumType) -> NumType
151162
{
152163
math_macro = \numminus,
164+
prose_application = "{a} minus {b}",
153165
};
154166

155167
operator num_negate[NumType](NumType) -> NumType
@@ -158,9 +170,10 @@ operator num_negate[NumType](NumType) -> NumType
158170
};
159171

160172
// Negation for number types.
161-
operator negate[NumType](NumType) -> NumType
173+
operator negate[NumType](n: NumType) -> NumType
162174
{
163175
math_macro = \negate,
176+
prose_application = "the negation of {n}"
164177
};
165178

166179
variadic operator num_times[NumType](list1(NumType)) -> NumType

asllib/aslspec/latex.ml

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
open Format
44
open AST
55
open LayoutUtils
6+
module StringMap = Map.Make (String)
67

78
let regex_underscore = Str.regexp_string "_"
89
let regexp_spaces_segment = Str.regexp "[ \t]+"
@@ -72,12 +73,27 @@ let elem_name_to_math_macro elem_name =
7273
let pp_comma = fun fmt () -> fprintf fmt ", "
7374
let pp_noop = fun _fmt () -> ()
7475

76+
let substitute template bindings =
77+
let substitutions_map =
78+
List.fold_left
79+
(fun acc_map (var_str, replacement) ->
80+
let template_var = spec_var_to_template_var var_str in
81+
StringMap.add template_var replacement acc_map)
82+
StringMap.empty bindings
83+
in
84+
let template_var_regexp = Str.regexp "{[a-zA-Z0-9_']+}" in
85+
Utils.string_replace_all template_var_regexp
86+
(fun var ->
87+
match StringMap.find_opt var substitutions_map with
88+
| Some replacement -> replacement
89+
| None -> var)
90+
template
91+
7592
(** [substitute_spec_vars_by_latex_vars math_mode s vars] returns a string [s]
7693
with every instance of [{my_var}] substituted by [\texttt{my\_var}]. If
7794
[math_mode] is true [{my_var}] is substituted by [$\texttt{my\_var}$]. This
7895
makes the returned string suitable to typesetting with LaTeX. *)
7996
let substitute_spec_vars_by_latex_vars ~math_mode str vars =
80-
let module StringMap = Map.Make (String) in
8197
(* Create a map from template variables to LaTeX variables
8298
to make replacement efficient. *)
8399
let substitutions_map =
@@ -282,3 +298,13 @@ let pp_fields pp_field_name pp_field_value fmt (fields, layout) =
282298
(PP.pp_sep_list ~sep:", " pp_field)
283299
fmt fields_values_with_layouts
284300
| Unspecified -> assert false
301+
302+
(** [pp_itemized_list pp_elem fmt elements] formats a LaTeX itemized list of
303+
[elements], where each element is formatted using [pp_elem]. *)
304+
let pp_itemized_list pp_elem fmt elements =
305+
let pp_item pp_elem fmt element = fprintf fmt "\\item %a" pp_elem element in
306+
fprintf fmt "@[<v>\\begin{itemize}@;<0 2>%a@;<0 0>\\end{itemize}@]"
307+
(pp_print_list
308+
~pp_sep:(fun fmt () -> fprintf fmt "@;<0 2>")
309+
(pp_item pp_elem))
310+
elements

0 commit comments

Comments
 (0)