(** *Even length*)
Inductive even : nat -> Prop :=
| EvenO : even 0
| EvenS : forall n, even n -> even (S (S n)).
Function length_of_even (ls:list nat) : option nat :=
match ls with
| nil => Some 0
| cons x1 (cons x2 ls') =>
match length_of_even ls' with
| Some n' => Some ( 2 + n')
| _ => None
end
| cons x nil => None
end.
(** * Perm_of_sh *)
Print perm_of_sh.
(** * Merge *)
Definition double_measure (lss: list nat * list nat):= (length (fst lss) + length (snd lss)).
Function merge (lss: list nat * list nat)
{measure double_measure}:=
match lss with
| (ls1, ls2) =>
match ls1 with
nil => ls2
| cons n ls1' =>
match ls2 with
nil => ls1
| cons m ls2' =>
if n <? m then
cons n (merge (ls1', ls2))
else
cons m (merge (ls1, ls2'))
end
end
end.
- intros; simpl.
unfold double_measure; simpl.
omega.
- intros; simpl.
unfold double_measure; simpl.
omega.
Defined.
(** *Mutual recursion*)
Inductive even_list : Set :=
| ENil : even_list
| ECons : nat -> odd_list -> even_list
with odd_list : Set :=
| OCons : nat -> even_list -> odd_list.
Function elength (el : even_list) : nat :=
match el with
| ENil => O
| ECons _ ol => S (olength ol)
end
with olength (ol : odd_list) : nat :=
match ol with
| OCons _ el => S (elength el)
end.
Function eapp (el1 el2 : even_list) : even_list :=
match el1 with
| ENil => el2
| ECons n ol => ECons n (oapp ol el2)
end
with oapp (ol : odd_list) (el : even_list) : odd_list :=
match ol with
| OCons n el' => OCons n (eapp el' el)
end.
Functional Scheme eapp_mut := Induction for eapp Sort Prop
with oapp_mut := Induction for oapp Sort Prop.

Theorem elength_eapp : forall el1 el2 : even_list,
elength (eapp el1 el2) = plus (elength el1) (elength el2).