aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--lib/util.ml1
-rw-r--r--lib/util.mli1
-rw-r--r--pretyping/cases.ml93
3 files changed, 45 insertions, 50 deletions
diff --git a/lib/util.ml b/lib/util.ml
index f7be7b0d7..a199aacd2 100644
--- a/lib/util.ml
+++ b/lib/util.ml
@@ -51,6 +51,7 @@ exception Error_in_file of string * (bool * string * loc) * exn
let on_fst f (a,b) = (f a,b)
let on_snd f (a,b) = (a,f b)
+let map_pair f (a,b) = (f a,f b)
(* Mapping under pairs *)
diff --git a/lib/util.mli b/lib/util.mli
index e24df1a31..a2a72453c 100644
--- a/lib/util.mli
+++ b/lib/util.mli
@@ -61,6 +61,7 @@ exception Error_in_file of string * (bool * string * loc) * exn
val on_fst : ('a -> 'b) -> 'a * 'c -> 'b * 'c
val on_snd : ('a -> 'b) -> 'c * 'a -> 'c * 'b
+val map_pair : ('a -> 'b) -> 'a * 'a -> 'b * 'b
(** Going down pairs *)
diff --git a/pretyping/cases.ml b/pretyping/cases.ml
index f56fb5a42..c7b6612f6 100644
--- a/pretyping/cases.ml
+++ b/pretyping/cases.ml
@@ -139,7 +139,7 @@ type tomatch_type =
type tomatch_status =
| Pushed of ((constr * tomatch_type) * int list * name)
- | Alias of (constr * rel_declaration * bool Lazy.t)
+ | Alias of (name * constr * (constr * types))
| NonDepAlias
| Abstract of int * rel_declaration
@@ -587,10 +587,9 @@ let relocate_index_tomatch n1 n2 =
let tm = map_tomatch_type (relocate_index n1 n2 depth) tm in
let l = List.map (relocate_rel n1 n2 depth) l in
Pushed ((c,tm),l,na) :: genrec depth rest
- | Alias (c,d,p) :: rest ->
- let d = map_rel_declaration (relocate_index n1 n2 depth) d in
+ | Alias (na,c,d) :: rest ->
(* [c] is out of relocation scope *)
- Alias (c,d,p) :: genrec depth rest
+ Alias (na,c,map_pair (relocate_index n1 n2 depth) d) :: genrec depth rest
| NonDepAlias :: rest ->
NonDepAlias :: genrec depth rest
| Abstract (i,d) :: rest ->
@@ -617,10 +616,9 @@ let replace_tomatch n c =
let tm = map_tomatch_type (replace_term n c depth) tm in
List.iter (fun i -> if i=n+depth then anomaly "replace_tomatch") l;
Pushed ((b,tm),l,na) :: replrec depth rest
- | Alias (b,d,p) :: rest ->
- let d = map_rel_declaration (replace_term n c depth) d in
- (* [c] is out of replacement scope *)
- Alias (b,d,p) :: replrec depth rest
+ | Alias (na,b,d) :: rest ->
+ (* [b] is out of replacement scope *)
+ Alias (na,b,map_pair (replace_term n c depth) d) :: replrec depth rest
| NonDepAlias :: rest ->
NonDepAlias :: replrec depth rest
| Abstract (i,d) :: rest ->
@@ -642,8 +640,8 @@ let rec liftn_tomatch_stack n depth = function
let tm = liftn_tomatch_type n depth tm in
let l = List.map (fun i -> if i<depth then i else i+n) l in
Pushed ((c,tm),l,na)::(liftn_tomatch_stack n depth rest)
- | Alias (c,d,p)::rest ->
- Alias (liftn n depth c,map_rel_declaration (liftn n depth) d,p)
+ | Alias (na,c,d)::rest ->
+ Alias (na,liftn n depth c,map_pair (liftn n depth) d)
::(liftn_tomatch_stack n depth rest)
| NonDepAlias :: rest ->
NonDepAlias :: liftn_tomatch_stack n depth rest
@@ -1000,27 +998,6 @@ let adjust_predicate_from_tomatch tomatch (current,typ as ct) pb =
| _ ->
pb, (ct,deps,na)
-(* Decide what to do with an alias *)
-
-let is_dep_pred n pb =
- (* Keep call to is_dep_pred lazy so that pb.evdref is fetched when really
- needed, and hopefully with a maximum of information on evar resolution *)
- let pred = nf_evar !(pb.evdref) pb.pred in
- not (noccur_predicate_between 1 (n+1) pred pb.tomatch)
-
-let mkSpecialLetIn orig (na,b,t) isdeppred c =
- if na = Anonymous || not (dependent (mkRel 1) c) then
- lift (-1) c
- else if Lazy.force isdeppred then
- mkLetIn (na,Option.get b,t,c)
- else
- (* Brutal replacement by the non-dependent alias if atomic *)
- (* Caution: is might violate typing if the alias is internally used *)
- (* to type the right-hand side even though it does not occur in the *)
- (* external type (e.g. with "f x refl" with "f:forall x,x=0 -> Prop" *)
- (* and x aliased to 0 *)
- if isRel orig then subst1 orig c else subst1 (Option.get b) c
-
(* Remove commutative cuts that turn out to be non-dependent after
some evars have been instantiated *)
@@ -1211,19 +1188,17 @@ let build_branch current realargs deps (realnames,curname) pb arsign eqns const_
let currents = List.map (fun x -> Pushed x) typs' in
- let ind =
- appvect (
- applist (mkInd (inductive_of_constructor const_info.cs_cstr),
- List.map (lift const_info.cs_nargs) const_info.cs_params),
- const_info.cs_concl_realargs) in
-
let alias =
if aliasname = Anonymous then
NonDepAlias
else
let cur_alias = lift const_info.cs_nargs current in
- let lazy_dep_pred = lazy (is_dep_pred (List.length realnames) pb) in
- Alias (cur_alias,(aliasname,Some ci,ind),lazy_dep_pred) in
+ let ind =
+ appvect (
+ applist (mkInd (inductive_of_constructor const_info.cs_cstr),
+ List.map (lift const_info.cs_nargs) const_info.cs_params),
+ const_info.cs_concl_realargs) in
+ Alias (aliasname,cur_alias,(ci,ind)) in
let tomatch = List.rev_append (alias :: currents) tomatch in
@@ -1332,18 +1307,36 @@ and compile_generalization pb i d rest =
{ uj_val = mkLambda_or_LetIn d j.uj_val;
uj_type = mkProd_wo_LetIn d j.uj_type }
-and compile_alias pb (orig,(_,ci,_ as alias),isdeppred) rest =
- let pb =
- { pb with
- env = push_rel alias pb.env;
- tomatch = lift_tomatch_stack 1 rest;
- pred = lift_predicate 1 pb.pred pb.tomatch;
- history = pop_history_pattern pb.history;
- mat = List.map (push_alias_eqn alias) pb.mat } in
- let j = compile pb in
- { uj_val = mkSpecialLetIn orig alias isdeppred j.uj_val;
- uj_type = subst1 (Option.get ci) j.uj_type }
+and compile_alias pb (na,orig,(expanded,expanded_typ)) rest =
+ let f c t =
+ let alias = (na,Some c,t) in
+ let pb =
+ { pb with
+ env = push_rel alias pb.env;
+ tomatch = lift_tomatch_stack 1 rest;
+ pred = lift_predicate 1 pb.pred pb.tomatch;
+ history = pop_history_pattern pb.history;
+ mat = List.map (push_alias_eqn alias) pb.mat } in
+ let j = compile pb in
+ { uj_val =
+ if isRel c or isVar c then subst1 c j.uj_val
+ else mkLetIn (na,c,t,j.uj_val);
+ uj_type = subst1 c j.uj_type } in
+ if isRel orig or isVar orig then
+ (* Try to compile first using non expanded alias *)
+ try f orig (Retyping.get_type_of pb.env !(pb.evdref) orig)
+ with e when precatchable_exception e ->
+ (* Try then to compile using expanded alias *)
+ f expanded expanded_typ
+ else
+ (* Try to compile first using expanded alias *)
+ try f expanded expanded_typ
+ with e when precatchable_exception e ->
+ (* Try then to compile using non expanded alias *)
+ f orig (Retyping.get_type_of pb.env !(pb.evdref) orig)
+
+(* Remember that a non-trivial pattern has been consumed *)
and compile_non_dep_alias pb rest =
let pb =
{ pb with