aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--pretyping/evarconv.ml26
-rw-r--r--test-suite/success/telescope_canonical.v70
2 files changed, 84 insertions, 12 deletions
diff --git a/pretyping/evarconv.ml b/pretyping/evarconv.ml
index bfc2a18db..dc7d10b47 100644
--- a/pretyping/evarconv.ml
+++ b/pretyping/evarconv.ml
@@ -196,7 +196,7 @@ let rec evar_conv_x ts env evd pbty term1 term2 =
evar_eqappr_x ts env evd pbty
(decompose_app term1) (decompose_app term2)
-and evar_eqappr_x ?(rhs_is_stuck_proj = false)
+and evar_eqappr_x ?(rhs_is_already_stuck = false)
ts env evd pbty (term1,l1 as appr1) (term2,l2 as appr2) =
(* Evar must be undefined since we have flushed evars *)
match (flex_kind_of_term term1 l1, flex_kind_of_term term2 l2) with
@@ -325,13 +325,25 @@ and evar_eqappr_x ?(rhs_is_stuck_proj = false)
(* heuristic: unfold second argument first, exception made
if the first argument is a beta-redex (expand a constant
only if necessary) or the second argument is potentially
- usable as a canonical projection *)
- let rhs_is_stuck_proj =
- rhs_is_stuck_proj || is_open_canonical_projection env i appr2 in
- if isLambda flex1 || rhs_is_stuck_proj then
+ usable as a canonical projection or canonical value *)
+ let rec is_unnamed (hd, args) = match kind_of_term hd with
+ | (Var _|Construct _|Ind _|Const _|Prod _|Sort _) -> false
+ | (Case _|Fix _|CoFix _|Meta _|Rel _)-> true
+ | Evar _ -> false (* immediate solution without Canon Struct *)
+ | Lambda _ -> assert(args = []); true
+ | LetIn (_,b,_,c) ->
+ is_unnamed (evar_apprec ts env i args (subst1 b c))
+ | App _| Cast _ -> assert false in
+ let rhs_is_stuck_and_unnamed () =
+ match eval_flexible_term ts env flex2 with
+ | None -> false
+ | Some v2 -> is_unnamed (evar_apprec ts env i l2 v2) in
+ let rhs_is_already_stuck =
+ rhs_is_already_stuck || rhs_is_stuck_and_unnamed () in
+ if isLambda flex1 || rhs_is_already_stuck then
match eval_flexible_term ts env flex1 with
| Some v1 ->
- evar_eqappr_x ~rhs_is_stuck_proj
+ evar_eqappr_x ~rhs_is_already_stuck
ts env i pbty (evar_apprec ts env i l1 v1) appr2
| None ->
match eval_flexible_term ts env flex2 with
@@ -545,7 +557,7 @@ and conv_record trs env evd (c,bs,(params,params1),(us,us2),(ts,ts1),c1,(n,t2))
(fun i -> evar_conv_x trs env i CONV c1 (applist (c,(List.rev ks))));
(fun i -> ise_list2 i (fun i -> evar_conv_x trs env i CONV) ts ts1)]
-(* getting rid of the optional argument rhs_is_stuck_proj *)
+(* getting rid of the optional argument rhs_is_already_stuck *)
let evar_eqappr_x ts env evd pbty appr1 appr2 =
evar_eqappr_x ts env evd pbty appr1 appr2
diff --git a/test-suite/success/telescope_canonical.v b/test-suite/success/telescope_canonical.v
index 8a607c936..73df5ca99 100644
--- a/test-suite/success/telescope_canonical.v
+++ b/test-suite/success/telescope_canonical.v
@@ -1,12 +1,72 @@
Structure Inner := mkI { is :> Type }.
Structure Outer := mkO { os :> Inner }.
-
Canonical Structure natInner := mkI nat.
Canonical Structure natOuter := mkO natInner.
-
Definition hidden_nat := nat.
-
Axiom P : forall S : Outer, is (os S) -> Prop.
-
-Lemma foo (n : hidden_nat) : P _ n.
+Lemma test1 (n : hidden_nat) : P _ n.
Admitted.
+
+Structure Pnat := mkP { getp : nat }.
+Definition my_getp := getp.
+Axiom W : nat -> Prop.
+
+(* Fix *)
+Canonical Structure add1Pnat n := mkP (plus n 1).
+Definition test_fix n := (refl_equal _ : W (my_getp _) = W (n + 1)).
+
+(* Case *)
+Definition pred n := match n with 0 => 0 | S m => m end.
+Canonical Structure predSS n := mkP (pred n).
+Definition test_case x := (refl_equal _ : W (my_getp _) = W (pred x)).
+Fail Definition test_case' := (refl_equal _ : W (my_getp _) = W (pred 0)).
+
+Canonical Structure letPnat' := mkP 0.
+Definition letin := (let n := 0 in n).
+Definition test4 := (refl_equal _ : W (getp _) = W letin).
+Definition test41 := (refl_equal _ : W (my_getp _) = W letin).
+Definition letin2 (x : nat) := (let n := x in n).
+Canonical Structure letPnat'' x := mkP (letin2 x).
+Definition test42 x := (refl_equal _ : W (my_getp _) = W (letin2 x)).
+Fail Definition test42' x := (refl_equal _ : W (my_getp _) = W x).
+
+Structure Morph := mkM { f :> nat -> nat }.
+Definition my_f := f.
+Axiom Q : (nat -> nat) -> Prop.
+
+(* Lambda *)
+Canonical Structure addMorh x := mkM (plus x).
+Definition test_lam x := (refl_equal _ : Q (my_f _) = Q (plus x)).
+Definition test_lam' := (refl_equal _ : Q (my_f _) = Q (plus 0)).
+
+(* Simple tests to justify Sort and Prod as "named".
+ They are already normal, so they cannot loose their names,
+ but still... *)
+Structure Sot := mkS { T : Type }.
+Axiom R : Type -> Prop.
+Canonical Structure tsot := mkS (Type).
+Definition test_sort := (refl_equal _ : R (T _) = R Type).
+Canonical Structure tsot2 := mkS (nat -> nat).
+Definition test_prod := (refl_equal _ : R (T _) = R (nat -> nat)).
+
+(* Var *)
+Section Foo.
+Variable v : nat.
+Definition my_v := v.
+Canonical Structure vP := mkP my_v.
+Definition test_var := (refl_equal _ : W (getp _) = W my_v).
+Canonical Structure vP' := mkP v.
+Definition test_var' := (refl_equal _ : W (my_getp _) = W my_v).
+End Foo.
+
+(* Rel *)
+Definition test_rel v := (refl_equal _ : W (my_getp _) = W (my_v v)).
+Goal True.
+pose (x := test_rel 2).
+match goal with x := _ : W (my_getp (vP 2)) = _ |- _ => idtac end.
+apply I.
+Qed.
+
+
+
+