+++ /dev/null
-(* Copyright (C) 2000, HELM Team.
- *
- * This file is part of HELM, an Hypertextual, Electronic
- * Library of Mathematics, developed at the Computer Science
- * Department, University of Bologna, Italy.
- *
- * HELM is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * HELM is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HELM; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- * MA 02111-1307, USA.
- *
- * For details, see the HELM World-Wide-Web page,
- * http://cs.unibo.it/helm/.
- *)
-
-exception Impossible of int;;
-exception NotRefinable of string;;
-exception Uncertain of string;;
-exception WrongUriToConstant of string;;
-exception WrongUriToVariable of string;;
-exception WrongUriToMutualInductiveDefinitions of string;;
-exception RelToHiddenHypothesis;;
-exception MetasenvInconsistency;;
-exception MutCaseFixAndCofixRefineNotImplemented;;
-exception FreeMetaFound of int;;
-
-let fdebug = ref 0;;
-let debug t context =
- let rec debug_aux t i =
- let module C = Cic in
- let module U = UriManager in
- CicPp.ppobj (C.Variable ("DEBUG", None, t, [])) ^ "\n" ^ i
- in
- if !fdebug = 0 then
- raise (NotRefinable ("\n" ^ List.fold_right debug_aux (t::context) ""))
- (*print_endline ("\n" ^ List.fold_right debug_aux (t::context) "") ; flush stdout*)
-;;
-
-let rec type_of_constant uri =
- let module C = Cic in
- let module R = CicReduction in
- let module U = UriManager in
- match CicEnvironment.get_cooked_obj uri with
- C.Constant (_,_,ty,_) -> ty
- | C.CurrentProof (_,_,_,ty,_) -> ty
- | _ -> raise (WrongUriToConstant (U.string_of_uri uri))
-
-and type_of_variable uri =
- let module C = Cic in
- let module R = CicReduction in
- let module U = UriManager in
- match CicEnvironment.get_cooked_obj uri with
- C.Variable (_,_,ty,_) -> ty
- | _ -> raise (WrongUriToVariable (UriManager.string_of_uri uri))
-
-and type_of_mutual_inductive_defs uri i =
- let module C = Cic in
- let module R = CicReduction in
- let module U = UriManager in
- match CicEnvironment.get_cooked_obj uri with
- C.InductiveDefinition (dl,_,_) ->
- let (_,_,arity,_) = List.nth dl i in
- arity
- | _ -> raise (WrongUriToMutualInductiveDefinitions (U.string_of_uri uri))
-
-and type_of_mutual_inductive_constr uri i j =
- let module C = Cic in
- let module R = CicReduction in
- let module U = UriManager in
- match CicEnvironment.get_cooked_obj uri with
- C.InductiveDefinition (dl,_,_) ->
- let (_,_,_,cl) = List.nth dl i in
- let (_,ty) = List.nth cl (j-1) in
- ty
- | _ -> raise (WrongUriToMutualInductiveDefinitions (U.string_of_uri uri))
-
-(* type_of_aux' is just another name (with a different scope) for type_of_aux *)
-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 bo) ->
- 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) =
- try
- List.find (function (m,_,_) -> n = m) metasenv
- with
- Not_found -> raise (FreeMetaFound n)
- 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 ty
- 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 _,subst',metasenv' = type_of_aux subst metasenv context s in
- let inferredty,subst'',metasenv'' =
- type_of_aux subst' metasenv' ((Some (n,(C.Def s)))::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 _
- | C.Fix _
- | C.CoFix _ -> raise MutCaseFixAndCofixRefineNotImplemented
-
- (* check_metasenv_consistency checks that the "canonical" context of a
- metavariable is consitent - up to relocation via the relocation list l -
- with the actual context *)
- and check_metasenv_consistency subst metasenv context canonical_context l =
- let module C = Cic in
- let module R = CicReduction in
- let module S = CicSubstitution in
- let lifted_canonical_context =
- let rec aux i =
- function
- [] -> []
- | (Some (n,C.Decl t))::tl ->
- (Some (n,C.Decl (S.lift_meta l (S.lift i t))))::(aux (i+1) tl)
- | (Some (n,C.Def t))::tl ->
- (Some (n,C.Def (S.lift_meta l (S.lift i t))))::(aux (i+1) tl)
- | None::tl -> None::(aux (i+1) tl)
- in
- aux 1 canonical_context
- in
- List.fold_left2
- (fun (subst,metasenv) t ct ->
- match (t,ct) with
- _,None -> subst,metasenv
- | Some t,Some (_,C.Def ct) ->
- (try
- CicUnification.fo_unif_subst subst context metasenv t ct
- with _ -> raise MetasenvInconsistency)
- | Some t,Some (_,C.Decl ct) ->
- let inferredty,subst',metasenv' =
- type_of_aux subst metasenv context t
- in
- (try
- CicUnification.fo_unif_subst subst context metasenv inferredty ct
- with _ -> raise MetasenvInconsistency)
- | _, _ -> raise MetasenvInconsistency
- ) (subst,metasenv) l lifted_canonical_context
-
- and check_exp_named_subst metasubst metasenv context =
- let rec check_exp_named_subst_aux metasubst metasenv substs =
- function
- [] -> metasubst,metasenv
- | ((uri,t) as subst)::tl ->
- let typeofvar =
- CicSubstitution.subst_vars substs (type_of_variable uri) in
- (match CicEnvironment.get_cooked_obj ~trust:false uri with
- Cic.Variable (_,Some bo,_,_) ->
- raise
- (NotRefinable
- "A variable with a body can not be explicit substituted")
- | Cic.Variable (_,None,_,_) -> ()
- | _ -> raise (WrongUriToVariable (UriManager.string_of_uri uri))
- ) ;
- let typeoft,metasubst',metasenv' =
- type_of_aux metasubst metasenv context t
- in
- try
- let metasubst'',metasenv'' =
- CicUnification.fo_unif_subst
- metasubst' context metasenv' typeoft typeofvar
- in
- check_exp_named_subst_aux metasubst'' metasenv'' (substs@[subst]) tl
- with _ ->
- raise (NotRefinable "Wrong Explicit Named Substitution")
- in
- check_exp_named_subst_aux metasubst metasenv []
-
- and sort_of_prod subst metasenv context (name,s) (t1, t2) =
- let module C = Cic in
- (* ti could be a metavariable in the domain of the substitution *)
- let subst',metasenv' = CicUnification.unwind_subst metasenv subst in
- let t1' = CicUnification.apply_subst subst' t1 in
- let t2' = CicUnification.apply_subst subst' t2 in
- let t1'' = CicReduction.whd context t1' in
- let t2'' = CicReduction.whd ((Some (name,C.Decl s))::context) t2' in
- match (t1'', t2'') with
- (C.Sort s1, C.Sort s2)
- when (s2 = C.Prop or s2 = C.Set) -> (* different from Coq manual!!! *)
- C.Sort s2,subst',metasenv'
- | (C.Sort s1, C.Sort s2) ->
- (*CSC manca la gestione degli universi!!! *)
- C.Sort C.Type,subst',metasenv'
- | (C.Meta _,_)
- | (_,C.Meta _) ->
- raise
- (Uncertain
- ("Two sorts were expected, found " ^ CicPp.ppterm t1'' ^ " and " ^
- CicPp.ppterm t2''))
- | (_,_) ->
- raise
- (NotRefinable
- ("Prod: sort1= "^ CicPp.ppterm t1'' ^ " ; sort2= "^ CicPp.ppterm t2''))
-
- and eat_prods subst metasenv context hetype =
- function
- [] -> hetype,subst,metasenv
- | (hete, hety)::tl ->
- (match (CicReduction.whd context hetype) with
- Cic.Prod (n,s,t) ->
- let subst',metasenv' =
- try
- CicUnification.fo_unif_subst subst context metasenv s hety
- with _ ->
- raise (NotRefinable "Appl: wrong parameter-type")
- in
- CicReduction.fdebug := -1 ;
- eat_prods subst' metasenv' context (CicSubstitution.subst hete t) tl
- | Cic.Meta _ as t ->
- raise
- (Uncertain
- ("Prod expected, " ^ CicPp.ppterm t ^ " found"))
- | _ -> raise (NotRefinable "Appl: wrong Prod-type")
- )
- in
- let ty,subst',metasenv' =
- type_of_aux [] metasenv context t
- in
- let subst'',metasenv'' = CicUnification.unwind_subst metasenv' subst' in
- (* we get rid of the metavariables that have been instantiated *)
- let metasenv''' =
- List.filter
- (function (i,_,_) -> not (List.exists (function (j,_) -> j=i) subst''))
- metasenv''
- in
- CicUnification.apply_subst subst'' t,
- CicUnification.apply_subst subst'' ty,
- subst'', metasenv'''
-;;
-
-(* DEBUGGING ONLY *)
-let type_of_aux' metasenv context term =
- try
- let (t,ty,s,m) =
- type_of_aux' metasenv context term
- in
- List.iter
- (function (i,t) ->
- prerr_endline ("+ ?" ^ string_of_int i ^ " := " ^ CicPp.ppterm t)) s ;
- List.iter
- (function (i,_,t) ->
- prerr_endline ("+ ?" ^ string_of_int i ^ " : " ^ CicPp.ppterm t)) m ;
- prerr_endline
- ("@@@ REFINE SUCCESSFUL: " ^ CicPp.ppterm t ^ " : " ^ CicPp.ppterm ty) ;
- (t,ty,s,m)
- with
- e ->
- List.iter
- (function (i,_,t) ->
- prerr_endline ("+ ?" ^ string_of_int i ^ " : " ^ CicPp.ppterm t))
- metasenv ;
- prerr_endline ("@@@ REFINE FAILED: " ^ Printexc.to_string e) ;
- raise e
-;;