Section Principle_of_Double_Recursion.
Variable    P               : nat -> nat -> Set.
Hypothesis  base_case1      : forall x:nat, P 0 x.
Hypothesis  base_case2      : forall x:nat, P (S x) 0.
Hypothesis  inductive_step   : forall n m:nat, P n m -> P (S n) (S m).
Fixpoint nat_double_rec (n m:nat){struct n} : P n m :=
match n, m return P n m with
|   0 ,     x    =>  base_case1 x
|  (S x),    0   => base_case2 x
|  (S x), (S y)  => inductive_step x y (nat_double_rec x y)
end.
End Principle_of_Double_Recursion.
Definition min : nat -> nat -> nat  :=
nat_double_rec (fun (x y:nat) => nat)
(fun (x:nat) => 0)
(fun (y:nat) => 0)
(fun (x y r:nat) => S r).
Eval compute in (min 5 8).
Eval compute in (min 8 5).

Lemma not_circular : forall n:nat, n <> S n.