let debug = ref false;;
let indent = ref "";;
+let times = ref [];;
let pp s =
if !debug then
prerr_endline (Printf.sprintf "%-20s" !indent ^ " " ^ Lazy.force s)
- else
- ()
;;
let inside c =
- indent := !indent ^ String.make 1 c;
- if !debug then prerr_endline ("{{{" ^ !indent ^ " ")
+ if !debug then
+ begin
+ let time1 = Unix.gettimeofday () in
+ indent := !indent ^ String.make 1 c;
+ times := time1 :: !times;
+ prerr_endline ("{{{" ^ !indent ^ " ")
+ end
;;
let outside ok =
- if !debug then prerr_endline "}}}";
- if not ok then pp (lazy "exception raised!");
- try
- indent := String.sub !indent 0 (String.length !indent -1)
- with
- Invalid_argument _ -> indent := "??"; ()
+ if !debug then
+ begin
+ let time2 = Unix.gettimeofday () in
+ let time1 =
+ match !times with time1::tl -> times := tl; time1 | [] -> assert false in
+ prerr_endline ("}}} " ^ string_of_float (time2 -. time1));
+ if not ok then prerr_endline "exception raised!";
+ try
+ indent := String.sub !indent 0 (String.length !indent -1)
+ with
+ Invalid_argument _ -> indent := "??"; ()
+ end
;;
| e -> raise e
;;
-let exp_implicit ~localise metasenv context expty t =
- let foo x = match expty with Some t -> `WithType t | None -> x in
+let exp_implicit rdb ~localise metasenv subst context with_type t =
function
- | `Closed -> NCicMetaSubst.mk_meta metasenv [] (foo `Term)
- | `Type -> NCicMetaSubst.mk_meta metasenv context (foo `Type)
- | `Term -> NCicMetaSubst.mk_meta metasenv context (foo `Term)
+ | `Closed ->
+ let metasenv,subst,expty =
+ match with_type with
+ None -> metasenv,subst,None
+ | Some typ ->
+ let (metasenv,subst),typ =
+ try
+ NCicMetaSubst.delift
+ ~unify:(fun m s c t1 t2 ->
+ try Some (NCicUnification.unify rdb m s c t1 t2)
+ with NCicUnification.UnificationFailure _ | NCicUnification.Uncertain _ -> None)
+ metasenv subst context 0 (0,NCic.Irl 0) typ
+ with
+ NCicMetaSubst.MetaSubstFailure _
+ | NCicMetaSubst.Uncertain _ ->
+ raise (RefineFailure (lazy (localise t,"Trying to create a closed meta with a non closed type: " ^ NCicPp.ppterm ~metasenv ~subst ~context typ)))
+
+ in
+ metasenv,subst,Some typ
+ in
+ NCicMetaSubst.mk_meta metasenv [] ?with_type:expty `IsTerm,subst
+ | `Type -> NCicMetaSubst.mk_meta metasenv context ?with_type `IsType,subst
+ | `Term -> NCicMetaSubst.mk_meta metasenv context ?with_type `IsTerm,subst
| `Tagged s ->
- NCicMetaSubst.mk_meta ~attrs:[`Name s] metasenv context (foo `Term)
+ NCicMetaSubst.mk_meta
+ ~attrs:[`Name s] metasenv context ?with_type `IsTerm,subst
| `Vector ->
raise (RefineFailure (lazy (localise t, "A vector of implicit terms " ^
"can only be used in argument position")))
match arity1 with
| C.Prod (name,so1,de1) (* , t ==?== C.Prod _ *) ->
let metasenv, _, meta, _ =
- NCicMetaSubst.mk_meta metasenv ((name,C.Decl so1)::context) `Type
+ NCicMetaSubst.mk_meta metasenv ((name,C.Decl so1)::context) `IsType
in
let metasenv, subst =
try NCicUnification.unify rdb metasenv subst context
aux metasenv subst ((name, C.Decl so1)::context)
(mkapp (NCicSubstitution.lift 1 ind) (C.Rel 1)) de1 meta
| C.Sort _ (* , t ==?== C.Prod _ *) ->
- let metasenv, _, meta, _ = NCicMetaSubst.mk_meta metasenv [] `Type in
+ let metasenv, _, meta, _ = NCicMetaSubst.mk_meta metasenv [] `IsSort in
let metasenv, subst =
try NCicUnification.unify rdb metasenv subst context
arity2 (C.Prod ("_", ind, meta))
raise (RefineFailure (lazy (localise t, Lazy.force msg)))
| NCicEnvironment.AssertFailure msg -> raise (AssertFailure msg))
| C.Implicit infos ->
- let metasenv,_,t,ty =
- exp_implicit ~localise metasenv context expty t infos
+ let (metasenv,_,t,ty),subst =
+ exp_implicit rdb ~localise metasenv subst context expty t infos
in
+ if expty = None then
+ typeof_aux metasenv subst context None t
+ else
metasenv, subst, t, ty
| C.Meta (n,l) as t ->
- let ty =
+ let metasenv, ty =
try
- let _,_,_,ty = NCicUtils.lookup_subst n subst in ty
- with NCicUtils.Subst_not_found _ -> try
- let _,_,ty = NCicUtils.lookup_meta n metasenv in
- match ty with C.Implicit _ ->
- prerr_endline (string_of_int n);
- prerr_endline (NCicPp.ppmetasenv ~subst metasenv);
- prerr_endline (NCicPp.ppsubst ~metasenv subst);
- assert false | _ -> ty
- with NCicUtils.Meta_not_found _ ->
- raise (AssertFailure (lazy (Printf.sprintf
- "%s not found" (NCicPp.ppterm ~subst ~metasenv ~context t))))
+ let _,_,_,ty = NCicUtils.lookup_subst n subst in metasenv, ty
+ with NCicUtils.Subst_not_found _ ->
+ NCicMetaSubst.extend_meta metasenv n
in
metasenv, subst, t, NCicSubstitution.subst_meta l ty
| C.Const _ ->
| C.Prod (_,s,t) -> Some s, Some t, false
| _ -> None, None, true
in
- let metasenv, subst, s, ty_s =
- typeof_aux metasenv subst context None s in
- let metasenv, subst, s, _ =
- force_to_sort rdb
- metasenv subst context s orig_s localise ty_s in
- let (metasenv,subst), exp_ty_t =
+ let (metasenv,subst), s =
match exp_s with
- | Some exp_s ->
- (try
- pp(lazy("Force source to: "^NCicPp.ppterm ~metasenv ~subst
- ~context exp_s));
- NCicUnification.unify rdb metasenv subst context s exp_s,exp_ty_t
- with exc -> raise (wrap_exc (lazy (localise orig_s, Printf.sprintf
- "Source type %s was expected to be %s" (NCicPp.ppterm ~metasenv
- ~subst ~context s) (NCicPp.ppterm ~metasenv ~subst ~context
- exp_s))) exc))
- | None -> (metasenv, subst), None
+ | Some exp_s ->
+ (* optimized case: implicit and implicitly typed meta
+ * the optimization prevents proliferation of metas *)
+ (match s with
+ | C.Implicit _ -> (metasenv,subst),exp_s
+ | _ ->
+ let metasenv, subst, s = match s with
+ | C.Meta (n,_)
+ when (try (match NCicUtils.lookup_meta n metasenv with
+ | _,_,C.Implicit (`Typeof _) -> true
+ | _ -> false)
+ with
+ | _ -> false) -> metasenv, subst, s
+ | _ -> check_type rdb ~localise metasenv subst context s in
+ (try
+ pp(lazy("Force source to: "^NCicPp.ppterm ~metasenv ~subst
+ ~context exp_s));
+ NCicUnification.unify ~test_eq_only:true rdb metasenv subst context s exp_s,s
+ with exc -> raise (wrap_exc (lazy (localise orig_s, Printf.sprintf
+ "Source type %s was expected to be %s" (NCicPp.ppterm ~metasenv
+ ~subst ~context s) (NCicPp.ppterm ~metasenv ~subst ~context
+ exp_s))) exc)))
+ | None ->
+ let metasenv, subst, s =
+ check_type rdb ~localise metasenv subst context s in
+ (metasenv, subst), s
in
let context_for_t = (n,C.Decl s) :: context in
let metasenv, subst, t, ty_t =
(C.Lambda(n,s,t)) (C.Prod (n,s,ty_t)) expty
else
metasenv, subst, C.Lambda(n,s,t), C.Prod (n,s,ty_t)
- | C.LetIn (n,(ty as orig_ty),t,bo) ->
- let metasenv, subst, ty, ty_ty =
- typeof_aux metasenv subst context None ty in
- let metasenv, subst, ty, _ =
- force_to_sort rdb
- metasenv subst context ty orig_ty localise ty_ty in
+ | C.LetIn (n,ty,t,bo) ->
+ let metasenv, subst, ty =
+ check_type rdb ~localise metasenv subst context ty in
let metasenv, subst, t, _ =
typeof_aux metasenv subst context (Some ty) t in
let context1 = (n, C.Def (t,ty)) :: context in
(* next lines are to do a subst-expansion of the outtype, so
that when it becomes a beta-abstraction, the beta-redex is
fired during substitution *)
- (*CSC: this is instantiate! should we move it from tactics to the
- refiner? I think so! *)
- let metasenv,metanoouttype,newouttype,metaoutsort =
- NCicMetaSubst.mk_meta metasenv context `Term in
- let metasenv,subst =
- NCicUnification.unify rdb metasenv subst context outsort metaoutsort in
- let metasenv =
- List.filter (function (j,_) -> j <> metanoouttype) metasenv in
+ let _,fresh_metanoouttype,newouttype,_ =
+ NCicMetaSubst.mk_meta metasenv context `IsTerm in
let subst =
- (metanoouttype,([`Name "outtype"],context,outtype,metaoutsort))::subst in
+ (fresh_metanoouttype,([`Name "outtype"],context,outtype,outsort))
+ ::subst in
let outtype = newouttype in
(* let's control if the sort elimination is allowed: [(I q1 ... qr)|B] *)
in
typeof_aux metasenv subst context expty term
+and check_type rdb ~localise metasenv subst context (ty as orig_ty) =
+ let metasenv, subst, ty, sort =
+ typeof rdb ~localise metasenv subst context ty None
+ in
+ let metasenv, subst, ty, _ =
+ force_to_sort rdb metasenv subst context ty orig_ty localise sort
+ in
+ metasenv, subst, ty
+
and try_coercions rdb
~localise
metasenv subst context t orig_t infty expty perform_unification exc
rdb metasenv subst context infty expty)
and force_to_sort rdb metasenv subst context t orig_t localise ty =
- match NCicReduction.whd ~subst context ty with
- | C.Meta (_,(0,(C.Irl 0 | C.Ctx []))) as ty ->
- metasenv, subst, t, ty
- | C.Meta (_i,(_,(C.Irl 0 | C.Ctx []))) -> assert false (*CSC: ???
- metasenv, subst, t, C.Meta(i,(0,C.Irl 0)) *)
- | C.Meta (i,(_,lc)) ->
- let len = match lc with C.Irl len->len | C.Ctx l->List.length l in
- let metasenv, subst, newmeta =
- if len > 0 then
- NCicMetaSubst.restrict metasenv subst i (HExtlib.list_seq 1 (len+1))
- else metasenv, subst, i
- in
- metasenv, subst, t, C.Meta (newmeta,(0,C.Irl 0))
- | C.Sort _ as ty -> metasenv, subst, t, ty
- | ty ->
- try_coercions rdb ~localise metasenv subst context
- t orig_t ty (NCic.Sort (NCic.Type NCicEnvironment.type0)) false
- (Uncertain (lazy (localise orig_t,
- "The type of " ^ NCicPp.ppterm ~metasenv ~subst ~context t
- ^ " is not a sort: " ^ NCicPp.ppterm ~metasenv ~subst ~context ty)))
+ try
+ let metasenv, subst, ty =
+ NCicUnification.sortfy (Failure "sortfy") metasenv subst context ty in
+ metasenv, subst, t, ty
+ with
+ Failure _ ->
+ let ty = NCicReduction.whd ~subst context ty in
+ try_coercions rdb ~localise metasenv subst context
+ t orig_t ty (NCic.Sort (NCic.Type
+ (match NCicEnvironment.get_universes () with
+ | x::_ -> x
+ | _ -> assert false))) false
+ (Uncertain (lazy (localise orig_t,
+ "The type of " ^ NCicPp.ppterm ~metasenv ~subst ~context t ^
+ " is not a sort: " ^ NCicPp.ppterm ~metasenv ~subst ~context ty)))
and sort_of_prod
localise metasenv subst context orig_s orig_t (name,s) t (t1, t2)
and eat_prods rdb ~localise force_ty metasenv subst context expty orig_t orig_he he ty_he args =
(*D*)inside 'E'; try let rc =
- let rec aux metasenv subst args_so_far he ty_he = function
+ let rec aux metasenv subst args_so_far he ty_he xxx =
+ (*D*)inside 'V'; try let rc =
+ match xxx with
| [] ->
let res = NCicUntrusted.mk_appl he (List.rev args_so_far) in
pp(lazy("FORCE FINAL APPL: " ^
aux metasenv subst args_so_far he ty_he
(NCic.Implicit `Term :: NCic.Implicit `Vector :: tl)
with
- Uncertain msg | RefineFailure msg -> raise (wrap_exc msg exc)))
+ Uncertain msg | RefineFailure msg -> raise (wrap_exc msg exc))
+ | RefineFailure msg when not (has_some_more_pis ty_he) ->
+ (* instantiating the head could change the has_some_more_pis flag *)
+ raise (Uncertain msg))
| arg::tl ->
match NCicReduction.whd ~subst context ty_he with
| C.Prod (_,s,t) ->
let name = guess_name subst context ty_arg in
let metasenv, _, meta, _ =
NCicMetaSubst.mk_meta metasenv
- ((name,C.Decl ty_arg) :: context) `Type
+ ((name,C.Decl ty_arg) :: context) `IsType
in
let flex_prod = C.Prod (name, ty_arg, meta) in
(* next line grants that ty_args is a type *)
(List.length args) (List.length args_so_far))))
in
aux metasenv subst [] newhead newheadty (arg :: tl)
+ (*D*)in outside true; rc with exc -> outside false; raise exc
in
(* We need to reverse the order of the new created metas since they
are pushed on top of the metasenv in the wrong order *)
let typeof_obj
rdb ?(localise=fun _ -> Stdpp.dummy_loc) (uri,height,metasenv,subst,obj)
=
- let check_type metasenv subst context (ty as orig_ty) = (* XXX fattorizza *)
- let metasenv, subst, ty, sort =
- typeof rdb ~localise metasenv subst context ty None
- in
- let metasenv, subst, ty, sort =
- force_to_sort rdb metasenv subst context ty orig_ty localise sort
- in
- metasenv, subst, ty, sort
- in
match obj with
- | C.Constant (relevance, name, bo, ty , attr) ->
- let metasenv, subst, ty, _ = check_type metasenv subst [] ty in
+ | C.Constant (relevance, name, bo, ty, attr) ->
+ let metasenv, subst, ty =
+ check_type rdb ~localise metasenv subst [] ty in
let metasenv, subst, bo, ty, height =
match bo with
| Some bo ->
let types, metasenv, subst, rev_fl =
List.fold_left
(fun (types, metasenv, subst, fl) (relevance,name,k,ty,bo) ->
- let metasenv, subst, ty, _ = check_type metasenv subst [] ty in
+ let metasenv, subst, ty =
+ check_type rdb ~localise metasenv subst [] ty in
let dbo = NCicTypeChecker.debruijn uri len [] ~subst bo in
let localise = relocalise localise dbo bo in
(name,C.Decl ty)::types,
let metasenv,subst,rev_itl,tys =
List.fold_left
(fun (metasenv,subst,res,ctx) (relevance,n,ty,cl) ->
- let metasenv, subst, ty, _ = check_type metasenv subst [] ty in
+ let metasenv, subst, ty =
+ check_type rdb ~localise metasenv subst [] ty in
metasenv,subst,(relevance,n,ty,cl)::res,(n,NCic.Decl ty)::ctx
) (metasenv,subst,[],[]) itl in
let metasenv,subst,itl,_ =
try snd (HExtlib.split_nth leftno k_relev)
with Failure _ -> k_relev in
let te = NCicTypeChecker.debruijn uri len [] ~subst te in
- let metasenv, subst, te, _ = check_type metasenv subst tys te in
+ let metasenv, subst, te =
+ check_type rdb ~localise metasenv subst tys te in
let context,te = NCicReduction.split_prods ~subst tys leftno te in
let _,chopped_context_rev =
HExtlib.split_nth (List.length tys) (List.rev context) in