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.magicRewriting/rewriting.ml.html
Source file rewriting.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
open UtilsLib open DatalogLib module ASProg = Datalog_AbstractSyntax.AbstractSyntax.Program module ASPred = Datalog_AbstractSyntax.AbstractSyntax.Predicate module ASRule = Datalog_AbstractSyntax.AbstractSyntax.Rule open Datalog module Log = Xlog.Make (struct let name = "Rewriting" end) module PredicateSet = Set.Make (struct type t = ASPred.predicate let compare pred pred2 = ASPred.compare ~with_arguments:false pred pred2 end) module QueryMap = Map.Make (struct type t = ASPred.pred_id * Adornment.status list let compare = Stdlib.compare end) module Elt = struct type t = Adornment.status let to_string = Adornment.status_to_string end module Ads = Product.Make (Elt) let generate_permutations len = let values = Ads.list_to_tuple [ Adornment.Bound ] in Ads.product len values type magic_context = { predicates_from_magic : Magic.extra_pred_type ASPred.PredIdMap.t; (* sets for the supp_zero, supp_k and magic added predicates *) unique_to_original_rules_ids_map : (int * int) Datalog_AbstractSyntax.RuleIdMap.t; magic_to_unique_rule_ids_map : int Datalog_AbstractSyntax.RuleIdMap.t; adorn_to_unadorm_pred_ids_map : Unique_binding.ASPred.pred_id Unique_binding.ASPred.PredIdMap.t; unique_binding_program : ASProg.program; } exception Break of ASRule.rule let find_in_set f s = try ASRule.Rules.fold (fun r acc -> match acc with | None -> if f r then raise (Break r) else acc | Some _ -> acc) s None with Break r -> Some r let pp_find_rule msg ?(with_id = false) prog fmt id = match find_in_set (fun r -> r.ASRule.id = id) prog.ASProg.rules with | Some r -> ASRule.pp ~with_id prog.ASProg.pred_table prog.ASProg.const_table fmt r | None -> Format.fprintf fmt "Could not find any rule (%s) with id %d" msg id let pp_mapping ?(with_id = false) f new_prog old_prog fmt map = let () = Format.fprintf fmt "[log_mapping] Old prog is:@,@[<v> @[%a@]@]@,[log_mapping] New prog is:@,@[<v> @[%a@]@]" (ASProg.pp ~with_position:false ~with_id) old_prog (ASProg.pp ~with_position:false ~with_id) new_prog in Datalog_AbstractSyntax.RuleIdMap.iter (fun k v -> let () = Format.fprintf fmt "Lookup for the %d -->> %d mapping:@," k (f v) in Format.fprintf fmt "%a -->> %a@," (pp_find_rule ~with_id "in new_prog" new_prog) k (pp_find_rule ~with_id "in old_prog" old_prog) (f v)) map let rewrite_program ~msg prog query = let () = Log.debug (fun m -> m "Starting rewrite for %s" msg) in let pred, ad = query in let pred_name = ASPred.PredIdTable.find_sym_from_id pred.ASPred.p_id prog.ASProg.pred_table in let c = Mtime_clock.counter () in let () = Log.info (fun m -> let adornment = Adornment.to_string ad in m "%sMagic program for query: %s_%s/%d" msg pred_name adornment pred.ASPred.arity ~tags:(Xlog.stamp c)) in let () = Log.debug (fun m -> m "@[<v>Rewriting the following program:@,@[<v>%a@]@]" (fun fmt rules -> ASRule.Rules.iter (fun r -> Format.fprintf fmt "Head: %a ->@,Rule: @[<hv>%a@]@," (ASPred.pp ~with_arity:true prog.ASProg.pred_table prog.ASProg.const_table) r.ASRule.lhs (ASRule.pp ~with_position:true ~with_id:true ~with_arity:true prog.ASProg.pred_table prog.ASProg.const_table) r) rules) prog.ASProg.rules) in let t = Timer.top () in let rgg = Rgg.build_rgg prog query in let () = Timer.debug (fun m -> let adornment = Adornment.to_string ad in m "@[For query: %s_%s/%d, rgg@ built@ in: %a@]" pred_name adornment pred.ASPred.arity Timer.elapsed t) in let t = Timer.top () in (* ATTENTION : map du programme unique binding (pas magic !) vers program original *) let unique_binding = Unique_binding.derive_program rgg prog in let () = Log.info (fun m -> m "Done.") in let unique_prog, unadorned_map, unique_prog_rules_to_old_rule_id_map = Unique_binding. ( unique_binding.adorned_prog, unique_binding.unadorned_map, unique_binding.rule_to_rule_map ) in let () = Timer.debug (fun m -> m "Unique binding computed in: %a" Timer.elapsed t) in let t = Timer.top () in let magic_prog, new_preds, magic_rules_to_unique_rule_id_map = Magic.make_magic unique_prog in let () = Timer.debug (fun m -> m "Running magic lasted: %a" Timer.elapsed t) in let () = Log.debug (fun m -> m "(SP) Mapping of unique binding rules to original program rules:@,@[<v> @[%a@]@]" (pp_mapping ~with_id:true (fun (id, _) -> id) unique_prog prog) unique_prog_rules_to_old_rule_id_map) in let () = Log.debug (fun m -> m "(SP) Mapping of magic rules to unique binding program rules:@,@[<v> @[%a@]@]" (pp_mapping ~with_id:true (fun id -> id) magic_prog unique_prog) magic_rules_to_unique_rule_id_map) in let () = Log.debug (fun m -> m "New Magic prog:@,@[<v>@[%a@]@]" (ASProg.pp ~with_position:false ~with_id:true) magic_prog) in let magic_context = { predicates_from_magic = new_preds; adorn_to_unadorm_pred_ids_map = unadorned_map; unique_to_original_rules_ids_map = unique_prog_rules_to_old_rule_id_map; magic_to_unique_rule_ids_map = magic_rules_to_unique_rule_id_map; unique_binding_program = unique_prog; } in let res = (magic_prog, magic_context) in res let rewrite_programs ?(msg = "") prog = let msg = if msg = "" then msg else Printf.sprintf "%s. " msg in let possible_adornments = Utils.IntMap.empty in let all_queries_to_prog, _ = ASRule.Rules.fold (fun rule ((queries_to_prog,all_adornments) as acc) -> let head = rule.ASRule.lhs in (* Check if the predicate corresponding to the head has already been processed *) if QueryMap.exists (fun (p_id, _) _ -> p_id = head.ASPred.p_id) queries_to_prog then (* if yes, then do nothing *) let () = Log.debug (fun m -> m "Intensional predicate %a already processed. Skipping it" (ASPred.pp prog.ASProg.pred_table prog.ASProg.const_table) head) in acc else (* generates all possible adornments for this predicate *) let adornments,new_all_adornments = match Utils.IntMap.find_opt head.ASPred.arity all_adornments with | None -> let ads = generate_permutations head.ASPred.arity in ads, Utils.IntMap.add head.ASPred.arity ads all_adornments | Some ads -> ads, all_adornments in (Ads.fold (fun l_acc ad -> let adornment = Ads.tuple_to_list ad in let () = Log.info (fun m -> m "Processing Intensional predicate %a with adornment: %s" (ASPred.pp prog.ASProg.pred_table prog.ASProg.const_table) head (Adornment.to_string adornment)) in QueryMap.add (head.ASPred.p_id, adornment) (rewrite_program ~msg prog (head, adornment)) l_acc) queries_to_prog adornments, new_all_adornments)) prog.ASProg.rules (QueryMap.empty,possible_adornments) in let () = Log.info (fun m -> m "rewrite_programms done.") in all_queries_to_prog let get_program query query_map = (*We build the adornment of term*) let bfs, _ = Adornment.adornment ~bound_variables:ASPred.TermSet.empty query in (*We get the progran in the map *) let the_magic_program, magic_context = QueryMap.find (query.ASPred.p_id, bfs) query_map in (*We build the magic rule*) (Magic.query_to_seed query the_magic_program, magic_context) let rec unmagic_premises premises pred_from_magic derivations = match premises with | [supp_k; pred] when ASPred.(PredIdMap.find_opt supp_k.p_id pred_from_magic) = Some Magic.Supp_k && ASPred.(PredIdMap.find_opt pred.p_id pred_from_magic) = None -> let supp_k_premises_set = Datalog.Predicate.PredicateMap.find supp_k derivations in Datalog.Predicate.PremiseSet.fold (fun (l_premises, _, _) acc -> (List.fold_left (fun l_acc elt -> (pred::elt)::l_acc) acc (unmagic_premises l_premises pred_from_magic derivations))) supp_k_premises_set [] | [pred; supp_k] when ASPred.(PredIdMap.find_opt supp_k.p_id pred_from_magic) = Some Magic.Supp_k && ASPred.(PredIdMap.find_opt pred.p_id pred_from_magic) = None -> let supp_k_premises_set = Datalog.Predicate.PredicateMap.find supp_k derivations in Datalog.Predicate.PremiseSet.fold (fun (l_premises, _, _) acc -> (List.fold_left (fun l_acc elt -> (pred::elt)::l_acc) acc (unmagic_premises l_premises pred_from_magic derivations))) supp_k_premises_set [] | [supp_zero; pred] when ASPred.(PredIdMap.find_opt supp_zero.p_id pred_from_magic) = Some Magic.Supp_zero && ASPred.(PredIdMap.find_opt pred.p_id pred_from_magic) = None -> [[pred]] | [pred; supp_zero] when ASPred.(PredIdMap.find_opt supp_zero.p_id pred_from_magic) = Some Magic.Supp_zero && ASPred.(PredIdMap.find_opt pred.p_id pred_from_magic) = None -> [[pred]] | [supp_zero] when ASPred.(PredIdMap.find_opt supp_zero.p_id pred_from_magic) = Some Magic.Supp_zero -> [] | _ -> failwith "Bug: Cannot be premises of a supp_k predicate" let rewrite_derivations derivations { predicates_from_magic; adorn_to_unadorm_pred_ids_map; magic_to_unique_rule_ids_map; unique_to_original_rules_ids_map; unique_binding_program = _; } = let rename_predicate p = match ASPred.(PredIdMap.find_opt p.p_id adorn_to_unadorm_pred_ids_map) with | None -> failwith "Bug: only non-magic and non-supp predicates can be renamed" | Some id -> ASPred.copy_predicate ~new_id:id p in let find_original_rule_characteristics r_id = Datalog_AbstractSyntax.RuleIdMap.(find (find r_id magic_to_unique_rule_ids_map) unique_to_original_rules_ids_map) in Datalog.Predicate.PredicateMap.fold (fun pred premises_set l_derivations -> match ASPred.(PredIdMap.find_opt pred.p_id predicates_from_magic) with | Some _ -> (* just remove derivation trees for supp_0, supp_k and magic predicates *) l_derivations | None -> (* otherwise, proceed *) let new_premises = Datalog.Predicate.PremiseSet.fold (fun (preds, r_id, _) ll_premise_set -> let original_rule_id, original_num = find_original_rule_characteristics r_id in match unmagic_premises preds predicates_from_magic derivations with | [] -> Datalog.Predicate.PremiseSet.add ([], original_rule_id, original_num) ll_premise_set | l_preds -> List.fold_left (fun acc l_premises -> Datalog.Predicate.PremiseSet.add (List.rev_map rename_predicate l_premises, original_rule_id, original_num) acc) ll_premise_set l_preds) premises_set Datalog.Predicate.PremiseSet.empty in Datalog.Predicate.PredicateMap.add (rename_predicate pred) new_premises l_derivations) derivations Datalog.Predicate.PredicateMap.empty
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>