Fixpoint bubble_sort0 (n : nat) : list nat -> list nat :=
  fun x : list nat =>
  match n with
  | O => x
  | S n0 => bubble_sort0 n0 (bubble x)
  end.Definition bubble_sort (x : list nat) : list nat :=
  bubble_sort0 (length nat x) x.(* == Tri fusion *)

Fixpoint fusion (x : list nat) : list nat -> list nat :=
  fun y : list nat =>
  match x with
  | Nil => y
  | Cons n l0 =>
      (fix fusion_r (y : list nat) : list nat :=
         match y with
         | Nil => x
         | Cons n0 l2 =>
             si (list nat) (inf_egal n n0)
               (Cons nat n (fusion l0 (Cons nat n0 l2)))
               (Cons nat n0 (fusion_r l2))
         end) y
  end.

(* Specifications: *)
Lemma fusion_eq1 : forall ms : list nat, fusion (Nil nat) ms = ms.
Lemma fusion_eq2 : forall (n : nat) (ns : list nat), fusion (Cons nat n ns) (Nil nat) = Cons nat n ns.
Lemma fusion_eq3 : forall (n : nat) (ns : list nat) (m : nat) (ms : list nat), fusion (Cons nat n ns) (Cons nat m ms) = si (list nat) (inf_egal n m) (Cons nat n (fusion ns (Cons nat m ms))) (Cons nat m (fusion (Cons nat n ns) ms)).