Library Apps.StringKey


Require Import LabelMap.
Require Import Ascii NArith String OrderedType FSetAVL.

Module StringKey.
  Definition t := string.

  Definition eq := @eq t.
  Definition lt (s1 s2 : t) := string_lt s1 s2 = true.

  Theorem eq_refl : x : t, eq x x.
    congruence.
  Qed.

  Theorem eq_sym : x y : t, eq x yeq y x.
    congruence.
  Qed.

  Theorem eq_trans : x y z : t, eq x yeq y zeq x z.
    congruence.
  Qed.

  Section hide_hints.
    Hint Resolve string_lt_trans.
    Hint Rewrite string_lt_irrel : LabelMap.
    Hint Immediate string_tail_neq.
    Hint Resolve string_lt_sym.
    Hint Rewrite string_lt_irrel : LabelMap.

    Theorem lt_trans : x y z : t, lt x ylt y zlt x z.
      unfold lt; intuition (congruence || eauto).
    Qed.

    Theorem lt_not_eq : x y : t, lt x y¬ eq x y.
      unfold lt, eq; intuition; subst; autorewrite with LabelMap in *; discriminate.
    Qed.

    Definition compare' (x y : t) : comparison :=
      if string_lt x y
        then Datatypes.Lt
        else if string_dec x y
          then Datatypes.Eq
          else Gt.

    Definition compare (x y : t) : Structures.OrderedType.Compare lt eq x y.
      refine (match compare' x y as c return c = compare' x yStructures.OrderedType.Compare lt eq x y with
                | Datatypes.Ltfun _Structures.OrderedType.LT _
                | Datatypes.Eqfun _Structures.OrderedType.EQ _
                | Gtfun _Structures.OrderedType.GT _
              end (refl_equal _)); abstract (unfold compare', eq, lt in *;
                repeat match goal with
                         | [ H : context[if ?E then _ else _] |- _ ] ⇒ let Heq := fresh "Heq" in case_eq E; (intros ? Heq || intro Heq);
                           rewrite Heq in H; try discriminate
                       end; intuition).
    Defined.

    Definition eq_dec x y : { eq x y } + { ¬ eq x y }.
      refine (if string_dec x y then left _ _ else right _ _);
        abstract (unfold eq in *; destruct x; destruct y; simpl in *; congruence).
    Defined.
  End hide_hints.
End StringKey.

Module String_as_OT := StringKey.

Require Import OrdersAlt.
Module String_as_OT_new := Update_OT String_as_OT.
Require Import Equalities.
Module String_as_UDT := Make_UDT String_as_OT.