-and type_of_aux' metasenv context t =
- let rec type_of_aux subst metasenv context =
- let module C = Cic in
- let module S = CicSubstitution in
- let module U = UriManager in
- let module Un = CicUnification in
- function
- C.Rel n ->
- (try
- match List.nth context (n - 1) with
- Some (_,C.Decl t) -> S.lift n t,subst,metasenv
- | Some (_,C.Def (_,Some ty)) -> S.lift n ty,subst,metasenv
- | Some (_,C.Def (bo,None)) ->
- type_of_aux subst metasenv context (S.lift n bo)
- | None -> raise RelToHiddenHypothesis
- with
- _ -> raise (NotRefinable "Not a close term")
- )
- | C.Var (uri,exp_named_subst) ->
- incr fdebug ;
- let subst',metasenv' =
- check_exp_named_subst subst metasenv context exp_named_subst in
- let ty =
- CicSubstitution.subst_vars exp_named_subst (type_of_variable uri)
- in
- decr fdebug ;
- ty,subst',metasenv'
- | C.Meta (n,l) ->
- let (_,canonical_context,ty) = CicUtil.lookup_meta n metasenv in
- let subst',metasenv' =
- check_metasenv_consistency subst metasenv context canonical_context l
- in
- CicSubstitution.lift_meta l ty, subst', metasenv'
- | C.Sort s ->
- C.Sort C.Type, (*CSC manca la gestione degli universi!!! *)
- subst,metasenv
- | C.Implicit -> raise (Impossible 21)
- | C.Cast (te,ty) ->
- let _,subst',metasenv' =
- type_of_aux subst metasenv context ty in
- let inferredty,subst'',metasenv'' =
- type_of_aux subst' metasenv' context te
- in
- (try
- let subst''',metasenv''' =
- Un.fo_unif_subst subst'' context metasenv'' inferredty ty
- in
- ty,subst''',metasenv'''
- with
- _ -> raise (NotRefinable "Cast"))
- | C.Prod (name,s,t) ->
- let sort1,subst',metasenv' = type_of_aux subst metasenv context s in
- let sort2,subst'',metasenv'' =
- type_of_aux subst' metasenv' ((Some (name,(C.Decl s)))::context) t
- in
- sort_of_prod subst'' metasenv'' context (name,s) (sort1,sort2)
- | C.Lambda (n,s,t) ->
- let sort1,subst',metasenv' = type_of_aux subst metasenv context s in
- let type2,subst'',metasenv'' =
- type_of_aux subst' metasenv' ((Some (n,(C.Decl s)))::context) t
- in
- let sort2,subst''',metasenv''' =
- type_of_aux subst'' metasenv''((Some (n,(C.Decl s)))::context) type2
- in
- (* only to check if the product is well-typed *)
- let _,subst'''',metasenv'''' =
- sort_of_prod subst''' metasenv''' context (n,s) (sort1,sort2)
- in
- C.Prod (n,s,type2),subst'''',metasenv''''
- | C.LetIn (n,s,t) ->
- (* only to check if s is well-typed *)
- let ty,subst',metasenv' = type_of_aux subst metasenv context s in
- let inferredty,subst'',metasenv'' =
- type_of_aux subst' metasenv' ((Some (n,(C.Def (s,Some ty))))::context) t
- in
- (* One-step LetIn reduction. Even faster than the previous solution.
- Moreover the inferred type is closer to the expected one. *)
- CicSubstitution.subst s inferredty,subst',metasenv'
- | C.Appl (he::tl) when List.length tl > 0 ->
- let hetype,subst',metasenv' = type_of_aux subst metasenv context he in
- let tlbody_and_type,subst'',metasenv'' =
- List.fold_right
- (fun x (res,subst,metasenv) ->
- let ty,subst',metasenv' =
- type_of_aux subst metasenv context x
- in
- (x, ty)::res,subst',metasenv'
- ) tl ([],subst',metasenv')
- in
- eat_prods subst'' metasenv'' context hetype tlbody_and_type
- | C.Appl _ -> raise (NotRefinable "Appl: no arguments")
- | C.Const (uri,exp_named_subst) ->
- incr fdebug ;
- let subst',metasenv' =
- check_exp_named_subst subst metasenv context exp_named_subst in
- let cty =
- CicSubstitution.subst_vars exp_named_subst (type_of_constant uri)
- in
- decr fdebug ;
- cty,subst',metasenv'
- | C.MutInd (uri,i,exp_named_subst) ->
- incr fdebug ;
- let subst',metasenv' =
- check_exp_named_subst subst metasenv context exp_named_subst in
- let cty =
- CicSubstitution.subst_vars exp_named_subst
- (type_of_mutual_inductive_defs uri i)
- in
- decr fdebug ;
- cty,subst',metasenv'
- | C.MutConstruct (uri,i,j,exp_named_subst) ->
- let subst',metasenv' =
- check_exp_named_subst subst metasenv context exp_named_subst in
- let cty =
- CicSubstitution.subst_vars exp_named_subst
- (type_of_mutual_inductive_constr uri i j)
- in
- cty,subst',metasenv'
- | C.MutCase (uri, i, outtype, term, pl) ->
- (* first, get the inductive type (and noparams) in the environment *)
- let (_,b,arity,constructors), expl_params, no_left_params =
- match CicEnvironment.get_cooked_obj ~trust:true uri with
- C.InductiveDefinition (l,expl_params,parsno) ->
- List.nth l i , expl_params, parsno
- | _ ->
- raise
- (WrongUriToMutualInductiveDefinitions (U.string_of_uri uri)) in
- let rec count_prod t =
- match CicMetaSubst.whd subst context t with
- C.Prod (_, _, t) -> 1 + (count_prod t)
- | _ -> 0 in
- let no_args = count_prod arity in
- (* now, create a "generic" MutInd *)
- let metasenv,left_args =
- CicMkImplicit.n_fresh_metas metasenv context no_left_params in
- let metasenv,right_args =
- let no_right_params = no_args - no_left_params in
- if no_right_params < 0 then assert false
- else CicMkImplicit.n_fresh_metas metasenv context no_right_params in
- let metasenv,exp_named_subst =
- CicMkImplicit.fresh_subst metasenv context expl_params in
- let expected_type =
- if no_args = 0 then
- C.MutInd (uri,i,exp_named_subst)
- else
- C.Appl (C.MutInd (uri,i,exp_named_subst)::(left_args @ right_args))
- in
- (* check consistency with the actual type of term *)
- let actual_type,subst,metasenv =
- type_of_aux subst metasenv context term in
- let _, subst, metasenv =
- type_of_aux subst metasenv context expected_type
- in
- let actual_type = CicMetaSubst.whd subst context actual_type in
- let subst,metasenv =
- Un.fo_unif_subst subst context metasenv expected_type actual_type
- in
- (* TODO: check if the sort elimination is allowed: [(I q1 ... qr)|B] *)
- let (_,outtypeinstances,subst,metasenv) =
- List.fold_left
- (fun (j,outtypeinstances,subst,metasenv) p ->
- let constructor =
- if left_args = [] then
- (C.MutConstruct (uri,i,j,exp_named_subst))
- else
- (C.Appl (C.MutConstruct (uri,i,j,exp_named_subst)::left_args))
- in
- let actual_type,subst,metasenv =
- type_of_aux subst metasenv context p in
- let expected_type, subst, metasenv =
- type_of_aux subst metasenv context constructor in
- let outtypeinstance,subst,metasenv =
- check_branch
- 0 context metasenv subst
- no_left_params actual_type constructor expected_type in
- (j+1,outtypeinstance::outtypeinstances,subst,metasenv))
- (1,[],subst,metasenv) pl in
- (* we are left to check that the outype matches his instances.
- The easy case is when the outype is specified, that amount
- to a trivial check. Otherwise, we should guess a type from
- its instances *)
- (* easy case *)
- let _, subst, metasenv =
- type_of_aux subst metasenv context
- (C.Appl ((outtype :: right_args) @ [term]))
- in
- let (subst,metasenv) =
- List.fold_left
- (fun (subst,metasenv) (constructor_args_no,context,instance,args) ->
- let instance' =
- let appl =
- let outtype' =
- CicSubstitution.lift constructor_args_no outtype
- in
- C.Appl (outtype'::args)
- in
-(*
- (* if appl is not well typed then the type_of below solves the
- * problem *)
- let (_, subst, metasenv) =
- type_of_aux subst metasenv context appl
- in
-*)
- CicMetaSubst.whd subst context appl
- in
- Un.fo_unif_subst subst context metasenv instance instance')
- (subst,metasenv) outtypeinstances in
- CicMetaSubst.whd subst
- context (C.Appl(outtype::right_args@[term])),subst,metasenv
- | C.Fix (i,fl) ->
- let subst,metasenv,types =
- List.fold_left
- (fun (subst,metasenv,types) (n,_,ty,_) ->
- let _,subst',metasenv' = type_of_aux subst metasenv context ty in
- subst',metasenv', Some (C.Name n,(C.Decl ty)) :: types
- ) (subst,metasenv,[]) fl
- in
- let len = List.length types in
- let context' = types@context in
- let subst,metasenv =
- List.fold_left
- (fun (subst,metasenv) (name,x,ty,bo) ->
- let ty_of_bo,subst,metasenv =
- type_of_aux subst metasenv context' bo
+and type_of_aux' metasenv context t ugraph =
+ let rec type_of_aux subst metasenv context t ugraph =
+ let module C = Cic in
+ let module S = CicSubstitution in
+ let module U = UriManager in
+ match t with
+ (* function *)
+ C.Rel n ->
+ (try
+ match List.nth context (n - 1) with
+ Some (_,C.Decl ty) ->
+ t,S.lift n ty,subst,metasenv, ugraph
+ | Some (_,C.Def (_,Some ty)) ->
+ t,S.lift n ty,subst,metasenv, ugraph
+ | Some (_,C.Def (bo,None)) ->
+ type_of_aux subst metasenv context (S.lift n bo) ugraph
+ | None -> raise (RefineFailure "Rel to hidden hypothesis")
+ with
+ _ -> raise (RefineFailure "Not a close term")
+ )
+ | C.Var (uri,exp_named_subst) ->
+ let exp_named_subst',subst',metasenv',ugraph1 =
+ check_exp_named_subst
+ subst metasenv context exp_named_subst ugraph
+ in
+ let ty_uri,ugraph1 = type_of_variable uri ugraph in
+ let ty =
+ CicSubstitution.subst_vars exp_named_subst' ty_uri
+ in
+ C.Var (uri,exp_named_subst'),ty,subst',metasenv',ugraph1
+ | C.Meta (n,l) ->
+ (try
+ let (canonical_context, term,ty) =
+ CicUtil.lookup_subst n subst
+ in
+ let l',subst',metasenv',ugraph1 =
+ check_metasenv_consistency n subst metasenv context
+ canonical_context l ugraph
+ in
+ (* trust or check ??? *)
+ C.Meta (n,l'),CicSubstitution.subst_meta l' ty,
+ subst', metasenv', ugraph1
+ (* type_of_aux subst metasenv
+ context (CicSubstitution.subst_meta l term) *)
+ with CicUtil.Subst_not_found _ ->
+ let (_,canonical_context,ty) = CicUtil.lookup_meta n metasenv in
+ let l',subst',metasenv', ugraph1 =
+ check_metasenv_consistency n subst metasenv context
+ canonical_context l ugraph
+ in
+ C.Meta (n,l'),CicSubstitution.subst_meta l' ty,
+ subst', metasenv',ugraph1)
+ | C.Sort (C.Type tno) ->
+ let tno' = CicUniv.fresh() in
+ let ugraph1 = CicUniv.add_gt tno' tno ugraph in
+ t,(C.Sort (C.Type tno')),subst,metasenv,ugraph1
+ | C.Sort _ ->
+ t,C.Sort (C.Type (CicUniv.fresh())),subst,metasenv,ugraph
+ | C.Implicit _ -> raise (AssertFailure "21")
+ | C.Cast (te,ty) ->
+ let ty',_,subst',metasenv',ugraph1 =
+ type_of_aux subst metasenv context ty ugraph
+ in
+ let te',inferredty,subst'',metasenv'',ugraph2 =
+ type_of_aux subst' metasenv' context te ugraph1
+ in
+ (try
+ let subst''',metasenv''',ugraph3 =
+ fo_unif_subst subst'' context metasenv''
+ inferredty ty' ugraph2
+ in
+ C.Cast (te',ty'),ty',subst''',metasenv''',ugraph3
+ with
+ _ -> raise (RefineFailure "Cast"))
+ | C.Prod (name,s,t) ->
+ let s',sort1,subst',metasenv',ugraph1 =
+ type_of_aux subst metasenv context s ugraph
+ in
+ let t',sort2,subst'',metasenv'',ugraph2 =
+ type_of_aux subst' metasenv'
+ ((Some (name,(C.Decl s')))::context) t ugraph1
+ in
+ let sop,subst''',metasenv''',ugraph3 =
+ sort_of_prod subst'' metasenv''
+ context (name,s') (sort1,sort2) ugraph2
+ in
+ C.Prod (name,s',t'),sop,subst''',metasenv''',ugraph3
+ | C.Lambda (n,s,t) ->
+ let s',sort1,subst',metasenv',ugraph1 =
+ type_of_aux subst metasenv context s ugraph
+ in
+ (match CicReduction.whd ~subst:subst' context sort1 with
+ C.Meta _
+ | C.Sort _ -> ()
+ | _ ->
+ raise (RefineFailure (sprintf
+ "Not well-typed lambda-abstraction: the source %s should be a type;
+ instead it is a term of type %s" (CicPp.ppterm s)
+ (CicPp.ppterm sort1)))
+ ) ;
+ let t',type2,subst'',metasenv'',ugraph2 =
+ type_of_aux subst' metasenv'
+ ((Some (n,(C.Decl s')))::context) t ugraph1
+ in
+ C.Lambda (n,s',t'),C.Prod (n,s',type2),
+ subst'',metasenv'',ugraph2
+ | C.LetIn (n,s,t) ->
+ (* only to check if s is well-typed *)
+ let s',ty,subst',metasenv',ugraph1 =
+ type_of_aux subst metasenv context s ugraph
+ in
+ let t',inferredty,subst'',metasenv'',ugraph2 =
+ type_of_aux subst' metasenv'
+ ((Some (n,(C.Def (s',Some ty))))::context) t ugraph1
+ in
+ (* One-step LetIn reduction.
+ * Even faster than the previous solution.
+ * Moreover the inferred type is closer to the expected one.
+ *)
+ C.LetIn (n,s',t'),CicSubstitution.subst s' inferredty,
+ subst',metasenv',ugraph2
+ | C.Appl (he::((_::_) as tl)) ->
+ let he',hetype,subst',metasenv',ugraph1 =
+ type_of_aux subst metasenv context he ugraph
+ in
+ let tlbody_and_type,subst'',metasenv'',ugraph2 =
+ List.fold_right
+ (fun x (res,subst,metasenv,ugraph) ->
+ let x',ty,subst',metasenv',ugraph1 =
+ type_of_aux subst metasenv context x ugraph
+ in
+ (x', ty)::res,subst',metasenv',ugraph1
+ ) tl ([],subst',metasenv',ugraph1)
+ in
+ let tl',applty,subst''',metasenv''',ugraph3 =
+ eat_prods subst'' metasenv'' context
+ hetype tlbody_and_type ugraph2
+ in
+ C.Appl (he'::tl'), applty,subst''',metasenv''',ugraph3
+ | C.Appl _ -> raise (RefineFailure "Appl: no arguments")
+ | C.Const (uri,exp_named_subst) ->
+ let exp_named_subst',subst',metasenv',ugraph1 =
+ check_exp_named_subst subst metasenv context
+ exp_named_subst ugraph in
+ let ty_uri,ugraph2 = type_of_constant uri ugraph1 in
+ let cty =
+ CicSubstitution.subst_vars exp_named_subst' ty_uri
+ in
+ C.Const (uri,exp_named_subst'),cty,subst',metasenv',ugraph2
+ | C.MutInd (uri,i,exp_named_subst) ->
+ let exp_named_subst',subst',metasenv',ugraph1 =
+ check_exp_named_subst subst metasenv context
+ exp_named_subst ugraph
+ in
+ let ty_uri,ugraph2 = type_of_mutual_inductive_defs uri i ugraph1 in
+ let cty =
+ CicSubstitution.subst_vars exp_named_subst' ty_uri in
+ C.MutInd (uri,i,exp_named_subst'),cty,subst',metasenv',ugraph2
+ | C.MutConstruct (uri,i,j,exp_named_subst) ->
+ let exp_named_subst',subst',metasenv',ugraph1 =
+ check_exp_named_subst subst metasenv context
+ exp_named_subst ugraph
+ in
+ let ty_uri,ugraph2 =
+ type_of_mutual_inductive_constr uri i j ugraph1
+ in
+ let cty =
+ CicSubstitution.subst_vars exp_named_subst' ty_uri
+ in
+ C.MutConstruct (uri,i,j,exp_named_subst'),cty,subst',
+ metasenv',ugraph2
+ | C.MutCase (uri, i, outtype, term, pl) ->
+ (* first, get the inductive type (and noparams)
+ * in the environment *)
+ let (_,b,arity,constructors), expl_params, no_left_params,ugraph =
+ let obj,u = CicEnvironment.get_obj ugraph uri in
+ match obj with
+ C.InductiveDefinition (l,expl_params,parsno,_) ->
+ List.nth l i , expl_params, parsno, u
+ | _ ->
+ raise
+ (RefineFailure
+ ("Unkown mutual inductive definition " ^
+ U.string_of_uri uri))