Module StringOT <: OrderedType.
Definition t := string.
Definition eq       := @Logic.eq       string.
Definition eq_refl  := @Logic.eq_refl  string.
Definition eq_sym   := @Logic.eq_sym   string.
Definition eq_trans := @Logic.eq_trans string.
Definition eq_dec   := string_dec.
Inductive SOrdering := SLT | SEQ | SGT.
Fixpoint strcmp (s1 s2 : string) : SOrdering :=
match s1, s2 with
| EmptyString,    EmptyString    => SEQ
| EmptyString,    String _ _     => SLT
| String _   _,   EmptyString    => SGT
| String ch1 s1', String ch2 s2' =>
match AsciiOT.compare ch1 ch2 with
| LT _ => SLT
| EQ _ => strcmp s1' s2'
| GT _ => SGT
end
end.
Definition lt (s1 s2 : string) := strcmp s1 s2 = SLT.
Local Ltac do_ascii_lt_trans :=
match goal with
| [  _ : AsciiOT.lt ?c1 ?c2
,  _ : AsciiOT.lt ?c2 ?c3
|- _ ]
=> assert (AsciiOT.lt c1 c3) by (eapply AsciiOT.lt_trans; eauto)
end.
Local Ltac not_ascii_lt_refl :=
match goal with
| [ _ : AsciiOT.lt ?c ?c |- _ ]
=> assert (c <> c) by (apply AsciiOT.lt_not_eq; assumption);
congruence
end.

(* Specifications: *)
Theorem lt_trans : forall s1 s2 s3 : string, lt s1 s2 -> lt s2 s3 -> lt s1 s3.
Theorem lt_not_eq : forall s1 s2 : string, lt s1 s2 -> ~ eq s1 s2.
Theorem compare : forall s1 s2 : t, Compare lt eq s1 s2.
End StringOT.