summaryrefslogtreecommitdiff
path: root/checker/declarations.ml
diff options
context:
space:
mode:
Diffstat (limited to 'checker/declarations.ml')
-rw-r--r--checker/declarations.ml582
1 files changed, 159 insertions, 423 deletions
diff --git a/checker/declarations.ml b/checker/declarations.ml
index 890996d1..c6709a78 100644
--- a/checker/declarations.ml
+++ b/checker/declarations.ml
@@ -1,44 +1,14 @@
open Util
open Names
+open Cic
open Term
-open Validate
-
-(* Bytecode *)
-type values
-type reloc_table
-type to_patch_substituted
-(*Retroknowledge *)
-type action
-type retroknowledge
-
-type engagement = ImpredicativeSet
-let val_eng = val_enum "eng" 1
-
-
-type polymorphic_arity = {
- poly_param_levels : Univ.universe option list;
- poly_level : Univ.universe;
-}
-let val_pol_arity =
- val_tuple ~name:"polyorphic_arity"[|val_list(val_opt val_univ);val_univ|]
-
-type constant_type =
- | NonPolymorphicType of constr
- | PolymorphicArity of rel_context * polymorphic_arity
-
-let val_cst_type =
- val_sum "constant_type" 0 [|[|val_constr|];[|val_rctxt;val_pol_arity|]|]
(** Substitutions, code imported from kernel/mod_subst *)
-type delta_hint =
- | Inline of int * constr option
- | Equiv of kernel_name
-
-
module Deltamap = struct
- type t = module_path MPmap.t * delta_hint KNmap.t
+ type t = delta_resolver
let empty = MPmap.empty, KNmap.empty
+ let is_empty (mm, km) = MPmap.is_empty mm && KNmap.is_empty km
let add_kn kn hint (mm,km) = (mm,KNmap.add kn hint km)
let add_mp mp mp' (mm,km) = (MPmap.add mp mp' mm, km)
let remove_mp mp (mm,km) = (MPmap.remove mp mm, km)
@@ -52,18 +22,10 @@ module Deltamap = struct
let join map1 map2 = fold add_mp add_kn map1 map2
end
-type delta_resolver = Deltamap.t
-
let empty_delta_resolver = Deltamap.empty
-module MBImap = Map.Make
- (struct
- type t = mod_bound_id
- let compare = Pervasives.compare
- end)
-
module Umap = struct
- type 'a t = 'a MPmap.t * 'a MBImap.t
+ type 'a t = 'a umap_t
let empty = MPmap.empty, MBImap.empty
let is_empty (m1,m2) = MPmap.is_empty m1 && MBImap.is_empty m2
let add_mbi mbi x (m1,m2) = (m1,MBImap.add mbi x m2)
@@ -78,29 +40,12 @@ module Umap = struct
let join map1 map2 = fold add_mp add_mbi map1 map2
end
-type substitution = (module_path * delta_resolver) Umap.t
type 'a subst_fun = substitution -> 'a -> 'a
let empty_subst = Umap.empty
let is_empty_subst = Umap.is_empty
-let val_delta_hint =
- val_sum "delta_hint" 0
- [|[|val_int; val_opt val_constr|];[|val_kn|]|]
-
-let val_res =
- val_tuple ~name:"delta_resolver"
- [|val_map ~name:"delta_resolver" val_mp val_mp;
- val_map ~name:"delta_resolver" val_kn val_delta_hint|]
-
-let val_mp_res = val_tuple [|val_mp;val_res|]
-
-let val_subst =
- val_tuple ~name:"substitution"
- [|val_map ~name:"substitution" val_mp val_mp_res;
- val_map ~name:"substitution" val_uid val_mp_res|]
-
let add_mbid mbid mp = Umap.add_mbi mbid (mp,empty_delta_resolver)
let add_mp mp1 mp2 = Umap.add_mp mp1 (mp2,empty_delta_resolver)
@@ -110,7 +55,7 @@ let map_mp mp1 mp2 = add_mp mp1 mp2 empty_subst
let mp_in_delta mp =
Deltamap.mem_mp mp
-let rec find_prefix resolve mp =
+let find_prefix resolve mp =
let rec sub_mp = function
| MPdot(mp,l) as mp_sup ->
(try Deltamap.find_mp mp_sup resolve
@@ -136,10 +81,8 @@ let solve_delta_kn resolve kn =
make_kn new_mp dir l
let gen_of_delta resolve x kn fix_can =
- try
- let new_kn = solve_delta_kn resolve kn in
- if kn == new_kn then x else fix_can new_kn
- with _ -> x
+ let new_kn = solve_delta_kn resolve kn in
+ if kn == new_kn then x else fix_can new_kn
let constant_of_delta resolve con =
let kn = user_con con in
@@ -221,6 +164,11 @@ let gen_subst_mp f sub mp1 mp2 =
| None, Some (mp',resolve) -> Canonical, (f mp1 mp'), resolve
| Some (mp1',_), Some (mp2',resolve2) -> Canonical, (f mp1' mp2'), resolve2
+let make_mind_equiv mpu mpc dir l =
+ let knu = make_kn mpu dir l in
+ if mpu == mpc then mind_of_kn knu
+ else mind_of_kn_equiv knu (make_kn mpc dir l)
+
let subst_ind sub mind =
let kn1,kn2 = user_mind mind, canonical_mind mind in
let mp1,dir,l = repr_kn kn1 in
@@ -233,12 +181,17 @@ let subst_ind sub mind =
| Canonical -> mind_of_delta2 resolve mind'
with No_subst -> mind
-let subst_con0 sub con =
+let make_con_equiv mpu mpc dir l =
+ let knu = make_kn mpu dir l in
+ if mpu == mpc then constant_of_kn knu
+ else constant_of_kn_equiv knu (make_kn mpc dir l)
+
+let subst_con0 sub con u =
let kn1,kn2 = user_con con,canonical_con con in
let mp1,dir,l = repr_kn kn1 in
let mp2,_,_ = repr_kn kn2 in
let rebuild_con mp1 mp2 = make_con_equiv mp1 mp2 dir l in
- let dup con = con, Const con in
+ let dup con = con, Const (con, u) in
let side,con',resolve = gen_subst_mp rebuild_con sub mp1 mp2 in
match constant_of_delta_with_inline resolve con' with
| Some t -> con', t
@@ -252,13 +205,21 @@ let subst_con0 sub con =
let rec map_kn f f' c =
let func = map_kn f f' in
match c with
- | Const kn -> (try snd (f' kn) with No_subst -> c)
- | Ind (kn,i) ->
+ | Const (kn, u) -> (try snd (f' kn u) with No_subst -> c)
+ | Proj (kn,t) ->
+ let kn' =
+ try fst (f' kn Univ.Instance.empty)
+ with No_subst -> kn
+ in
+ let t' = func t in
+ if kn' == kn && t' == t then c
+ else Proj (kn', t')
+ | Ind ((kn,i),u) ->
let kn' = f kn in
- if kn'==kn then c else Ind (kn',i)
- | Construct ((kn,i),j) ->
+ if kn'==kn then c else Ind ((kn',i),u)
+ | Construct (((kn,i),j),u) ->
let kn' = f kn in
- if kn'==kn then c else Construct ((kn',i),j)
+ if kn'==kn then c else Construct (((kn',i),j),u)
| Case (ci,p,ct,l) ->
let ci_ind =
let (kn,i) = ci.ci_ind in
@@ -267,7 +228,7 @@ let rec map_kn f f' c =
in
let p' = func p in
let ct' = func ct in
- let l' = array_smartmap func l in
+ let l' = Array.smartmap func l in
if (ci.ci_ind==ci_ind && p'==p
&& l'==l && ct'==ct)then c
else
@@ -296,21 +257,21 @@ let rec map_kn f f' c =
else LetIn (na, b', t', ct')
| App (ct,l) ->
let ct' = func ct in
- let l' = array_smartmap func l in
+ let l' = Array.smartmap func l in
if (ct'== ct && l'==l) then c
else App (ct',l')
| Evar (e,l) ->
- let l' = array_smartmap func l in
+ let l' = Array.smartmap func l in
if (l'==l) then c
else Evar (e,l')
| Fix (ln,(lna,tl,bl)) ->
- let tl' = array_smartmap func tl in
- let bl' = array_smartmap func bl in
+ let tl' = Array.smartmap func tl in
+ let bl' = Array.smartmap func bl in
if (bl == bl'&& tl == tl') then c
else Fix (ln,(lna,tl',bl'))
| CoFix(ln,(lna,tl,bl)) ->
- let tl' = array_smartmap func tl in
- let bl' = array_smartmap func bl in
+ let tl' = Array.smartmap func tl in
+ let bl' = Array.smartmap func bl in
if (bl == bl'&& tl == tl') then c
else CoFix (ln,(lna,tl',bl'))
| _ -> c
@@ -318,24 +279,10 @@ let rec map_kn f f' c =
let subst_mps sub c =
if is_empty_subst sub then c
else map_kn (subst_ind sub) (subst_con0 sub) c
-
-
-type 'a lazy_subst =
- | LSval of 'a
- | LSlazy of substitution list * 'a
-
-type 'a substituted = 'a lazy_subst ref
-
-let val_substituted val_a =
- val_ref
- (val_sum "constr_substituted" 0
- [|[|val_a|];[|val_list val_subst;val_a|]|])
-
-let from_val a = ref (LSval a)
let rec replace_mp_in_mp mpfrom mpto mp =
match mp with
- | _ when mp = mpfrom -> mpto
+ | _ when ModPath.equal mp mpfrom -> mpto
| MPdot (mp1,l) ->
let mp1' = replace_mp_in_mp mpfrom mpto mp1 in
if mp1==mp1' then mp
@@ -344,7 +291,7 @@ let rec replace_mp_in_mp mpfrom mpto mp =
let rec mp_in_mp mp mp1 =
match mp1 with
- | _ when mp1 = mp -> true
+ | _ when ModPath.equal mp1 mp -> true
| MPdot (mp2,l) -> mp_in_mp mp mp2
| _ -> false
@@ -417,14 +364,14 @@ let update_delta_resolver resolver1 resolver2 =
let add_delta_resolver resolver1 resolver2 =
if resolver1 == resolver2 then
resolver2
- else if resolver2 = empty_delta_resolver then
+ else if Deltamap.is_empty resolver2 then
resolver1
else
Deltamap.join (update_delta_resolver resolver1 resolver2) resolver2
let substition_prefixed_by k mp subst =
let mp_prefixmp kmp (mp_to,reso) sub =
- if mp_in_mp mp kmp && mp <> kmp then
+ if mp_in_mp mp kmp && not (ModPath.equal mp kmp) then
let new_key = replace_mp_in_mp mp k kmp in
Umap.add_mp new_key (mp_to,reso) sub
else sub
@@ -455,75 +402,51 @@ let join subst1 subst2 =
let subst = Umap.fold mp_apply_subst mbi_apply_subst subst1 empty_subst in
Umap.join subst2 subst
-let force fsubst r =
- match !r with
- | LSval a -> a
- | LSlazy(s,a) ->
- let subst = List.fold_left join empty_subst (List.rev s) in
- let a' = fsubst subst a in
- r := LSval a';
- a'
-
-let subst_substituted s r =
- match !r with
- | LSval a -> ref (LSlazy([s],a))
- | LSlazy(s',a) ->
- ref (LSlazy(s::s',a))
+let from_val x = { subst_value = x; subst_subst = []; }
-let force_constr = force subst_mps
+let force fsubst r = match r.subst_subst with
+| [] -> r.subst_value
+| s ->
+ let subst = List.fold_left join empty_subst (List.rev s) in
+ let x = fsubst subst r.subst_value in
+ let () = r.subst_subst <- [] in
+ let () = r.subst_value <- x in
+ x
-type constr_substituted = constr substituted
+let subst_substituted s r = { r with subst_subst = s :: r.subst_subst; }
-let val_cstr_subst = val_substituted val_constr
+let force_constr = force subst_mps
let subst_constr_subst = subst_substituted
-(** Beware! In .vo files, lazy_constr are stored as integers
- used as indexes for a separate table. The actual lazy_constr is restored
- later, by [Safe_typing.LightenLibrary.load]. This allows us
- to use here a different definition of lazy_constr than coqtop:
- since the checker will inspect all proofs parts, even opaque
- ones, no need to use Lazy.t here *)
-
-type lazy_constr = constr_substituted
-let subst_lazy_constr = subst_substituted
-let force_lazy_constr = force_constr
-let lazy_constr_from_val c = c
-let val_lazy_constr = val_cstr_subst
-
-(** Inlining level of parameters at functor applications.
- This is ignored by the checker. *)
-
-type inline = int option
+let subst_lazy_constr sub = function
+ | Indirect (l,dp,i) -> Indirect (sub::l,dp,i)
-(** A constant can have no body (axiom/parameter), or a
- transparent body, or an opaque one *)
+let indirect_opaque_access =
+ ref ((fun dp i -> assert false) : DirPath.t -> int -> constr)
+let indirect_opaque_univ_access =
+ ref ((fun dp i -> assert false) : DirPath.t -> int -> Univ.constraints)
-type constant_def =
- | Undef of inline
- | Def of constr_substituted
- | OpaqueDef of lazy_constr
+let force_lazy_constr = function
+ | Indirect (l,dp,i) ->
+ let c = !indirect_opaque_access dp i in
+ force_constr (List.fold_right subst_constr_subst l (from_val c))
-let val_cst_def =
- val_sum "constant_def" 0
- [|[|val_opt val_int|]; [|val_cstr_subst|]; [|val_lazy_constr|]|]
+let force_lazy_constr_univs = function
+ | OpaqueDef (Indirect (l,dp,i)) -> !indirect_opaque_univ_access dp i
+ | _ -> Univ.empty_constraint
let subst_constant_def sub = function
| Undef inl -> Undef inl
| Def c -> Def (subst_constr_subst sub c)
| OpaqueDef lc -> OpaqueDef (subst_lazy_constr sub lc)
-type constant_body = {
- const_hyps : section_context; (* New: younger hyp at top *)
- const_body : constant_def;
- const_type : constant_type;
- const_body_code : to_patch_substituted;
- const_constraints : Univ.constraints }
+(** Local variables and graph *)
let body_of_constant cb = match cb.const_body with
| Undef _ -> None
- | Def c -> Some c
- | OpaqueDef c -> Some c
+ | Def c -> Some (force_constr c)
+ | OpaqueDef c -> Some (force_lazy_constr c)
let constant_has_body cb = match cb.const_body with
| Undef _ -> false
@@ -533,40 +456,18 @@ let is_opaque cb = match cb.const_body with
| OpaqueDef _ -> true
| Def _ | Undef _ -> false
-let val_cb = val_tuple ~name:"constant_body"
- [|val_nctxt;
- val_cst_def;
- val_cst_type;
- no_val;
- val_cstrs|]
-
let subst_rel_declaration sub (id,copt,t as x) =
let copt' = Option.smartmap (subst_mps sub) copt in
let t' = subst_mps sub t in
- if copt == copt' & t == t' then x else (id,copt',t')
-
-let subst_rel_context sub = list_smartmap (subst_rel_declaration sub)
+ if copt == copt' && t == t' then x else (id,copt',t')
-type recarg =
- | Norec
- | Mrec of inductive
- | Imbr of inductive
-let val_recarg = val_sum "recarg" 1 (* Norec *)
- [|[|val_ind|] (* Mrec *);[|val_ind|] (* Imbr *)|]
+let subst_rel_context sub = List.smartmap (subst_rel_declaration sub)
let subst_recarg sub r = match r with
| Norec -> r
| (Mrec(kn,i)|Imbr (kn,i)) -> let kn' = subst_ind sub kn in
if kn==kn' then r else Imbr (kn',i)
-type wf_paths = recarg Rtree.t
-let val_wfp = val_rec_sum "wf_paths" 0
- (fun val_wfp ->
- [|[|val_int;val_int|]; (* Rtree.Param *)
- [|val_recarg;val_array val_wfp|]; (* Rtree.Node *)
- [|val_int;val_array val_wfp|] (* Rtree.Rec *)
- |])
-
let mk_norec = Rtree.mk_node Norec [||]
let mk_paths r recargs =
@@ -581,6 +482,14 @@ let dest_subterms p =
let subst_wf_paths sub p = Rtree.smartmap (subst_recarg sub) p
+let eq_recarg r1 r2 = match r1, r2 with
+ | Norec, Norec -> true
+ | Mrec i1, Mrec i2 -> Names.eq_ind i1 i2
+ | Imbr i1, Imbr i2 -> Names.eq_ind i1 i2
+ | _ -> false
+
+let eq_wf_paths = Rtree.equal eq_recarg
+
(**********************************************************************)
(* Representation of mutual inductive types in the kernel *)
(*
@@ -589,142 +498,66 @@ let subst_wf_paths sub p = Rtree.smartmap (subst_recarg sub) p
with In (params) : Un := cn1 : Tn1 | ... | cnpn : Tnpn
*)
-type monomorphic_inductive_arity = {
- mind_user_arity : constr;
- mind_sort : sorts;
-}
-let val_mono_ind_arity =
- val_tuple ~name:"monomorphic_inductive_arity"[|val_constr;val_sort|]
-
-type inductive_arity =
-| Monomorphic of monomorphic_inductive_arity
-| Polymorphic of polymorphic_arity
-let val_ind_arity = val_sum "inductive_arity" 0
- [|[|val_mono_ind_arity|];[|val_pol_arity|]|]
-
-type one_inductive_body = {
-
-(* Primitive datas *)
-
- (* Name of the type: [Ii] *)
- mind_typename : identifier;
- (* Arity context of [Ii] with parameters: [forall params, Ui] *)
- mind_arity_ctxt : rel_context;
+let subst_decl_arity f g sub ar =
+ match ar with
+ | RegularArity x ->
+ let x' = f sub x in
+ if x' == x then ar
+ else RegularArity x'
+ | TemplateArity x ->
+ let x' = g sub x in
+ if x' == x then ar
+ else TemplateArity x'
- (* Arity sort, original user arity, and allowed elim sorts, if monomorphic *)
- mind_arity : inductive_arity;
+let map_decl_arity f g = function
+ | RegularArity a -> RegularArity (f a)
+ | TemplateArity a -> TemplateArity (g a)
- (* Names of the constructors: [cij] *)
- mind_consnames : identifier array;
- (* Types of the constructors with parameters: [forall params, Tij],
- where the Ik are replaced by de Bruijn index in the context
- I1:forall params, U1 .. In:forall params, Un *)
- mind_user_lc : constr array;
-
-(* Derived datas *)
-
- (* Number of expected real arguments of the type (no let, no params) *)
- mind_nrealargs : int;
-
- (* Length of realargs context (with let, no params) *)
- mind_nrealargs_ctxt : int;
-
- (* List of allowed elimination sorts *)
- mind_kelim : sorts_family list;
-
- (* Head normalized constructor types so that their conclusion is atomic *)
- mind_nf_lc : constr array;
-
- (* Length of the signature of the constructors (with let, w/o params) *)
- mind_consnrealdecls : int array;
-
- (* Signature of recursive arguments in the constructors *)
- mind_recargs : wf_paths;
-
-(* Datas for bytecode compilation *)
-
- (* number of constant constructor *)
- mind_nb_constant : int;
-
- (* number of no constant constructor *)
- mind_nb_args : int;
-
- mind_reloc_tbl : reloc_table;
- }
-
-let val_one_ind = val_tuple ~name:"one_inductive_body"
- [|val_id;val_rctxt;val_ind_arity;val_array val_id;val_array val_constr;
- val_int;val_int;val_list val_sortfam;val_array val_constr;val_array val_int;
- val_wfp;val_int;val_int;no_val|]
-
-
-type mutual_inductive_body = {
-
- (* The component of the mutual inductive block *)
- mind_packets : one_inductive_body array;
-
- (* Whether the inductive type has been declared as a record *)
- mind_record : bool;
-
- (* Whether the type is inductive or coinductive *)
- mind_finite : bool;
-
- (* Number of types in the block *)
- mind_ntypes : int;
-
- (* Section hypotheses on which the block depends *)
- mind_hyps : section_context;
+let subst_rel_declaration sub (id,copt,t as x) =
+ let copt' = Option.smartmap (subst_mps sub) copt in
+ let t' = subst_mps sub t in
+ if copt == copt' && t == t' then x else (id,copt',t')
- (* Number of expected parameters *)
- mind_nparams : int;
+let subst_rel_context sub = List.smartmap (subst_rel_declaration sub)
- (* Number of recursively uniform (i.e. ordinary) parameters *)
- mind_nparams_rec : int;
+let subst_template_cst_arity sub (ctx,s as arity) =
+ let ctx' = subst_rel_context sub ctx in
+ if ctx==ctx' then arity else (ctx',s)
- (* The context of parameters (includes let-in declaration) *)
- mind_params_ctxt : rel_context;
+let subst_arity sub s = subst_decl_arity subst_mps subst_template_cst_arity sub s
- (* Universes constraints enforced by the inductive declaration *)
- mind_constraints : Univ.constraints;
+(* TODO: should be changed to non-coping after Term.subst_mps *)
+(* NB: we leave bytecode and native code fields untouched *)
+let subst_const_body sub cb =
+ { cb with
+ const_body = subst_constant_def sub cb.const_body;
+ const_type = subst_arity sub cb.const_type }
- }
-let val_ind_pack = val_tuple ~name:"mutual_inductive_body"
- [|val_array val_one_ind;val_bool;val_bool;val_int;val_nctxt;
- val_int; val_int; val_rctxt;val_cstrs|]
+let subst_regular_ind_arity sub s =
+ let uar' = subst_mps sub s.mind_user_arity in
+ if uar' == s.mind_user_arity then s
+ else { mind_user_arity = uar'; mind_sort = s.mind_sort }
-let subst_arity sub = function
-| NonPolymorphicType s -> NonPolymorphicType (subst_mps sub s)
-| PolymorphicArity (ctx,s) -> PolymorphicArity (subst_rel_context sub ctx,s)
+let subst_template_ind_arity sub s = s
-(* TODO: should be changed to non-coping after Term.subst_mps *)
-let subst_const_body sub cb = {
- const_hyps = (assert (cb.const_hyps=[]); []);
- const_body = subst_constant_def sub cb.const_body;
- const_type = subst_arity sub cb.const_type;
- const_body_code = (*Cemitcodes.subst_to_patch_subst sub*) cb.const_body_code;
- const_constraints = cb.const_constraints}
-
-let subst_arity sub = function
-| Monomorphic s ->
- Monomorphic {
- mind_user_arity = subst_mps sub s.mind_user_arity;
- mind_sort = s.mind_sort;
- }
-| Polymorphic s as x -> x
+(* FIXME records *)
+let subst_ind_arity =
+ subst_decl_arity subst_regular_ind_arity subst_template_ind_arity
let subst_mind_packet sub mbp =
{ mind_consnames = mbp.mind_consnames;
mind_consnrealdecls = mbp.mind_consnrealdecls;
+ mind_consnrealargs = mbp.mind_consnrealargs;
mind_typename = mbp.mind_typename;
- mind_nf_lc = array_smartmap (subst_mps sub) mbp.mind_nf_lc;
+ mind_nf_lc = Array.smartmap (subst_mps sub) mbp.mind_nf_lc;
mind_arity_ctxt = subst_rel_context sub mbp.mind_arity_ctxt;
- mind_arity = subst_arity sub mbp.mind_arity;
- mind_user_lc = array_smartmap (subst_mps sub) mbp.mind_user_lc;
+ mind_arity = subst_ind_arity sub mbp.mind_arity;
+ mind_user_lc = Array.smartmap (subst_mps sub) mbp.mind_user_lc;
mind_nrealargs = mbp.mind_nrealargs;
- mind_nrealargs_ctxt = mbp.mind_nrealargs_ctxt;
+ mind_nrealdecls = mbp.mind_nrealdecls;
mind_kelim = mbp.mind_kelim;
mind_recargs = subst_wf_paths sub mbp.mind_recargs (*wf_paths*);
mind_nb_constant = mbp.mind_nb_constant;
@@ -733,146 +566,49 @@ let subst_mind_packet sub mbp =
let subst_mind sub mib =
- { mind_record = mib.mind_record ;
- mind_finite = mib.mind_finite ;
- mind_ntypes = mib.mind_ntypes ;
- mind_hyps = (assert (mib.mind_hyps=[]); []) ;
- mind_nparams = mib.mind_nparams;
- mind_nparams_rec = mib.mind_nparams_rec;
- mind_params_ctxt =
- map_rel_context (subst_mps sub) mib.mind_params_ctxt;
- mind_packets = array_smartmap (subst_mind_packet sub) mib.mind_packets ;
- mind_constraints = mib.mind_constraints }
+ { mib with
+ mind_params_ctxt = map_rel_context (subst_mps sub) mib.mind_params_ctxt;
+ mind_packets = Array.smartmap (subst_mind_packet sub) mib.mind_packets }
(* Modules *)
-(* Whenever you change these types, please do update the validation
- functions below *)
-type structure_field_body =
- | SFBconst of constant_body
- | SFBmind of mutual_inductive_body
- | SFBmodule of module_body
- | SFBmodtype of module_type_body
-
-and structure_body = (label * structure_field_body) list
-
-and struct_expr_body =
- | SEBident of module_path
- | SEBfunctor of mod_bound_id * module_type_body * struct_expr_body
- | SEBapply of struct_expr_body * struct_expr_body * Univ.constraints
- | SEBstruct of structure_body
- | SEBwith of struct_expr_body * with_declaration_body
-
-and with_declaration_body =
- With_module_body of identifier list * module_path
- | With_definition_body of identifier list * constant_body
-
-and module_body =
- { mod_mp : module_path;
- mod_expr : struct_expr_body option;
- mod_type : struct_expr_body;
- mod_type_alg : struct_expr_body option;
- mod_constraints : Univ.constraints;
- mod_delta : delta_resolver;
- mod_retroknowledge : action list}
-
-and module_type_body =
- { typ_mp : module_path;
- typ_expr : struct_expr_body;
- typ_expr_alg : struct_expr_body option ;
- typ_constraints : Univ.constraints;
- typ_delta :delta_resolver}
-
-(* the validation functions: *)
-let rec val_sfb o = val_sum "struct_field_body" 0
- [|[|val_cb|]; (* SFBconst *)
- [|val_ind_pack|]; (* SFBmind *)
- [|val_module|]; (* SFBmodule *)
- [|val_modtype|] (* SFBmodtype *)
- |] o
-and val_sb o = val_list (val_tuple ~name:"label*sfb"[|val_id;val_sfb|]) o
-and val_seb o = val_sum "struct_expr_body" 0
- [|[|val_mp|]; (* SEBident *)
- [|val_uid;val_modtype;val_seb|]; (* SEBfunctor *)
- [|val_seb;val_seb;val_cstrs|]; (* SEBapply *)
- [|val_sb|]; (* SEBstruct *)
- [|val_seb;val_with|] (* SEBwith *)
- |] o
-and val_with o = val_sum "with_declaration_body" 0
- [|[|val_list val_id;val_mp|];
- [|val_list val_id;val_cb|]|] o
-and val_module o = val_tuple ~name:"module_body"
- [|val_mp;val_opt val_seb;val_seb;
- val_opt val_seb;val_cstrs;val_res;no_val|] o
-and val_modtype o = val_tuple ~name:"module_type_body"
- [|val_mp;val_seb;val_opt val_seb;val_cstrs;val_res|] o
-
-
-let rec subst_with_body sub = function
- | With_module_body(id,mp) ->
- With_module_body(id,subst_mp sub mp)
- | With_definition_body(id,cb) ->
- With_definition_body( id,subst_const_body sub cb)
-
-and subst_modtype sub mtb=
- let typ_expr' = subst_struct_expr sub mtb.typ_expr in
- let typ_alg' =
- Option.smartmap
- (subst_struct_expr sub) mtb.typ_expr_alg in
- let mp = subst_mp sub mtb.typ_mp
- in
- if typ_expr'==mtb.typ_expr &&
- typ_alg'==mtb.typ_expr_alg && mp==mtb.typ_mp then
- mtb
- else
- {mtb with
- typ_mp = mp;
- typ_expr = typ_expr';
- typ_expr_alg = typ_alg'}
+let rec functor_map fty f0 = function
+ | NoFunctor a -> NoFunctor (f0 a)
+ | MoreFunctor (mbid,ty,e) -> MoreFunctor(mbid,fty ty,functor_map fty f0 e)
-and subst_structure sub sign =
- let subst_body = function
- SFBconst cb ->
- SFBconst (subst_const_body sub cb)
- | SFBmind mib ->
- SFBmind (subst_mind sub mib)
- | SFBmodule mb ->
- SFBmodule (subst_module sub mb)
- | SFBmodtype mtb ->
- SFBmodtype (subst_modtype sub mtb)
- in
- List.map (fun (l,b) -> (l,subst_body b)) sign
+let implem_map fs fa = function
+ | Struct s -> Struct (fs s)
+ | Algebraic a -> Algebraic (fa a)
+ | impl -> impl
+let subst_with_body sub = function
+ | WithMod(id,mp) -> WithMod(id,subst_mp sub mp)
+ | WithDef(id,c) -> WithDef(id,subst_mps sub c)
-and subst_module sub mb =
- let mtb' = subst_struct_expr sub mb.mod_type in
- let typ_alg' = Option.smartmap
- (subst_struct_expr sub ) mb.mod_type_alg in
- let me' = Option.smartmap
- (subst_struct_expr sub) mb.mod_expr in
- let mp = subst_mp sub mb.mod_mp in
- if mtb'==mb.mod_type && mb.mod_expr == me'
- && mp == mb.mod_mp
- then mb else
- { mb with
- mod_mp = mp;
- mod_expr = me';
- mod_type_alg = typ_alg';
- mod_type=mtb'}
-
-and subst_struct_expr sub = function
- | SEBident mp -> SEBident (subst_mp sub mp)
- | SEBfunctor (mbid, mtb, meb') ->
- SEBfunctor(mbid,subst_modtype sub mtb
- ,subst_struct_expr sub meb')
- | SEBstruct (str)->
- SEBstruct( subst_structure sub str)
- | SEBapply (meb1,meb2,cst)->
- SEBapply(subst_struct_expr sub meb1,
- subst_struct_expr sub meb2,
- cst)
- | SEBwith (meb,wdb)->
- SEBwith(subst_struct_expr sub meb,
- subst_with_body sub wdb)
+let rec subst_expr sub = function
+ | MEident mp -> MEident (subst_mp sub mp)
+ | MEapply (me1,mp2)-> MEapply (subst_expr sub me1, subst_mp sub mp2)
+ | MEwith (me,wd)-> MEwith (subst_expr sub me, subst_with_body sub wd)
+
+let rec subst_expression sub me =
+ functor_map (subst_module sub) (subst_expr sub) me
+and subst_signature sub sign =
+ functor_map (subst_module sub) (subst_structure sub) sign
+and subst_structure sub struc =
+ let subst_body = function
+ | SFBconst cb -> SFBconst (subst_const_body sub cb)
+ | SFBmind mib -> SFBmind (subst_mind sub mib)
+ | SFBmodule mb -> SFBmodule (subst_module sub mb)
+ | SFBmodtype mtb -> SFBmodtype (subst_module sub mtb)
+ in
+ List.map (fun (l,b) -> (l,subst_body b)) struc
+
+and subst_module sub mb =
+ { mb with
+ mod_mp = subst_mp sub mb.mod_mp;
+ mod_expr =
+ implem_map (subst_signature sub) (subst_expression sub) mb.mod_expr;
+ mod_type = subst_signature sub mb.mod_type;
+ mod_type_alg = Option.smartmap (subst_expression sub) mb.mod_type_alg }