Section Between.
Variables P Q : nat -> Prop.
(** The [between] type expresses the concept [forall i: nat, k <= i < l -> P i.]. *)
Inductive between k : nat -> Prop :=
| bet_emp : between k k
| bet_S : forall l, between k l -> P l -> between k (S l).
Hint Constructors between: arith.
Hint Resolve bet_eq: arith.
Hint Immediate between_le: arith.
Hint Resolve between_Sk_l: arith.
(** The [exists_between] type expresses the concept [exists i: nat, k <= i < l /\ Q i]. *)
Inductive exists_between k : nat -> Prop :=
| exists_S : forall l, exists_between k l -> exists_between k (S l)
| exists_le : forall l, k <= l -> Q l -> exists_between k (S l).
Hint Constructors exists_between: arith.
Proof exists_le_S.
Hint Immediate exists_le_S exists_lt: arith.
Hint Immediate exists_S_le: arith.
Definition in_int p q r := p <= r /\ r < q.
Hint Resolve in_int_intro: arith.
Hint Resolve in_int_S: arith.
Hint Immediate in_int_Sp_q: arith.

Lemma between_or_exists :
forall k l,
k <= l ->
(forall n:nat, in_int k l n -> P n \/ Q n) ->
between k l \/ exists_between k l.