diff options
Diffstat (limited to 'interp/constrintern.ml')
-rw-r--r-- | interp/constrintern.ml | 160 |
1 files changed, 110 insertions, 50 deletions
diff --git a/interp/constrintern.ml b/interp/constrintern.ml index 7fba83e66..0905ad1d6 100644 --- a/interp/constrintern.ml +++ b/interp/constrintern.ml @@ -93,7 +93,7 @@ let global_reference_of_reference ref = locate_reference (snd (qualid_of_reference ref)) let global_reference id = - constr_of_global (locate_reference (qualid_of_ident id)) + Universes.constr_of_global (locate_reference (qualid_of_ident id)) let construct_reference ctx id = try @@ -102,7 +102,7 @@ let construct_reference ctx id = global_reference id let global_reference_in_absolute_module dir id = - constr_of_global (Nametab.global_of_path (Libnames.make_path dir id)) + Universes.constr_of_global (Nametab.global_of_path (Libnames.make_path dir id)) (**********************************************************************) (* Internalization errors *) @@ -300,7 +300,7 @@ let reset_tmp_scope env = {env with tmp_scope = None} let set_scope env = function | CastConv (GSort _) -> set_type_scope env - | CastConv (GRef (_,ref) | GApp (_,GRef (_,ref),_)) -> + | CastConv (GRef (_,ref,_) | GApp (_,GRef (_,ref,_),_)) -> {env with tmp_scope = compute_scope_of_global ref} | _ -> env @@ -410,7 +410,7 @@ let intern_generalized_binder ?(global_level=false) intern_type lvar let name = let id = match ty with - | CApp (_, (_, CRef (Ident (loc,id))), _) -> id + | CApp (_, (_, CRef (Ident (loc,id),_)), _) -> id | _ -> Id.of_string "H" in Implicit_quantifiers.make_fresh ids' (Global.env ()) id in Name name @@ -650,7 +650,7 @@ let intern_var genv (ltacvars,ntnvars) namedctx loc id = try let ty,expl_impls,impls,argsc = Id.Map.find id genv.impls in let expl_impls = List.map - (fun id -> CRef (Ident (loc,id)), Some (loc,ExplByName id)) expl_impls in + (fun id -> CRef (Ident (loc,id),None), Some (loc,ExplByName id)) expl_impls in let tys = string_of_ty ty in Dumpglob.dump_reference loc "<>" (Id.to_string id) tys; GVar (loc,id), make_implicits_list impls, argsc, expl_impls @@ -682,19 +682,38 @@ let intern_var genv (ltacvars,ntnvars) namedctx loc id = let impls = implicits_of_global ref in let scopes = find_arguments_scope ref in Dumpglob.dump_reference loc "<>" (string_of_qualid (Decls.variable_secpath id)) "var"; - GRef (loc, ref), impls, scopes, [] + GRef (loc, ref, None), impls, scopes, [] with e when Errors.noncritical e -> (* [id] a goal variable *) GVar (loc,id), [], [], [] -let find_appl_head_data = function - | GRef (_,ref) as x -> x,implicits_of_global ref,find_arguments_scope ref,[] - | GApp (_,GRef (_,ref),l) as x +let is_projection_ref = function + | ConstRef r -> if Environ.is_projection r (Global.env ()) then Some r else None + | _ -> None + +let find_appl_head_data c = + match c with + | GRef (loc,ref,_) as x -> + let impls = implicits_of_global ref in + let isproj, impls = + match is_projection_ref ref with + | Some r -> true, List.map (projection_implicits (Global.env ()) r) impls + | None -> false, impls + in + let scopes = find_arguments_scope ref in + x, isproj, impls, scopes, [] + | GApp (_,GRef (_,ref,_),l) as x when l != [] && Flags.version_strictly_greater Flags.V8_2 -> let n = List.length l in - x,List.map (drop_first_implicits n) (implicits_of_global ref), - List.skipn_at_least n (find_arguments_scope ref),[] - | x -> x,[],[],[] + let impls = implicits_of_global ref in + let isproj, impls = + match is_projection_ref ref with + | Some r -> true, List.map (projection_implicits (Global.env ()) r) impls + | None -> false, impls + in + x, isproj, List.map (drop_first_implicits n) impls, + List.skipn_at_least n (find_arguments_scope ref),[] + | x -> x,false,[],[],[] let error_not_enough_arguments loc = user_err_loc (loc,"",str "Abbreviation is not applied enough.") @@ -726,8 +745,7 @@ let intern_reference ref = (* Is it a global reference or a syntactic definition? *) let intern_qualid loc qid intern env lvar args = match intern_extended_global_of_qualid (loc,qid) with - | TrueGlobal ref -> - GRef (loc, ref), args + | TrueGlobal ref -> GRef (loc, ref, None), args | SynDef sp -> let (ids,c) = Syntax_def.search_syntactic_definition sp in let nids = List.length ids in @@ -742,7 +760,7 @@ let intern_qualid loc qid intern env lvar args = (* Rule out section vars since these should have been found by intern_var *) let intern_non_secvar_qualid loc qid intern env lvar args = match intern_qualid loc qid intern env lvar args with - | GRef (_, VarRef _),_ -> raise Not_found + | GRef (_, VarRef _, _),_ -> raise Not_found | r -> r let intern_applied_reference intern env namedctx lvar args = function @@ -751,22 +769,24 @@ let intern_applied_reference intern env namedctx lvar args = function try intern_qualid loc qid intern env lvar args with Not_found -> error_global_not_found_loc loc qid in - find_appl_head_data r, args2 + let x, isproj, imp, scopes, l = find_appl_head_data r in + (x,imp,scopes,l), isproj, args2 | Ident (loc, id) -> - try intern_var env lvar namedctx loc id, args + try intern_var env lvar namedctx loc id, false, args with Not_found -> let qid = qualid_of_ident id in try let r,args2 = intern_non_secvar_qualid loc qid intern env lvar args in - find_appl_head_data r, args2 + let x, isproj, imp, scopes, l = find_appl_head_data r in + (x,imp,scopes,l), isproj, args2 with Not_found -> (* Extra allowance for non globalizing functions *) if !interning_grammar || env.unb then - (GVar (loc,id), [], [], []),args + (GVar (loc,id), [], [], []), false, args else error_global_not_found_loc loc qid let interp_reference vars r = - let (r,_,_,_),_ = + let (r,_,_,_),_,_ = intern_applied_reference (fun _ -> error_not_enough_arguments Loc.ghost) {ids = Id.Set.empty; unb = false ; tmp_scope = None; scopes = []; impls = empty_internalization_env} [] @@ -1276,10 +1296,9 @@ let merge_impargs l args = let check_projection isproj nargs r = match (r,isproj) with - | GRef (loc, ref), Some _ -> + | GRef (loc, ref, _), Some _ -> (try - let n = Recordops.find_projection_nparams ref + 1 in - if not (Int.equal nargs n) then + if not (Int.equal nargs 1) then user_err_loc (loc,"",str "Projection does not have the right number of explicit parameters."); with Not_found -> user_err_loc @@ -1291,7 +1310,8 @@ let get_implicit_name n imps = Some (Impargs.name_of_implicit (List.nth imps (n-1))) let set_hole_implicit i b = function - | GRef (loc,r) | GApp (_,GRef (loc,r),_) -> (loc,Evar_kinds.ImplicitArg (r,i,b),None) + | GRef (loc,r,_) | GApp (_,GRef (loc,r,_),_) -> (loc,Evar_kinds.ImplicitArg (r,i,b),None) + | GProj (loc,p,_) -> (loc,Evar_kinds.ImplicitArg (ConstRef p,i,b),None) | GVar (loc,id) -> (loc,Evar_kinds.ImplicitArg (VarRef id,i,b),None) | _ -> anomaly (Pp.str "Only refs have implicits") @@ -1335,14 +1355,17 @@ let extract_explicit_arg imps args = (**********************************************************************) (* Main loop *) +let is_projection_ref env = function + | ConstRef c -> Environ.is_projection c env + | _ -> false + let internalize globalenv env allow_patvar lvar c = let rec intern env = function - | CRef ref as x -> - let (c,imp,subscopes,l),_ = + | CRef (ref,us) as x -> + let (c,imp,subscopes,l),isproj,_ = intern_applied_reference intern env (Environ.named_context globalenv) lvar [] ref in - (match intern_impargs c env imp subscopes l with - | [] -> c - | l -> GApp (constr_loc x, c, l)) + apply_impargs (None, isproj) c env imp subscopes l (constr_loc x) + | CFix (loc, (locid,iddef), dl) -> let lf = List.map (fun ((_, id),_,_,_,_) -> id) dl in let dl = Array.of_list dl in @@ -1435,33 +1458,35 @@ let internalize globalenv env allow_patvar lvar c = | CDelimiters (loc, key, e) -> intern {env with tmp_scope = None; scopes = find_delimiters_scope loc key :: env.scopes} e - | CAppExpl (loc, (isproj,ref), args) -> - let (f,_,args_scopes,_),args = + | CAppExpl (loc, (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 globalenv) lvar args ref in - check_projection isproj (List.length args) f; + intern_applied_reference intern env (Environ.named_context globalenv) + lvar args ref in + (* check_projection isproj (List.length args) f; *) (* Rem: GApp(_,f,[]) stands for @f *) - GApp (loc, f, intern_args env args_scopes (List.map fst args)) + GApp (loc, f, intern_args env args_scopes (List.map fst args)) + | CApp (loc, (isproj,f), args) -> let isproj,f,args = match f with (* Compact notations like "t.(f args') args" *) - | CApp (_,(Some _,f), args') when not (Option.has_some isproj) -> 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 *) | _ -> isproj,f,args in - let (c,impargs,args_scopes,l),args = + let (c,impargs,args_scopes,l),isprojf,args = match f with - | CRef ref -> intern_applied_reference intern env (Environ.named_context globalenv) lvar args ref + | CRef (ref,us) -> + intern_applied_reference intern env + (Environ.named_context globalenv) lvar args ref | CNotation (loc,ntn,([],[],[])) -> let c = intern_notation intern env lvar loc ntn ([],[],[]) in - find_appl_head_data c, args - | x -> (intern env f,[],[],[]), args in - let args = - intern_impargs c env impargs args_scopes (merge_impargs l args) in - check_projection isproj (List.length args) c; - (match c with - (* Now compact "(f args') args" *) - | GApp (loc', f', args') -> GApp (Loc.merge loc' loc, f',args'@args) - | _ -> GApp (loc, c, args)) + let x, isproj, impl, scopes, l = find_appl_head_data c in + (x,impl,scopes,l), false, args + | x -> (intern env f,[],[],[]), false, args in + apply_impargs (isproj,isprojf) c env impargs args_scopes + (merge_impargs l args) loc + | CRecord (loc, _, fs) -> let cargs = sort_fields true loc fs @@ -1472,7 +1497,7 @@ let internalize globalenv env allow_patvar lvar c = | None -> user_err_loc (loc, "intern", str"No constructor inference.") | Some (n, constrname, args) -> let pars = List.make n (CHole (loc, None, None)) in - let app = CAppExpl (loc, (None, constrname), List.rev_append pars args) in + let app = CAppExpl (loc, (None, constrname,None), List.rev_append pars args) in intern env app end | CCases (loc, sty, rtnpo, tms, eqns) -> @@ -1500,7 +1525,7 @@ let internalize globalenv env allow_patvar lvar c = | [] -> Option.map (intern_type env') rtnpo (* Only PatVar in "in" clauses *) | l -> let thevars,thepats=List.split l in Some ( - GCases(Loc.ghost,Term.RegularStyle,Some (GSort (Loc.ghost,GType None)), (* "return Type" *) + GCases(Loc.ghost,Term.RegularStyle,(* Some (GSort (Loc.ghost,GType None)) *)None, (* "return Type" *) List.map (fun id -> GVar (Loc.ghost,id),(Name id,None)) thevars, (* "match v1,..,vn" *) [Loc.ghost,[],thepats, (* "|p1,..,pn" *) Option.cata (intern_type env') (GHole(Loc.ghost,Evar_kinds.CasesType,None)) rtnpo; (* "=> P" is there were a P "=> _" else *) @@ -1599,7 +1624,7 @@ let internalize globalenv env allow_patvar lvar c = (* the "as" part *) let extra_id,na = match tm', na with | GVar (loc,id), None when not (Id.Map.mem id (snd lvar)) -> Some id,(loc,Name id) - | GRef (loc, VarRef id), None -> Some id,(loc,Name id) + | GRef (loc, VarRef id, _), None -> Some id,(loc,Name id) | _, None -> None,(Loc.ghost,Anonymous) | _, Some (loc,na) -> None,(loc,na) in (* the "in" part *) @@ -1691,6 +1716,41 @@ let internalize globalenv env allow_patvar lvar c = intern_args env subscopes rargs in aux 1 l subscopes eargs rargs + and make_first_explicit (l, r) = + match r with + | hd :: tl -> l, None :: tl + | [] -> l, [] + + and apply_impargs (isproj,isprojf) c env imp subscopes l loc = + let l = + let imp = + if isprojf && isproj <> None then + (* Drop first implicit which corresponds to record given in c.(p) notation *) + List.map make_first_explicit imp + else imp + in intern_impargs c env imp subscopes l + in + if isprojf then + match c, l with + | GApp (loc', GRef (loc'', ConstRef f, _), hd :: tl), rest -> + let proj = GProj (Loc.merge loc'' (loc_of_glob_constr hd), f, hd) in + if List.is_empty tl then smart_gapp proj loc rest + else GApp (loc, proj, tl @ rest) + | GRef (loc', ConstRef f, _), hd :: tl -> + let proj = GProj (Loc.merge loc' (loc_of_glob_constr hd), f, hd) in + smart_gapp proj loc tl + | _ -> user_err_loc (loc, "apply_impargs", + str"Projection is not applied to enough arguments") + else + (* check_projection isproj *) + smart_gapp c loc l + + and smart_gapp f loc = function + | [] -> f + | l -> match f with + | GApp (loc', g, args) -> GApp (Loc.merge loc' loc, g, args@l) + | _ -> GApp (Loc.merge (loc_of_glob_constr f) loc, f, l) + and intern_args env subscopes = function | [] -> [] | a::args -> @@ -1871,7 +1931,7 @@ let interp_rawcontext_evars evdref env bl = (push_rel d env, d::params, succ n, impls) | Some b -> let c = understand_judgment_tcc evdref env b in - let d = (na, Some c.uj_val, Termops.refresh_universes c.uj_type) in + let d = (na, Some c.uj_val, c.uj_type) in (push_rel d env, d::params, succ n, impls)) (env,[],1,[]) (List.rev bl) in (env, par), impls |