aboutsummaryrefslogtreecommitdiff
path: root/interp/constrintern.ml
diff options
context:
space:
mode:
Diffstat (limited to 'interp/constrintern.ml')
-rw-r--r--interp/constrintern.ml199
1 files changed, 103 insertions, 96 deletions
diff --git a/interp/constrintern.ml b/interp/constrintern.ml
index 349402035c..c0801067ce 100644
--- a/interp/constrintern.ml
+++ b/interp/constrintern.ml
@@ -96,21 +96,6 @@ let is_global id =
with Not_found ->
false
-let global_reference_of_reference qid =
- locate_reference qid
-
-let global_reference id =
- locate_reference (qualid_of_ident id)
-
-let construct_reference ctx id =
- try
- VarRef (let _ = Context.Named.lookup id ctx in id)
- with Not_found ->
- global_reference id
-
-let global_reference_in_absolute_module dir id =
- Nametab.global_of_path (Libnames.make_path dir id)
-
(**********************************************************************)
(* Internalization errors *)
@@ -658,7 +643,7 @@ let terms_of_binders bl =
| PatCstr (c,l,_) ->
let qid = qualid_of_path ?loc (Nametab.path_of_global (ConstructRef c)) in
let hole = CAst.make ?loc @@ CHole (None,IntroAnonymous,None) in
- let params = List.make (Inductiveops.inductive_nparams (fst c)) hole in
+ let params = List.make (Inductiveops.inductive_nparams (Global.env()) (fst c)) hole in
CAppExpl ((None,qid,None),params @ List.map term_of_pat l)) pt in
let rec extract_variables l = match l with
| bnd :: l ->
@@ -753,7 +738,7 @@ let instantiate_notation_constr loc intern intern_pat ntnvars subst infos c =
else
let _,((disjpat,_),_),_ = intern_pat ntnvars nenv c in
match disjpat with
- | [pat] -> (glob_constr_of_cases_pattern pat, None)
+ | [pat] -> (glob_constr_of_cases_pattern (Global.env()) pat, None)
| _ -> error_cannot_coerce_disjunctive_pattern_term ?loc:c.loc ()
in
let terms = Id.Map.fold mk_env terms Id.Map.empty in
@@ -815,7 +800,7 @@ let instantiate_notation_constr loc intern intern_pat ntnvars subst infos c =
else
let env,((disjpat,ids),id),na = intern_pat ntnvars env pat in
match disjpat with
- | [pat] -> glob_constr_of_cases_pattern pat
+ | [pat] -> glob_constr_of_cases_pattern (Global.env()) pat
| _ -> user_err Pp.(str "Cannot turn a disjunctive pattern into a term.")
with Not_found ->
try
@@ -1033,7 +1018,7 @@ let intern_qualid ?(no_secvar=false) qid intern env ntnvars us args =
| TrueGlobal (VarRef _) when no_secvar ->
(* Rule out section vars since these should have been found by intern_var *)
raise Not_found
- | TrueGlobal ref -> (DAst.make ?loc @@ GRef (ref, us)), true, args
+ | TrueGlobal ref -> (DAst.make ?loc @@ GRef (ref, us)), Some ref, args
| SynDef sp ->
let (ids,c) = Syntax_def.search_syntactic_definition ?loc sp in
let nids = List.length ids in
@@ -1043,7 +1028,6 @@ let intern_qualid ?(no_secvar=false) qid intern env ntnvars us args =
let terms = make_subst ids (List.map fst args1) in
let subst = (terms, Id.Map.empty, Id.Map.empty, Id.Map.empty) in
let infos = (Id.Map.empty, env) in
- let projapp = match c with NRef _ -> true | _ -> false in
let c = instantiate_notation_constr loc intern intern_cases_pattern_as_binder ntnvars subst infos c in
let loc = c.loc in
let err () =
@@ -1067,33 +1051,60 @@ let intern_qualid ?(no_secvar=false) qid intern env ntnvars us args =
user_err ?loc (str "Cannot change universe level of notation " ++ pr_qualid qid)
| Some _, _ -> err ()
in
- c, projapp, args2
+ c, None, args2
+
+let warn_nonprimitive_projection =
+ CWarnings.create ~name:"nonprimitive-projection-syntax" ~category:"syntax" ~default:CWarnings.Disabled
+ Pp.(fun f -> pr_qualid f ++ str " used as a primitive projection but is not one.")
+
+let error_nonprojection_syntax ?loc qid =
+ CErrors.user_err ?loc ~hdr:"nonprojection-syntax" Pp.(pr_qualid qid ++ str" is not a projection.")
+
+let check_applied_projection isproj realref qid =
+ match isproj with
+ | None -> ()
+ | Some projargs ->
+ let is_prim = match realref with
+ | None | Some (IndRef _ | ConstructRef _ | VarRef _) -> false
+ | Some (ConstRef c) ->
+ if Recordops.is_primitive_projection c then true
+ else if Recordops.is_projection c then false
+ else error_nonprojection_syntax ?loc:qid.loc qid
+ (* TODO check projargs, note we will need implicit argument info *)
+ in
+ if not is_prim then warn_nonprimitive_projection ?loc:qid.loc qid
-let intern_applied_reference intern env namedctx (_, ntnvars as lvar) us args qid =
+let intern_applied_reference ~isproj intern env namedctx (_, ntnvars as lvar) us args qid =
let loc = qid.CAst.loc in
if qualid_is_ident qid then
- try intern_var env lvar namedctx loc (qualid_basename qid) us, args
+ try
+ let res = intern_var env lvar namedctx loc (qualid_basename qid) us in
+ check_applied_projection isproj None qid;
+ res, args
with Not_found ->
try
- let r, projapp, args2 = intern_qualid ~no_secvar:true qid intern env ntnvars us args in
+ let r, realref, args2 = intern_qualid ~no_secvar:true qid intern env ntnvars us args in
+ check_applied_projection isproj realref qid;
let x, imp, scopes, l = find_appl_head_data r in
(x,imp,scopes,l), args2
with Not_found ->
(* Extra allowance for non globalizing functions *)
if !interning_grammar || env.unb then
+ (* check_applied_projection ?? *)
(gvar (loc,qualid_basename qid) us, [], [], []), args
else Nametab.error_global_not_found qid
else
- let r,projapp,args2 =
+ let r,realref,args2 =
try intern_qualid qid intern env ntnvars us args
with Not_found -> Nametab.error_global_not_found qid
in
+ check_applied_projection isproj realref qid;
let x, imp, scopes, l = find_appl_head_data r in
(x,imp,scopes,l), args2
let interp_reference vars r =
let (r,_,_,_),_ =
- intern_applied_reference (fun _ -> error_not_enough_arguments ?loc:None)
+ intern_applied_reference ~isproj:None (fun _ -> error_not_enough_arguments ?loc:None)
{ids = Id.Set.empty; unb = false ;
tmp_scope = None; scopes = []; impls = empty_internalization_env}
Environ.empty_named_context_val
@@ -1186,10 +1197,10 @@ let check_or_pat_variables loc ids idsl =
@return if letin are included *)
let check_constructor_length env loc cstr len_pl pl0 =
let n = len_pl + List.length pl0 in
- if Int.equal n (Inductiveops.constructor_nallargs cstr) then false else
- (Int.equal n (Inductiveops.constructor_nalldecls cstr) ||
+ if Int.equal n (Inductiveops.constructor_nallargs env cstr) then false else
+ (Int.equal n (Inductiveops.constructor_nalldecls env cstr) ||
(error_wrong_numarg_constructor ?loc env cstr
- (Inductiveops.constructor_nrealargs cstr)))
+ (Inductiveops.constructor_nrealargs env cstr)))
open Declarations
@@ -1215,9 +1226,9 @@ let add_local_defs_and_check_length loc env g pl args = match g with
have been given in the "explicit" arguments, which come from a
"@C args" notation or from a custom user notation *)
let pl' = insert_local_defs_in_pattern cstr pl in
- let maxargs = Inductiveops.constructor_nalldecls cstr in
+ let maxargs = Inductiveops.constructor_nalldecls env cstr in
if List.length pl' + List.length args > maxargs then
- error_wrong_numarg_constructor ?loc env cstr (Inductiveops.constructor_nrealargs cstr);
+ error_wrong_numarg_constructor ?loc env cstr (Inductiveops.constructor_nrealargs env cstr);
(* Two possibilities: either the args are given with explict
variables for local definitions, then we give the explicit args
extended with local defs, so that there is nothing more to be
@@ -1247,15 +1258,15 @@ let add_implicits_check_length fail nargs nargs_with_letin impls_st len_pl1 pl2
in aux 0 (impl_list,pl2)
let add_implicits_check_constructor_length env loc c len_pl1 pl2 =
- let nargs = Inductiveops.constructor_nallargs c in
- let nargs' = Inductiveops.constructor_nalldecls c in
+ let nargs = Inductiveops.constructor_nallargs env c in
+ let nargs' = Inductiveops.constructor_nalldecls env c in
let impls_st = implicits_of_global (ConstructRef c) in
add_implicits_check_length (error_wrong_numarg_constructor ?loc env c)
nargs nargs' impls_st len_pl1 pl2
let add_implicits_check_ind_length env loc c len_pl1 pl2 =
- let nallargs = inductive_nallargs_env env c in
- let nalldecls = inductive_nalldecls_env env c in
+ let nallargs = inductive_nallargs env c in
+ let nalldecls = inductive_nalldecls env c in
let impls_st = implicits_of_global (IndRef c) in
add_implicits_check_length (error_wrong_numarg_inductive ?loc env c)
nallargs nalldecls impls_st len_pl1 pl2
@@ -1263,8 +1274,8 @@ let add_implicits_check_ind_length env loc c len_pl1 pl2 =
(** Do not raise NotEnoughArguments thanks to preconditions*)
let chop_params_pattern loc ind args with_letin =
let nparams = if with_letin
- then Inductiveops.inductive_nparamdecls ind
- else Inductiveops.inductive_nparams ind in
+ then Inductiveops.inductive_nparamdecls (Global.env()) ind
+ else Inductiveops.inductive_nparams (Global.env()) ind in
assert (nparams <= List.length args);
let params,args = List.chop nparams args in
List.iter (fun c -> match DAst.get c with
@@ -1284,10 +1295,11 @@ let find_constructor loc add_params ref =
in
cstr, match add_params with
| Some nb_args ->
+ let env = Global.env () in
let nb =
- if Int.equal nb_args (Inductiveops.constructor_nrealdecls cstr)
- then Inductiveops.inductive_nparamdecls ind
- else Inductiveops.inductive_nparams ind
+ if Int.equal nb_args (Inductiveops.constructor_nrealdecls env cstr)
+ then Inductiveops.inductive_nparamdecls env ind
+ else Inductiveops.inductive_nparams env ind
in
List.make nb ([], [(Id.Map.empty, DAst.make @@ PatVar Anonymous)])
| None -> []
@@ -1328,7 +1340,7 @@ let sort_fields ~complete loc fields completer =
| (first_field_ref, first_field_value):: other_fields ->
let (first_field_glob_ref, record) =
try
- let gr = global_reference_of_reference first_field_ref in
+ let gr = locate_reference first_field_ref in
(gr, Recordops.find_projection gr)
with Not_found ->
raise (InternalizationError(loc, NotAProjection first_field_ref))
@@ -1386,7 +1398,7 @@ let sort_fields ~complete loc fields completer =
let rec index_fields fields remaining_projs acc =
match fields with
| (field_ref, field_value) :: fields ->
- let field_glob_ref = try global_reference_of_reference field_ref
+ let field_glob_ref = try locate_reference field_ref
with Not_found ->
user_err ?loc ~hdr:"intern"
(str "The field \"" ++ pr_qualid field_ref ++ str "\" does not exist.") in
@@ -1461,8 +1473,9 @@ let alias_of als = match als.alias_ids with
let is_zero s =
let rec aux i =
- Int.equal (String.length s) i || (s.[i] == '0' && aux (i+1))
+ Int.equal (String.length s) i || ((s.[i] == '0' || s.[i] == '_') && aux (i+1))
in aux 0
+let is_zero n = is_zero n.NumTok.int && is_zero n.NumTok.frac
let merge_subst s1 s2 = Id.Map.fold Id.Map.add s1 s2
@@ -1487,11 +1500,11 @@ let rec subst_pat_iterator y t = DAst.(map (function
| RCPatOr pl -> RCPatOr (List.map (subst_pat_iterator y t) pl)))
let is_non_zero c = match c with
-| { CAst.v = CPrim (Numeral (p, true)) } -> not (is_zero p)
+| { CAst.v = CPrim (Numeral (SPlus, p)) } -> not (is_zero p)
| _ -> false
let is_non_zero_pat c = match c with
-| { CAst.v = CPatPrim (Numeral (p, true)) } -> not (is_zero p)
+| { CAst.v = CPatPrim (Numeral (SPlus, p)) } -> not (is_zero p)
| _ -> false
let get_asymmetric_patterns = Goptions.declare_bool_option_and_ref
@@ -1602,8 +1615,8 @@ let drop_notations_pattern looked_for genv =
let (argscs1,_) = find_remaining_scopes expl_pl pl g in
DAst.make ?loc @@ RCPatCstr (g, List.map2 (in_pat_sc scopes) argscs1 expl_pl @ List.map (in_pat false scopes) pl, [])
| CPatNotation ((InConstrEntrySomeLevel,"- _"),([a],[]),[]) when is_non_zero_pat a ->
- let p = match a.CAst.v with CPatPrim (Numeral (p, _)) -> p | _ -> assert false in
- let pat, _df = Notation.interp_prim_token_cases_pattern_expr ?loc (ensure_kind false loc) (Numeral (p,false)) scopes in
+ let p = match a.CAst.v with CPatPrim (Numeral (_, p)) -> p | _ -> assert false in
+ let pat, _df = Notation.interp_prim_token_cases_pattern_expr ?loc (ensure_kind false loc) (Numeral (SMinus,p)) scopes in
rcp_of_glob scopes pat
| CPatNotation ((InConstrEntrySomeLevel,"( _ )"),([a],[]),[]) ->
in_pat top scopes a
@@ -1827,56 +1840,49 @@ let internalize globalenv env pattern_mode (_, ntnvars as lvar) c =
let rec intern env = CAst.with_loc_val (fun ?loc -> function
| CRef (ref,us) ->
let (c,imp,subscopes,l),_ =
- intern_applied_reference intern env (Environ.named_context_val globalenv)
- lvar us [] ref
+ intern_applied_reference ~isproj:None intern env (Environ.named_context_val globalenv)
+ lvar us [] ref
in
apply_impargs c env imp subscopes l loc
- | CFix ({ CAst.loc = locid; v = iddef}, dl) ->
+ | CFix ({ CAst.loc = locid; v = iddef}, dl) ->
let lf = List.map (fun ({CAst.v = id},_,_,_,_) -> id) dl in
let dl = Array.of_list dl in
- let n =
- try List.index0 Id.equal iddef lf
+ let n =
+ try List.index0 Id.equal iddef lf
with Not_found ->
- raise (InternalizationError (locid,UnboundFixName (false,iddef)))
- in
- let idl_temp = Array.map
- (fun (id,(n,order),bl,ty,_) ->
- let intern_ro_arg f =
- let before, after = split_at_annot bl n in
- let (env',rbefore) = List.fold_left intern_local_binder (env,[]) before in
- let ro = f (intern env') in
- let n' = Option.map (fun _ -> List.count (fun c -> match DAst.get c with
- | GLocalAssum _ -> true
- | _ -> false (* remove let-ins *))
- rbefore) n in
- n', ro, List.fold_left intern_local_binder (env',rbefore) after
- in
- let n, ro, (env',rbl) =
- match order with
- | CStructRec ->
- intern_ro_arg (fun _ -> GStructRec)
- | CWfRec c ->
- intern_ro_arg (fun f -> GWfRec (f c))
- | CMeasureRec (m,r) ->
- intern_ro_arg (fun f -> GMeasureRec (f m, Option.map f r))
- in
- let bl = List.rev (List.map glob_local_binder_of_extended rbl) in
- ((n, ro), bl, intern_type env' ty, env')) dl in
+ raise (InternalizationError (locid,UnboundFixName (false,iddef)))
+ in
+ let idl_temp = Array.map
+ (fun (id,recarg,bl,ty,_) ->
+ let recarg = Option.map (function { CAst.v = v } -> match v with
+ | CStructRec i -> i
+ | _ -> anomaly Pp.(str "Non-structural recursive argument in non-program fixpoint")) recarg
+ in
+ let before, after = split_at_annot bl recarg in
+ let (env',rbefore) = List.fold_left intern_local_binder (env,[]) before in
+ let n = Option.map (fun _ -> List.count (fun c -> match DAst.get c with
+ | GLocalAssum _ -> true
+ | _ -> false (* remove let-ins *))
+ rbefore) recarg in
+ let (env',rbl) = List.fold_left intern_local_binder (env',rbefore) after in
+ let bl = List.rev (List.map glob_local_binder_of_extended rbl) in
+ (n, bl, intern_type env' ty, env')) dl in
let idl = Array.map2 (fun (_,_,_,_,bd) (a,b,c,env') ->
- let env'' = List.fold_left_i (fun i en name ->
- let (_,bli,tyi,_) = idl_temp.(i) in
- let fix_args = (List.map (fun (na, bk, _, _) -> (build_impls bk na)) bli) in
- push_name_env ntnvars (impls_type_list ~args:fix_args tyi)
- en (CAst.make @@ Name name)) 0 env' lf in
- (a,b,c,intern {env'' with tmp_scope = None} bd)) dl idl_temp in
- DAst.make ?loc @@
- GRec (GFix
- (Array.map (fun (ro,_,_,_) -> ro) idl,n),
+ let env'' = List.fold_left_i (fun i en name ->
+ let (_,bli,tyi,_) = idl_temp.(i) in
+ let fix_args = (List.map (fun (na, bk, _, _) -> (build_impls bk na)) bli) in
+ push_name_env ntnvars (impls_type_list ~args:fix_args tyi)
+ en (CAst.make @@ Name name)) 0 env' lf in
+ (a,b,c,intern {env'' with tmp_scope = None} bd)) dl idl_temp in
+ DAst.make ?loc @@
+ GRec (GFix
+ (Array.map (fun (ro,_,_,_) -> ro) idl,n),
Array.of_list lf,
Array.map (fun (_,bl,_,_) -> bl) idl,
Array.map (fun (_,_,ty,_) -> ty) idl,
Array.map (fun (_,_,_,bd) -> bd) idl)
+
| CCoFix ({ CAst.loc = locid; v = iddef }, dl) ->
let lf = List.map (fun ({CAst.v = id},_,_,_) -> id) dl in
let dl = Array.of_list dl in
@@ -1918,8 +1924,8 @@ let internalize globalenv env pattern_mode (_, ntnvars as lvar) c =
GLetIn (na.CAst.v, inc1, int,
intern (push_name_env ntnvars (impls_term_list inc1) env na) c2)
| CNotation ((InConstrEntrySomeLevel,"- _"), ([a],[],[],[])) when is_non_zero a ->
- let p = match a.CAst.v with CPrim (Numeral (p, _)) -> p | _ -> assert false in
- intern env (CAst.make ?loc @@ CPrim (Numeral (p,false)))
+ let p = match a.CAst.v with CPrim (Numeral (_, p)) -> p | _ -> assert false in
+ intern env (CAst.make ?loc @@ CPrim (Numeral (SMinus,p)))
| CNotation ((InConstrEntrySomeLevel,"( _ )"),([a],[],[],[])) -> intern env a
| CNotation (ntn,args) ->
intern_notation intern env ntnvars loc ntn args
@@ -1933,30 +1939,31 @@ let internalize globalenv env pattern_mode (_, ntnvars as lvar) c =
| CAppExpl ((isproj,ref,us), args) ->
let (f,_,args_scopes,_),args =
let args = List.map (fun a -> (a,None)) args in
- intern_applied_reference intern env (Environ.named_context_val globalenv)
- lvar us args ref
+ intern_applied_reference ~isproj intern env (Environ.named_context_val globalenv)
+ lvar us args ref
in
(* Rem: GApp(_,f,[]) stands for @f *)
if args = [] then DAst.make ?loc @@ GApp (f,[]) else
smart_gapp f loc (intern_args env args_scopes (List.map fst args))
| CApp ((isproj,f), args) ->
- let f,args = match f.CAst.v with
+ let isproj,f,args = match f.CAst.v with
(* Compact notations like "t.(f args') args" *)
- | CApp ((Some _,f), args') when not (Option.has_some isproj) ->
- f,args'@args
+ | CApp ((Some _ as isproj',f), args') when not (Option.has_some isproj) ->
+ isproj',f,args'@args
(* Don't compact "(f args') args" to resolve implicits separately *)
- | _ -> f,args in
+ | _ -> isproj,f,args in
let (c,impargs,args_scopes,l),args =
match f.CAst.v with
| CRef (ref,us) ->
- intern_applied_reference intern env
+ intern_applied_reference ~isproj intern env
(Environ.named_context_val globalenv) lvar us args ref
| CNotation (ntn,([],[],[],[])) ->
+ assert (Option.is_empty isproj);
let c = intern_notation intern env ntnvars loc ntn ([],[],[],[]) in
let x, impl, scopes, l = find_appl_head_data c in
(x,impl,scopes,l), args
- | _ -> (intern env f,[],[],[]), args in
+ | _ -> assert (Option.is_empty isproj); (intern env f,[],[],[]), args in
apply_impargs c env impargs args_scopes
(merge_impargs l args) loc