(**********************************************************************)
(* A few examples showing the current limits of the conversion algorithm *)
(**********************************************************************)
(*** We define (pseudo-)divergence from Ackermann function ***)
Definition ack (n : nat) :=
(fix F (n0 : nat) : nat -> nat :=
match n0 with
| O => S
| S n1 =>
fun m : nat =>
(fix F0 (n2 : nat) : nat :=
match n2 with
| O => F n1 1
| S n3 => F n1 (F0 n3)
end) m
end) n.
Notation OMEGA := (ack 4 4).
Definition f (x:nat) := x.
reflexivity.  (* succeed: identity *)
Qed.          (* succeed: identity *)
reflexivity.  (* fail: conversion wants to convert OMEGA with f OMEGA *)
Abort.        (* but it reduces the right side first! *)
reflexivity.  (* succeed: reduce left side first *)
Qed.          (* succeed: expected concl (the one with f) is on the left *)
assert (f OMEGA = OMEGA) by reflexivity. (* succeed *)
unfold f in H.   (* succeed: no type-checking *)
exact H.         (* succeed: identity *)
Qed.             (* fail: "f" is on the left *)

(* This example would fail whatever the preferred side is *)
Lemma l5 : OMEGA = f OMEGA.