aboutsummaryrefslogtreecommitdiffhomepage
path: root/toplevel
diff options
context:
space:
mode:
authorGravatar herbelin <herbelin@85f007b7-540e-0410-9357-904b9bb8a0f7>2001-01-24 16:19:49 +0000
committerGravatar herbelin <herbelin@85f007b7-540e-0410-9357-904b9bb8a0f7>2001-01-24 16:19:49 +0000
commit49d89ef0a7d3baaa28d76e66ce4658d8cc6155b6 (patch)
tree63d9a9951ba4786562cecd4722a00306d4ad99cd /toplevel
parentfd07bda1ac92972c4224868f6d9dfeb430b7f379 (diff)
Ajout de constantes locales dans les Records
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@1266 85f007b7-540e-0410-9357-904b9bb8a0f7
Diffstat (limited to 'toplevel')
-rw-r--r--toplevel/record.ml223
-rw-r--r--toplevel/record.mli7
-rw-r--r--toplevel/vernacentries.ml24
3 files changed, 133 insertions, 121 deletions
diff --git a/toplevel/record.ml b/toplevel/record.ml
index 826732c24..45f50d441 100644
--- a/toplevel/record.ml
+++ b/toplevel/record.ml
@@ -5,167 +5,166 @@ open Pp
open Util
open Names
open Term
+open Environ
open Declarations
open Declare
open Coqast
-open Ast
open Astterm
open Command
(********** definition d'un record (structure) **************)
-let make_constructor fields appc =
+let make_constructor idstruc idps fields =
+ let app_constructor =
+ Ast.ope("APPLISTEXPL",
+ (Ast.nvar (string_of_id idstruc))::
+ List.map (fun id -> Ast.nvar(string_of_id id)) idps) in
let rec aux fields =
match fields with
- | [] -> appc
- | (id,ty)::l -> ope("PROD",[ty; slam(Some (string_of_id id), aux l)])
+ | [] -> app_constructor
+ | (id,true,ty)::l ->
+ Ast.ope("PROD",[ty; Ast.slam(Some (string_of_id id), aux l)])
+ | (id,false,c)::l ->
+ Ast.ope("LETIN",[c; Ast.slam(Some (string_of_id id), aux l)])
in
aux fields
-(* free_vars existe de'ja` dans ast.ml *)
-
-let rec drop = function
- | [] -> []
- | (None::t) -> drop t
- | ((Some id)::t) -> id::(drop t)
-
-let fold curriedf l base =
- List.fold_right (fun a -> fun b -> curriedf(a,b)) l base
-
-let free_vars t =
- let rec aux = function
- | (Nvar(_,s),accum) -> list_add_set (id_of_string s) accum
- | (Node(_,_,tl),accum) -> fold aux tl accum
- | (Slam(_,None,body),accum) -> (aux(body,[]))@accum
- | (Slam(_,Some id,body),accum) ->
- (list_subtract (aux(body,[])) [(id_of_string id)])@accum
- | (_,accum) -> accum
- in
- aux(t,[])
-
-let free_in_asts id l =
- let rec aux =
- function
- | [] -> true
- | a::l -> (not (List.mem id (free_vars a))) & (aux l)
- in
- aux l
+let occur_fields id fs =
+ List.exists (fun (_,_,a) -> Ast.occur_var_ast (string_of_id id) a) fs
-let all_vars t =
- let rec aux = function
- | (Nvar(_,id),accum) -> list_add_set (id_of_string id) accum
- | (Node(_,_,tl),accum) -> fold aux tl accum
- | (Slam(_,None,body),accum) -> aux (body,accum)
- | (Slam(_,Some id,body),accum) ->
- aux (body,(list_union accum [(id_of_string id)]))
- | (_,accum) -> accum
- in
- aux(t,[])
-
-let pr_id_list l =
- [< 'sTR "[" ; prlist_with_sep pr_coma pr_id l; 'sTR "]" >]
-
-open Environ
+let interp_decl sigma env (id,assum,t) =
+ if assum then
+ (id,None,interp_type Evd.empty env t)
+ else
+ let j = judgment_of_rawconstr Evd.empty env t in
+ (id,Some j.uj_val, j.uj_type)
let typecheck_params_and_field ps fs =
let env0 = Global.env () in
let env1,newps =
List.fold_left
(fun (env,newps) (id,t) ->
- let tj = interp_type Evd.empty env t in
- (push_named_assum (id,tj) env,(id,tj)::newps))
+ let decl = interp_decl Evd.empty env (id,true,t) in
+ (push_named_decl decl env,decl::newps))
(env0,[]) ps
in
let env2,newfs =
List.fold_left
- (fun (env,newfs) (id,t) ->
- let ass = interp_type Evd.empty env t in
- (push_named_assum (id,ass) env,(id,ass)::newfs)) (env1,[]) fs
+ (fun (env,newfs) d ->
+ let decl = interp_decl Evd.empty env d in
+ (push_named_decl decl env, decl::newfs))
+ (env1,[]) fs
+ in
+ newps, newfs
+
+type record_error =
+ | MissingProj of identifier * identifier list
+ | BadTypedProj of identifier * path_kind * env * Type_errors.type_error
+
+let warning_or_error coe err =
+ let st = match err with
+ | MissingProj (fi,projs) ->
+ let s,have = if List.length projs > 1 then "s","have" else "","has" in
+ [< 'sTR(string_of_id fi);
+ 'sTR" cannot be defined because the projection"; 'sTR s; 'sPC;
+ prlist_with_sep pr_coma pr_id projs; 'sPC; 'sTR have; 'sTR "n't." >]
+ | BadTypedProj (fi,k,ctx,te) ->
+ [<'sTR (string_of_id fi);
+ 'sTR" cannot be defined for the following reason:";
+ 'fNL; 'sTR " "; hOV 2 (Himsg.explain_type_error k ctx te) >]
in
- List.rev(newps),List.rev(newfs)
-
-let mk_LambdaCit = List.fold_right (fun (x,a) b -> mkNamedLambda x a b)
-
-let warning_or_error coe st =
if coe then errorlabstrm "structure" st;
pPNL (hOV 0 [< 'sTR"Warning: "; st >])
(* We build projections *)
-let declare_projections idstruc coers params fields =
+let declare_projections idstruc coers paramdecls fields =
let r = global_reference CCI idstruc in
- let lp = List.length params in
- let rp1 = applist (r,(rel_list 0 lp)) in
- let rp2 = applist (r,(rel_list 1 lp)) in
+ let paramargs = List.rev (List.map (fun (id,_,_) -> mkVar id) paramdecls) in
+ let rp = applist (r, paramargs) in
let x = Environ.named_hd (Global.env()) r Anonymous in
- let args = (* Rel 1 refers to "x" *)
- (List.map (fun (id,_) -> mkVar id) params)@[mkRel 1] in
+ let proj_args = (* Rel 1 refers to "x" *) paramargs@[mkRel 1] in
let (sp_projs,_,_) =
List.fold_left2
- (fun (sp_projs,ids_not_ok,subst) coe (fi,ti) ->
- let fv_ti = global_vars ti in
+ (fun (sp_projs,ids_not_ok,subst) coe (fi,optci,ti) ->
+ let fv_ti = match optci with
+ | Some ci -> global_vars ci (* Type is then meaningless *)
+ | None -> global_vars ti in
let bad_projs = (list_intersect ids_not_ok fv_ti) in
if bad_projs <> [] then begin
- let s,have =
- if List.length bad_projs > 1 then "s","have" else "","has" in
- (warning_or_error coe
- [< 'sTR(string_of_id fi);
- 'sTR" cannot be defined because the projection"; 'sTR s; 'sPC;
- prlist_with_sep pr_coma pr_id bad_projs;
- 'sPC; 'sTR have; 'sTR "n't." >]);
+ warning_or_error coe (MissingProj (fi,bad_projs));
(None::sp_projs,fi::ids_not_ok,subst)
- end else
- let p = mkLambda (x, rp2, replace_vars subst ti) in
- let branch = mk_LambdaCit fields (mkVar fi) in
- let ci = Inductive.make_case_info
- (Global.lookup_mind_specif (destMutInd r))
- (Some PrintLet) [| RegularPat |] in
- let proj = mk_LambdaCit params
- (mkLambda (x, rp1,
- mkMutCase (ci, p, mkRel 1, [|branch|]))) in
+ end else
+ let body = match optci with
+ | Some ci -> replace_vars subst ci
+ | None ->
+ let p = mkLambda (x, rp, replace_vars subst ti) in
+ let branch = it_mkNamedLambda_or_LetIn (mkVar fi) fields in
+ let ci = Inductive.make_case_info
+ (Global.lookup_mind_specif (destMutInd r))
+ (Some PrintLet) [| RegularPat |] in
+ mkMutCase (ci, p, mkRel 1, [|branch|]) in
+ let proj =
+ it_mkNamedLambda_or_LetIn (mkLambda (x, rp, body)) paramdecls in
let ok =
try
- let cie =
- { const_entry_body = proj;
- const_entry_type = None } in
- (declare_constant fi (ConstantEntry cie,NeverDischarge,false);
- true)
- with Type_errors.TypeError (k,ctx,te) ->
- ((warning_or_error coe
- [<'sTR (string_of_id fi);
- 'sTR" cannot be defined for the following reason:";
- 'fNL; 'sTR " ";
- hOV 2 (Himsg.explain_type_error k ctx te) >]);
- false) in
+ let cie = { const_entry_body = proj; const_entry_type = None} in
+ declare_constant fi (ConstantEntry cie,NeverDischarge,false);
+ true
+ with Type_errors.TypeError (k,ctx,te) -> begin
+ warning_or_error coe (BadTypedProj (fi,k,ctx,te));
+ false
+ end in
if not ok then
(None::sp_projs,fi::ids_not_ok,subst)
else begin
if coe then
Class.try_add_new_coercion_record fi NeverDischarge idstruc;
let constr_fi = global_reference CCI fi in
- let constr_fip = applist (constr_fi,args)
+ let constr_fip = applist (constr_fi,proj_args)
in (Some(path_of_const constr_fi)::sp_projs,
ids_not_ok, (fi,constr_fip)::subst)
end)
- ([],[],[]) coers fields
+ ([],[],[]) coers (List.rev fields)
in sp_projs
-(* Fields have names [idfs] and types [tyfs]; [coers] is a boolean list
- telling if the corresponding field must me a coercion *)
+let degenerate_decl env =
+ snd
+ (List.fold_right
+ (fun (id,c,t) (ids,env) ->
+ let d = match c with
+ | None -> LocalAssum (subst_vars ids t)
+ | Some c -> LocalDef (subst_vars ids c) in
+ (id::ids, (id,d)::env))
+ env ([],[]))
+
+(* [fs] corresponds to fields and [ps] to parameters; [coers] is a boolean
+ list telling if the corresponding fields must me declared as coercion *)
let definition_structure (is_coe,idstruc,ps,cfs,idbuild,s) =
- let coers,fs = List.split cfs in
- let idps,typs = List.split ps in
- let idfs,tyfs = List.split fs in
- if not (free_in_asts idstruc tyfs) then error "A record cannot be recursive";
- let newps,newfs = typecheck_params_and_field ps fs in
- let app_constructor =
- ope("APPLISTEXPL",
- (nvar (string_of_id idstruc))::
- List.map (fun id -> nvar(string_of_id id)) idps) in
- let type_constructor = make_constructor fs app_constructor in
- let sp = build_mutual_give_path
- ps [(idstruc,s,[(idbuild,type_constructor)])] true in
- let sp_projs = declare_projections idstruc coers newps newfs in
-
+ let coers,fs = List.split cfs in
+ let nparams = List.length ps in
+ let idps = List.map fst ps in
+ let allnames = idstruc::idps@(List.map (fun (id,_,_) -> id) fs) in
+ if not (list_distinct allnames) then error "Two objects have the same name";
+ if occur_fields idstruc fs then error "A record cannot be recursive";
+ (* Now, younger decl in params and fields is on top *)
+ let params,fields = typecheck_params_and_field ps fs in
+ let args = List.map mkVar idps in
+ let ind = applist (mkVar idstruc, args) in
+ let subst = List.rev (idstruc::idps) in
+ let named_type_constructor = it_mkNamedProd_or_LetIn ind fields in
+ let type_constructor = subst_vars subst named_type_constructor in
+ let mie_ind =
+ { mind_entry_nparams = nparams;
+ mind_entry_params = degenerate_decl params;
+ mind_entry_typename = idstruc;
+ mind_entry_arity = mkSort s;
+ mind_entry_consnames = [idbuild];
+ mind_entry_lc = [type_constructor] } in
+ let mie =
+ { mind_entry_finite = true;
+ mind_entry_inds = [mie_ind] } in
+ let sp = declare_mutual_with_eliminations mie in
+ let sp_projs = declare_projections idstruc coers params fields in
let rsp = (sp,0) in
if is_coe then Class.try_add_new_coercion idbuild NeverDischarge;
- Recordops.add_new_struc (rsp,idbuild,List.length idps,List.rev sp_projs)
+ Recordops.add_new_struc (rsp,idbuild,nparams,List.rev sp_projs)
diff --git a/toplevel/record.mli b/toplevel/record.mli
index 88a3e120f..d6093fdc1 100644
--- a/toplevel/record.mli
+++ b/toplevel/record.mli
@@ -4,6 +4,7 @@
(*i*)
open Names
open Term
+open Sign
(*i*)
(* [declare_projections id coers params fields] declare projections of
@@ -12,10 +13,8 @@ open Term
val declare_projections :
identifier -> bool list ->
- (identifier * types) list -> (identifier * types) list ->
- constant_path option list
+ named_context -> named_context -> constant_path option list
val definition_structure :
bool * identifier * (identifier * Coqast.t) list *
- (bool * (identifier * Coqast.t)) list * identifier *
- Coqast.t -> unit
+ (bool * (identifier * bool * Coqast.t)) list * identifier * sorts -> unit
diff --git a/toplevel/vernacentries.ml b/toplevel/vernacentries.ml
index f5599792e..5714bbded 100644
--- a/toplevel/vernacentries.ml
+++ b/toplevel/vernacentries.ml
@@ -542,13 +542,21 @@ let _ =
| VARG_CONSTANT sp -> Global.set_transparent sp
| _ -> bad_vernac_args "TRANSPARENT")
id_list)
-
+
+let warning_opaque s =
+ warning (
+ "This command turns the constants which depend on the definition/proof
+of "^s^" un-re-checkable until the next \"Transparent "^s^"\" command.")
+
let _ =
add "OPAQUE"
(fun id_list () ->
List.iter
(function
- | VARG_CONSTANT sp -> Global.set_opaque sp
+ | VARG_CONSTANT sp ->
+ warning_opaque
+ (string_of_qualid (Global.qualid_of_global (ConstRef sp)));
+ Global.set_opaque sp
| _ -> bad_vernac_args "OPAQUE")
id_list)
@@ -1114,7 +1122,7 @@ let _ =
| [VARG_STRING coe;
VARG_IDENTIFIER struc;
VARG_BINDERLIST binders;
- VARG_CONSTR s;
+ VARG_CONSTR sort;
VARG_VARGLIST namec;
VARG_VARGLIST cfs] ->
let ps = join_binders binders in
@@ -1122,8 +1130,13 @@ let _ =
List.map
(function
| (VARG_VARGLIST
- [VARG_STRING str; VARG_IDENTIFIER id; VARG_CONSTR c]) ->
- (str = "COERCION",(id,c))
+ [VARG_STRING str; VARG_STRING b;
+ VARG_IDENTIFIER id; VARG_CONSTR c]) ->
+ let assum = match b with
+ | "ASSUM" -> true
+ | "DEF" -> false
+ | _ -> bad_vernac_args "RECORD" in
+ (str = "COERCION", (id, assum, c))
| _ -> bad_vernac_args "RECORD")
cfs in
let const = match namec with
@@ -1131,6 +1144,7 @@ let _ =
| [VARG_IDENTIFIER id] -> id
| _ -> bad_vernac_args "RECORD" in
let iscoe = (coe = "COERCION") in
+ let s = interp_sort sort in
fun () -> Record.definition_structure (iscoe,struc,ps,cfs,const,s)
| _ -> bad_vernac_args "RECORD")