End CORRECTNESS_EXPR.
(** ** Measure over CminorSel states *)
Local Open Scope nat_scope.
Fixpoint size_stmt (s: stmt) : nat :=
match s with
| Sskip => 0
| Sseq s1 s2 => (size_stmt s1 + size_stmt s2 + 1)
| Sifthenelse c s1 s2 => (size_stmt s1 + size_stmt s2 + 1)
| Sloop s1 => (size_stmt s1 + 1)
| Sblock s1 => (size_stmt s1 + 1)
| Sexit n => 0
| Slabel lbl s1 => (size_stmt s1 + 1)
| _ => 1
end.
Fixpoint size_cont (k: cont) : nat :=
match k with
| Kseq s k1 => (size_stmt s + size_cont k1 + 1)
| Kblock k1 => (size_cont k1 + 1)
| _ => 0%nat
end.
Definition measure_state (S: CminorSel.state) :=
match S with
| CminorSel.State _ s k _ _ _ => (size_stmt s + size_cont k, size_stmt s)
| _                           => (0, 0)
end.
Definition lt_state (S1 S2: CminorSel.state) :=
lex_ord lt lt (measure_state S1) (measure_state S2).

(* Specifications: *)
Lemma lt_state_intro:
forall f1 s1 k1 sp1 e1 m1 f2 s2 k2 sp2 e2 m2,
size_stmt s1 + size_cont k1 < size_stmt s2 + size_cont k2
\/ (size_stmt s1 + size_cont k1 = size_stmt s2 + size_cont k2
/\ size_stmt s1 < size_stmt s2) ->
lt_state (CminorSel.State f1 s1 k1 sp1 e1 m1)
(CminorSel.State f2 s2 k2 sp2 e2 m2).