(** Checks that all nats before n are P *)

Fixpoint allbefore (P : nat -> Prop) (n : nat) {struct n} : Prop :=
  match n with
  | O => True
  | S x => allbefore P x /\ P x
  end.(** Checks that some nat before n is P *)

Fixpoint exbefore (P : nat -> Prop) (n : nat) {struct n} : Prop :=
  match n with
  | O => False
  | S x => exbefore P x \/ P x
  end.

(* Specifications: *)
Theorem allbefore_ok : forall (P : nat -> Prop) (n : nat), (forall q : nat, q < n -> P q) <-> allbefore P n.
Theorem exbefore_ok : forall (P : nat -> Prop) (n : nat), (exists q : nat, q < n /\ P q) <-> exbefore P n.
Lemma eqdec : forall n m : nat, n = m \/ n <> m.
Lemma ledec : forall n m : nat, n <= m \/ ~ n <= m.
Lemma ltdec : forall n m : nat, n < m \/ ~ n < m.
Lemma gedec : forall n m : nat, n >= m \/ ~ n >= m.
Lemma gtdec : forall n m : nat, n > m \/ ~ n > m.
Lemma zeqdec : forall x y : Z, x = y \/ x <> y.
Lemma notdec : forall P : Prop, P \/ ~ P -> ~ P \/ ~ ~ P.
Lemma anddec : forall P Q : Prop, P \/ ~ P -> Q \/ ~ Q -> P /\ Q \/ ~ (P /\ Q).
Lemma ordec : forall P Q : Prop, P \/ ~ P -> Q \/ ~ Q -> (P \/ Q) \/ ~ (P \/ Q).
Lemma impdec : forall P Q : Prop, P \/ ~ P -> Q \/ ~ Q -> (P -> Q) \/ ~ (P -> Q).
Lemma iffdec : forall P Q : Prop, P \/ ~ P -> Q \/ ~ Q -> (P <-> Q) \/ ~ (P <-> Q).
Theorem alldec : forall (P : nat -> Prop) (N : nat), (forall n : nat, P n \/ ~ P n) -> (forall x : nat, x < N -> P x) \/ ~ (forall x : nat, x < N -> P x).
Theorem exdec : forall (P : nat -> Prop) (N : nat), (forall n : nat, P n \/ ~ P n) -> (exists x : nat, x < N /\ P x) \/ ~ (exists x : nat, x < N /\ P x).
Theorem decDeMorgan : forall (N : nat) (P : nat -> Prop), (forall n : nat, P n \/ ~ P n) -> ((exists x : nat, x < N /\ P x) <-> ~ (forall x : nat, x < N -> ~ P x)).