aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorherbelin2001-11-21 21:28:59 +0000
committerherbelin2001-11-21 21:28:59 +0000
commit0e054620f3dd7379a058cc85aef52fb106d8bff5 (patch)
tree8c60de03b0be6165fb0c0cc93bd86a6e1de6e8f4
parent37920925cd660cf172bb49bb9b1b37999fa33221 (diff)
Simplification de la propagation du prédicat, bugs, et messages d'erreurs
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@2234 85f007b7-540e-0410-9357-904b9bb8a0f7
-rw-r--r--pretyping/cases.ml136
-rw-r--r--pretyping/cases.mli1
2 files changed, 68 insertions, 69 deletions
diff --git a/pretyping/cases.ml b/pretyping/cases.ml
index 0261062f1a..11c03a23e8 100644
--- a/pretyping/cases.ml
+++ b/pretyping/cases.ml
@@ -37,6 +37,7 @@ type pattern_matching_error =
| NeedsInversion of constr * constr
| UnusedClause of cases_pattern list
| NonExhaustive of cases_pattern list
+ | CannotInferPredicate of (constr * types) array
exception PatternMatchingError of env * pattern_matching_error
@@ -197,18 +198,14 @@ let it_mkSpecialLetIn =
*)
type alias_constr =
- | DepAlias of types
- | NonDepAlias of types
+ | DepAlias
+ | NonDepAlias
-let lift_alias_constr k = function
- | DepAlias t -> DepAlias (lift k t)
- | NonDepAlias t -> NonDepAlias (lift k t)
-
-let mkSpecialLetInJudge j (na,(deppat,nondeppat,t)) =
+let mkSpecialLetInJudge j (na,(deppat,nondeppat,d,t)) =
{ uj_val =
- (match t with
- | DepAlias t -> mkLetIn (na,deppat,t,j.uj_val)
- | NonDepAlias t ->
+ (match d with
+ | DepAlias -> mkLetIn (na,deppat,t,j.uj_val)
+ | NonDepAlias ->
if (not (dependent (mkRel 1) j.uj_type))
or (* A leaf: *) isRel deppat
then
@@ -273,7 +270,7 @@ type tomatch_stack = tomatch_status list
type predicate_signature =
| PrLetIn of (constr list * constr option) * predicate_signature
- | PrProd of (bool * name * tomatch_type) * predicate_signature
+ | PrProd of name * tomatch_type * predicate_signature
| PrNotInd of constr option * predicate_signature
| PrCcl of constr
@@ -346,7 +343,7 @@ let rec eval_partial_args k (cargs,pargs as args) = function
| HistoryLift n :: h -> eval_partial_args (k+n) args h
| [] -> k, args
-let rec simplify_lifted_history k = function
+let rec simplify_history = function
| Continuation (0, l, Top) -> [], Result (eval_partial_pattern_args [] l)
| Continuation (0, l, MakeAlias (f, rh)) ->
let (k,(cargs,pargs)) = eval_partial_args 0 ([],[]) l in
@@ -354,18 +351,16 @@ let rec simplify_lifted_history k = function
| AliasConstructor ((c1,c2,d),pci) ->
let c1 = applist(lift k c1,cargs) in
let c2 = lift k c2 in
- let d = lift_alias_constr k d in
(c1,c2,d), PatCstr (dummy_loc,pci,pargs,Anonymous)
| AliasLeaf (x,t) ->
assert (l = []);
let c = lift k x in
- let t = lift k t in
- (c,c,NonDepAlias t), PatVar (dummy_loc, Anonymous) in
- let l, h = simplify_lifted_history k (feed_history (nondeppat,pat) rh) in
+ (c,c,NonDepAlias), PatVar (dummy_loc, Anonymous) in
+ let l, h = simplify_history
+ (feed_history (nondeppat,pat) (lift_history k rh)) in
(d::l, h)
- | h -> [], lift_history k h
+ | h -> [], h
-let simplify_history = simplify_lifted_history 0
(* Builds a continuation expecting [n] arguments and building [ci] applied
to this [n] arguments *)
@@ -411,6 +406,7 @@ type pattern_matching_problem =
tomatch : tomatch_stack;
history : pattern_continuation;
mat : matrix;
+ caseloc : loc;
typing_function: type_constraint -> env -> rawconstr -> unsafe_judgment }
(************************************************************************)
@@ -726,26 +722,15 @@ let build_aliases_context env sigma names allpats pats =
| _::pats, Anonymous::names ->
insert env sign1 sign2
n newallpats (List.map List.tl oldallpats) (pats,names)
- | (deppat,nondeppat,d as a)::pats, na::names ->
+ | (deppat,nondeppat,d)::pats, na::names ->
let nondeppat = lift n nondeppat in
let deppat = lift n deppat in
- let d = lift_alias_constr n d in
-(*
- let t = Retyping.get_type_of env sigma pat in
-*)
let newallpats =
List.map2 (fun l1 l2 -> List.hd l2::l1) newallpats oldallpats in
let oldallpats = List.map List.tl oldallpats in
- let decl =
- match d with
- | DepAlias t ->
- (* The alias refinement induces a refinement of its type *)
- (* The body is needed to ensure the type *)
- (na,Some deppat,t)
- | NonDepAlias t ->
- (* The type of alias is the same as its expansion *)
- (* Do as if it has no body *)
- (na,Some deppat,t) in
+ let t = Retyping.get_type_of env sigma deppat in
+ let decl = (na,Some deppat,t) in
+ let a = (deppat,nondeppat,d,t) in
insert (push_rel decl env) (decl::sign1) ((na,a)::sign2) (n+1)
newallpats oldallpats (pats,names)
| [], [] -> newallpats, sign1, sign2, env
@@ -882,7 +867,7 @@ let abstract_conclusion typ cs =
let (sign,p) = decompose_prod_n n typ in
lam_it p sign
-let infer_predicate env isevars typs cstrs ((mis,_) as indf) =
+let infer_predicate loc env isevars typs cstrs ((mis,_) as indf) =
(* Il faudra substituer les isevars a un certain moment *)
if Array.length cstrs = 0 then (* "TODO4-3" *)
error "Inference of annotation for empty inductive types not implemented"
@@ -919,8 +904,14 @@ let infer_predicate env isevars typs cstrs ((mis,_) as indf) =
let pred = it_mkLambda_or_LetIn (lift (List.length sign) mtyp) sign in
*)
(* "TODO4-2" *)
- error ("Unable to infer a Cases predicate\n"^
-"Either there is a type incompatiblity or the problem involves dependencies")
+ (* We skip parameters *)
+ let cis =
+ Array.map
+ (fun cs ->
+ applist (mkConstruct cs.cs_cstr, extended_rel_list 0 cs.cs_args))
+ cstrs in
+ let ct = array_map2 (fun ci (_,_,t) -> (ci,t)) cis eqns in
+ raise_pattern_matching_error (loc,env, CannotInferPredicate ct)
(*
(true,pred)
*)
@@ -933,8 +924,8 @@ let liftn_predicate n k pred =
| PrNotInd (copt,ccl) ->
let p = if copt = None then 0 else 1 in
PrNotInd (option_app (liftn n k) copt,liftrec (k+p) ccl)
- | PrProd ((dep,na,t),pred) ->
- PrProd ((dep,na,liftn_tomatch_type n k t), liftrec (k+1) pred)
+ | PrProd (na,t,pred) ->
+ PrProd (na,liftn_tomatch_type n k t, liftrec (k+1) pred)
| PrLetIn ((args,copt),pred) ->
let args' = List.map (liftn n k) args in
let copt' = option_app (liftn n k) copt in
@@ -954,8 +945,8 @@ let subst_predicate (args,copt) pred =
| PrNotInd (copt,pred) ->
let p = if copt = None then 0 else 1 in
PrNotInd (option_app (substnl sigma k) copt, substrec (k+p) pred)
- | PrProd ((dep,na,t),pred) ->
- PrProd ((dep,na,substnl_tomatch sigma k t), substrec (k+1) pred)
+ | PrProd (na,t,pred) ->
+ PrProd (na, substnl_tomatch sigma k t, substrec (k+1) pred)
| PrLetIn ((args,copt),pred) ->
let args' = List.map (substnl sigma k) args in
let copt' = option_app (substnl sigma k) copt in
@@ -970,7 +961,7 @@ let specialize_predicate_var = function
| PrLetIn (tm,pred) -> subst_predicate tm pred
let rec extract_predicate = function
- | PrProd ((_,na,t),pred) -> mkProdTomatch na t (extract_predicate pred)
+ | PrProd (na,t,pred) -> mkProdTomatch na t (extract_predicate pred)
| PrNotInd (Some c,pred) -> substl [c] (extract_predicate pred)
| PrNotInd (None,pred) -> extract_predicate pred
| PrLetIn ((args,Some c),pred) -> substl (c::(List.rev args)) (extract_predicate pred)
@@ -1012,21 +1003,30 @@ let weaken_predicate q pred =
if n=0 then pred else match pred with
| (PrLetIn _ | PrCcl _ | PrNotInd _) ->
anomaly "weaken_predicate: only product can be weakened"
- | PrProd ((dep,_,IsInd (_,IndType(indf,realargs))),pred) ->
- (* To make it more uniform, we apply realargs but they dont occur! *)
+ | PrProd (_,t,pred) ->
+ (* copt can occur in pred even if the original problem *)
+ (* is not dependent *)
+ let dep =
+ (* We are lazy, and do as if it were always dependent *)
+ true
+ (* dependent_predicate (mkRel 1) pred *)
+ in
let copt, p = if dep then Some (mkRel (n+k)), 1 else None, 0 in
- (* We replace 1 product by |realargs| arguments + possibly copt *)
- (* Then we need to shift pred accordingly (but *)
- let nletargs = (List.length realargs)+p in
- let pred = liftn_predicate (nletargs-p) (p+1) pred in
- (* The current lift to refer to the y1...yn is now k+nletargs *)
- PrLetIn ((realargs, copt), weakrec (n-1) (nletargs+k) pred)
- | PrProd ((dep,_,NotInd _),pred) ->
- (* Does copt occur in pred ? Does it need to be remembered ? *)
- let copt, p = if dep then Some (mkRel (n+k)), 1 else None, 0 in
- (* PrNotInd is a binding iff copt <> None *)
- PrNotInd (copt, weakrec (n-1) (k+p) pred)
- in weakrec q 0 (lift_predicate q pred)
+ match t with
+ | IsInd (_,IndType(_,realargs)) ->
+ (* To make it more uniform, we apply realargs but *)
+ (* they dont occur! *)
+ (* We replace 1 product by |realargs| arguments + possibly *)
+ (* copt Then we need to shift pred accordingly *)
+ let nletargs = List.length realargs in
+ let pred = liftn_predicate nletargs (p+1) pred in
+ (* The lift to refer to the y1...yn is now k+nletargs+p *)
+ PrLetIn ((realargs, copt), weakrec (n-1) (k+nletargs+p) pred)
+ | NotInd _ ->
+ PrNotInd (copt, weakrec (n-1) (k+p) pred) in
+ (* We inserted q arguments in context then we lift pred by q *)
+ let pred = lift_predicate q pred in
+ weakrec q 0 pred
(*****************************************************************************)
(* pred = [X:=realargs;x:=e]P types the following problem: *)
@@ -1046,8 +1046,7 @@ let specialize_predicate_match tomatchs cs = function
(* Assume some gamma st: gamma, (X,x:=realargs,copt) |- pred *)
let k = List.length args + (if copt = None then 0 else 1) in
(* We adjust pred st: gamma, x1...xn, (X,x:=realargs,copt) |- pred *)
- let depth = if copt = None then 0 else cs.cs_nargs in
- let pred' = liftn_predicate depth (k+1) pred in
+ let pred' = liftn_predicate cs.cs_nargs (k+1) pred in
let argsi = Array.to_list cs.cs_concl_realargs in
let copti = option_app (fun _ -> build_dependent_constructor cs) copt in
(* The substituends argsi, copti are all defined in gamma, x1...xn *)
@@ -1055,14 +1054,15 @@ let specialize_predicate_match tomatchs cs = function
let pred'' = subst_predicate (argsi, copti) pred' in
let dep = (copt <> None) in
List.fold_right
- (* Ne perd-on pas des cas en ne posant pas true à la place de dep ? *)
- (fun ((na,t),_) p -> PrProd ((dep,na,t),p)) tomatchs pred''
+ (* realargs doit être rehaussé non? *)
+ (fun ((na,t),_) p -> PrProd (na,t,p)) tomatchs pred''
-let find_predicate env isevars p typs cstrs current (IndType (indf,realargs)) =
+let find_predicate loc env isevars p typs cstrs current
+ (IndType (indf,realargs)) =
let (dep,pred) =
match p with
| Some p -> abstract_predicate env (evars_of isevars) indf p
- | None -> infer_predicate env isevars typs cstrs indf in
+ | None -> infer_predicate loc env isevars typs cstrs indf in
let typ = whd_beta (applist (pred, realargs)) in
if dep then
(pred, whd_beta (applist (typ, [current])), new_Type ())
@@ -1131,12 +1131,9 @@ let build_branch current typ pb eqns const_info =
if Array.length const_info.cs_concl_realargs = 0
& not (known_dependent pb.pred)
then
- NonDepAlias (type_of_tomatch typ)
- else
- let tyi = inductive_of_constructor const_info.cs_cstr in
- let params = List.map (lift const_info.cs_nargs) const_info.cs_params in
+ NonDepAlias
+ else
DepAlias
- (applist(mkInd tyi,params@Array.to_list const_info.cs_concl_realargs))
in
let partialci =
applist (mkConstruct const_info.cs_cstr, const_info.cs_params) in
@@ -1224,7 +1221,7 @@ and match_current pb (n,tm) =
let brtyps = Array.map (fun (_,j) -> body_of_type j.uj_type) brs in
let tags = Array.map fst brs in
let (pred,typ,s) =
- find_predicate pb.env pb.isevars
+ find_predicate pb.caseloc pb.env pb.isevars
pb.pred brtyps cstrs current indt in
let ci = make_case_info pb.env mind None tags in
pattern_status tags,
@@ -1323,8 +1320,8 @@ let prepare_initial_alias_eqn isdep tomatchl eqn =
let env = rename_env subst eqn.rhs.rhs_env in
{ eqn with patterns = pats; rhs = { eqn.rhs with rhs_env = env } }
-let prepare_initial_aliases isdep tomatchl mat =
- List.map (prepare_initial_alias_eqn isdep tomatchl) mat
+let prepare_initial_aliases isdep tomatchl mat = mat
+(* List.map (prepare_initial_alias_eqn isdep tomatchl) mat*)
(*
let prepare_initial_alias lpat tomatchl rhs =
@@ -1598,6 +1595,7 @@ let compile_cases loc (typing_fun,isevars) tycon env (predopt, tomatchl, eqns)=
tomatch = initial_pushed;
history = start_history (List.length initial_pushed);
mat = matx;
+ caseloc = loc;
typing_function = typing_fun } in
let _, j = compile pb in
diff --git a/pretyping/cases.mli b/pretyping/cases.mli
index 193882ba0f..222300028a 100644
--- a/pretyping/cases.mli
+++ b/pretyping/cases.mli
@@ -26,6 +26,7 @@ type pattern_matching_error =
| NeedsInversion of constr * constr
| UnusedClause of cases_pattern list
| NonExhaustive of cases_pattern list
+ | CannotInferPredicate of (constr * types) array
exception PatternMatchingError of env * pattern_matching_error