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 Bool Basics OrdersTac. Require Export Orders. Set Implicit Arguments. Unset Strict Implicit.
Module Type CompareFacts (Import O:DecStrOrder'). Local Infix "?=" := compare (at level 70, no associativity).x, y:t(x ?= y) = Eq <-> x == ycase compare_spec; intro H; split; try easy; intro EQ; contradict H; rewrite EQ; apply irreflexivity. Qed.x, y:t(x ?= y) = Eq <-> x == yx, y:t(x ?= y) = Eq -> x == yapply compare_eq_iff. Qed.x, y:t(x ?= y) = Eq -> x == yx, y:t(x ?= y) = Lt <-> x < ycase compare_spec; intro H; split; try easy; intro LT; contradict LT; rewrite H; apply irreflexivity. Qed.x, y:t(x ?= y) = Lt <-> x < yx, y:t(x ?= y) = Gt <-> y < xcase compare_spec; intro H; split; try easy; intro LT; contradict LT; rewrite H; apply irreflexivity. Qed.x, y:t(x ?= y) = Gt <-> y < xx, y:t(x ?= y) <> Lt <-> ~ x < yrewrite compare_lt_iff; intuition. Qed.x, y:t(x ?= y) <> Lt <-> ~ x < yx, y:t(x ?= y) <> Gt <-> ~ y < xrewrite compare_gt_iff; intuition. Qed. Hint Rewrite compare_eq_iff compare_lt_iff compare_gt_iff : order.x, y:t(x ?= y) <> Gt <-> ~ y < xProper (eq ==> eq ==> Logic.eq) compareProper (eq ==> eq ==> Logic.eq) comparecase (compare_spec x' y'); autorewrite with order; now rewrite Hxx', Hyy'. Qed.x, x':tHxx':x == x'y, y':tHyy':y == y'(x ?= y) = (x' ?= y')x:t(x ?= x) = Eqcase compare_spec; intros; trivial; now elim irreflexivity with x. Qed.x:t(x ?= x) = Eqx, y:t(y ?= x) = CompOpp (x ?= y)case (compare_spec x y); simpl; autorewrite with order; trivial; now symmetry. Qed. End CompareFacts.x, y:t(y ?= x) = CompOpp (x ?= y)
Module OrderedTypeFullFacts (Import O:OrderedTypeFull'). Module OrderTac := OTF_to_OrderTac O. Ltac order := OrderTac.order. Ltac iorder := intuition order.Proper (eq ==> eq ==> iff) lerepeat red; iorder. Qed.Proper (eq ==> eq ==> iff) lePreOrder lesplit; red; order. Qed.PreOrder lePartialOrder eq lecompute; iorder. Qed.PartialOrder eq leAntisymmetric t eq leapply partial_order_antisym; auto with *. Qed.Antisymmetric t eq leforall x y : t, x <= y <-> ~ y < xiorder. Qed.forall x y : t, x <= y <-> ~ y < xforall x y : t, x < y <-> ~ y <= xiorder. Qed.forall x y : t, x < y <-> ~ y <= xforall x y : t, x <= y \/ y < xforall x y : t, x <= y \/ y < xrewrite le_lteq; destruct (O.compare_spec x y); auto. Qed.x, y:tx <= y \/ y < xforall x y : t, x < y \/ y <= xforall x y : t, x < y \/ y <= xrewrite le_lteq; destruct (O.compare_spec x y); iorder. Qed.x, y:tx < y \/ y <= xforall x y : t, x == y <-> x <= y <= xiorder. Qed. Include CompareFacts O.forall x y : t, x == y <-> x <= y <= xx, y:t(x ?= y) <> Gt <-> x <= yx, y:t(x ?= y) <> Gt <-> x <= yapply compare_ngt_iff. Qed.x, y:t(x ?= y) <> Gt <-> ~ y < xx, y:t(x ?= y) <> Lt <-> y <= xx, y:t(x ?= y) <> Lt <-> y <= xapply compare_nlt_iff. Qed. End OrderedTypeFullFacts.x, y:t(x ?= y) <> Lt <-> ~ x < y
Module OrderedTypeFacts (Import O: OrderedType'). Module OrderTac := OT_to_OrderTac O. Ltac order := OrderTac.order. Declare Scope order. Notation "x <= y" := (~lt y x) : order. Infix "?=" := compare (at level 70, no associativity) : order. Local Open Scope order. Tactic Notation "elim_compare" constr(x) constr(y) := destruct (compare_spec x y). Tactic Notation "elim_compare" constr(x) constr(y) "as" ident(h) := destruct (compare_spec x y) as [h|h|h].
The following lemmas are either re-phrasing of eq_equiv and
lt_strorder or immediately provable by order. Interest:
compatibility, test of order, etc
Definition eq_refl (x:t) : x==x := Equivalence_Reflexive x. Definition eq_sym (x y:t) : x==y -> y==x := Equivalence_Symmetric x y. Definition eq_trans (x y z:t) : x==y -> y==z -> x==z := Equivalence_Transitive x y z. Definition lt_trans (x y z:t) : x<y -> y<z -> x<z := StrictOrder_Transitive x y z. Definition lt_irrefl (x:t) : ~x<x := StrictOrder_Irreflexive x. Include CompareFacts O. Notation compare_le_iff := compare_ngt_iff (only parsing). Notation compare_ge_iff := compare_nlt_iff (only parsing).
For compatibility reasons
Definition eq_dec := eq_dec.forall x y : t, {x < y} + {y <= x}intros x y; destruct (CompSpec2Type (compare_spec x y)); [ right | left | right ]; order. Defined. Definition eqb x y : bool := if eq_dec x y then true else false.forall x y : t, {x < y} + {y <= x}forall (x y : t) (B : Type) (b b' : B), (if eq_dec x y then b else b') = match x ?= y with | Eq => b | _ => b' endintros; destruct eq_dec; elim_compare x y; auto; order. Qed.forall (x y : t) (B : Type) (b b' : B), (if eq_dec x y then b else b') = match x ?= y with | Eq => b | _ => b' endforall x y : t, eqb x y = match x ?= y with | Eq => true | _ => false endunfold eqb; intros; apply if_eq_dec. Qed.forall x y : t, eqb x y = match x ?= y with | Eq => true | _ => false endProper (eq ==> eq ==> Logic.eq) eqbProper (eq ==> eq ==> Logic.eq) eqbrewrite 2 eqb_alt, Hxx', Hyy'; auto. Qed. End OrderedTypeFacts.x, x':tHxx':x == x'y, y':tHyy':y == y'eqb x y = eqb x' y'
Module OrderedTypeTest (Import O:OrderedType'). Module Import MO := OrderedTypeFacts O. Local Open Scope order.x, y:tx < y -> x ~= yorder. Qed.x, y:tx < y -> x ~= yx, y, z:tx < y -> y == z -> x < zorder. Qed.x, y, z:tx < y -> y == z -> x < zx, y, z:tx == y -> y < z -> x < zorder. Qed.x, y, z:tx == y -> y < z -> x < zx, y, z:tx <= y -> y == z -> x <= zorder. Qed.x, y, z:tx <= y -> y == z -> x <= zx, y, z:tx == y -> y <= z -> x <= zorder. Qed.x, y, z:tx == y -> y <= z -> x <= zx, y, z:tx ~= y -> y == z -> x ~= zorder. Qed.x, y, z:tx ~= y -> y == z -> x ~= zx, y, z:tx == y -> y ~= z -> x ~= zorder. Qed.x, y, z:tx == y -> y ~= z -> x ~= zx, y, z:tx <= y -> y < z -> x < zorder. Qed.x, y, z:tx <= y -> y < z -> x < zx, y, z:tx < y -> y <= z -> x < zorder. Qed.x, y, z:tx < y -> y <= z -> x < zx, y, z:tx <= y -> y <= z -> x <= zorder. Qed.x, y, z:tx <= y -> y <= z -> x <= zx, y:tx <= y -> y <= x -> x == yorder. Qed.x, y:tx <= y -> y <= x -> x == yx, y:tx <= y -> x ~= y -> x < yorder. Qed.x, y:tx <= y -> x ~= y -> x < yx, y:tx ~= y -> y ~= xorder. Qed.x, y:tx ~= y -> y ~= xx, y:tx < y -> x <= yorder. Qed.x, y:tx < y -> x <= yx, y:ty < x -> x ~= yorder. Qed.x, y:ty < x -> x ~= yx, y:tx == y -> y <= xorder. Qed.x, y:tx == y -> y <= xx, y:tx == y -> x <= yorder. Qed.x, y:tx == y -> x <= yx, y:tx < y -> x <= yorder. Qed.x, y:tx < y -> x <= yx, y:tx == y <-> y <= x /\ x <= yintuition; order. Qed. End OrderedTypeTest.x, y:tx == y <-> y <= x /\ x <= y
Reversed OrderedTypeFull.
Module OrderedTypeRev (O:OrderedTypeFull) <: OrderedTypeFull. Definition t := O.t. Definition eq := O.eq. Instance eq_equiv : Equivalence eq. Definition eq_dec := O.eq_dec. Definition lt := flip O.lt. Definition le := flip O.le.StrictOrder ltunfold lt; auto with *. Qed.StrictOrder ltProper (eq ==> eq ==> iff) ltunfold lt; auto with *. Qed.Proper (eq ==> eq ==> iff) ltforall x y : O.t, le x y <-> lt x y \/ eq x yforall x y : O.t, le x y <-> lt x y \/ eq x yrewrite O.le_lteq; intuition. Qed. Definition compare := flip O.compare.x, y:O.tO.le y x <-> O.lt y x \/ eq x yforall x y : O.t, CompSpec eq lt x y (compare x y)forall x y : O.t, CompSpec eq lt x y (compare x y)destruct (O.compare_spec y x); auto with relations. Qed. End OrderedTypeRev. Unset Implicit Arguments.x, y:O.tCompSpec O.eq (fun x0 y0 : O.t => O.lt y0 x0) x y (O.compare y x)
Order relations derived from a compare function.
Module Type CompareBasedOrder (Import E:EqLtLe')(Import C:HasCmp E). Include CmpNotation E C. Include IsEq E. Axiom compare_eq_iff : forall x y, (x ?= y) = Eq <-> x == y. Axiom compare_lt_iff : forall x y, (x ?= y) = Lt <-> x < y. Axiom compare_le_iff : forall x y, (x ?= y) <> Gt <-> x <= y. Axiom compare_antisym : forall x y, (y ?= x) = CompOpp (x ?= y). End CompareBasedOrder. Module Type CompareBasedOrderFacts (Import E:EqLtLe') (Import C:HasCmp E) (Import O:CompareBasedOrder E C).x, y:tCompareSpec (x == y) (x < y) (y < x) (x ?= y)x, y:tCompareSpec (x == y) (x < y) (y < x) (x ?= y)x, y:tH:(x ?= y) = Eqx == yx, y:tH:(x ?= y) = Ltx < yx, y:tH:(x ?= y) = Gty < xnow apply compare_eq_iff.x, y:tH:(x ?= y) = Eqx == ynow apply compare_lt_iff.x, y:tH:(x ?= y) = Ltx < yx, y:tH:(x ?= y) = Gty < xnow apply compare_lt_iff. Qed.x, y:tH:(y ?= x) = CompOpp Gty < xx, y:t(x ?= y) = Eq -> x == yapply compare_eq_iff. Qed.x, y:t(x ?= y) = Eq -> x == yx:t(x ?= x) = Eqnow apply compare_eq_iff. Qed.x:t(x ?= x) = Eqx, y:t(x ?= y) = Gt <-> y < xnow rewrite <- compare_lt_iff, compare_antisym, CompOpp_iff. Qed.x, y:t(x ?= y) = Gt <-> y < xx, y:t(x ?= y) <> Lt <-> y <= xnow rewrite <- compare_le_iff, compare_antisym, CompOpp_iff. Qed.x, y:t(x ?= y) <> Lt <-> y <= xx, y:t(x ?= y) <> Gt <-> ~ y < xrewrite compare_gt_iff; intuition. Qed.x, y:t(x ?= y) <> Gt <-> ~ y < xx, y:t(x ?= y) <> Lt <-> ~ x < yrewrite compare_lt_iff; intuition. Qed.x, y:t(x ?= y) <> Lt <-> ~ x < yx, y:t(x ?= y) = Gt <-> ~ x <= yx, y:t(x ?= y) = Gt <-> ~ x <= ydestruct compare; split; easy || now destruct 1. Qed.x, y:t(x ?= y) = Gt <-> ~ (x ?= y) <> Gtx, y:t(x ?= y) = Lt <-> ~ y <= xnow rewrite <- compare_nle_iff, compare_antisym, CompOpp_iff. Qed.x, y:t(x ?= y) = Lt <-> ~ y <= xx:t~ x < xnow rewrite <- compare_lt_iff, compare_refl. Qed.x:t~ x < xn, m:tn <= m <-> n < m \/ n == mn, m:tn <= m <-> n < m \/ n == mdestruct (n ?= m); now intuition. Qed. End CompareBasedOrderFacts.n, m:t(n ?= m) <> Gt <-> (n ?= m) = Lt \/ (n ?= m) = Eq
Basic facts about boolean comparisons
Module Type BoolOrderFacts (Import E:EqLtLe') (Import C:HasCmp E) (Import F:HasBoolOrdFuns' E) (Import O:CompareBasedOrder E C) (Import S:BoolOrdSpecs E F). Include CompareBasedOrderFacts E C O.
Nota : apart from eqb_compare below, facts about eqb
are in BoolEqualityFacts
Alternate specifications based on BoolSpec and reflect
x, y:treflect (x <= y) (x <=? y)x, y:treflect (x <= y) (x <=? y)x, y:tx <= y <-> x <=? y = trueapply leb_le. Defined.x, y:tx <=? y = true <-> x <= yx, y:tBoolSpec (x <= y) (y < x) (x <=? y)x, y:tBoolSpec (x <= y) (y < x) (x <=? y)now rewrite <- compare_lt_iff, compare_nge_iff. Qed.x, y:tn:~ x <= yy < xx, y:treflect (x < y) (x <? y)x, y:treflect (x < y) (x <? y)x, y:tx < y <-> x <? y = trueapply ltb_lt. Defined.x, y:tx <? y = true <-> x < yx, y:tBoolSpec (x < y) (y <= x) (x <? y)x, y:tBoolSpec (x < y) (y <= x) (x <? y)now rewrite <- compare_le_iff, compare_ngt_iff. Qed.x, y:tn:~ x < yy <= x
Negated variants of the specifications
x, y:tx <=? y = false <-> ~ x <= ynow rewrite <- not_true_iff_false, leb_le. Qed.x, y:tx <=? y = false <-> ~ x <= yx, y:tx <=? y = false <-> y < xnow rewrite leb_nle, <- compare_lt_iff, compare_nge_iff. Qed.x, y:tx <=? y = false <-> y < xx, y:tx <? y = false <-> ~ x < ynow rewrite <- not_true_iff_false, ltb_lt. Qed.x, y:tx <? y = false <-> ~ x < yx, y:tx <? y = false <-> y <= xnow rewrite ltb_nlt, <- compare_le_iff, compare_ngt_iff. Qed.x, y:tx <? y = false <-> y <= x
Basic equality laws for boolean tests
x:tx <=? x = truex:tx <=? x = truex:tx <= xnow right. Qed.x:tx < x \/ x == xx, y:ty <=? x = negb (x <? y)x, y:ty <=? x = negb (x <? y)now rewrite negb_true_iff, leb_le, ltb_ge. Qed.x, y:ty <=? x = true <-> negb (x <? y) = truex:tx <? x = falsex:tx <? x = falsex:tx <= xnow right. Qed.x:tx < x \/ x == xx, y:ty <? x = negb (x <=? y)x, y:ty <? x = negb (x <=? y)now rewrite negb_true_iff, ltb_lt, leb_gt. Qed.x, y:ty <? x = true <-> negb (x <=? y) = true
Relation between compare and the boolean comparisons
x, y:t(x =? y) = match x ?= y with | Eq => true | _ => false endx, y:t(x =? y) = match x ?= y with | Eq => true | _ => false endx, y:t(x =? y) = true <-> match x ?= y with | Eq => true | _ => false end = truenow destruct compare. Qed.x, y:t(x ?= y) = Eq <-> match x ?= y with | Eq => true | _ => false end = truex, y:tx <? y = match x ?= y with | Lt => true | _ => false endx, y:tx <? y = match x ?= y with | Lt => true | _ => false endx, y:tx <? y = true <-> match x ?= y with | Lt => true | _ => false end = truenow destruct compare. Qed.x, y:t(x ?= y) = Lt <-> match x ?= y with | Lt => true | _ => false end = truex, y:tx <=? y = match x ?= y with | Gt => false | _ => true endx, y:tx <=? y = match x ?= y with | Gt => false | _ => true endx, y:tx <=? y = true <-> match x ?= y with | Gt => false | _ => true end = truenow destruct compare. Qed. End BoolOrderFacts.x, y:t(x ?= y) <> Gt <-> match x ?= y with | Gt => false | _ => true end = true