package acgtk
Abstract Categorial Grammar development toolkit
Install
Dune Dependency
Authors
Maintainers
Sources
acg-2.1.0-20240219.tar.gz
sha512=5d380a947658fb1201895cb4cb449b1f60f54914c563e85181d628a89f045c1dd7b5b2226bb7865dd090f87caa9187e0ea6c7a4ee3dc3dda340d404c4e76c7c2
doc/src/acgtk.svg_rendering/show.ml.html
Source file show.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 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320
open Cairo open Diagram open UtilsLib open AcgData.Environment open AcgData.Signature open AcgData.Acg_lexicon open Logic.Abstract_syntax open Logic.Lambda.Lambda open Show_exts module Lambda_show (T : Show_text_sig) = struct open T let rec fix (f : ('a -> 'b) -> 'a -> 'b) : 'a -> 'b = fun x -> f (fix f) x let parenthesize_d ((d, b) : diagram * bool) : diagram = match b with true -> d | false -> hcat [ n "("; d; n ")" ] let term_to_diagram_open (recur_fn : term -> int -> int -> env * env -> consts -> diagram * bool) (t : term) (l_level : int) (level : int) ((l_env, env) : env * env) (id_to_sym : consts) : diagram * bool = let recurse t l_level level (l_env, env) = recur_fn t l_level level (l_env, env) id_to_sym in let d, b = match t with | Var i -> (n @@ List.assoc (level - 1 - i) env, true) | LVar i -> (n @@ List.assoc (l_level - 1 - i) l_env, true) | Const id | DConst id -> (n @@ snd @@ id_to_sym id, true) | Abs (x, t) -> let x' = generate_var_name x (l_env, env) in let vars, l, u = unfold_abs [ (level, x') ] (level + 1) (l_env, (level, x') :: env) t in ( hcat [ n "λ"; n @@ Utils.string_of_list " " snd @@ List.rev vars; n ". "; fst @@ recurse u l_level l (l_env, vars @ env); ], false ) | LAbs (x, t) -> let x' = generate_var_name x (l_env, env) in let vars, l, u = unfold_labs [ (l_level, x') ] (l_level + 1) ((l_level, x') :: l_env, env) t in ( hcat [ n "λᵒ"; n @@ Utils.string_of_list " " snd @@ List.rev vars; n ". "; fst @@ recurse u l level (vars @ l_env, env); ], false ) | App (((Const id | DConst id) as binder), Abs (x, u)) when is_binder id id_to_sym -> let x' = generate_var_name x (l_env, env) in let vars, l_l, l, u = unfold_binder id l_level (level + 1) id_to_sym [ (level, (x', Abstract_syntax.Non_linear)) ] (l_env, (level, x') :: env) u in let new_env = List.fold_right (fun (l, (x, abs)) (l_acc, acc) -> match abs with | Abstract_syntax.Non_linear -> (l_acc, (l, x) :: acc) | Abstract_syntax.Linear -> ((l, x) :: l_acc, acc)) vars (l_env, env) in ( hcat [ parenthesize_d @@ recurse binder l_l l new_env; n " "; n @@ Utils.string_of_list " " (snd >> fst) @@ List.rev vars; n ". "; fst @@ recurse u l_l l new_env; ], false ) | App (((Const id | DConst id) as binder), LAbs (x, u)) when is_binder id id_to_sym -> let x' = generate_var_name x (l_env, env) in let vars, l_l, l, u = unfold_binder id (l_level + 1) level id_to_sym [ (l_level, (x', Abstract_syntax.Linear)) ] ((l_level, x') :: l_env, env) u in let new_env = List.fold_right (fun (l, (x, abs)) (l_acc, acc) -> match abs with | Abstract_syntax.Non_linear -> (l_acc, (l, x) :: acc) | Abstract_syntax.Linear -> ((l, x) :: l_acc, acc)) vars (l_env, env) in ( hcat [ parenthesize_d @@ recurse binder l_l l new_env; n " "; n @@ Utils.string_of_list " " (snd >> fst) @@ List.rev vars; n ". "; fst @@ recurse u l_l l new_env; ], false ) | App (App (((Const id | DConst id) as op), t1), t2) when is_infix id id_to_sym -> ( hcat [ parenthesize_d @@ recurse t1 l_level level (l_env, env); n " "; parenthesize_d @@ recurse op l_level level (l_env, env); n " "; parenthesize_d @@ recurse t2 l_level level (l_env, env); ], false ) | App (t1, t2) -> let args, fn = unfold_app [ t2 ] t1 in ( hcat @@ [ parenthesize_d @@ recurse fn l_level level (l_env, env); n " "; ] @ Utils.intersperse (n " ") @@ List.map (fun x -> parenthesize_d @@ recurse x l_level level (l_env, env)) args, false ) | _ -> failwith "Not yet implemented" in (centerX d, b) let term_to_diagram (t : term) (id_to_sym : consts) : diagram = fst @@ fix term_to_diagram_open t 0 0 ([], []) id_to_sym end module Make (E : module type of Environment) (T : Show_text_sig) (C : Show_colors_sig) (Emb : Show_embellish_sig) = struct type signature = Data_Signature.t type lexicon = AcgData.Acg_lexicon.Data_Lexicon.t type term = Data_Signature.term type 'a tree = 'a Tree.t open T module L = Lambda_show (T) open L let replace_with_dict : (string * string) list -> string -> string = List.fold_right (fun (ugly, pretty) -> Str.global_replace (Str.regexp_string ugly) pretty) let type_to_diagram (sg : signature) (ty : stype) : diagram = Format.asprintf "%a" (Data_Signature.pp_type sg) ty |> replace_with_dict [ ("->", "⊸"); ("=>", "→") ] |> n [@@warning "-32"] let abstract_sig (lex : lexicon) : signature = fst @@ Data_Lexicon.get_sig lex let object_sig (lex : lexicon) : signature = snd @@ Data_Lexicon.get_sig lex let sig_name (sg : signature) : string = fst @@ Data_Signature.name sg let interpret_term (t : term) (lex : lexicon) : term = Data_Lexicon.interpret_term t lex |> normalize ~id_to_term:(fun i -> Data_Signature.unfold_term_definition i @@ object_sig lex) let rec term_to_graph (sg : signature) (t : term) : term tree = let children = match t with | Var _ | LVar _ | Const _ | DConst _ -> [] | Abs (_, body) | LAbs (_, body) -> [ body ] | App (App (((Const id | DConst id) as op), t1), t2) when is_infix id (Data_Signature.id_to_string sg) -> [ t1; op; t2 ] | App (fn, arg) -> [ fn; arg ] | _ -> failwith "Not yet implemented" in Tree.T (t, List.map (term_to_graph sg) children) let rec render_term_graph ?(non_linear = false) (l_level : int) (level : int) ((l_env, env) : env * env) (render_term : term -> int -> int -> env * env -> diagram) (Tree.T (term, children) : term tree) : diagram tree = let render_children_in l_level level (l_env, env) = List.map (render_term_graph ~non_linear l_level level (l_env, env) render_term) children in let children_d = match term with | LAbs (x, _) when not non_linear -> let x' = generate_var_name x (l_env, env) in let l_env' = (l_level, x') :: l_env in let l_level' = l_level + 1 in render_children_in l_level' level (l_env', env) | Abs (x, _) | LAbs (x, _) -> let x' = generate_var_name x (l_env, env) in let env' = (level, x') :: env in let level' = level + 1 in render_children_in l_level level' (l_env, env') | _ -> render_children_in l_level level (l_env, env) in Tree.T (render_term term l_level level (l_env, env), children_d) let term_to_diagram_in (config : Rendering_config.config) (sg : signature) (t : term) (l_level : int) (level : int) ((l_env, env) : env * env) : diagram = let ttd = term_to_diagram_open (* |> Emb.embellishments (sig_name sg) *) |> Emb.embellishments_functions (sig_name sg) config |> fix in let consts = Data_Signature.id_to_string sg in fst @@ ttd t l_level level (l_env, env) consts let merge_trees : 'a tree list -> 'a list tree = List.map (Tree.map (fun x -> [ x ])) >> Utils.fold_left1 (Tree.map2 ( @ )) let decorate_lines (lines : diagram list) : diagram list = lines |> List.map (pad_abs ~horizontal:2.0) |> List.map (pad_rel ~vertical:0.05) |> List.map2 color @@ Utils.cycle (List.length lines) C.lines let rec align_sister_lines (tree : diagram list tree) : diagram list tree = match tree with | Tree.T (_lines, []) -> tree | Tree.T (lines, children) -> let children = List.map align_sister_lines children in let heights = List.map (fun (Tree.T (c_lines, _)) -> List.map (fun c_line -> (extents c_line).h) c_lines) children in let max_heights = Utils.fold_left1 (List.map2 max) heights in let children = List.map (fun (Tree.T (c_lines, c_children)) -> Tree.T ( List.map2 (fun c_line new_height -> let height_diff = new_height -. (extents c_line).h in pad_abs ~vertical:(height_diff /. 2.) c_line) c_lines max_heights, c_children )) children in Tree.T (lines, children) let realize_diagram (abs_term : term) (lexs : lexicon list) (config : Rendering_config.config) : diagram = let abs_sig = abstract_sig @@ List.hd lexs in (* let obj_sigs = List.map object_sig lexs in *) (* let _sigs = abs_sig :: obj_sigs in *) let expanded_abs_term = normalize (Data_Signature.expand_term abs_term abs_sig) in let abs_terms_differ = abs_term != expanded_abs_term in let term_graph = term_to_graph abs_sig abs_term in let render_abs_term = term_to_diagram_in config abs_sig in let render_obj_term lex abs_term = let obj_sig = object_sig lex in let obj_term = interpret_term abs_term lex in term_to_diagram_in config obj_sig obj_term in let abs_term_tree = render_term_graph 0 0 ([], []) render_abs_term term_graph in let last_abs_term_graph = if abs_terms_differ then term_to_graph abs_sig expanded_abs_term else term_graph in let obj_term_trees = List.map (fun lex -> render_term_graph ~non_linear:(not (Data_Lexicon.is_linear lex)) 0 0 ([], []) (render_obj_term lex) last_abs_term_graph) lexs in let trees = if abs_terms_differ then let expanded_abs_term_tree = render_term_graph 0 0 ([], []) render_abs_term last_abs_term_graph in (* abs_term_tree :: (expanded_abs_term_tree :: obj_term_trees) *) (* abs_term_tree :: obj_term_trees *) expanded_abs_term_tree :: obj_term_trees else abs_term_tree :: obj_term_trees in trees |> merge_trees |> Tree.map decorate_lines |> align_sister_lines |> Tree.map (List.map centerX >> vcat) |> Tree.map (bg_color (C.node_background config)) |> Tree.to_diagram |> setup (fun cr -> set_line_width cr 1.5) |> bg_color (C.background config) |> color C.tree end
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>