Module R.
Inductive t : Type := Nil | Cons (lo hi: Z) (tl: t).
Fixpoint In (x: Z) (s: t) :=
match s with
| Nil => False
| Cons l h s' => l <= x < h \/ In x s'
end.
Inductive ok: t -> Prop :=
| ok_nil: ok Nil
| ok_cons: forall l h s
(BOUNDS: l < h)
(BELOW: forall x, In x s -> h < x)
(OK: ok s),
ok (Cons l h s).
Fixpoint mem (x: Z) (s: t) : bool :=
match s with
| Nil => false
| Cons l h s' => if zlt x h then zle l x else mem x s'
end.
Fixpoint contains (L H: Z) (s: t) : bool :=
match s with
| Nil => false
| Cons l h s' => (zle H h && zle l L) || contains L H s'
end.
Fixpoint add (L H: Z) (s: t) {struct s} : t :=
match s with
| Nil => Cons L H Nil
| Cons l h s' =>
if zlt h L then Cons l h (add L H s')
else if zlt H l then Cons L H s
else add (Z.min l L) (Z.max h H) s'
end.
Fixpoint remove (L H: Z) (s: t) {struct s} : t :=
match s with
| Nil => Nil
| Cons l h s' =>
if zlt h L then Cons l h (remove L H s')
else if zlt H l then s
else if zlt l L then
if zlt H h then Cons l L (Cons H h s') else Cons l L (remove L H s')
else
if zlt H h then Cons H h s' else remove L H s'
end.
Fixpoint inter (s1 s2: t) {struct s1} : t :=
let fix intr (s2: t) : t :=
match s1, s2 with
| Nil, _ => Nil
| _, Nil => Nil
| Cons l1 h1 s1', Cons l2 h2 s2' =>
if zle h1 l2 then inter s1' s2
else if zle h2 l1 then intr s2'
else if zle l1 l2 then
if zle h2 h1 then Cons l2 h2 (intr s2') else Cons l2 h1 (inter s1' s2)
else
if zle h1 h2 then Cons l1 h1 (inter s1' s2) else Cons l1 h2 (intr s2')
end
in intr s2.
Fixpoint union (s1 s2: t) : t :=
match s1, s2 with
| Nil, _ => s2
| _, Nil => s1
| Cons l1 h1 s1', Cons l2 h2 s2' => add l1 h1 (add l2 h2 (union s1' s2'))
end.

Lemma In_ok_union:
forall s1, ok s1 -> forall s2, ok s2 ->
ok (union s1 s2) /\ (forall x, In x s1 \/ In x s2 <-> In x (union s1 s2)).