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.acgData/reduction.ml.html
Source file reduction.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 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405
open Logic.Lambda open UtilsLib.Utils open DatalogLib.Datalog_AbstractSyntax open DatalogLib.Datalog module Log = UtilsLib.Xlog.Make (struct let name = "Reduction" end) module Make (Sg : module type of Signature.Data_Signature) = struct let rec sequentialize_rev stype sequence = match stype with | Lambda.Atom i -> i :: sequence | Lambda.DAtom _ -> failwith "Bug: type definition should be unfolded" | Lambda.LFun (alpha, beta) | Lambda.Fun (alpha, beta) -> sequentialize_rev beta (sequentialize_rev alpha sequence) | _ -> failwith "Bug: Not a 2nd order type" let sequentialize stype = List.rev (sequentialize_rev stype []) (** [map_types abs_type obj_type sg] returns a list of triple [(id_n,name_n,image_n);...;(id_2,name_2,image_2);(id_1,name_1,image_1)] where [abst_type=Atom(id_1) -> Atom(id_2) -> ... Atom(id_n)] and is defined as [name_1 -> name_2 -> ... -> name_n] and [obj_type=image_1 -> image_2 -> ... -> image_n]. Note that the list is in the {em reverse order} and that [abs_type] should be 2nd order. *) let map_types abs_type obj_type sg = let log_type ?raw_type_info msg pp_type t = let raw_type = match raw_type_info with | None -> "" | Some (f, t) -> Printf.sprintf " (%s)" (f t) in Log.debug (fun m -> m "%s%a%s" msg pp_type t raw_type) in let rec map_types_aux abs_type obj_type lst = log_type "Mapping (aux) type:" (Sg.pp_type sg) abs_type; log_type "On (aux): " (fun fmt ty -> Format.fprintf fmt "%s" (Lambda.raw_type_to_string ty)) obj_type; match (abs_type, obj_type) with | Lambda.Atom i, _ -> (i, snd (Sg.id_to_string sg i), obj_type) :: lst | Lambda.DAtom _, _ -> failwith (Format.asprintf "Bug: type definition in \"%a\" as \"%s\" should be unfolded" (Sg.pp_type sg) abs_type (Lambda.raw_type_to_string abs_type)) | Lambda.LFun (Lambda.Atom i, beta), Lambda.Fun (alpha', beta') | Lambda.Fun (Lambda.Atom i, beta), Lambda.Fun (alpha', beta') -> map_types_aux beta beta' ((i, snd (Sg.id_to_string sg i), alpha') :: lst) | Lambda.LFun _, Lambda.Fun _ | Lambda.Fun _, Lambda.Fun _ -> failwith "Bug: should be 2nd order type for abstract constant" | _, _ -> failwith "Bug: Not a 2nd order type or not corresponding abstract and \ object type" in log_type ~raw_type_info:(Lambda.raw_type_to_string, abs_type) "Mapping type:" (Sg.pp_type sg) abs_type; log_type "On: " (fun fmt ty -> Format.fprintf fmt "%s" (Lambda.raw_type_to_string ty)) obj_type; map_types_aux abs_type obj_type [] let log_pred name o_type atom_seq = Log.debug (fun m -> m "Build predicate from %s: %s ([%s])" name (Lambda.raw_type_to_string o_type) (string_of_list ";" string_of_int atom_seq)) (** [build_predicate_w_var_args (name,obj_type) (prog,var_gen,type_to_var_map)] returns [(prog',var_gen',type_to_var_map')] where: - [name] is the name of an abstract type of some ACG that has to be turned into a predicate of the associated datalog program - [ob_type] is the principal type of its realisation by this ACG - [prog] is the current associated datalog program - [var_gen] is a variable generator that records the variable associated with this predicate (according to the principal type [obj_type] of its image). It can be updated to [var_gen'] if some new variables are needed - [type_to_var_map] records to which variable each atomic type of the principal type is associated with. It can be updated to [type_to_var_map'] if some new variables were needed. - [prog'] is [prog] where the new predicate has been added *) let build_predicate_w_var_args (name, obj_type) (prog, var_gen, type_to_var_map) = let atom_sequence = sequentialize_rev obj_type [] in log_pred name obj_type atom_sequence; let var_sequence, var_gen, type_to_var_map = List.fold_left (fun (l_var_seq, l_var_gen, l_type_to_var_map) i -> let var, l_var_gen, l_type_to_var_map = try (IntMap.find i l_type_to_var_map, l_var_gen, l_type_to_var_map) with Not_found -> let var, l_var_gen = VarGen.get_fresh_id l_var_gen in (var, l_var_gen, IntMap.add i var l_type_to_var_map) in ( AbstractSyntax.Predicate.Var var :: l_var_seq, l_var_gen, l_type_to_var_map )) ([], var_gen, type_to_var_map) atom_sequence in let () = Log.debug (fun m -> match AbstractSyntax.Predicate.PredIdTable.find_id_of_sym_opt name prog.Datalog.Program.pred_table with | None -> m "The predicate '%s' was not already present in the program" name | Some _ -> m "The predicate '%s' was indeed already present in the program" name) in (* Except for variables and constants, the program [prog] is unchanged *) let p_id, prog = Datalog.Program.add_pred_sym name prog in ( AbstractSyntax.Predicate. { p_id; arity = List.length var_sequence; arguments = var_sequence }, (prog, var_gen, type_to_var_map) ) (** [build_predicate_w_cst_args (name,obj_type) prog] returns a pair [pred,prog'] where [pred] is a fully instantiated predicate where: - [name] is the name of an abstract type of some ACG that has to be turned into a the querying predicate for the associated datalog program - [ob_type] is the principal type of its realisation by this ACG that is interpreted as Datalog constants - [prog] is the current associated datalog program. [prog'] differs from [prog] only by keeping track of the constants added (and possibly the predicate, although it should already be present *) let build_predicate_w_cst_args ?(check_no_new_pred = true) (name, obj_type) prog = let atom_sequence = sequentialize obj_type in log_pred name obj_type atom_sequence; let const_sequence, prog = List.fold_left (fun (l_const_seq, l_prog) i -> let const_id, l_prog = (* l_prog output differs from l_prog input only by the association between (string_of_int i) and const_id *) Datalog.Program.get_fresh_cst_id (string_of_int i) l_prog in (AbstractSyntax.Predicate.Const const_id :: l_const_seq, l_prog)) ([], prog) atom_sequence in let () = if check_no_new_pred then Log.debug (fun m -> let () = assert ( match AbstractSyntax.Predicate.PredIdTable.find_id_of_sym_opt name prog.Datalog.Program.pred_table with | None -> false | Some _ -> true) in m "The predicate '%s' was indeed already present in the program" name) (* Except for variables and constants, the program [prog] is unchanged *) (* prog as input differs from prog as output only with the association between [name] and [p_id].*) else () in let p_id, prog = Datalog.Program.add_pred_sym name prog in ( AbstractSyntax.Predicate. { p_id; arity = List.length const_sequence; arguments = List.rev const_sequence; }, prog ) let get_constant_id = function | Lambda.Const i -> i | _ -> failwith "Bug: Predicates should be build only for declared constants" (** [generate_and_add_rule ~abs_cst ~obj_princ_type ~obj_typing_env prog abs_sig obj_sig] returns a pair [(r,prog')] where: - [r] is the generated rule - [prog'] is [prog] where the rule [r] has been added - [abs_cst] is the abstract constant from the abstract signature [abs_sig] that triggers the rule generation - [obj_princ_type] is the principal type of the image by the lexicon of [abs_cst] - [obj_typing_env] is its typing environment. The latter maps the position of the object constants in the realisation of [abs_cst] to a pair [(t,ty)] where [t] is the object constant itself, and [ty] the type associated by the principal typing environment. - [prog] is the current datalog program - [abs_sig] and [obj_sig] are the abstract signature and the object signature of some ACG. *) let generate_and_add_rule ~abs_cst:(_, abs_t_type) ~obj_princ_type:principle_type ~obj_typing_env:env ~abs_sig ~obj_sig ~update_fct ~syms prog = let rule_id, prog = Datalog.Program.get_fresh_rule_id prog in let type_lst = map_types abs_t_type principle_type abs_sig in match type_lst with | [] -> failwith "Bug: there should be a type correspondance" | (_, name, image) :: tl -> let lhs, (prog, var_gen, type_to_var_map) = build_predicate_w_var_args (name, image) (prog, VarGen.init (), IntMap.empty) in (* intensional predicates come before extensional ones*) let e_rhs, e_rhs_length, (prog, var_gen, type_to_var_map), new_syms = IntMap.fold (fun _ (cst, cst_type) (rhs, l_length, l_tables, l_syms) -> let () = assert ( let e_pred_name_candidate = Format.asprintf "%a" (Sg.pp_term obj_sig) cst in match Sg.is_constant e_pred_name_candidate obj_sig with | true, Some (_, false, _) -> true | _ -> false) in let const_name, l_syms' = update_fct cst l_syms in let new_pred, new_tables = build_predicate_w_var_args (const_name, cst_type) l_tables in let l_length = l_length + 1 in ((new_pred, l_length) :: rhs, l_length, new_tables, l_syms')) env ([], 0, (prog, var_gen, type_to_var_map), syms) in let i_rhs, length, (prog, _, _) = List.fold_left (fun (rhs, l_length, l_tables) (_, l_name, l_image) -> let new_pred, new_tables = build_predicate_w_var_args (l_name, l_image) l_tables in let l_length = l_length + 1 in ((new_pred, l_length) :: rhs, l_length, new_tables)) ([], e_rhs_length, (prog, var_gen, type_to_var_map)) tl in let new_rule = AbstractSyntax.Rule. { id = rule_id; lhs; e_rhs; i_rhs; i_rhs_num = length - e_rhs_length; rhs_num = length; } in let () = Log.debug (fun m -> m "The following rule was generated: %a" (AbstractSyntax.Rule.pp ~with_position:true prog.Datalog.Program.pred_table prog.Datalog.Program.const_table) new_rule) in ( new_rule, Datalog.Program.add_rule ~intensional:true new_rule prog, new_syms ) (** [edb_and_query ~obj_term ~obj_type ~obj_typing_env ~dist_type prog ~abs_sig ~obj_sig] returns a pair [(q,prog')] where: - [q] is the predicate corresponding to the query generated by the object term [obj_term] to parse - [prog'] is [prog] where the extensional database resulting from the reduction of the object term [obj_term] - [obj_type] is the principal type of [obj_term] - [obj_typing_env] is its typing environment. The latter maps the position of the object constants in the realisation of [abs_cst] to a pair [(t,ty)] where [t] is the object constant itself, and [ty] the type associated by the principal typing environment. - [dist_type] is the distinguished type of the ACG - [prog] is the current datalog program - [abs_sig] and [obj_sig] are the abstract signature and the object signature of some ACG. *) let edb_and_query ~obj_term ~obj_type ~obj_typing_env ~dist_type ?adornment prog ~abs_sig ~obj_sig ~syms:(syms, _) = (* It makes the assumption that no constant has been previously defined or used in the program *) let type_lst = map_types dist_type obj_type abs_sig in match type_lst with | [] -> failwith "Bug: there should be a type correspondance" | [ (_, name, image) ] -> let e_facts, prog = IntMap.fold (fun _ (cst, cst_type) (l_facts, l_prog) -> let cst_id = get_constant_id cst in let () = assert ( let const_name = Format.asprintf "%a" (Sg.pp_term obj_sig) cst in match Sg.is_constant const_name obj_sig with | true, Some (_, false, _) -> true | _ -> false) in let const_name = match UtilsLib.Utils.IntMap.find_opt cst_id syms with | None -> Format.asprintf "%a" (Sg.pp_term obj_sig) cst | Some name -> name in let new_pred, l_prog = build_predicate_w_cst_args (const_name, cst_type) l_prog in let rule_id, l_prog = Datalog.Program.get_fresh_rule_id l_prog in let new_fact = AbstractSyntax.Rule. { id = rule_id; lhs = new_pred; e_rhs = []; i_rhs = []; i_rhs_num = 0; rhs_num = 0; } in (new_fact :: l_facts, l_prog)) obj_typing_env ([], prog) in let () = Log.debug (fun m -> m "Done (query in reduction)") in let prog = Datalog.Program.add_e_facts prog ( e_facts, prog.Datalog.Program.const_table, prog.Datalog.Program.rule_id_gen ) in (* if there is an adornment, adds it to the name *) let name = match adornment with | None -> name | Some ad -> Printf.sprintf "%s_%s" name (MagicRewriting.Adornment.to_string ad) in build_predicate_w_cst_args (name, image) prog | (_, _, _) :: tl -> failwith "Bug: querying non atomic types is not yet implemented" [@@warning "-27"] let only_edb_and_query ~obj_term ~obj_type ~obj_typing_env ~dist_type prog ~abs_sig ~obj_sig ~syms:(syms, _) = (* It makes the assumption that no constant has been previously defined or used in the program *) let type_lst = map_types dist_type obj_type abs_sig in match type_lst with | [] -> failwith "Bug: there should be a type correspondance" | [ (_, name, image) ] -> let e_facts, prog = IntMap.fold (fun _ (cst, cst_type) (l_facts, l_prog) -> let cst_id = get_constant_id cst in let () = assert ( let const_name = Format.asprintf "%a" (Sg.pp_term obj_sig) cst in match Sg.is_constant const_name obj_sig with | true, Some (_, false, _) -> true | _ -> false) in let const_name = match UtilsLib.Utils.IntMap.find_opt cst_id syms with | None -> Format.asprintf "%a" (Sg.pp_term obj_sig) cst | Some name -> name in let new_pred, l_prog = build_predicate_w_cst_args (const_name, cst_type) l_prog in (* only constants are added to the program. No rule *) (new_pred :: l_facts, l_prog)) obj_typing_env ([], prog) in let () = Log.debug (fun m -> m "Done (query in reduction)") in (* [new_ prog] only differs from [prog] by vars/constants. No new rule is added *) let query, new_prog = build_predicate_w_cst_args (name, image) prog in (query, e_facts, new_prog) | (_, _, _) :: tl -> failwith "Bug: querying non atomic types is not yet implemented" [@@warning "-27"] end
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>