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.parsers/scoping.ml.html
Source file scoping.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
open Kernel.Basic open Kernel.Term open Kernel.Rule open Preterm exception Scoping_error of loc * string let get_db_index ctx id = let rec aux n = function | [] -> None | x :: _ when ident_eq id x -> Some n | _ :: lst -> aux (n + 1) lst in aux 0 ctx let empty = mk_ident "" let rec t_of_pt md (ctx : ident list) (pte : preterm) : term = let t_of_pt = t_of_pt md in match pte with | PreType l -> mk_Type l | PreId (l, id) -> ( match get_db_index ctx id with | None -> mk_Const l (mk_name md id) | Some n -> mk_DB l id n) | PreQId (l, cst) -> mk_Const l cst | PreApp (f, a, args) -> mk_App (t_of_pt ctx f) (t_of_pt ctx a) (List.map (t_of_pt ctx) args) | PrePi (l, None, a, b) -> mk_Arrow l (t_of_pt ctx a) (t_of_pt (empty :: ctx) b) | PrePi (l, Some x, a, b) -> mk_Pi l x (t_of_pt ctx a) (t_of_pt (x :: ctx) b) | PreLam (l, id, None, b) -> mk_Lam l id None (t_of_pt (id :: ctx) b) | PreLam (l, id, Some a, b) -> mk_Lam l id (Some (t_of_pt ctx a)) (t_of_pt (id :: ctx) b) let scope_term md ctx (pte : preterm) : term = t_of_pt md (List.map (fun (_, x, _) -> x) ctx) pte (******************************************************************************) type pre_context = preterm option context (* [get_vars_order vars p] traverses the pattern [p] from left to right and * builds the list of variables, turning jokers into unapplied fresh variables. * Return false as second argument if some variables never occur (warning needed). *) let get_vars_order (vars : pcontext) (ppat : prepattern) : pre_context * bool * bool = let nb_jokers = ref 0 in let has_brackets = ref false in let get_fresh_name () = incr nb_jokers; mk_ident ("?_" ^ string_of_int !nb_jokers) in let is_a_var id1 = let rec aux = function | [] -> None | ((l, id2), ty) :: _ when ident_eq id1 id2 -> Some (l, id2, ty) | _ :: lst -> aux lst in aux vars in let rec aux (bvar : ident list) (ctx : pre_context) : prepattern -> pre_context = function | PPattern (_, None, id, pargs) -> if List.exists (ident_eq id) bvar then List.fold_left (aux bvar) ctx pargs else let new_ctx = match is_a_var id with | Some l when not (List.exists (fun (_, a, _) -> ident_eq id a) ctx) -> l :: ctx | _ -> ctx in List.fold_left (aux bvar) new_ctx pargs | PPattern (_, Some _, _, pargs) -> List.fold_left (aux bvar) ctx pargs | PLambda (_, x, pp) -> aux (x :: bvar) ctx pp | PCondition _ -> has_brackets := true; ctx | PJoker (l, _) -> (l, get_fresh_name (), None) :: ctx | PApp plist -> List.fold_left (aux bvar) ctx plist in let ordered_ctx = aux [] [] ppat in ( ordered_ctx, List.length ordered_ctx <> List.length vars + !nb_jokers, !has_brackets ) let p_of_pp md (ctx : ident list) (ppat : prepattern) : pattern = let nb_jokers = ref 0 in let get_fresh_name () = incr nb_jokers; mk_ident ("?_" ^ string_of_int !nb_jokers) in let rec aux (ctx : ident list) : prepattern -> pattern = function | PPattern (l, None, id, pargs) -> ( match get_db_index ctx id with | Some n -> Var (l, id, n, List.map (aux ctx) pargs) | None -> Pattern (l, mk_name md id, List.map (aux ctx) pargs)) | PPattern (l, Some md, id, pargs) -> Pattern (l, mk_name md id, List.map (aux ctx) pargs) | PLambda (l, x, pp) -> Lambda (l, x, aux (x :: ctx) pp) | PCondition pte -> Brackets (t_of_pt md ctx pte) | PJoker (l, pargs) -> ( let id = get_fresh_name () in match get_db_index ctx id with | Some n -> Var (l, id, n, List.map (aux ctx) pargs) | None -> assert false) (* The cleaning of prepatterns suppress all the PApp *) | PApp _ -> assert false in aux ctx (clean_pre_pattern ppat) (******************************************************************************) let scope_rule md ((l, pname, pctx, md_opt, id, pargs, pri) : prule) : partially_typed_rule = let top = PPattern (l, md_opt, id, pargs) in let ctx, unused_vars, has_brackets = get_vars_order pctx top in if unused_vars then ( Debug.(debug d_warn "Local variables in the rule:\n%a\nare not used (%a)") pp_prule (l, pname, pctx, md_opt, id, pargs, pri) pp_loc l; if has_brackets then raise @@ Scoping_error ( l, "Unused variables in context may create scoping ambiguity in \ bracket" )); let idents = List.map (fun (_, x, _) -> x) ctx in let b, id = match pname with | None -> let id = Format.sprintf "%s!%d" (string_of_ident id) (fst (of_loc l)) in (false, mk_ident id) | Some (_, id) -> (true, id) in let name = Gamma (b, mk_name md id) in let rec ctx_of_pctx ctx acc = function | [] -> acc | (l, x, ty) :: tl -> ctx_of_pctx (x :: ctx) ((l, x, map_opt (t_of_pt md ctx) ty) :: acc) tl in { name; ctx = ctx_of_pctx [] [] (List.rev ctx); pat = p_of_pp md idents top; rhs = t_of_pt md idents pri; }
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>