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).
Definition eq_nat_dec : forall n p:nat , {n=p}+{n <> p}.
Definition minus_decrease : forall x y:nat, Acc lt x ->
x <> 0 ->
y <> 0 ->
Acc lt (x-y).

Lemma vector0_is_vnil : forall (A:Set)(v:Vector.t A 0), v = Vector.nil A.