Inductive lex_lt: string -> string -> Prop :=
| lex_lt_lt : forall (c1 c2 : ascii) (s1 s2 : string),
nat_of_ascii c1 < nat_of_ascii c2 ->
lex_lt (String c1 s1) (String c2 s2)
| lex_lt_eq : forall (c : ascii) (s1 s2 : string),
lex_lt s1 s2 ->
lex_lt (String c s1) (String c s2)
| lex_lt_empty : forall (c : ascii) (s : string),
lex_lt EmptyString (String c s).
Inductive lex_order : string -> string -> Prop :=
| lex_order_empty :
lex_order EmptyString EmptyString
| lex_order_char_lt :
forall (c1 c2: ascii) (s1 s2: string),
nat_of_ascii c1 < nat_of_ascii c2 ->
lex_order (String c1 s1) (String c2 s2)
| lex_order_char_eq :
forall (c: ascii) (s1 s2: string),
lex_order s1 s2 ->
lex_order (String c s1) (String c s2)
| lex_order_empty_string :
forall s, lex_order EmptyString s.
Definition lex_le (s1 s2 : string) : Prop := lex_lt s1 s2 \/ s1 = s2.
intros s1 s2 H_le.
case H_le; intro H_le'.
- induction H_le'.
* apply lex_order_char_lt.
assumption.
* apply lex_order_char_eq.
apply IHH_le'.
left.
assumption.
* apply lex_order_empty_string.
- rewrite <- H_le'.
apply lex_order_refl.
Qed.

Theorem lex_lt_trans : forall s0 s1 s2,
lex_lt s0 s1 -> lex_lt s1 s2 -> lex_lt s0 s2.