package dedukti
An implementation of The Lambda-Pi Modulo Theory
Install
Dune Dependency
Authors
Maintainers
Sources
v2.7.tar.gz
sha512=97171b48dd96043d84587581d72edb442f63e7b5ac1695771aa1c3c9074739e15bc7d17678fedb7062acbf403a0bf323d97485c31b92376b80c63b5c2300ee3c
sha256=5e1b6a859dfa1eb2098947a99c7d11ee450f750d96da1720f4834e1505d1096c
doc/src/dedukti.kernel/signature.ml.html
Source file signature.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 406 407 408 409 410 411 412 413 414 415
(** Global Environment *) open Basic open Term open Rule let d_module = Debug.register_flag "Module" type file = string type signature_error = | UnmarshalBadVersionNumber of loc * string | UnmarshalSysError of loc * string * string | UnmarshalUnknown of loc * string | SymbolNotFound of loc * name | AlreadyDefinedSymbol of loc * name | CannotMakeRuleInfos of Rule.rule_error | CannotBuildDtree of Dtree.dtree_error | CannotAddRewriteRules of loc * name | ConfluenceErrorImport of loc * mident * Confluence.confluence_error | ConfluenceErrorRules of loc * rule_infos list * Confluence.confluence_error | GuardNotSatisfied of loc * term * term | CannotExportModule of mident * exn | PrivateSymbol of loc * name | ExpectedACUSymbol of loc * name exception Signature_error of signature_error module HMd = Hashtbl.Make (struct type t = mident let equal = mident_eq let hash = Hashtbl.hash end) module HId = Hashtbl.Make (struct type t = ident let equal = ident_eq let hash = Hashtbl.hash end) type staticity = Static | Definable of algebra | Injective let algebra_of_staticity = function | Static | Injective -> Free | Definable a -> a type scope = Public | Private (** The pretty printer for the type [staticity] *) (* let pp_staticity fmt s = * Format.fprintf fmt "%s" (if s=Static then "Static" else "Definable") *) type rw_infos = { stat : staticity; ty : term; scope : scope; rules : rule_infos list; decision_tree : Dtree.t option; } type t = { md : mident; (** [tables] maps module ident to the hastable of their symbols. It should only contain a single entry for each module. Each module's hashtable should only contain a single entry for each of its symbols. *) tables : rw_infos HId.t HMd.t; mutable external_rules : rule_infos list list; get_file : loc -> mident -> string; } let make md get_file = let tables = HMd.create 19 in HMd.replace tables md (HId.create 251); {md; tables; external_rules = []; get_file} let get_name sg = sg.md (******************************************************************************) let marshal : mident -> mident list -> rw_infos HId.t -> rule_infos list list -> out_channel -> unit = fun md deps env ext oc -> try Marshal.to_channel oc Version.version []; Marshal.to_channel oc deps []; Marshal.to_channel oc env []; Marshal.to_channel oc ext [] with e -> raise @@ Signature_error (CannotExportModule (md, e)) let unmarshal (lc : loc) (file : string) : mident list * rw_infos HId.t * rule_infos list list = try let ic = open_in file in let ver : string = Marshal.from_channel ic in if String.compare ver Version.version <> 0 then raise (Signature_error (UnmarshalBadVersionNumber (lc, file))); let deps : mident list = Marshal.from_channel ic in let ctx : rw_infos HId.t = Marshal.from_channel ic in let ext : rule_infos list list = Marshal.from_channel ic in close_in ic; (deps, ctx, ext) with | Sys_error s -> raise (Signature_error (UnmarshalSysError (lc, file, s))) | Signature_error s -> raise (Signature_error s) let fold_symbols f sg = HMd.fold (fun md table t -> HId.fold (f md) table t) sg.tables let iter_symbols f sg = fold_symbols (fun md id rw () -> f md id rw) sg () (******************************************************************************) (* let get_type_from_AC (ty:term) = * match ty with * | Pi(_,_,t,_) -> t * | _ -> assert false *) let to_rule_infos_aux (r : unit rule) = try Rule.to_rule_infos r with Rule_error e -> raise (Signature_error (CannotMakeRuleInfos e)) let comm_rule (name : name) = to_rule_infos_aux { name = Gamma ( true, mk_name (md name) (mk_ident ("comm_" ^ string_of_ident (id name))) ); ctx = [(dloc, mk_ident "x", ()); (dloc, mk_ident "y", ())]; pat = Pattern ( dloc, name, [Var (dloc, mk_ident "x", 0, []); Var (dloc, mk_ident "y", 1, [])] ); rhs = mk_App (mk_Const dloc name) (mk_DB dloc (mk_ident "y") 1) [mk_DB dloc (mk_ident "x") 0]; } let asso_rule (name : name) = to_rule_infos_aux { name = Gamma ( true, mk_name (md name) (mk_ident ("asso_" ^ string_of_ident (id name))) ); ctx = [ (dloc, mk_ident "x", ()); (dloc, mk_ident "y", ()); (dloc, mk_ident "z", ()); ]; pat = Pattern ( dloc, name, [ Pattern ( dloc, name, [ Var (dloc, mk_ident "x", 0, []); Var (dloc, mk_ident "y", 1, []); ] ); Var (dloc, mk_ident "z", 2, []); ] ); rhs = mk_App (mk_Const dloc name) (mk_DB dloc (mk_ident "x") 0) [ mk_App (mk_Const dloc name) (mk_DB dloc (mk_ident "y") 1) [mk_DB dloc (mk_ident "z") 2]; ]; } let neu1_rule (name : name) (_ : term) = to_rule_infos_aux { name = Gamma ( true, mk_name (md name) (mk_ident ("neut_" ^ string_of_ident (id name))) ); ctx = [(dloc, mk_ident "x", ())]; pat = Pattern ( dloc, name, [ Var (dloc, mk_ident "x", 0, []) (* FIXME: Translate term argument to pattern here *); ] ); rhs = mk_App (mk_Const dloc name) (mk_DB dloc (mk_ident "x") 0) []; } let neu2_rule (name : name) (neu : term) = to_rule_infos_aux { name = Gamma ( true, mk_name (md name) (mk_ident ("neut_" ^ string_of_ident (id name))) ); ctx = [(dloc, mk_ident "x", ())]; pat = Pattern (dloc, name, [Var (dloc, mk_ident "x", 0, [])]); rhs = mk_App (mk_Const dloc name) (mk_DB dloc (mk_ident "x") 0) [neu]; } let check_confluence_on_import lc (md : mident) (ctx : rw_infos HId.t) : unit = let open Confluence in let aux id infos = let cst = mk_name md id in add_constant cst; add_rules infos.rules; match infos.stat with | Definable AC -> add_rules [comm_rule cst; asso_rule cst] | Definable (ACU neu) -> add_rules [comm_rule cst; asso_rule cst; neu1_rule cst neu; neu2_rule cst neu] | _ -> () in HId.iter aux ctx; Debug.debug d_confluence "Checking confluence after loading module '%a'..." pp_mident md; try check () with Confluence_error e -> raise (Signature_error (ConfluenceErrorImport (lc, md, e))) let add_external_declaration sg lc cst scope stat ty = try let env = HMd.find sg.tables (md cst) in if HId.mem env (id cst) then raise (Signature_error (AlreadyDefinedSymbol (lc, cst))) else HId.replace env (id cst) {stat; ty; scope; rules = []; decision_tree = None} with Not_found -> HMd.replace sg.tables (md cst) (HId.create 11); let env = HMd.find sg.tables (md cst) in HId.replace env (id cst) {stat; ty; scope; rules = []; decision_tree = None} (* Recursively load a module and its dependencies*) let rec import sg lc md = if HMd.mem sg.tables md then Debug.( debug d_warn "Trying to import the already loaded module %s." (string_of_mident md)) else let deps, ctx, ext = unmarshal lc (sg.get_file lc md) in HMd.replace sg.tables md ctx; List.iter (fun dep -> if not (HMd.mem sg.tables dep) then import sg lc dep) deps; Debug.(debug d_module "Loading module '%a'..." pp_mident md); List.iter (fun rs -> add_rule_infos sg rs) ext; check_confluence_on_import lc md ctx and add_rule_infos sg (lst : rule_infos list) : unit = match lst with | [] -> () | r :: _ as rs -> let infos, env = get_info_env sg r.l r.cst in if infos.stat = Static then raise (Signature_error (CannotAddRewriteRules (r.l, r.cst))); HId.replace env (id r.cst) { infos with rules = List.rev_append rs infos.rules; decision_tree = None; } (* [rs] is in the order the user declared the rules, but a [rw_infos] is a Lifo pile, hence the [rev_append]. *) and compute_dtree sg (lc : Basic.loc) (cst : Basic.name) : Dtree.t = let infos, env = get_info_env sg lc cst in match (infos.decision_tree, infos.rules) with (* Non-empty set of rule but decision trees not computed *) | None, rules -> let trees = try Dtree.of_rules cst (get_algebra sg dloc) (List.rev rules) with Dtree.Dtree_error e -> raise (Signature_error (CannotBuildDtree e)) in HId.replace env (id cst) {infos with decision_tree = Some trees}; trees | Some t, _ -> t and get_info_env sg lc cst = let md = md cst in let env = (* Fetch module, import it if it's missing *) try HMd.find sg.tables md with Not_found -> import sg lc md; HMd.find sg.tables md in try (HId.find env (id cst), env) with Not_found -> raise (Signature_error (SymbolNotFound (lc, cst))) and get_infos sg lc cst = fst (get_info_env sg lc cst) (* and get_type sg lc name = (get_infos sg lc name).ty *) and get_staticity sg lc name = (get_infos sg lc name).stat and get_algebra sg lc name = algebra_of_staticity (get_staticity sg lc name) and is_AC sg lc name = Term.is_AC (get_algebra sg lc name) (******************************************************************************) let get_deps sg : mident list = (*only direct dependencies*) HMd.fold (fun md _ lst -> if mident_eq md sg.md then lst else md :: lst) sg.tables [] let import_signature sg sg_ext = HMd.iter (fun m hid -> if not (HMd.mem sg.tables m) then HMd.replace sg.tables m (HId.copy hid)) sg_ext.tables; List.iter (fun rs -> add_rule_infos sg rs) sg_ext.external_rules let export sg oc = let mod_table = HMd.find sg.tables sg.md in marshal sg.md (get_deps sg) mod_table sg.external_rules oc (******************************************************************************) let is_static sg lc cst = match (get_infos sg lc cst).stat with | Static -> true | Definable _ | Injective -> false let stat_code = function | Static -> 0 | Definable Free -> 1 | Definable AC -> 2 | Definable (ACU _) -> 3 | Injective -> 4 let get_id_comparator sg cst cst' = compare (stat_code (get_staticity sg dloc cst), cst) (stat_code (get_staticity sg dloc cst'), cst') let get_neutral sg lc cst = match get_algebra sg lc cst with | ACU neu -> neu | _ -> raise (Signature_error (ExpectedACUSymbol (lc, cst))) let get_env sg lc cst = let md = md cst in try HMd.find sg.tables md with Not_found -> import sg lc md; HMd.find sg.tables md let get_infos sg lc cst = try HId.find (get_env sg lc cst) (id cst) with Not_found -> raise (Signature_error (SymbolNotFound (lc, cst))) let is_injective sg lc cst = match (get_infos sg lc cst).stat with | Static | Injective -> true | Definable _ -> false let get_type sg lc cst = let infos = get_infos sg lc cst in if infos.scope = Public || md cst = sg.md then infos.ty else raise (Signature_error (PrivateSymbol (lc, cst))) let get_rules sg lc cst = (get_infos sg lc cst).rules let get_dtree sg lc cst = compute_dtree sg lc cst (******************************************************************************) let add_declaration sg lc v st ty = let cst = mk_name sg.md v in add_external_declaration sg lc cst st ty let add_rules sg = function | [] -> () | r :: _ as rs -> ( try add_rule_infos sg rs; if not (mident_eq sg.md (md r.cst)) then sg.external_rules <- rs :: sg.external_rules; Confluence.add_rules rs; Debug.( debug Confluence.d_confluence "Checking confluence after adding rewrite rules on symbol '%a'" pp_name r.cst); try Confluence.check () with Confluence.Confluence_error e -> raise (Signature_error (ConfluenceErrorRules (r.l, rs, e))) with Rule_error e -> raise (Signature_error (CannotMakeRuleInfos e))) let get_rw_infos sg md id = if HMd.mem sg.tables md then let sig_md = HMd.find sg.tables md in if HId.mem sig_md id then Some (HId.find sig_md id) else None else None
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>