(************************************************************************) (* * The Rocq Prover / The Rocq Development Team *) (* v * Copyright INRIA, CNRS and contributors *) (* <O___,, * (see version control and CREDITS file for authors & dates) *) (* \VV/ **************************************************************) (* // * This file is distributed under the terms of the *) (* * GNU Lesser General Public License Version 2.1 *) (* * (see LICENSE file for the text of the license) *) (************************************************************************)
(** Declaration of uninterpretation functions (i.e. printing rules)
for notations *)
(*i*) open Util open Names open Globnames open Constrexpr open Notation_term open Glob_term (*i*)
let notation_with_optional_scope_eq inscope1 inscope2 = match (inscope1,inscope2) with
| LastLonelyNotation, LastLonelyNotation -> true
| NotationInScope s1, NotationInScope s2 -> String.equal s1 s2
| (LastLonelyNotation | NotationInScope _), _ -> false
type t val empty : t val add : notation_rule -> t -> t val remove : notation_rule -> t -> t val repr : t -> notation_rule list
end = struct
type diff = Add | Sub
type data = {
ntn_todo : (diff * notation_rule) list;
ntn_done : notation_rule list;
}
type t = data refoption
let empty = None
let push k r s = match s with
| None -> Some (ref { ntn_done = []; ntn_todo = [k, r] })
| Some { contents = s } ->
Some (ref { ntn_done = s.ntn_done; ntn_todo = (k, r) :: s.ntn_todo })
let add r s = push Add r s
let remove r s = push Sub r s
let force s = ifList.is_empty s.ntn_todo then None else let cmp r1 r2 = Notation_ops.strictly_finer_interpretation_than r1.not_patt r2.not_patt in (* strictly finer interpretation are kept in front *) let fold accu (knd, ntn) = match knd with
| Add -> let finer, rest = List.partition (fun c -> cmp c ntn) accu in
(finer @ ntn :: rest)
| Sub -> List.remove_first (fun rule -> notation_rule_eq ntn rule) accu in
Some (List.fold_left fold s.ntn_done (List.rev s.ntn_todo))
let repr s = match s with
| None -> []
| Some r -> match force !r with
| None -> r.contents.ntn_done
| Some ans -> let () = r := { ntn_done = ans; ntn_todo = [] } in
ans
end
let keymap_add key interp map = let old = try KeyMap.find key mapwith Not_found -> NotationSet.empty in
KeyMap.add key (NotationSet.add interp old) map
let keymap_remove key interp map = let old = try KeyMap.find key mapwith Not_found -> NotationSet.empty in
KeyMap.add key (NotationSet.remove interp old) map
let keymap_find key map = try NotationSet.repr (KeyMap.find key map) with Not_found -> []
let uninterp_notations c = List.map_append (fun key -> keymap_find key !notations_key_table)
(glob_constr_keys c)
let uninterp_cases_pattern_notations c =
keymap_find (cases_pattern_key c) !notations_key_table
let uninterp_ind_pattern_notations ind =
keymap_find (RefKey (canonical_gr (GlobRef.IndRef ind))) !notations_key_table
let remove_uninterpretation rule (metas,c as pat) = let (key,n) = notation_constr_key c in
notations_key_table := keymap_remove key { not_rule = rule; not_patt = pat; not_status = n } !notations_key_table
let declare_uninterpretation rule (metas,c as pat) = let (key,n) = notation_constr_key c in
notations_key_table := keymap_add key { not_rule = rule; not_patt = pat; not_status = n } !notations_key_table
let freeze () =
!notations_key_table
let unfreeze fkm =
notations_key_table := fkm
let with_notation_uninterpretation_protection f x = let fs = freeze () in trylet a = f x in unfreeze fs; a with reraise -> let reraise = Exninfo.capture reraise in let () = unfreeze fs in
Exninfo.iraise reraise