aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Matthieu Sozeau <matthieu.sozeau@inria.fr>2014-09-11 13:28:56 +0200
committerGravatar Matthieu Sozeau <matthieu.sozeau@inria.fr>2014-09-11 13:30:33 +0200
commitedb9ac51f38f2c4dddf652db918e5d5b6ba3b108 (patch)
tree407632a9cde212bdf834baec723dd529ce1496a1
parent12ef55e112a1ccfe00c8880e0ba5958e02ab97e1 (diff)
Fix bug #3594: eta for constructors and functions at the same time which
was failing in this case due to the wrong postponment of an unsolvable ?X = RigidContext[?X] problem.
-rw-r--r--pretyping/evarconv.ml23
-rw-r--r--test-suite/bugs/closed/3594.v51
2 files changed, 72 insertions, 2 deletions
diff --git a/pretyping/evarconv.ml b/pretyping/evarconv.ml
index 99d9364df..190a025ac 100644
--- a/pretyping/evarconv.ml
+++ b/pretyping/evarconv.ml
@@ -97,6 +97,22 @@ let position_problem l2r = function
| CONV -> None
| CUMUL -> Some l2r
+let occur_rigidly ev evd t =
+ let (l, app) = decompose_app_vect t in
+ let rec aux t =
+ match kind_of_term (whd_evar evd t) with
+ | App (f, c) -> if aux f then Array.exists aux c else false
+ | Construct _ | Ind _ | Sort _ | Meta _ | Fix _ | CoFix _ -> true
+ | Proj (p, c) -> not (aux c)
+ | Evar (ev',_) -> if Evar.equal ev ev' then raise Occur else false
+ | Cast (p, _, _) -> aux p
+ | Lambda _ | LetIn _ -> false
+ | Const _ -> false
+ | Prod (_, b, t) -> ignore(aux b || aux t); true
+ | Rel _ | Var _ -> false
+ | Case _ -> false
+ in Array.exists (fun t -> try ignore(aux t); false with Occur -> true) app
+
(* [check_conv_record (t1,l1) (t2,l2)] tries to decompose the problem
(t1 l1) = (t2 l2) into a problem
@@ -428,8 +444,11 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) ts env evd pbty
(fun () ->
ise_try evd
[eta;(* Postpone the use of an heuristic *)
- (fun i -> switch (fun x y -> Success (add_conv_pb (pbty,env,x,y) i))
- (Stack.zip apprF) tR)])
+ (fun i ->
+ if not (occur_rigidly (fst ev) i tR) then
+ switch (fun x y -> Success (add_conv_pb (pbty,env,x,y) i))
+ (Stack.zip apprF) tR
+ else quick_fail i)])
ev lF tR evd
in ise_try evd [f; eta]
in
diff --git a/test-suite/bugs/closed/3594.v b/test-suite/bugs/closed/3594.v
new file mode 100644
index 000000000..d1aae7b44
--- /dev/null
+++ b/test-suite/bugs/closed/3594.v
@@ -0,0 +1,51 @@
+(* File reduced by coq-bug-finder from original input, then from 8752 lines to 735 lines, then from 735 lines to 310 lines, then from 228 lines to 105 lines, then from 98 lines to 41 lines *)
+(* coqc version trunk (September 2014) compiled on Sep 6 2014 6:15:6 with OCaml 4.01.0
+ coqtop version cagnode17:/afs/csail.mit.edu/u/j/jgross/coq-trunk,trunk (3ea6d6888105edd5139ae0a4d8f8ecdb586aff6c) *)
+Notation idmap := (fun x => x).
+Axiom path_forall : forall {A : Type} {P : A -> Type} (f g : forall x : A, P x), (forall x, f x = g x) -> f = g.
+Local Set Primitive Projections.
+Record PreCategory := { object :> Type ; morphism : object -> object -> Type }.
+Bind Scope category_scope with PreCategory.
+Set Implicit Arguments.
+Delimit Scope functor_scope with functor.
+Record Functor (C D : PreCategory) := {}.
+Definition opposite (C : PreCategory) : PreCategory := @Build_PreCategory C (fun s d => morphism C d s).
+Notation "C ^op" := (opposite C) (at level 3, format "C '^op'") : category_scope.
+Definition oppositeF C D (F : Functor C D) : Functor C^op D^op := Build_Functor (C^op) (D^op).
+Local Notation "F ^op" := (oppositeF F) (at level 3, format "F ^op") : functor_scope.
+Axiom oppositeF_involutive : forall C D (F : Functor C D), ((F^op)^op)%functor = F.
+Local Open Scope functor_scope.
+Goal forall C D : PreCategory,
+ (fun c : Functor C^op D^op => (c^op)^op) = idmap.
+ intros.
+ exact (path_forall (fun F : Functor C^op D^op => (F^op)^op) _ (@oppositeF_involutive _ _)).
+ Undo.
+ Unset Printing Notations.
+ Set Debug Unification.
+(* Check (eq_refl : Build_PreCategory (opposite D).(object) *)
+(* (fun s d : (opposite D).(object) => *)
+(* (opposite D).(morphism) d s) = *)
+(* @Build_PreCategory D (fun s d => morphism D d s)). *)
+(* opposite D). *)
+ exact (path_forall (fun F => (F^op)^op) _ (@oppositeF_involutive _ _)).
+Qed.
+ (* Toplevel input, characters 22-101:
+Error:
+In environment
+C : PreCategory
+D : PreCategory
+The term
+ "path_forall
+ (fun F : Functor (opposite C) (opposite D) => oppositeF (oppositeF F))
+ (fun F : Functor (opposite C) (opposite D) => F)
+ (oppositeF_involutive (D:=opposite D))" has type
+ "eq (fun F : Functor (opposite C) (opposite D) => oppositeF (oppositeF F))
+ (fun F : Functor (opposite C) (opposite D) => F)"
+while it is expected to have type
+ "eq (fun c : Functor (opposite C) (opposite D) => oppositeF (oppositeF c))
+ (fun x : Functor (opposite C) (opposite D) => x)"
+(cannot unify "{|
+ object := opposite D;
+ morphism := fun s d : opposite D => morphism (opposite D) d s |}"
+and "opposite D").
+ *) \ No newline at end of file