(** * Checking properties on all elements of an interval *)
Section FORALL.
Variables P Q: Z -> Prop.
Variable f: forall (x: Z), {P x} + {Q x}.
Variable lo: Z.
Program Fixpoint forall_rec (hi: Z) {wf (Zwf lo) hi}:
{forall x, lo <= x < hi -> P x}
+ {exists x, lo <= x < hi /\ Q x} :=
if zlt lo hi then
match f (hi - 1) with
| left _ =>
match forall_rec (hi - 1) with
| left _ => left _ _
| right _ => right _ _
end
| right _ => right _ _
end
else
left _ _
.
Next Obligation.
red. omega.
Qed.
Next Obligation.
assert (x = hi - 1 \/ x < hi - 1) by omega.
destruct H2. congruence. auto.
Qed.
Next Obligation.
exists wildcard'; split; auto. omega.
Qed.
Next Obligation.
exists (hi - 1); split; auto. omega.
Qed.
Next Obligation.
omegaContradiction.
Defined.
End FORALL.
Definition forall_dec
(P Q: Z -> Prop) (f: forall (x: Z), {P x} + {Q x}) (i: interv) :
{forall x, In x i -> P x} + {exists x, In x i /\ Q x} :=
forall_rec P Q f (fst i) (snd i).
(** * Folding a function over all elements of an interval *)
Section FOLD.
Variable A: Type.
Variable f: Z -> A -> A.
Variable lo: Z.
Variable a: A.
Function fold_rec (hi: Z) {wf (Zwf lo) hi} : A :=
if zlt lo hi then f (hi - 1) (fold_rec (hi - 1)) else a.

Lemma fold_rec_elements:
forall hi, fold_rec hi = List.fold_right f a (elements_rec lo hi).