Fixpoint revsize (n: positive) (lr l: list key) : positive * list key :=
match l with
| nil => (n, lr)
| x::xs => revsize (Psucc n) (x::lr) xs
end.
Function linear_union_aux (st : tree*tree) (nl: positive * list key)
{measure (fun st => size (fst st) + size (snd st)) st} : positive * list key  :=
match rgopher (fst st), rgopher (snd st) with
| EE , EE => nl
| T _ sl j EE as st1 , T _ tl j' EE as st2 =>
match K.compare j j' with
| Lt => linear_union_aux (st1, tl) (Psucc (fst nl), j':: snd nl)
| Gt => linear_union_aux (sl, st2) (Psucc (fst nl), j:: snd nl)
| Eq => linear_union_aux (sl,tl) (Psucc (fst nl), j:: snd nl)
end
| T _ sl j EE, EE => linear_union_aux (sl,EE) (Psucc (fst nl), j:: snd nl)
|  EE, T _ tl j' EE => linear_union_aux (EE,tl) (Psucc (fst nl), j':: snd nl)
| _, _ => nl (* impossible *)
end.

Lemma treeify_f_length:
forall n l, length l >= nat_of_P n ->
length(snd(treeify_f n l))+nat_of_P n = length l.