Built with Alectryon, running Coq+SerAPI v8.10.0+0.7.0. Coq sources are in this panel; goals and messages will appear in the other. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑ Ctrl+↓ to navigate, Ctrl+🖱️ to focus.
(************************************************************************) (* * The Coq Proof Assistant / The Coq Development Team *) (* v * INRIA, CNRS and contributors - Copyright 1999-2018 *) (* <O___,, * (see CREDITS file for the list of authors) *) (* \VV/ **************************************************************) (* // * This file is distributed under the terms of the *) (* * GNU Lesser General Public License Version 2.1 *) (* * (see LICENSE file for the text of the license) *) (************************************************************************) Require Import OrderedType. Require Import ZArith. Require Import PeanoNat. Require Import Ascii String. Require Import Omega. Require Import NArith Ndec. Require Import Compare_dec.
First, a particular case of OrderedType where
the equality is the usual one of Coq.
Module Type UsualOrderedType. Parameter Inline t : Type. Definition eq := @eq t. Parameter Inline lt : t -> t -> Prop. Definition eq_refl := @eq_refl t. Definition eq_sym := @eq_sym t. Definition eq_trans := @eq_trans t. Axiom lt_trans : forall x y z : t, lt x y -> lt y z -> lt x z. Axiom lt_not_eq : forall x y : t, lt x y -> ~ eq x y. Parameter compare : forall x y : t, Compare lt eq x y. Parameter eq_dec : forall x y : t, { eq x y } + { ~ eq x y }. End UsualOrderedType.
a UsualOrderedType is in particular an OrderedType.
Module UOT_to_OT (U:UsualOrderedType) <: OrderedType := U.
nat is an ordered type with respect to the usual order on natural numbers.
Module Nat_as_OT <: UsualOrderedType. Definition t := nat. Definition eq := @eq nat. Definition eq_refl := @eq_refl t. Definition eq_sym := @eq_sym t. Definition eq_trans := @eq_trans t. Definition lt := lt.forall x y z : t, lt x y -> lt y z -> lt x zunfold lt; intros; apply lt_trans with y; auto. Qed.forall x y z : t, lt x y -> lt y z -> lt x zforall x y : t, lt x y -> ~ eq x yunfold lt, eq; intros; omega. Qed.forall x y : t, lt x y -> ~ eq x yx, y:natCompare lt eq x yx, y:natCompare lt eq x yx, y:natH:(x ?= y) = EqCompare lt eq x yx, y:natH:(x ?= y) = LtCompare lt eq x yx, y:natH:(x ?= y) = GtCompare lt eq x yx, y:natH:(x ?= y) = EqCompare lt eq x ynow apply nat_compare_eq.x, y:natH:(x ?= y) = Eqeq x yx, y:natH:(x ?= y) = LtCompare lt eq x ynow apply nat_compare_Lt_lt.x, y:natH:(x ?= y) = Ltlt x yx, y:natH:(x ?= y) = GtCompare lt eq x ynow apply nat_compare_Gt_gt. Defined. Definition eq_dec := eq_nat_dec. End Nat_as_OT.x, y:natH:(x ?= y) = Gtlt y x
Z is an ordered type with respect to the usual order on integers.
Local Open Scope Z_scope. Module Z_as_OT <: UsualOrderedType. Definition t := Z. Definition eq := @eq Z. Definition eq_refl := @eq_refl t. Definition eq_sym := @eq_sym t. Definition eq_trans := @eq_trans t. Definition lt (x y:Z) := (x<y).forall x y z : Z, x < y -> y < z -> x < zintros; omega. Qed.forall x y z : Z, x < y -> y < z -> x < zforall x y : Z, x < y -> x <> yintros; omega. Qed.forall x y : Z, x < y -> x <> yx, y:ZCompare lt eq x yx, y:ZCompare lt eq x yx, y:ZH:(x ?= y) = EqCompare lt eq x yx, y:ZH:(x ?= y) = LtCompare lt eq x yx, y:ZH:(x ?= y) = GtCompare lt eq x yx, y:ZH:(x ?= y) = EqCompare lt eq x ynow apply Z.compare_eq.x, y:ZH:(x ?= y) = Eqeq x yx, y:ZH:(x ?= y) = LtCompare lt eq x yassumption.x, y:ZH:(x ?= y) = Ltlt x yx, y:ZH:(x ?= y) = GtCompare lt eq x ynow apply Z.gt_lt. Defined. Definition eq_dec := Z.eq_dec. End Z_as_OT.x, y:ZH:(x ?= y) = Gtlt y x
positive is an ordered type with respect to the usual order on natural numbers.
Local Open Scope positive_scope. Module Positive_as_OT <: UsualOrderedType. Definition t:=positive. Definition eq:=@eq positive. Definition eq_refl := @eq_refl t. Definition eq_sym := @eq_sym t. Definition eq_trans := @eq_trans t. Definition lt := Pos.lt. Definition lt_trans := Pos.lt_trans.forall x y : t, lt x y -> ~ eq x yforall x y : t, lt x y -> ~ eq x yx, y:tH:lt x y~ eq x yx, y:tH:eq x y~ lt x yapply Pos.lt_irrefl. Qed.x, y:tH:eq x y~ lt y yx, y:positiveCompare lt eq x yx, y:positiveCompare lt eq x yx, y:positiveH:(x ?= y) = EqCompare lt eq x yx, y:positiveH:(x ?= y) = LtCompare lt eq x yx, y:positiveH:(x ?= y) = GtCompare lt eq x yx, y:positiveH:(x ?= y) = EqCompare lt eq x ynow apply Pos.compare_eq.x, y:positiveH:(x ?= y) = Eqeq x yapply LT; assumption.x, y:positiveH:(x ?= y) = LtCompare lt eq x yx, y:positiveH:(x ?= y) = GtCompare lt eq x ynow apply Pos.gt_lt. Defined. Definition eq_dec := Pos.eq_dec. End Positive_as_OT.x, y:positiveH:(x ?= y) = Gtlt y x
N is an ordered type with respect to the usual order on natural numbers.
Module N_as_OT <: UsualOrderedType. Definition t:=N. Definition eq:=@eq N. Definition eq_refl := @eq_refl t. Definition eq_sym := @eq_sym t. Definition eq_trans := @eq_trans t. Definition lt := N.lt. Definition lt_trans := N.lt_trans. Definition lt_not_eq := N.lt_neq.x, y:NCompare lt eq x yx, y:NCompare lt eq x yx, y:NH:(x ?= y)%N = EqCompare lt eq x yx, y:NH:(x ?= y)%N = LtCompare lt eq x yx, y:NH:(x ?= y)%N = GtCompare lt eq x yx, y:NH:(x ?= y)%N = EqCompare lt eq x ynow apply N.compare_eq.x, y:NH:(x ?= y)%N = Eqeq x yx, y:NH:(x ?= y)%N = LtCompare lt eq x yassumption.x, y:NH:(x ?= y)%N = Ltlt x yx, y:NH:(x ?= y)%N = GtCompare lt eq x ynow apply N.gt_lt. Defined. Definition eq_dec := N.eq_dec. End N_as_OT.x, y:NH:(x ?= y)%N = Gtlt y x
From two ordered types, we can build a new OrderedType
over their cartesian product, using the lexicographic order.
Module PairOrderedType(O1 O2:OrderedType) <: OrderedType. Module MO1:=OrderedTypeFacts(O1). Module MO2:=OrderedTypeFacts(O2). Definition t := prod O1.t O2.t. Definition eq x y := O1.eq (fst x) (fst y) /\ O2.eq (snd x) (snd y). Definition lt x y := O1.lt (fst x) (fst y) \/ (O1.eq (fst x) (fst y) /\ O2.lt (snd x) (snd y)).forall x : t, eq x xintros (x1,x2); red; simpl; auto. Qed.forall x : t, eq x xforall x y : t, eq x y -> eq y xintros (x1,x2) (y1,y2); unfold eq; simpl; intuition. Qed.forall x y : t, eq x y -> eq y xforall x y z : t, eq x y -> eq y z -> eq x zintros (x1,x2) (y1,y2) (z1,z2); unfold eq; simpl; intuition eauto. Qed.forall x y z : t, eq x y -> eq y z -> eq x zforall x y z : t, lt x y -> lt y z -> lt x zforall x y z : t, lt x y -> lt y z -> lt x zx1:O1.tx2:O2.ty1:O1.ty2:O2.tz1:O1.tz2:O2.tH1:O1.lt x1 y1H:O1.lt y1 z1O1.lt x1 z1 \/ O1.eq x1 z1 /\ O2.lt x2 z2x1:O1.tx2:O2.ty1:O1.ty2:O2.tz1:O1.tz2:O2.tH1:O1.lt x1 y1H0:O1.eq y1 z1H2:O2.lt y2 z2O1.lt x1 z1 \/ O1.eq x1 z1 /\ O2.lt x2 z2x1:O1.tx2:O2.ty1:O1.ty2:O2.tz1:O1.tz2:O2.tH:O1.eq x1 y1H2:O2.lt x2 y2H1:O1.lt y1 z1O1.lt x1 z1 \/ O1.eq x1 z1 /\ O2.lt x2 z2x1:O1.tx2:O2.ty1:O1.ty2:O2.tz1:O1.tz2:O2.tH:O1.eq x1 y1H2:O2.lt x2 y2H0:O1.eq y1 z1H3:O2.lt y2 z2O1.lt x1 z1 \/ O1.eq x1 z1 /\ O2.lt x2 z2x1:O1.tx2:O2.ty1:O1.ty2:O2.tz1:O1.tz2:O2.tH1:O1.lt x1 y1H0:O1.eq y1 z1H2:O2.lt y2 z2O1.lt x1 z1 \/ O1.eq x1 z1 /\ O2.lt x2 z2x1:O1.tx2:O2.ty1:O1.ty2:O2.tz1:O1.tz2:O2.tH:O1.eq x1 y1H2:O2.lt x2 y2H1:O1.lt y1 z1O1.lt x1 z1 \/ O1.eq x1 z1 /\ O2.lt x2 z2x1:O1.tx2:O2.ty1:O1.ty2:O2.tz1:O1.tz2:O2.tH:O1.eq x1 y1H2:O2.lt x2 y2H0:O1.eq y1 z1H3:O2.lt y2 z2O1.lt x1 z1 \/ O1.eq x1 z1 /\ O2.lt x2 z2x1:O1.tx2:O2.ty1:O1.ty2:O2.tz1:O1.tz2:O2.tH:O1.eq x1 y1H2:O2.lt x2 y2H1:O1.lt y1 z1O1.lt x1 z1 \/ O1.eq x1 z1 /\ O2.lt x2 z2x1:O1.tx2:O2.ty1:O1.ty2:O2.tz1:O1.tz2:O2.tH:O1.eq x1 y1H2:O2.lt x2 y2H0:O1.eq y1 z1H3:O2.lt y2 z2O1.lt x1 z1 \/ O1.eq x1 z1 /\ O2.lt x2 z2right; split; eauto. Qed.x1:O1.tx2:O2.ty1:O1.ty2:O2.tz1:O1.tz2:O2.tH:O1.eq x1 y1H2:O2.lt x2 y2H0:O1.eq y1 z1H3:O2.lt y2 z2O1.lt x1 z1 \/ O1.eq x1 z1 /\ O2.lt x2 z2forall x y : t, lt x y -> ~ eq x yforall x y : t, lt x y -> ~ eq x yx1:O1.tx2:O2.ty1:O1.ty2:O2.tH1:O1.eq x1 y1H2:O2.eq x2 y2H0:O1.lt x1 y1Falsex1:O1.tx2:O2.ty1:O1.ty2:O2.tH1:O1.eq x1 y1H2:O2.eq x2 y2H:O1.eq x1 y1H3:O2.lt x2 y2Falseapply (O2.lt_not_eq H3 H2). Qed.x1:O1.tx2:O2.ty1:O1.ty2:O2.tH1:O1.eq x1 y1H2:O2.eq x2 y2H:O1.eq x1 y1H3:O2.lt x2 y2Falseforall x y : t, Compare lt eq x yx1:O1.tx2:O2.ty1:O1.ty2:O2.tCompare lt eq (x1, x2) (y1, y2)x1:O1.tx2:O2.ty1:O1.ty2:O2.tl:O1.lt x1 y1Compare lt eq (x1, x2) (y1, y2)x1:O1.tx2:O2.ty1:O1.ty2:O2.te:O1.eq x1 y1Compare lt eq (x1, x2) (y1, y2)x1:O1.tx2:O2.ty1:O1.ty2:O2.tl:O1.lt y1 x1Compare lt eq (x1, x2) (y1, y2)x1:O1.tx2:O2.ty1:O1.ty2:O2.te:O1.eq x1 y1Compare lt eq (x1, x2) (y1, y2)x1:O1.tx2:O2.ty1:O1.ty2:O2.tl:O1.lt y1 x1Compare lt eq (x1, x2) (y1, y2)x1:O1.tx2:O2.ty1:O1.ty2:O2.te:O1.eq x1 y1l:O2.lt x2 y2Compare lt eq (x1, x2) (y1, y2)x1:O1.tx2:O2.ty1:O1.ty2:O2.te:O1.eq x1 y1e0:O2.eq x2 y2Compare lt eq (x1, x2) (y1, y2)x1:O1.tx2:O2.ty1:O1.ty2:O2.te:O1.eq x1 y1l:O2.lt y2 x2Compare lt eq (x1, x2) (y1, y2)x1:O1.tx2:O2.ty1:O1.ty2:O2.tl:O1.lt y1 x1Compare lt eq (x1, x2) (y1, y2)x1:O1.tx2:O2.ty1:O1.ty2:O2.te:O1.eq x1 y1e0:O2.eq x2 y2Compare lt eq (x1, x2) (y1, y2)x1:O1.tx2:O2.ty1:O1.ty2:O2.te:O1.eq x1 y1l:O2.lt y2 x2Compare lt eq (x1, x2) (y1, y2)x1:O1.tx2:O2.ty1:O1.ty2:O2.tl:O1.lt y1 x1Compare lt eq (x1, x2) (y1, y2)x1:O1.tx2:O2.ty1:O1.ty2:O2.te:O1.eq x1 y1l:O2.lt y2 x2Compare lt eq (x1, x2) (y1, y2)x1:O1.tx2:O2.ty1:O1.ty2:O2.tl:O1.lt y1 x1Compare lt eq (x1, x2) (y1, y2)apply GT; unfold lt; auto. Defined.x1:O1.tx2:O2.ty1:O1.ty2:O2.tl:O1.lt y1 x1Compare lt eq (x1, x2) (y1, y2)forall x y : t, {eq x y} + {~ eq x y}forall x y : t, {eq x y} + {~ eq x y}x, y:tH:lt x y~ eq x yx, y:tH:lt y x~ eq x yassert (~ eq y x); auto using lt_not_eq, eq_sym. Defined. End PairOrderedType.x, y:tH:lt y x~ eq x y
Even if positive can be seen as an ordered type with respect to the
usual order (see above), we can also use a lexicographic order over bits
(lower bits are considered first). This is more natural when using
positive as indexes for sets or maps (see FSetPositive and FMapPositive.
Module PositiveOrderedTypeBits <: UsualOrderedType. Definition t:=positive. Definition eq:=@eq positive. Definition eq_refl := @eq_refl t. Definition eq_sym := @eq_sym t. Definition eq_trans := @eq_trans t. Fixpoint bits_lt (p q:positive) : Prop := match p, q with | xH, xI _ => True | xH, _ => False | xO p, xO q => bits_lt p q | xO _, _ => True | xI p, xI q => bits_lt p q | xI _, _ => False end. Definition lt:=bits_lt.forall x y z : positive, bits_lt x y -> bits_lt y z -> bits_lt x zforall x y z : positive, bits_lt x y -> bits_lt y z -> bits_lt x zx:positiveIHx:forall y z : positive, bits_lt x y -> bits_lt y z -> bits_lt x zforall y z : positive, bits_lt x~1 y -> bits_lt y z -> bits_lt x~1 zx:positiveIHx:forall y z : positive, bits_lt x y -> bits_lt y z -> bits_lt x zforall y z : positive, bits_lt x~0 y -> bits_lt y z -> bits_lt x~0 zforall y z : positive, bits_lt 1 y -> bits_lt y z -> bits_lt 1 zx:positiveIHx:forall y z : positive, bits_lt x y -> bits_lt y z -> bits_lt x zforall y z : positive, bits_lt x~0 y -> bits_lt y z -> bits_lt x~0 zforall y z : positive, bits_lt 1 y -> bits_lt y z -> bits_lt 1 zinduction y; destruct z; simpl; eauto; intuition. Qed.forall y z : positive, bits_lt 1 y -> bits_lt y z -> bits_lt 1 zforall x y z : t, lt x y -> lt y z -> lt x zexact bits_lt_trans. Qed.forall x y z : t, lt x y -> lt y z -> lt x zforall x : positive, ~ bits_lt x xinduction x; simpl; auto. Qed.forall x : positive, ~ bits_lt x xforall x y : t, lt x y -> ~ eq x yforall x y : t, lt x y -> ~ eq x yx, y:tH:lt x yH0:eq x yFalsex:tH:lt x xFalseexact (bits_lt_antirefl x H). Qed.x:tH:bits_lt x xFalseforall x y : t, Compare lt eq x yforall x y : t, Compare lt eq x yx:positiveIHx:forall y0 : t, Compare lt eq x y0y:positiveCompare lt eq x~1 y~1x:positiveIHx:forall y0 : t, Compare lt eq x y0y:positiveCompare lt eq x~1 y~0x:positiveIHx:forall y : t, Compare lt eq x yCompare lt eq x~1 1x:positiveIHx:forall y0 : t, Compare lt eq x y0y:positiveCompare lt eq x~0 y~1x:positiveIHx:forall y0 : t, Compare lt eq x y0y:positiveCompare lt eq x~0 y~0x:positiveIHx:forall y : t, Compare lt eq x yCompare lt eq x~0 1y:positiveCompare lt eq 1 y~1y:positiveCompare lt eq 1 y~0Compare lt eq 1 1x:positiveIHx:forall y0 : t, Compare lt eq x y0y:positiveCompare lt eq x~1 y~1x:positiveIHx:forall y0 : t, Compare lt eq x y0y:positivel:lt x yCompare lt eq x~1 y~1x:positiveIHx:forall y0 : t, Compare lt eq x y0y:positivee:eq x yCompare lt eq x~1 y~1x:positiveIHx:forall y0 : t, Compare lt eq x y0y:positiveg:lt y xCompare lt eq x~1 y~1x:positiveIHx:forall y0 : t, Compare lt eq x y0y:positivee:eq x yCompare lt eq x~1 y~1x:positiveIHx:forall y0 : t, Compare lt eq x y0y:positiveg:lt y xCompare lt eq x~1 y~1apply GT; auto.x:positiveIHx:forall y0 : t, Compare lt eq x y0y:positiveg:lt y xCompare lt eq x~1 y~1apply GT; simpl; auto.x:positiveIHx:forall y0 : t, Compare lt eq x y0y:positiveCompare lt eq x~1 y~0apply GT; simpl; auto.x:positiveIHx:forall y : t, Compare lt eq x yCompare lt eq x~1 1apply LT; simpl; auto.x:positiveIHx:forall y0 : t, Compare lt eq x y0y:positiveCompare lt eq x~0 y~1x:positiveIHx:forall y0 : t, Compare lt eq x y0y:positiveCompare lt eq x~0 y~0x:positiveIHx:forall y0 : t, Compare lt eq x y0y:positivel:lt x yCompare lt eq x~0 y~0x:positiveIHx:forall y0 : t, Compare lt eq x y0y:positivee:eq x yCompare lt eq x~0 y~0x:positiveIHx:forall y0 : t, Compare lt eq x y0y:positiveg:lt y xCompare lt eq x~0 y~0x:positiveIHx:forall y0 : t, Compare lt eq x y0y:positivee:eq x yCompare lt eq x~0 y~0x:positiveIHx:forall y0 : t, Compare lt eq x y0y:positiveg:lt y xCompare lt eq x~0 y~0apply GT; auto.x:positiveIHx:forall y0 : t, Compare lt eq x y0y:positiveg:lt y xCompare lt eq x~0 y~0apply LT; simpl; auto.x:positiveIHx:forall y : t, Compare lt eq x yCompare lt eq x~0 1apply LT; simpl; auto.y:positiveCompare lt eq 1 y~1apply GT; simpl; auto.y:positiveCompare lt eq 1 y~0apply EQ; red; auto. Qed.Compare lt eq 1 1x, y:positive{x = y} + {x <> y}x, y:positive{x = y} + {x <> y}x, y:positive{x = y} + {x <> y}x, y:positiveH:(x ?= y) = Eq{x = y} + {x <> y}x, y:positiveH:(x ?= y) = Lt{x = y} + {x <> y}x, y:positiveH:(x ?= y) = Gt{x = y} + {x <> y}x, y:positiveH:(x ?= y) = Eq{x = y} + {x <> y}now apply Pos.compare_eq.x, y:positiveH:(x ?= y) = Eqx = yx, y:positiveH:(x ?= y) = Lt{x = y} + {x <> y}x, y:positiveH:(x ?= y) = Ltx <> yx, y:positiveH:(x ?= y) = LtH0:x = yFalsenow rewrite (Pos.compare_refl x) in *.x:positiveH:(x ?= x) = LtFalsex, y:positiveH:(x ?= y) = Gt{x = y} + {x <> y}x, y:positiveH:(x ?= y) = Gtx <> yx, y:positiveH:(x ?= y) = GtH0:x = yFalsenow rewrite (Pos.compare_refl x) in *. Qed. End PositiveOrderedTypeBits.x:positiveH:(x ?= x) = GtFalse
String is an ordered type with respect to the usual lexical order.
Module String_as_OT <: UsualOrderedType. Definition t := string. Definition eq := @eq string. Definition eq_refl := @eq_refl t. Definition eq_sym := @eq_sym t. Definition eq_trans := @eq_trans t. Inductive lts : string -> string -> Prop := | lts_empty : forall a s, lts EmptyString (String a s) | lts_tail : forall a s1 s2, lts s1 s2 -> lts (String a s1) (String a s2) | lts_head : forall (a b : ascii) s1 s2, lt (nat_of_ascii a) (nat_of_ascii b) -> lts (String a s1) (String b s2). Definition lt := lts.a, b:asciinat_of_ascii a = nat_of_ascii b -> a = ba, b:asciinat_of_ascii a = nat_of_ascii b -> a = ba, b:asciiH:nat_of_ascii a = nat_of_ascii ba = ba, b:asciiH:nat_of_ascii a = nat_of_ascii bascii_of_nat (nat_of_ascii a) = bapply f_equal; auto. Qed.a, b:asciiH:nat_of_ascii a = nat_of_ascii bascii_of_nat (nat_of_ascii a) = ascii_of_nat (nat_of_ascii b)a:asciis1, s2:stringlt (String a s1) (String a s2) -> lt s1 s2a:asciis1, s2:stringlt (String a s1) (String a s2) -> lt s1 s2a:asciis1, s2:stringH:lt (String a s1) (String a s2)H1:(nat_of_ascii a < nat_of_ascii a)%natlt s1 s2apply lt_irrefl in H1; inversion H1. Qed.a:asciis1, s2:stringH:lt (String a s1) (String a s2)x:natHeqx:x = nat_of_ascii aH1:(x < x)%natlt s1 s2forall x y z : t, lt x y -> lt y z -> lt x zforall x y z : t, lt x y -> lt y z -> lt x zy, z:tH1:lt "" yH2:lt y zlt "" za:asciix:stringIHx:forall y0 z0 : t, lt x y0 -> lt y0 z0 -> lt x z0y, z:tH1:lt (String a x) yH2:lt y zlt (String a x) zy, z:tH1:lt "" yH2:lt y zlt "" zdestruct z as [| c z']; inversion H2; constructor.b:asciiy':stringz:tH1:lt "" (String b y')H2:lt (String b y') za:asciis:stringH:a = bH3:s = y'lt "" za:asciix:stringIHx:forall y0 z0 : t, lt x y0 -> lt y0 z0 -> lt x z0y, z:tH1:lt (String a x) yH2:lt y zlt (String a x) zx:stringIHx:forall y z : t, lt x y -> lt y z -> lt x zy':stringc:asciiz':stringH2:lt (String c y') (String c z')H1:lt (String c x) (String c y')H0:lts x y'H3:lts y' z'lt (String c x) (String c z')x:stringIHx:forall y z : t, lt x y -> lt y z -> lt x zb:asciiy':stringc:asciiz':stringH1:lt (String b x) (String b y')H2:lt (String b y') (String c z')H0:lts x y'H3:(nat_of_ascii b < nat_of_ascii c)%natlt (String b x) (String c z')a:asciix:stringIHx:forall y z : t, lt x y -> lt y z -> lt x zy':stringc:asciiz':stringH0:(nat_of_ascii a < nat_of_ascii c)%natH2:lt (String c y') (String c z')H1:lt (String a x) (String c y')H3:lts y' z'lt (String a x) (String c z')a:asciix:stringIHx:forall y z : t, lt x y -> lt y z -> lt x zb:asciiy':stringc:asciiz':stringH1:lt (String a x) (String b y')H2:lt (String b y') (String c z')H0:(nat_of_ascii a < nat_of_ascii b)%natH3:(nat_of_ascii b < nat_of_ascii c)%natlt (String a x) (String c z')x:stringIHx:forall y z : t, lt x y -> lt y z -> lt x zy':stringc:asciiz':stringH2:lt (String c y') (String c z')H1:lt (String c x) (String c y')H0:lts x y'H3:lts y' z'lt (String c x) (String c z')eapply IHx; eauto.x:stringIHx:forall y z : t, lt x y -> lt y z -> lt x zy':stringc:asciiz':stringH2:lt (String c y') (String c z')H1:lt (String c x) (String c y')H0:lts x y'H3:lts y' z'lts x z'constructor; assumption.x:stringIHx:forall y z : t, lt x y -> lt y z -> lt x zb:asciiy':stringc:asciiz':stringH1:lt (String b x) (String b y')H2:lt (String b y') (String c z')H0:lts x y'H3:(nat_of_ascii b < nat_of_ascii c)%natlt (String b x) (String c z')constructor; assumption.a:asciix:stringIHx:forall y z : t, lt x y -> lt y z -> lt x zy':stringc:asciiz':stringH0:(nat_of_ascii a < nat_of_ascii c)%natH2:lt (String c y') (String c z')H1:lt (String a x) (String c y')H3:lts y' z'lt (String a x) (String c z')a:asciix:stringIHx:forall y z : t, lt x y -> lt y z -> lt x zb:asciiy':stringc:asciiz':stringH1:lt (String a x) (String b y')H2:lt (String b y') (String c z')H0:(nat_of_ascii a < nat_of_ascii b)%natH3:(nat_of_ascii b < nat_of_ascii c)%natlt (String a x) (String c z')eapply lt_trans; eassumption. Qed.a:asciix:stringIHx:forall y z : t, lt x y -> lt y z -> lt x zb:asciiy':stringc:asciiz':stringH1:lt (String a x) (String b y')H2:lt (String b y') (String c z')H0:(nat_of_ascii a < nat_of_ascii b)%natH3:(nat_of_ascii b < nat_of_ascii c)%nat(nat_of_ascii a < nat_of_ascii c)%natforall x y : t, lt x y -> ~ eq x yforall x y : t, lt x y -> ~ eq x yy:tLT:lt "" y~ eq "" ya:asciix:stringIHx:forall y0 : t, lt x y0 -> ~ eq x y0y:tLT:lt (String a x) y~ eq (String a x) yy:tLT:lt "" y~ eq "" yy:tLT:lt "" ya:asciis:stringH0:String a s = y~ eq "" (String a s)inversion H.y:tLT:lt "" ya:asciis:stringH0:String a s = yH:eq "" (String a s)Falsea:asciix:stringIHx:forall y0 : t, lt x y0 -> ~ eq x y0y:tLT:lt (String a x) y~ eq (String a x) ya:asciix:stringIHx:forall y : t, lt x y -> ~ eq x ys2:stringLT:lt (String a x) (String a s2)H2:lts x s2EQ:eq (String a x) (String a s2)Falsea:asciix:stringIHx:forall y : t, lt x y -> ~ eq x yb:asciis2:stringLT:lt (String a x) (String b s2)H2:(nat_of_ascii a < nat_of_ascii b)%natEQ:eq (String a x) (String b s2)Falsea:asciix:stringIHx:forall y : t, lt x y -> ~ eq x ys2:stringLT:lt (String a x) (String a s2)H2:lts x s2EQ:eq (String a x) (String a s2)Falsea:asciix, s2:stringIHx:~ eq x s2LT:lt (String a x) (String a s2)H2:lts x s2EQ:eq (String a x) (String a s2)Falseapply IHx; unfold eq; auto.a:asciis2:stringEQ:eq (String a s2) (String a s2)H2:lts s2 s2LT:lt (String a s2) (String a s2)IHx:~ eq s2 s2Falsea:asciix:stringIHx:forall y : t, lt x y -> ~ eq x yb:asciis2:stringLT:lt (String a x) (String b s2)H2:(nat_of_ascii a < nat_of_ascii b)%natEQ:eq (String a x) (String b s2)Falseapply Nat.lt_irrefl in H2; auto. Qed.s2:stringb:asciiEQ:eq (String b s2) (String b s2)IHx:forall y : t, lt s2 y -> ~ eq s2 yH2:(nat_of_ascii b < nat_of_ascii b)%natLT:lt (String b s2) (String b s2)Falsex, y:stringCompare lt eq x yx, y:stringCompare lt eq x yx:stringforall y : string, Compare lt eq x yCompare lt eq ""%string ""%stringb:asciis2:stringCompare lt eq ""%string (String b s2)a:asciis1:stringIHs1:forall y : string, Compare lt eq s1 yCompare lt eq (String a s1) ""%stringa:asciis1:stringIHs1:forall y : string, Compare lt eq s1 yb:asciis2:stringCompare lt eq (String a s1) (String b s2)apply EQ; constructor.Compare lt eq ""%string ""%stringapply LT; constructor.b:asciis2:stringCompare lt eq ""%string (String b s2)apply GT; constructor.a:asciis1:stringIHs1:forall y : string, Compare lt eq s1 yCompare lt eq (String a s1) ""%stringa:asciis1:stringIHs1:forall y : string, Compare lt eq s1 yb:asciis2:stringCompare lt eq (String a s1) (String b s2)a:asciis1:stringIHs1:forall y : string, Compare lt eq s1 yb:asciis2:stringltb:(nat_of_ascii a ?= nat_of_ascii b)%nat = EqCompare lt eq (String a s1) (String b s2)a:asciis1:stringIHs1:forall y : string, Compare lt eq s1 yb:asciis2:stringltb:(nat_of_ascii a ?= nat_of_ascii b)%nat = LtCompare lt eq (String a s1) (String b s2)a:asciis1:stringIHs1:forall y : string, Compare lt eq s1 yb:asciis2:stringltb:(nat_of_ascii a ?= nat_of_ascii b)%nat = GtCompare lt eq (String a s1) (String b s2)a:asciis1:stringIHs1:forall y : string, Compare lt eq s1 yb:asciis2:stringltb:(nat_of_ascii a ?= nat_of_ascii b)%nat = EqCompare lt eq (String a s1) (String b s2)a:asciis1:stringIHs1:forall y : string, Compare lt eq s1 yb:asciis2:stringltb:(nat_of_ascii a ?= nat_of_ascii b)%nat = Eqa = ba:asciis1:stringIHs1:forall y : string, Compare lt eq s1 yb:asciis2:stringltb:(nat_of_ascii a ?= nat_of_ascii b)%nat = EqH:a = bCompare lt eq (String a s1) (String b s2)a:asciis1:stringIHs1:forall y : string, Compare lt eq s1 yb:asciis2:stringltb:(nat_of_ascii a ?= nat_of_ascii b)%nat = Eqa = ba:asciis1:stringIHs1:forall y : string, Compare lt eq s1 yb:asciis2:stringltb:nat_of_ascii a = nat_of_ascii ba = ba:asciis1:stringIHs1:forall y : string, Compare lt eq s1 yb:asciis2:stringltb:nat_of_ascii a = nat_of_ascii bH:ascii_of_nat (nat_of_ascii a) = ascii_of_nat (nat_of_ascii b)a = bauto.a:asciis1:stringIHs1:forall y : string, Compare lt eq s1 yb:asciis2:stringltb:nat_of_ascii a = nat_of_ascii bH:a = ba = ba:asciis1:stringIHs1:forall y : string, Compare lt eq s1 yb:asciis2:stringltb:(nat_of_ascii a ?= nat_of_ascii b)%nat = EqH:a = bCompare lt eq (String a s1) (String b s2)s1:stringIHs1:forall y : string, Compare lt eq s1 yb:asciis2:stringltb:(nat_of_ascii b ?= nat_of_ascii b)%nat = EqCompare lt eq (String b s1) (String b s2)s1:stringIHs1:forall y : string, Compare lt eq s1 yb:asciis2:stringltb:(nat_of_ascii b ?= nat_of_ascii b)%nat = Eql:lt s1 s2Compare lt eq (String b s1) (String b s2)s1:stringIHs1:forall y : string, Compare lt eq s1 yb:asciis2:stringltb:(nat_of_ascii b ?= nat_of_ascii b)%nat = Eqe:eq s1 s2Compare lt eq (String b s1) (String b s2)s1:stringIHs1:forall y : string, Compare lt eq s1 yb:asciis2:stringltb:(nat_of_ascii b ?= nat_of_ascii b)%nat = Eql:lt s2 s1Compare lt eq (String b s1) (String b s2)apply LT; constructor; auto.s1:stringIHs1:forall y : string, Compare lt eq s1 yb:asciis2:stringltb:(nat_of_ascii b ?= nat_of_ascii b)%nat = Eql:lt s1 s2Compare lt eq (String b s1) (String b s2)s1:stringIHs1:forall y : string, Compare lt eq s1 yb:asciis2:stringltb:(nat_of_ascii b ?= nat_of_ascii b)%nat = Eqe:eq s1 s2Compare lt eq (String b s1) (String b s2)s1:stringIHs1:forall y : string, Compare lt eq s1 yb:asciis2:stringltb:(nat_of_ascii b ?= nat_of_ascii b)%nat = Eqe:eq s1 s2eq (String b s1) (String b s2)s1:stringIHs1:forall y : string, Compare lt eq s1 yb:asciis2:stringltb:(nat_of_ascii b ?= nat_of_ascii b)%nat = Eqe:s1 = s2eq (String b s1) (String b s2)constructor; auto.s2:stringIHs1:forall y : string, Compare lt eq s2 yb:asciiltb:(nat_of_ascii b ?= nat_of_ascii b)%nat = Eqeq (String b s2) (String b s2)apply GT; constructor; auto.s1:stringIHs1:forall y : string, Compare lt eq s1 yb:asciis2:stringltb:(nat_of_ascii b ?= nat_of_ascii b)%nat = Eql:lt s2 s1Compare lt eq (String b s1) (String b s2)a:asciis1:stringIHs1:forall y : string, Compare lt eq s1 yb:asciis2:stringltb:(nat_of_ascii a ?= nat_of_ascii b)%nat = LtCompare lt eq (String a s1) (String b s2)apply LT; constructor; auto.a:asciis1:stringIHs1:forall y : string, Compare lt eq s1 yb:asciis2:stringltb:(nat_of_ascii a < nat_of_ascii b)%natCompare lt eq (String a s1) (String b s2)a:asciis1:stringIHs1:forall y : string, Compare lt eq s1 yb:asciis2:stringltb:(nat_of_ascii a ?= nat_of_ascii b)%nat = GtCompare lt eq (String a s1) (String b s2)apply GT; constructor; auto. Defined. Definition eq_dec (x y : string): {x = y} + { ~ (x = y)} := string_dec x y. End String_as_OT.a:asciis1:stringIHs1:forall y : string, Compare lt eq s1 yb:asciis2:stringltb:(nat_of_ascii a > nat_of_ascii b)%natCompare lt eq (String a s1) (String b s2)