exception NotPositiveOccurrences of string;;
exception NotWellFormedTypeOfInductiveConstructor of string;;
exception WrongRequiredArgument of string;;
+exception RelToHiddenHypothesis;;
+exception MetasenvInconsistency;;
let fdebug = ref 0;;
let debug t context =
(* only to check that ty is well-typed *)
let _ = type_of ty in ()
| C.CurrentProof (_,conjs,te,ty) ->
+ (*CSC: bisogna controllare anche il metasenv!!! *)
let _ = type_of_aux' conjs [] ty in
if not (R.are_convertible [] (type_of_aux' conjs [] te) ty)
then
| C.Implicit -> true
| C.Cast (te,ty) ->
does_not_occur context n nn te && does_not_occur context n nn ty
- | C.Prod (_,so,dest) ->
+ | C.Prod (name,so,dest) ->
does_not_occur context n nn so &&
- does_not_occur ((C.Decl so)::context) (n + 1) (nn + 1) dest
- | C.Lambda (_,so,dest) ->
+ does_not_occur((Some (name,(C.Decl so)))::context) (n + 1) (nn + 1) dest
+ | C.Lambda (name,so,dest) ->
does_not_occur context n nn so &&
- does_not_occur ((C.Decl so)::context) (n + 1) (nn + 1) dest
- | C.LetIn (_,so,dest) ->
+ does_not_occur((Some (name,(C.Decl so)))::context) (n + 1) (nn + 1) dest
+ | C.LetIn (name,so,dest) ->
does_not_occur context n nn so &&
- does_not_occur ((C.Def so)::context) (n + 1) (nn + 1) dest
+ does_not_occur ((Some (name,(C.Def so)))::context) (n + 1) (nn + 1) dest
| C.Appl l ->
List.fold_right (fun x i -> i && does_not_occur context n nn x) l true
| C.Const _
- | C.Abst _
| C.MutInd _
| C.MutConstruct _ -> true
| C.MutCase (_,_,_,out,te,pl) ->
let len = List.length fl in
let n_plus_len = n + len in
let nn_plus_len = nn + len in
- let tys = List.map (fun (_,_,ty,_) -> Cic.Decl ty) fl in
+ let tys =
+ List.map (fun (n,_,ty,_) -> Some (C.Name n,(Cic.Decl ty))) fl
+ in
List.fold_right
(fun (_,_,ty,bo) i ->
i && does_not_occur context n nn ty &&
let len = List.length fl in
let n_plus_len = n + len in
let nn_plus_len = nn + len in
- let tys = List.map (fun (_,ty,_) -> Cic.Decl ty) fl in
+ let tys =
+ List.map (fun (n,ty,_) -> Some (C.Name n,(Cic.Decl ty))) fl
+ in
List.fold_right
(fun (_,ty,bo) i ->
i && does_not_occur context n nn ty &&
| C.Prod (C.Anonimous,source,dest) ->
strictly_positive context n nn
(subst_inductive_type_with_dummy_mutind source) &&
- weakly_positive ((C.Decl source)::context) (n + 1) (nn + 1) uri dest
+ weakly_positive ((Some (C.Anonimous,(C.Decl source)))::context)
+ (n + 1) (nn + 1) uri dest
| C.Prod (name,source,dest) when
- does_not_occur ((C.Decl source)::context) 0 n dest ->
+ does_not_occur ((Some (name,(C.Decl source)))::context) 0 n dest ->
(* dummy abstraction, so we behave as in the anonimous case *)
strictly_positive context n nn
(subst_inductive_type_with_dummy_mutind source) &&
- weakly_positive ((C.Decl source)::context) (n + 1) (nn + 1) uri dest
- | C.Prod (_,source,dest) ->
+ weakly_positive ((Some (name,(C.Decl source)))::context)
+ (n + 1) (nn + 1) uri dest
+ | C.Prod (name,source,dest) ->
does_not_occur context n nn
(subst_inductive_type_with_dummy_mutind source)&&
- weakly_positive ((C.Decl source)::context) (n + 1) (nn + 1) uri dest
+ weakly_positive ((Some (name,(C.Decl source)))::context)
+ (n + 1) (nn + 1) uri dest
| _ -> raise (NotWellFormedTypeOfInductiveConstructor ("Guess where the error is ;-)"))
(* instantiate_parameters ps (x1:T1)...(xn:Tn)C *)
| C.Cast (te,ty) ->
(*CSC: bisogna controllare ty????*)
strictly_positive context n nn te
- | C.Prod (_,so,ta) ->
+ | C.Prod (name,so,ta) ->
does_not_occur context n nn so &&
- strictly_positive ((C.Decl so)::context) (n+1) (nn+1) ta
+ strictly_positive ((Some (name,(C.Decl so)))::context) (n+1) (nn+1) ta
| C.Appl ((C.Rel m)::tl) when m > n && m <= nn ->
List.fold_right (fun x i -> i && does_not_occur context n nn x) tl true
| C.Appl ((C.MutInd (uri,_,i))::tl) ->
- let (ok,paramsno,ity,cl) =
+ let (ok,paramsno,ity,cl,name) =
match CicEnvironment.get_obj uri with
C.InductiveDefinition (tl,_,paramsno) ->
- let (_,_,ity,cl) = List.nth tl i in
- (List.length tl = 1, paramsno, ity, cl)
+ let (name,_,ity,cl) = List.nth tl i in
+ (List.length tl = 1, paramsno, ity, cl, name)
| _ -> raise(WrongUriToMutualInductiveDefinitions(U.string_of_uri uri))
in
let (params,arguments) = split tl paramsno in
List.fold_right
(fun x i ->
i &&
- weakly_positive ((Cic.Decl ity)::context) (n+1) (nn+1) uri x
+ weakly_positive
+ ((Some (C.Name name,(Cic.Decl ity)))::context) (n+1) (nn+1) uri x
) cl' true
| t -> does_not_occur context n nn t
raise (WrongRequiredArgument (UriManager.string_of_uri uri))
| C.Prod (C.Anonimous,source,dest) ->
strictly_positive context n nn source &&
- are_all_occurrences_positive ((C.Decl source)::context) uri indparamsno
+ are_all_occurrences_positive
+ ((Some (C.Anonimous,(C.Decl source)))::context) uri indparamsno
(i+1) (n + 1) (nn + 1) dest
| C.Prod (name,source,dest) when
- does_not_occur ((C.Decl source)::context) 0 n dest ->
+ does_not_occur ((Some (name,(C.Decl source)))::context) 0 n dest ->
(* dummy abstraction, so we behave as in the anonimous case *)
strictly_positive context n nn source &&
- are_all_occurrences_positive ((C.Decl source)::context) uri indparamsno
+ are_all_occurrences_positive
+ ((Some (name,(C.Decl source)))::context) uri indparamsno
(i+1) (n + 1) (nn + 1) dest
- | C.Prod (_,source,dest) ->
+ | C.Prod (name,source,dest) ->
does_not_occur context n nn source &&
- are_all_occurrences_positive ((C.Decl source)::context) uri indparamsno
- (i+1) (n + 1) (nn + 1) dest
+ are_all_occurrences_positive ((Some (name,(C.Decl source)))::context)
+ uri indparamsno (i+1) (n + 1) (nn + 1) dest
| _ -> raise (NotWellFormedTypeOfInductiveConstructor (UriManager.string_of_uri uri))
(*CSC: cambiare il nome, torna unit! *)
(*CSC: siamo sicuri che non debba fare anche un List.rev? Il bug *)
(*CSC: si manifesterebbe solamene con tipi veramente mutualmente *)
(*CSC: induttivi... *)
- let tys = List.map (fun (_,_,ty,_) -> Cic.Decl ty) itl in
+ let tys =
+ List.map (fun (n,_,ty,_) -> Some (Cic.Name n,(Cic.Decl ty))) itl in
let _ =
List.fold_right
(fun (_,_,_,cl) i ->
| C.Sort _
| C.Implicit
| C.Cast _ (*CSC ??? *) -> raise (Impossible 3) (* due to type-checking *)
- | C.Prod (_,so,de) ->
+ | C.Prod (name,so,de) ->
(not (does_not_occur context n nn so)) ::
- (recursive_args ((C.Decl so)::context) (n+1) (nn + 1) de)
+ (recursive_args ((Some (name,(C.Decl so)))::context) (n+1) (nn + 1) de)
| C.Lambda _
| C.LetIn _ -> raise (Impossible 4) (* due to type-checking *)
| C.Appl _ -> []
- | C.Const _
- | C.Abst _ -> raise (Impossible 5)
+ | C.Const _ -> raise (Impossible 5)
| C.MutInd _
| C.MutConstruct _
| C.MutCase _
let module U = UriManager in
let module R = CicReduction in
match (R.whd context c, R.whd context p, rl) with
- (C.Prod (_,so,ta1), C.Lambda (_,_,ta2), b::tl) ->
+ (C.Prod (_,so,ta1), C.Lambda (name,_,ta2), b::tl) ->
(* we are sure that the two sources are convertible because we *)
(* have just checked this. So let's go along ... *)
let safes' =
let safes'' =
if b then 1::safes' else safes'
in
- get_new_safes ((C.Decl so)::context) ta2 ta1 tl safes'' (n+1) (nn+1)
- (x+1)
+ get_new_safes ((Some (name,(C.Decl so)))::context)
+ ta2 ta1 tl safes'' (n+1) (nn+1) (x+1)
| (C.Prod _, (C.MutConstruct _ as e), _)
| (C.Prod _, (C.Rel _ as e), _)
| (C.MutInd _, e, [])
let module R = CicReduction in
match (n, R.whd context te) with
(0, _) -> context,te
- | (n, C.Prod (_,so,ta)) when n > 0 ->
- split_prods ((C.Decl so)::context) (n - 1) ta
+ | (n, C.Prod (name,so,ta)) when n > 0 ->
+ split_prods ((Some (name,(C.Decl so)))::context) (n - 1) ta
| (_, _) -> raise (Impossible 8)
and eat_lambdas context n te =
let module R = CicReduction in
match (n, R.whd context te) with
(0, _) -> (te, 0, context)
- | (n, C.Lambda (_,so,ta)) when n > 0 ->
- let (te, k, context') = eat_lambdas ((C.Decl so)::context) (n - 1) ta in
+ | (n, C.Lambda (name,so,ta)) when n > 0 ->
+ let (te, k, context') =
+ eat_lambdas ((Some (name,(C.Decl so)))::context) (n - 1) ta
+ in
(te, k + 1, context')
| (_, _) -> raise (Impossible 9)
check_is_really_smaller_arg (n+1) (nn+1) kl (x+1)
(List.map (fun x -> x + 1) safes) ta*)
| C.Prod _ -> raise (Impossible 10)
- | C.Lambda (_,so,ta) ->
+ | C.Lambda (name,so,ta) ->
check_is_really_smaller_arg context n nn kl x safes so &&
- check_is_really_smaller_arg ((C.Decl so)::context) (n+1) (nn+1) kl (x+1)
- (List.map (fun x -> x + 1) safes) ta
- | C.LetIn (_,so,ta) ->
+ check_is_really_smaller_arg ((Some (name,(C.Decl so)))::context)
+ (n+1) (nn+1) kl (x+1) (List.map (fun x -> x + 1) safes) ta
+ | C.LetIn (name,so,ta) ->
check_is_really_smaller_arg context n nn kl x safes so &&
- check_is_really_smaller_arg ((C.Def so)::context) (n+1) (nn+1) kl (x+1)
- (List.map (fun x -> x + 1) safes) ta
+ check_is_really_smaller_arg ((Some (name,(C.Def so)))::context)
+ (n+1) (nn+1) kl (x+1) (List.map (fun x -> x + 1) safes) ta
| C.Appl (he::_) ->
(*CSC: sulla coda ci vogliono dei controlli? secondo noi no, ma *)
(*CSC: solo perche' non abbiamo trovato controesempi *)
check_is_really_smaller_arg context n nn kl x safes he
| C.Appl [] -> raise (Impossible 11)
| C.Const _
- | C.Abst _
| C.MutInd _ -> raise (Impossible 12)
| C.MutConstruct _ -> false
| C.MutCase (uri,_,i,outtype,term,pl) ->
let (isinductive,paramsno,cl) =
match CicEnvironment.get_obj uri with
C.InductiveDefinition (tl,_,paramsno) ->
- let tys = List.map (fun (_,_,ty,_) -> Cic.Decl ty) tl in
+ let tys =
+ List.map (fun (n,_,ty,_) -> Some (Cic.Name n,(Cic.Decl ty))) tl
+ in
let (_,isinductive,_,cl) = List.nth tl i in
let cl' =
List.map
match CicEnvironment.get_obj uri with
C.InductiveDefinition (tl,_,paramsno) ->
let (_,isinductive,_,cl) = List.nth tl i in
- let tys = List.map (fun (_,_,ty,_) -> Cic.Decl ty) tl in
+ let tys =
+ List.map (fun (n,_,ty,_) -> Some(Cic.Name n,(Cic.Decl ty))) tl
+ in
let cl' =
List.map
(fun (id,ty,r) ->
let n_plus_len = n + len
and nn_plus_len = nn + len
and x_plus_len = x + len
- (*CSC: Is a Decl of the ty ok or should I use Def of a Fix? *)
- and tys = List.map (fun (_,_,ty,_) -> C.Decl ty) fl
+ and tys = List.map (fun (n,_,ty,_) -> Some (C.Name n,(C.Decl ty))) fl
and safes' = List.map (fun x -> x + len) safes in
List.fold_right
(fun (_,_,ty,bo) i ->
let n_plus_len = n + len
and nn_plus_len = nn + len
and x_plus_len = x + len
- (*CSC: Is a Decl of the ty ok or should I use Def of a Fix? *)
- and tys = List.map (fun (_,ty,_) -> C.Decl ty) fl
+ and tys = List.map (fun (n,ty,_) -> Some (C.Name n,(C.Decl ty))) fl
and safes' = List.map (fun x -> x + len) safes in
List.fold_right
(fun (_,ty,bo) i ->
C.Rel m when m > n && m <= nn -> false
| C.Rel n ->
(match List.nth context (n-1) with
- C.Decl _ -> true
- | C.Def bo -> guarded_by_destructors context n nn kl x safes bo
+ Some (_,C.Decl _) -> true
+ | Some (_,C.Def bo) -> guarded_by_destructors context n nn kl x safes bo
+ | None -> raise RelToHiddenHypothesis
)
| C.Var _
| C.Meta _
| C.Cast (te,ty) ->
guarded_by_destructors context n nn kl x safes te &&
guarded_by_destructors context n nn kl x safes ty
- | C.Prod (_,so,ta) ->
+ | C.Prod (name,so,ta) ->
guarded_by_destructors context n nn kl x safes so &&
- guarded_by_destructors ((C.Decl so)::context) (n+1) (nn+1) kl (x+1)
- (List.map (fun x -> x + 1) safes) ta
- | C.Lambda (_,so,ta) ->
+ guarded_by_destructors ((Some (name,(C.Decl so)))::context)
+ (n+1) (nn+1) kl (x+1) (List.map (fun x -> x + 1) safes) ta
+ | C.Lambda (name,so,ta) ->
guarded_by_destructors context n nn kl x safes so &&
- guarded_by_destructors ((C.Decl so)::context) (n+1) (nn+1) kl (x+1)
- (List.map (fun x -> x + 1) safes) ta
- | C.LetIn (_,so,ta) ->
+ guarded_by_destructors ((Some (name,(C.Decl so)))::context)
+ (n+1) (nn+1) kl (x+1) (List.map (fun x -> x + 1) safes) ta
+ | C.LetIn (name,so,ta) ->
guarded_by_destructors context n nn kl x safes so &&
- guarded_by_destructors ((C.Def so)::context) (n+1) (nn+1) kl (x+1)
- (List.map (fun x -> x + 1) safes) ta
+ guarded_by_destructors ((Some (name,(C.Def so)))::context)
+ (n+1) (nn+1) kl (x+1) (List.map (fun x -> x + 1) safes) ta
| C.Appl ((C.Rel m)::tl) when m > n && m <= nn ->
let k = List.nth kl (m - n - 1) in
if not (List.length tl > k) then false
(fun t i -> i && guarded_by_destructors context n nn kl x safes t)
tl true
| C.Const _
- | C.Abst _
| C.MutInd _
| C.MutConstruct _ -> true
| C.MutCase (uri,_,i,outtype,term,pl) ->
match CicEnvironment.get_obj uri with
C.InductiveDefinition (tl,_,paramsno) ->
let (_,isinductive,_,cl) = List.nth tl i in
- let tys = List.map (fun (_,_,ty,_) -> Cic.Decl ty) tl in
+ let tys =
+ List.map (fun (n,_,ty,_) -> Some(Cic.Name n,(Cic.Decl ty))) tl
+ in
let cl' =
List.map
(fun (id,ty,r) ->
match CicEnvironment.get_obj uri with
C.InductiveDefinition (tl,_,paramsno) ->
let (_,isinductive,_,cl) = List.nth tl i in
- let tys = List.map (fun (_,_,ty,_) -> Cic.Decl ty) tl in
+ let tys =
+ List.map (fun (n,_,ty,_) -> Some(Cic.Name n,(Cic.Decl ty))) tl
+ in
let cl' =
List.map
(fun (id,ty,r) ->
let n_plus_len = n + len
and nn_plus_len = nn + len
and x_plus_len = x + len
- (*CSC: Is a Decl of the ty ok or should I use Def of a Fix? *)
- and tys = List.map (fun (_,_,ty,_) -> C.Decl ty) fl
+ and tys = List.map (fun (n,_,ty,_) -> Some (C.Name n,(C.Decl ty))) fl
and safes' = List.map (fun x -> x + len) safes in
List.fold_right
(fun (_,_,ty,bo) i ->
let n_plus_len = n + len
and nn_plus_len = nn + len
and x_plus_len = x + len
- (*CSC: Is a Decl of the ty ok or should I use Def of a Fix? *)
- and tys = List.map (fun (_,ty,_) -> C.Decl ty) fl
+ and tys = List.map (fun (n,ty,_) -> Some (C.Name n,(C.Decl ty))) fl
and safes' = List.map (fun x -> x + len) safes in
List.fold_right
(fun (_,ty,bo) i ->
| C.Prod _
| C.LetIn _ ->
raise (Impossible 17) (* the term has just been type-checked *)
- | C.Lambda (_,so,de) ->
+ | C.Lambda (name,so,de) ->
does_not_occur context n nn so &&
- guarded_by_constructors ((C.Decl so)::context) (n + 1) (nn + 1) h de args
- coInductiveTypeURI
+ guarded_by_constructors ((Some (name,(C.Decl so)))::context)
+ (n + 1) (nn + 1) h de args coInductiveTypeURI
| C.Appl ((C.Rel m)::tl) when m > n && m <= nn ->
h &&
List.fold_right (fun x i -> i && does_not_occur context n nn x) tl true
does_not_occur context n nn te
| C.Implicit
| C.Cast _ -> raise (Impossible 24) (* due to type-checking *)
- | C.Prod (_,so,de) ->
- analyse_branch ((C.Decl so)::context) de te
+ | C.Prod (name,so,de) ->
+ analyse_branch ((Some (name,(C.Decl so)))::context) de te
| C.Lambda _
| C.LetIn _ -> raise (Impossible 25) (* due to type-checking *)
| C.Appl ((C.MutInd (uri,_,_))::tl) as ty
guarded_by_constructors context n nn true te tl coInductiveTypeURI
| C.Appl _ ->
does_not_occur context n nn te
- | C.Const _
- | C.Abst _ -> raise (Impossible 26)
+ | C.Const _ -> raise (Impossible 26)
| C.MutInd (uri,_,_) when uri == coInductiveTypeURI ->
guarded_by_constructors context n nn true te [] coInductiveTypeURI
| C.MutInd _ ->
| C.Sort _
| C.Implicit
| C.Cast _ -> raise (Impossible 29) (* due to type-checking *)
- | C.Prod (_,so,de) ->
+ | C.Prod (name,so,de) ->
begin
match l with
[] -> true
| he::tl ->
analyse_branch context so he &&
- analyse_instantiated_type ((C.Decl so)::context) de tl
+ analyse_instantiated_type ((Some (name,(C.Decl so)))::context)
+ de tl
end
| C.Lambda _
| C.LetIn _ -> raise (Impossible 30) (* due to type-checking *)
| C.Appl _ ->
List.fold_left
(fun i x -> i && does_not_occur context n nn x) true l
- | C.Const _
- | C.Abst _ -> raise (Impossible 31)
+ | C.Const _ -> raise (Impossible 31)
| C.MutInd _ ->
List.fold_left
(fun i x -> i && does_not_occur context n nn x) true l
let n_plus_len = n + len
and nn_plus_len = nn + len
(*CSC: Is a Decl of the ty ok or should I use Def of a Fix? *)
- and tys = List.map (fun (_,ty,_) -> C.Decl ty) fl in
+ and tys = List.map (fun (n,ty,_) -> Some (C.Name n,(C.Decl ty))) fl in
List.fold_right
(fun (_,ty,bo) i ->
i && does_not_occur context n nn ty &&
| C.Appl l ->
List.fold_right (fun x i -> i && does_not_occur context n nn x) l true
| C.Const _ -> true
- | C.Abst _
| C.MutInd _ -> assert false
| C.MutConstruct _ -> true
| C.MutCase (_,_,_,out,te,pl) ->
let n_plus_len = n + len
and nn_plus_len = nn + len
(*CSC: Is a Decl of the ty ok or should I use Def of a Fix? *)
- and tys = List.map (fun (_,_,ty,_) -> C.Decl ty) fl in
+ and tys = List.map (fun (n,_,ty,_) -> Some (C.Name n,(C.Decl ty))) fl in
List.fold_right
(fun (_,_,ty,bo) i ->
i && does_not_occur context n nn ty &&
let n_plus_len = n + len
and nn_plus_len = nn + len
(*CSC: Is a Decl of the ty ok or should I use Def of a Fix? *)
- and tys = List.map (fun (_,ty,_) -> C.Decl ty) fl in
+ and tys = List.map (fun (n,ty,_) -> Some (C.Name n,(C.Decl ty))) fl in
List.fold_right
(fun (_,ty,bo) i ->
i && does_not_occur context n nn ty &&
| (C.Sort C.Set, C.Sort C.Type) when need_dummy ->
(match CicEnvironment.get_obj uri with
C.InductiveDefinition (itl,_,paramsno) ->
- let tys = List.map (fun (_,_,ty,_) -> Cic.Decl ty) itl in
+ let tys =
+ List.map (fun (n,_,ty,_) -> Some (Cic.Name n,(Cic.Decl ty))) itl
+ in
let (_,_,_,cl) = List.nth itl i in
List.fold_right
(fun (_,x,_) i -> i && is_small tys paramsno x) cl true
raise (WrongUriToMutualInductiveDefinitions (U.string_of_uri uri))
)
| (C.Sort C.Type, C.Sort _) when need_dummy -> true
- | (C.Sort C.Prop, C.Prod (_,so,ta)) when not need_dummy ->
+ | (C.Sort C.Prop, C.Prod (name,so,ta)) when not need_dummy ->
let res = CicReduction.are_convertible context so ind
in
res &&
- (match CicReduction.whd ((C.Decl so)::context) ta with
+ (match CicReduction.whd ((Some (name,(C.Decl so)))::context) ta with
C.Sort C.Prop -> true
| C.Sort C.Set ->
(match CicEnvironment.get_obj uri with
)
| _ -> false
)
- | (C.Sort C.Set, C.Prod (_,so,ta)) when not need_dummy ->
+ | (C.Sort C.Set, C.Prod (name,so,ta)) when not need_dummy ->
let res = CicReduction.are_convertible context so ind
in
res &&
- (match CicReduction.whd ((C.Decl so)::context) ta with
+ (match CicReduction.whd ((Some (name,(C.Decl so)))::context) ta with
C.Sort C.Prop
| C.Sort C.Set -> true
| C.Sort C.Type ->
(match CicEnvironment.get_obj uri with
C.InductiveDefinition (itl,_,paramsno) ->
let (_,_,_,cl) = List.nth itl i in
- let tys = List.map (fun (_,_,ty,_) -> Cic.Decl ty) itl in
+ let tys =
+ List.map
+ (fun (n,_,ty,_) -> Some (Cic.Name n,(Cic.Decl ty))) itl
+ in
List.fold_right
(fun (_,x,_) i -> i && is_small tys paramsno x) cl true
| _ ->
else
C.Appl (outtype::arguments@(if need_dummy then [] else [term]))
| C.Prod (name,so,de) ->
- C.Prod (C.Anonimous,so,type_of_branch ((C.Decl so)::context) argsno
- need_dummy (CicSubstitution.lift 1 outtype)
- (C.Appl [CicSubstitution.lift 1 term ; C.Rel 1]) de)
+ let term' =
+ match CicSubstitution.lift 1 term with
+ C.Appl l -> C.Appl (l@[C.Rel 1])
+ | t -> C.Appl [t ; C.Rel 1]
+ in
+ C.Prod (C.Anonimous,so,type_of_branch
+ ((Some (name,(C.Decl so)))::context) argsno need_dummy
+ (CicSubstitution.lift 1 outtype) term' de)
| _ -> raise (Impossible 20)
-
-
+
+(* 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 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.iter2
+ (fun t ct ->
+ let res =
+ match (t,ct) with
+ _,None -> true
+ | Some t,Some (_,C.Def ct) ->
+ R.are_convertible context t ct
+ | Some t,Some (_,C.Decl ct) ->
+ R.are_convertible context (type_of_aux' metasenv context t) ct
+ | _, _ -> false
+ in
+ if not res then raise MetasenvInconsistency
+ ) l lifted_canonical_context
+
(* 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 context =
C.Rel n ->
(try
match List.nth context (n - 1) with
- C.Decl t -> S.lift n t
- | C.Def bo -> type_of_aux context (S.lift n bo)
+ Some (_,C.Decl t) -> S.lift n t
+ | Some (_,C.Def bo) -> type_of_aux context (S.lift n bo)
+ | None -> raise RelToHiddenHypothesis
with
_ -> raise (NotWellTyped "Not a close term")
)
let ty = type_of_variable uri in
decr fdebug ;
ty
- | C.Meta n -> List.assoc n metasenv
+ | C.Meta (n,l) ->
+ let (_,canonical_context,ty) =
+ List.find (function (m,_,_) -> n = m) metasenv
+ in
+ check_metasenv_consistency metasenv context canonical_context l;
+ CicSubstitution.lift_meta l ty
| C.Sort s -> C.Sort C.Type (*CSC manca la gestione degli universi!!! *)
| C.Implicit -> raise (Impossible 21)
| C.Cast (te,ty) ->
let _ = type_of_aux context ty in
if R.are_convertible context (type_of_aux context te) ty then ty
else raise (NotWellTyped "Cast")
- | C.Prod (_,s,t) ->
+ | C.Prod (name,s,t) ->
let sort1 = type_of_aux context s
- and sort2 = type_of_aux ((C.Decl s)::context) t in
- sort_of_prod (sort1,sort2)
+ and sort2 = type_of_aux ((Some (name,(C.Decl s)))::context) t in
+ sort_of_prod context (name,s) (sort1,sort2)
| C.Lambda (n,s,t) ->
let sort1 = type_of_aux context s
- and type2 = type_of_aux ((C.Decl s)::context) t in
- let sort2 = type_of_aux ((C.Decl s)::context) type2 in
+ and type2 = type_of_aux ((Some (n,(C.Decl s)))::context) t in
+ let sort2 = type_of_aux ((Some (n,(C.Decl s)))::context) type2 in
(* only to check if the product is well-typed *)
- let _ = sort_of_prod (sort1,sort2) in
+ let _ = sort_of_prod context (n,s) (sort1,sort2) in
C.Prod (n,s,type2)
| C.LetIn (n,s,t) ->
- let t' = CicSubstitution.subst s t in
- type_of_aux context t'
+ (* only to check if s is well-typed *)
+ let _ = type_of_aux context s in
+ C.LetIn (n,s, type_of_aux ((Some (n,(C.Def s)))::context) t)
| C.Appl (he::tl) when List.length tl > 0 ->
let hetype = type_of_aux context he
and tlbody_and_type = List.map (fun x -> (x, type_of_aux context x)) tl in
let cty = cooked_type_of_constant uri cookingsno in
decr fdebug ;
cty
- | C.Abst _ -> raise (Impossible 22)
| C.MutInd (uri,cookingsno,i) ->
incr fdebug ;
let cty = cooked_type_of_mutual_inductive_defs uri cookingsno i in
let rec guess_args context t =
match CicReduction.whd context t with
C.Sort _ -> (true, 0)
- | C.Prod (_, s, t) ->
- let (b, n) = guess_args ((C.Decl s)::context) t in
+ | C.Prod (name, s, t) ->
+ let (b, n) = guess_args ((Some (name,(C.Decl s)))::context) t in
if n = 0 then
(* last prod before sort *)
match CicReduction.whd context s with
let types_times_kl =
List.rev
(List.map
- (fun (_,k,ty,_) ->
- let _ = type_of_aux context ty in (C.Decl ty,k)) fl)
+ (fun (n,k,ty,_) ->
+ let _ = type_of_aux context ty in
+ (Some (C.Name n,(C.Decl ty)),k)) fl)
in
let (types,kl) = List.split types_times_kl in
let len = List.length types in
let types =
List.rev
(List.map
- (fun (_,ty,_) -> let _ = type_of_aux context ty in C.Decl ty) fl)
+ (fun (n,ty,_) ->
+ let _ = type_of_aux context ty in Some (C.Name n,(C.Decl ty))) fl)
in
let len = List.length types in
List.iter
then
begin
(* let's control that the returned type is coinductive *)
- match returns_a_coinductive ty with
+ match returns_a_coinductive context ty with
None ->
raise(NotWellTyped "CoFix: does not return a coinductive type")
| Some uri ->
let (_,ty,_) = List.nth fl i in
ty
- and sort_of_prod (t1, t2) =
+ and sort_of_prod context (name,s) (t1, t2) =
let module C = Cic in
let t1' = CicReduction.whd context t1 in
- let t2' = CicReduction.whd context t2 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!!! *)
| _ -> raise (NotWellTyped "Appl: wrong Prod-type")
)
- and returns_a_coinductive ty =
+ and returns_a_coinductive context ty =
let module C = Cic in
match CicReduction.whd context ty with
C.MutInd (uri,cookingsno,i) ->
raise (WrongUriToMutualInductiveDefinitions
(UriManager.string_of_uri uri))
)
- | C.Prod (_,_,de) -> returns_a_coinductive de
+ | C.Prod (n,so,de) ->
+ returns_a_coinductive ((Some (n,C.Decl so))::context) de
| _ -> None
in
let rec is_small_aux context c =
let module C = Cic in
match CicReduction.whd context c with
- C.Prod (_,so,de) ->
+ C.Prod (n,so,de) ->
(*CSC: [] is an empty metasenv. Is it correct? *)
let s = type_of_aux' [] context so in
(s = C.Sort C.Prop || s = C.Sort C.Set) &&
- is_small_aux ((C.Decl so)::context) de
+ is_small_aux ((Some (n,(C.Decl so)))::context) de
| _ -> true (*CSC: we trust the type-checker *)
in
let (context',dx) = split_prods context paramsno c in
(* only to check that ty is well-typed *)
let _ = type_of ty in ()
| C.CurrentProof (_,conjs,te,ty) ->
- (*CSC [] wrong *)
+ (*CSC: bisogna controllare anche il metasenv!!! *)
let _ = type_of_aux' conjs [] ty in
debug (type_of_aux' conjs [] te) [] ;
if not (R.are_convertible [] (type_of_aux' conjs [] te) ty) then