(* cbn is able to refold mutual recursive calls *)
Fixpoint foo (n : nat) := match n with
| 0 => true
| S n => g n end with g (n : nat) : bool := match n with
| 0 => true
| S n => foo n end. Goalforall n, foo (S n) = g n. intros. cbn. matchgoalwith
|- g _ = g _ => reflexivity end. Qed.
(* simpl nomatch *)
Definition thing n := match n with 0 => True | S n => False end.
Section S. Variable p:nat. Fixpoint f n := match n with 0 => p | S n => f n + g n end with g n := match n with 0 => p | S n => f n + g n end. End S.
Goalforall n, f n (S n) = g 0 (S n). intros. cbn. matchgoalwith [ |- f n n + g n n = f 0 n + g 0 n ] => idtacend. Abort.
CoInductive stream {A:Type} : Type :=
| scons: A->stream->stream. Definition stream_unfold {A} (s: @ stream A) := match s with
| scons a s' => (a, scons a s') end.
Section C. Variable (x:nat).
CoFixpoint mut_stream1 (n:nat) := scons n (mut_stream2 (n+x)) with mut_stream2 (n:nat) := scons n (mut_stream1 (n+x)). End C.
Goal (forall x n, stream_unfold (mut_stream1 x n) = stream_unfold (mut_stream2 x n)). intros. cbn. matchgoalwith [ |- (n, scons n (mut_stream2 x (n + x))) = (n, scons n (mut_stream1 x (n + x))) ] => idtacend. Abort.