(************************************************************************) (* * 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) *) (************************************************************************)
(* File created by Vincent Siles, Oct 2007, extended into a generic
support for generation of inductive schemes by Hugo Herbelin, Nov 2009 *)
(* This file provides support for registering inductive scheme builders,
declaring schemes and generating schemes on demand *)
open Names open Nameops open Declarations open Constr open Util
(**********************************************************************) (* Registering schemes in the environment *)
let is_visible_name id = try ignore (Nametab.locate (Libnames.qualid_of_ident id)); true with Not_found -> false
let compute_name internal id = if internal then
Namegen.next_ident_away_from (add_prefix "internal_" id) is_visible_name else id
let declare_definition_scheme = ref (fun ~internal ~univs ~role ~name ~effs ?loc c ->
CErrors.anomaly (Pp.str "scheme declaration not registered"))
let lookup_scheme kind ind = try Some (DeclareScheme.lookup_scheme kind ind) with Not_found -> None
let redeclare_schemes eff = let fold c role accu = match role with
| Evd.Schema (ind, kind) -> try let _ = DeclareScheme.lookup_scheme kind ind in
accu with Not_found -> let old = tryString.Map.find kind accu with Not_found -> [] in String.Map.add kind ((ind, c) :: old) accu in let schemes = Cmap.fold fold eff.Evd.seff_roles String.Map.empty in let iter kind defs = List.iter (DeclareScheme.declare_scheme SuperGlobal kind) defs in String.Map.iter iter schemes
let local_lookup_scheme eff kind ind = match lookup_scheme kind ind with
| Some _ as ans -> ans
| None -> let exception Found of Constant.t in let iter c role = match role with
| Evd.Schema (i, k) -> ifString.equal k kind && Ind.UserOrd.equal i ind thenraise (Found c) in (* Inefficient O(n), but the number of locally declared schemes is small and
this is very rarely called *) trylet _ = Cmap.iter iter eff.Evd.seff_roles in None with Found c -> Some c
let local_check_scheme kind ind eff = Option.has_some (local_lookup_scheme eff kind ind)
let define ?loc internal role id c poly uctx effs = let id = compute_name internal id in let uctx = UState.collapse_above_prop_sort_variables ~to_prop:true uctx in let uctx = UState.minimize uctx in let c = UState.nf_universes uctx c in let uctx = UState.restrict uctx (Vars.universes_of_constr c) in let univs = UState.univ_entry ~poly uctx in
!declare_definition_scheme ~internal ~univs ~role ~name:id ~effs ?loc c
module Locmap : sig
type t
val default : Loc.t option -> t val make : ?default:Loc.t -> MutInd.t -> Loc.t optionlist -> t val lookup : locmap:t -> Names.inductive -> Loc.t option
end = struct
type t = {
default : Loc.t option;
ind_to_loc : Loc.t Names.Indmap.t;
} let lookup ~locmap:{ ind_to_loc; default } x =
Names.Indmap.find_opt x ind_to_loc |> fun loc -> Option.append loc default
let default default = { default; ind_to_loc = Names.Indmap.empty }
let make ?default mind locs = let default, ind_to_loc =
CList.fold_left_i (fun i (default,m) loc -> let m = match loc with
| None -> m
| Some loc -> Indmap.add (mind, i) loc m in let default = ifOption.has_some default then default else loc in
default, m)
0 (default,Names.Indmap.empty) locs in
{ default; ind_to_loc }
end
(* Assumes that dependencies are already defined *) let rec define_individual_scheme_base ?loc kind suff f ~internal idopt (mind,i as ind) eff = (* FIXME: do not rely on the imperative modification of the global environment *) let (c, ctx) = f (Global.env ()) eff ind in let mib = Global.lookup_mind mind in let id = match idopt with
| Some id -> id
| None -> add_suffix mib.mind_packets.(i).mind_typename ("_"^suff) in let role = Evd.Schema (ind, kind) in letconst, eff = define ?loc internal role id c (Declareops.inductive_is_polymorphic mib) ctx eff in const, eff
and define_individual_scheme ?loc kind ~internal names (mind,i as ind) eff = match Hashtbl.find scheme_object_table kind with
| _,MutualSchemeFunction _ -> assert false
| s,IndividualSchemeFunction (f, deps) -> let deps = match deps with None -> [] | Some deps -> deps (Global.env ()) ind in let eff = List.fold_left (fun eff dep -> declare_scheme_dependence eff dep) eff deps in let _, eff = define_individual_scheme_base ?loc kind s f ~internal names ind eff in
eff
(* Assumes that dependencies are already defined *) and define_mutual_scheme_base ?(locmap=Locmap.default None) kind suff f ~internal names mind eff = (* FIXME: do not rely on the imperative modification of the global environment *) let (cl, ctx) = f (Global.env ()) eff mind in let mib = Global.lookup_mind mind in let ids = Array.init (Array.length mib.mind_packets) (fun i -> try Int.List.assoc i names with Not_found -> add_suffix mib.mind_packets.(i).mind_typename ("_"^suff)) in let fold i effs id cl = let role = Evd.Schema ((mind, i), kind)in let loc = Locmap.lookup ~locmap (mind,i) in let cst, effs = define ?loc internal role id cl (Declareops.inductive_is_polymorphic mib) ctx effs in
(effs, cst) in let (eff, consts) = Array.fold_left2_map_i fold eff ids cl in
consts, eff
and define_mutual_scheme ?locmap kind ~internal names mind eff = match Hashtbl.find scheme_object_table kind with
| _,IndividualSchemeFunction _ -> assert false
| s,MutualSchemeFunction (f, deps) -> let deps = match deps with None -> [] | Some deps -> deps (Global.env ()) mind in let eff = List.fold_left (fun eff dep -> declare_scheme_dependence eff dep) eff deps in let _, eff = define_mutual_scheme_base ?locmap kind s f ~internal names mind eff in
eff
and declare_scheme_dependence eff sd = match sd with
| SchemeIndividualDep (ind, kind) -> if local_check_scheme kind ind eff then eff else define_individual_scheme kind ~internal:true None ind eff
| SchemeMutualDep (mind, kind) -> if local_check_scheme kind (mind, 0) eff then eff else define_mutual_scheme kind ~internal:true [] mind eff
let find_scheme kind (mind,i as ind) = letopen Proofview.Notations in
Proofview.tclEVARMAP >>= fun sigma -> match local_lookup_scheme (Evd.eval_side_effects sigma) kind ind with
| Some s ->
Proofview.tclUNIT s
| None -> try match Hashtbl.find scheme_object_table kind with
| s,IndividualSchemeFunction (f, deps) -> let deps = match deps with None -> [] | Some deps -> deps (Global.env ()) ind in let eff = List.fold_left (fun eff dep -> declare_scheme_dependence eff dep) Evd.empty_side_effects deps in let c, eff = define_individual_scheme_base kind s f ~internal:true None ind eff in
Proofview.tclEFFECTS eff <*> Proofview.tclUNIT c
| s,MutualSchemeFunction (f, deps) -> let deps = match deps with None -> [] | Some deps -> deps (Global.env ()) mind in let eff = List.fold_left (fun eff dep -> declare_scheme_dependence eff dep) Evd.empty_side_effects deps in let ca, eff = define_mutual_scheme_base kind s f ~internal:true [] mind eff in
Proofview.tclEFFECTS eff <*> Proofview.tclUNIT ca.(i) with Rocqlib.NotFoundRef _ as e -> let e, info = Exninfo.capture e in
Proofview.tclZERO ~info e
let define_individual_scheme ?loc kind names ind = let eff = define_individual_scheme ?loc kind ~internal:false names ind Evd.empty_side_effects in
redeclare_schemes eff
let define_mutual_scheme ?locmap kind names mind = let eff = define_mutual_scheme ?locmap kind ~internal:false names mind Evd.empty_side_effects in
redeclare_schemes eff
¤ Dauer der Verarbeitung: 0.15 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.