Notation "x ≤ y ≤ z" := (x ≤ y ∧ y ≤ z) (at level 70, y at next level).
Notation "x < y ≤ z" := (x < y ∧ y ≤ z) (at level 70, y at next level).
Notation "x ≤ y < z" := (x ≤ y ∧ y < z) (at level 70, y at next level).
Section Monad.
Definition state := nat.
Definition monad (A:Type) := state → state * A.
Definition Meval {A:Type} (m:monad A) st := m st.
Definition Meq {A:Type} (m:monad A) := ∀ st, st = fst (Meval m st).
Definition Mlt {A:Type} (m:monad A) := ∀ st, st < fst (Meval m st).
Definition Mle {A:Type} (m:monad A) := ∀ st, st ≤ fst (Meval m st).

(* Specifications: *)
Lemma Mlt_Mle_incl {A:Type} (m:monad A): Mlt m → Mle m.
Lemma lt_le_Mbind_lt {A B:Type} (ma:monad A) (f:A → monad B):
Mlt ma → (∀ a, Mle (f a)) → Mlt (ma >>= f).
Lemma eq_eq_Mbind_eq {A B:Type} (ma:monad A) (f:A → monad B):
Meq ma → (∀ a, Meq (f a)) → Meq (ma >>= f).
Lemma lt_lt_Mbind_lt {A B:Type} (ma:monad A) (f:A → monad B):
Mlt ma → (∀ a, Mlt (f a)) → Mlt (ma >>= f).
Lemma mono_mono_Mbind_mono {A B:Type} (ma:monad A) (f:A → monad B):
Mmono ma → Mmono_one f → Mmono (ma >>= f).
Lemma Mbind_ind {A:Type} (ma:monad A) (f:A→monad A) (P:A → Prop):
(∀ st, P (snd (ma st))) → (∀ (a:A), P a → ∀ st, P (snd ((f a) st))) →
∀ st, P (snd ((ma>>=f) st)).