Section AdAlloc.
Variable A : Set.
(** Allocator: returns an address not in the domain of [m]. This allocator is optimal in that it returns the lowest possible address, in the usual ordering on integers. It is not the most efficient, however. *)
Fixpoint ad_alloc_opt (m:Map A) : ad :=
match m with
| M0 => N0
| M1 a _ => if N.eqb a N0 then Npos 1 else N0
| M2 m1 m2 =>
N.min (N.double (ad_alloc_opt m1))
(Ndouble_plus_one (ad_alloc_opt m2))
end.

Lemma ad_alloc_opt_allocates_1 :
forall m:Map A, MapGet A m (ad_alloc_opt m) = None.