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) *)
(************************************************************************)
This file proposes an implementation of the non-dependent
interface MSetInterface.S using strictly ordered list.
Require Export MSetInterface OrdersFacts OrdersLists. Set Implicit Arguments. Unset Strict Implicit.
Functions over lists
Module Ops (X:OrderedType) <: WOps X. Definition elt := X.t. Definition t := list elt. Definition empty : t := nil. Definition is_empty (l : t) := if l then true else false.
Fixpoint mem x s := match s with | nil => false | y :: l => match X.compare x y with | Lt => false | Eq => true | Gt => mem x l end end. Fixpoint add x s := match s with | nil => x :: nil | y :: l => match X.compare x y with | Lt => x :: s | Eq => s | Gt => y :: add x l end end. Definition singleton (x : elt) := x :: nil. Fixpoint remove x s : t := match s with | nil => nil | y :: l => match X.compare x y with | Lt => s | Eq => l | Gt => y :: remove x l end end. Fixpoint union (s : t) : t -> t := match s with | nil => fun s' => s' | x :: l => (fix union_aux (s' : t) : t := match s' with | nil => s | x' :: l' => match X.compare x x' with | Lt => x :: union l s' | Eq => x :: union l l' | Gt => x' :: union_aux l' end end) end. Fixpoint inter (s : t) : t -> t := match s with | nil => fun _ => nil | x :: l => (fix inter_aux (s' : t) : t := match s' with | nil => nil | x' :: l' => match X.compare x x' with | Lt => inter l s' | Eq => x :: inter l l' | Gt => inter_aux l' end end) end. Fixpoint diff (s : t) : t -> t := match s with | nil => fun _ => nil | x :: l => (fix diff_aux (s' : t) : t := match s' with | nil => s | x' :: l' => match X.compare x x' with | Lt => x :: diff l s' | Eq => diff l l' | Gt => diff_aux l' end end) end. Fixpoint equal (s : t) : t -> bool := fun s' : t => match s, s' with | nil, nil => true | x :: l, x' :: l' => match X.compare x x' with | Eq => equal l l' | _ => false end | _, _ => false end. Fixpoint subset s s' := match s, s' with | nil, _ => true | x :: l, x' :: l' => match X.compare x x' with | Lt => false | Eq => subset l l' | Gt => subset s l' end | _, _ => false end. Definition fold (B : Type) (f : elt -> B -> B) (s : t) (i : B) : B := fold_left (flip f) s i. Fixpoint filter (f : elt -> bool) (s : t) : t := match s with | nil => nil | x :: l => if f x then x :: filter f l else filter f l end. Fixpoint for_all (f : elt -> bool) (s : t) : bool := match s with | nil => true | x :: l => if f x then for_all f l else false end. Fixpoint exists_ (f : elt -> bool) (s : t) : bool := match s with | nil => false | x :: l => if f x then true else exists_ f l end. Fixpoint partition (f : elt -> bool) (s : t) : t * t := match s with | nil => (nil, nil) | x :: l => let (s1, s2) := partition f l in if f x then (x :: s1, s2) else (s1, x :: s2) end. Definition cardinal (s : t) : nat := length s. Definition elements (x : t) : list elt := x. Definition min_elt (s : t) : option elt := match s with | nil => None | x :: _ => Some x end. Fixpoint max_elt (s : t) : option elt := match s with | nil => None | x :: nil => Some x | _ :: l => max_elt l end. Definition choose := min_elt. Fixpoint compare s s' := match s, s' with | nil, nil => Eq | nil, _ => Lt | _, nil => Gt | x::s, x'::s' => match X.compare x x' with | Eq => compare s s' | Lt => Lt | Gt => Gt end end. End Ops. Module MakeRaw (X: OrderedType) <: RawSets X. Module Import MX := OrderedTypeFacts X. Module Import ML := OrderedTypeLists X. Include Ops X.
Section ForNotations. Definition inf x l := match l with | nil => true | y::_ => match X.compare x y with Lt => true | _ => false end end. Fixpoint isok l := match l with | nil => true | x::l => inf x l && isok l end. Notation Sort l := (isok l = true). Notation Inf := (lelistA X.lt). Notation In := (InA X.eq). Existing Instance X.eq_equiv. Hint Extern 20 => solve [order] : core. Definition IsOk s := Sort s. Class Ok (s:t) : Prop := ok : Sort s. Hint Resolve ok : core. Hint Unfold Ok : core. Instance Sort_Ok s `(Hs : Sort s) : Ok s := { ok := Hs }.forall (x : X.t) (l : list X.t), Inf x l <-> inf x l = trueforall (x : X.t) (l : list X.t), Inf x l <-> inf x l = true(* -> *)x:X.tl:list X.tH:Inf x linf x l = truex:X.tl:list X.tH:inf x l = trueInf x lx:X.ttrue = truex, b:X.tl:list X.tH:X.lt x bmatch X.compare x b with | Lt => true | _ => false end = truex:X.tl:list X.tH:inf x l = trueInf x lx, b:X.tl:list X.tH:X.lt x bmatch X.compare x b with | Lt => true | _ => false end = truex:X.tl:list X.tH:inf x l = trueInf x l(* <- *)x:X.tl:list X.tH:inf x l = trueInf x lx:X.tH:true = trueInf x nilx, y:X.tys:list X.tH:match X.compare x y with | Lt => true | _ => false end = trueInf x (y :: ys)x, y:X.tys:list X.tH:match X.compare x y with | Lt => true | _ => false end = trueInf x (y :: ys)x, y:X.tys:list X.tX.compare x y = Lt -> true = true -> Inf x (y :: ys)x, y:X.tys:list X.tHa:X.compare x y = LtInf x (y :: ys)constructor; assumption. Qed.x, y:X.tys:list X.tHa:X.lt x yInf x (y :: ys)forall l : list X.t, Sorted X.lt l <-> Ok lforall l : list X.t, Sorted X.lt l <-> Ok l(* -> *)l:list X.tH:Sorted X.lt lOk ll:list X.tH:Ok lSorted X.lt ll:list X.tH:Sorted X.lt lOk nill:list X.tH:Sorted X.lt lforall (a : X.t) (l0 : list X.t), Sorted X.lt l0 -> Ok l0 -> Inf a l0 -> Ok (a :: l0)l:list X.tH:Ok lSorted X.lt ll:list X.tH:Sorted X.lt lforall (a : X.t) (l0 : list X.t), Sorted X.lt l0 -> Ok l0 -> Inf a l0 -> Ok (a :: l0)l:list X.tH:Ok lSorted X.lt ll:list X.tH:Sorted X.lt ly:X.tys:list X.tHa:Sorted X.lt ysHb:Ok ysHc:Inf y ysOk (y :: ys)l:list X.tH:Ok lSorted X.lt ll:list X.tH:Sorted X.lt ly:X.tys:list X.tHa:Sorted X.lt ysHb:Ok ysHc:Inf y ysinf y ys && isok ys = truel:list X.tH:Ok lSorted X.lt ll:list X.tH:Sorted X.lt ly:X.tys:list X.tHa:Sorted X.lt ysHb:Ok ysHc:inf y ys = trueinf y ys && isok ys = truel:list X.tH:Ok lSorted X.lt l(* <- *)l:list X.tH:Ok lSorted X.lt lH:Ok nilSorted X.lt nilx:X.txs:list X.tH:Ok (x :: xs)IHxs:Ok xs -> Sorted X.lt xsSorted X.lt (x :: xs)x:X.txs:list X.tH:Ok (x :: xs)IHxs:Ok xs -> Sorted X.lt xsSorted X.lt (x :: xs)x:X.txs:list X.tH:inf x xs && isok xs = trueIHxs:Ok xs -> Sorted X.lt xsSorted X.lt (x :: xs)destruct H; constructor; tauto. Qed. Hint Extern 1 (Ok _) => rewrite <- isok_iff : core. Ltac inv_ok := match goal with | H:sort X.lt (_ :: _) |- _ => inversion_clear H; inv_ok | H:sort X.lt nil |- _ => clear H; inv_ok | H:sort X.lt ?l |- _ => change (Ok l) in H; inv_ok | H:Ok _ |- _ => rewrite <- isok_iff in H; inv_ok | |- Ok _ => rewrite <- isok_iff | _ => idtac end. Ltac inv := invlist InA; inv_ok; invlist lelistA. Ltac constructors := repeat constructor. Ltac sort_inf_in := match goal with | H:Inf ?x ?l, H':In ?y ?l |- _ => cut (X.lt x y); [ intro | apply Sort_Inf_In with l; auto] | _ => fail end.x:X.txs:list X.tH:Inf x xs /\ Sort xsIHxs:Ok xs -> Sorted X.lt xsSorted X.lt (x :: xs)s:list X.tH:Sort sOk ss:list X.tH:Sort sOk sassumption. Qed. Definition Equal s s' := forall a : elt, In a s <-> In a s'. Definition Subset s s' := forall a : elt, In a s -> In a s'. Definition Empty s := forall a : elt, ~ In a s. Definition For_all (P : elt -> Prop) s := forall x, In x s -> P x. Definition Exists (P : elt -> Prop) (s : t) := exists x, In x s /\ P x.s:list X.tH:Sort sOk sforall (s : t) (x : elt), Ok s -> mem x s = true <-> In x sforall (s : t) (x : elt), Ok s -> mem x s = true <-> In x sx:eltfalse = true <-> In x nila:elts:list eltIHs:forall x0 : elt, Ok s -> mem x0 s = true <-> In x0 sx:eltH:Sorted X.lt sH0:Inf a smatch X.compare x a with | Eq => true | Lt => false | Gt => mem x s end = true <-> In x (a :: s)x:eltH:false = trueIn x nilx:eltH:In x nilfalse = truea:elts:list eltIHs:forall x0 : elt, Ok s -> mem x0 s = true <-> In x0 sx:eltH:Sorted X.lt sH0:Inf a smatch X.compare x a with | Eq => true | Lt => false | Gt => mem x s end = true <-> In x (a :: s)x:eltH:In x nilfalse = truea:elts:list eltIHs:forall x0 : elt, Ok s -> mem x0 s = true <-> In x0 sx:eltH:Sorted X.lt sH0:Inf a smatch X.compare x a with | Eq => true | Lt => false | Gt => mem x s end = true <-> In x (a :: s)a:elts:list eltIHs:forall x0 : elt, Ok s -> mem x0 s = true <-> In x0 sx:eltH:Sorted X.lt sH0:Inf a smatch X.compare x a with | Eq => true | Lt => false | Gt => mem x s end = true <-> In x (a :: s)a:elts:list eltIHs:forall x0 : elt, Ok s -> mem x0 s = true <-> In x0 sx:eltH:Sorted X.lt sH0:Inf a sH1:X.lt x aH2:false = trueX.eq x a \/ In x sa:elts:list eltIHs:forall x0 : elt, Ok s -> mem x0 s = true <-> In x0 sx:eltH:Sorted X.lt sH0:Inf a sH1:X.lt x aH3:In x sfalse = truea:elts:list eltIHs:forall x0 : elt, Ok s -> mem x0 s = true <-> In x0 sx:eltH:Sorted X.lt sH0:Inf a sH1:X.lt a xH2:mem x s = trueX.eq x a \/ In x sa:elts:list eltIHs:forall x0 : elt, Ok s -> mem x0 s = true <-> In x0 sx:eltH:Sorted X.lt sH0:Inf a sH1:X.lt a xH3:In x smem x s = truea:elts:list eltIHs:forall x0 : elt, Ok s -> mem x0 s = true <-> In x0 sx:eltH:Sorted X.lt sH0:Inf a sH1:X.lt x aH3:In x sfalse = truea:elts:list eltIHs:forall x0 : elt, Ok s -> mem x0 s = true <-> In x0 sx:eltH:Sorted X.lt sH0:Inf a sH1:X.lt a xH2:mem x s = trueX.eq x a \/ In x sa:elts:list eltIHs:forall x0 : elt, Ok s -> mem x0 s = true <-> In x0 sx:eltH:Sorted X.lt sH0:Inf a sH1:X.lt a xH3:In x smem x s = truea:elts:list eltIHs:forall x0 : elt, Ok s -> mem x0 s = true <-> In x0 sx:eltH:Sorted X.lt sH0:Inf a sH1:X.lt x aH3:In x sH2:X.lt a xfalse = truea:elts:list eltIHs:forall x0 : elt, Ok s -> mem x0 s = true <-> In x0 sx:eltH:Sorted X.lt sH0:Inf a sH1:X.lt a xH2:mem x s = trueX.eq x a \/ In x sa:elts:list eltIHs:forall x0 : elt, Ok s -> mem x0 s = true <-> In x0 sx:eltH:Sorted X.lt sH0:Inf a sH1:X.lt a xH3:In x smem x s = truea:elts:list eltIHs:forall x0 : elt, Ok s -> mem x0 s = true <-> In x0 sx:eltH:Sorted X.lt sH0:Inf a sH1:X.lt a xH2:mem x s = trueX.eq x a \/ In x sa:elts:list eltIHs:forall x0 : elt, Ok s -> mem x0 s = true <-> In x0 sx:eltH:Sorted X.lt sH0:Inf a sH1:X.lt a xH3:In x smem x s = truerewrite IHs; auto. Qed.a:elts:list eltIHs:forall x0 : elt, Ok s -> mem x0 s = true <-> In x0 sx:eltH:Sorted X.lt sH0:Inf a sH1:X.lt a xH3:In x smem x s = trueforall (s : t) (x a : elt), Inf a s -> X.lt a x -> Inf a (add x s)forall (s : t) (x a : elt), Inf a s -> X.lt a x -> Inf a (add x s)s:tforall x a : elt, Inf a nil -> X.lt a x -> Inf a (x :: nil)s:tforall (a : elt) (l : list elt), (forall x a0 : elt, Inf a0 l -> X.lt a0 x -> Inf a0 (add x l)) -> forall x a0 : elt, Inf a0 (a :: l) -> X.lt a0 x -> Inf a0 match X.compare x a with | Eq => a :: l | Lt => x :: a :: l | Gt => a :: add x l endintros; elim_compare x a; inv; intuition. Qed. Hint Resolve add_inf : core.s:tforall (a : elt) (l : list elt), (forall x a0 : elt, Inf a0 l -> X.lt a0 x -> Inf a0 (add x l)) -> forall x a0 : elt, Inf a0 (a :: l) -> X.lt a0 x -> Inf a0 match X.compare x a with | Eq => a :: l | Lt => x :: a :: l | Gt => a :: add x l ends:tx:X.tOk s -> Ok (add x s)s:tx:X.tOk s -> Ok (add x s)forall (s : t) (x : X.t), Sorted X.lt s -> Sorted X.lt (add x s)s:tforall x : X.t, Sorted X.lt nil -> Sorted X.lt (x :: nil)s:tforall (a : elt) (l : list elt), (forall x : X.t, Sorted X.lt l -> Sorted X.lt (add x l)) -> forall x : X.t, Sorted X.lt (a :: l) -> Sorted X.lt match X.compare x a with | Eq => a :: l | Lt => x :: a :: l | Gt => a :: add x l endintros; elim_compare x a; inv; auto. Qed.s:tforall (a : elt) (l : list elt), (forall x : X.t, Sorted X.lt l -> Sorted X.lt (add x l)) -> forall x : X.t, Sorted X.lt (a :: l) -> Sorted X.lt match X.compare x a with | Eq => a :: l | Lt => x :: a :: l | Gt => a :: add x l endforall (s : t) (x y : elt), Ok s -> In y (add x s) <-> X.eq y x \/ In y sforall (s : t) (x y : elt), Ok s -> In y (add x s) <-> X.eq y x \/ In y sx, y:eltHs:Ok nilIn y (x :: nil) <-> X.eq y x \/ In y nila:elts:list eltIHs:forall x0 y0 : elt, Ok s -> In y0 (add x0 s) <-> X.eq y0 x0 \/ In y0 sx, y:eltHs:Ok (a :: s)In y match X.compare x a with | Eq => a :: s | Lt => x :: a :: s | Gt => a :: add x s end <-> X.eq y x \/ In y (a :: s)x, y:eltHs:Ok nilH:In y (x :: nil)X.eq y x \/ In y nila:elts:list eltIHs:forall x0 y0 : elt, Ok s -> In y0 (add x0 s) <-> X.eq y0 x0 \/ In y0 sx, y:eltHs:Ok (a :: s)In y match X.compare x a with | Eq => a :: s | Lt => x :: a :: s | Gt => a :: add x s end <-> X.eq y x \/ In y (a :: s)elim_compare x a; inv; rewrite !InA_cons, ?IHs; intuition. Qed.a:elts:list eltIHs:forall x0 y0 : elt, Ok s -> In y0 (add x0 s) <-> X.eq y0 x0 \/ In y0 sx, y:eltHs:Ok (a :: s)In y match X.compare x a with | Eq => a :: s | Lt => x :: a :: s | Gt => a :: add x s end <-> X.eq y x \/ In y (a :: s)forall (s : t) (x a : elt), Ok s -> Inf a s -> Inf a (remove x s)forall (s : t) (x a : elt), Ok s -> Inf a s -> Inf a (remove x s)elt -> forall a : elt, Ok nil -> Inf a nil -> Inf a nila:elts:list eltIHs:forall x a0 : elt, Ok s -> Inf a0 s -> Inf a0 (remove x s)forall x a0 : elt, Ok (a :: s) -> Inf a0 (a :: s) -> Inf a0 match X.compare x a with | Eq => s | Lt => a :: s | Gt => a :: remove x s enda:elts:list eltIHs:forall x a0 : elt, Ok s -> Inf a0 s -> Inf a0 (remove x s)forall x a0 : elt, Ok (a :: s) -> Inf a0 (a :: s) -> Inf a0 match X.compare x a with | Eq => s | Lt => a :: s | Gt => a :: remove x s endapply Inf_lt with a; auto. Qed. Hint Resolve remove_inf : core.a:elts:list eltIHs:forall x0 a1 : elt, Ok s -> Inf a1 s -> Inf a1 (remove x0 s)x, a0:eltH0:X.eq x aH1:Sorted X.lt sH2:Inf a sH3:X.lt a0 aInf a0 ss:tx:X.tOk s -> Ok (remove x s)s:tx:X.tOk s -> Ok (remove x s)forall (s : t) (x : X.t), Sorted X.lt s -> Sorted X.lt (remove x s)X.t -> Sorted X.lt nil -> Sorted X.lt nila:elts:list eltIHs:forall x : X.t, Sorted X.lt s -> Sorted X.lt (remove x s)forall x : X.t, Sorted X.lt (a :: s) -> Sorted X.lt match X.compare x a with | Eq => s | Lt => a :: s | Gt => a :: remove x s endintros; elim_compare x a; inv; auto. Qed.a:elts:list eltIHs:forall x : X.t, Sorted X.lt s -> Sorted X.lt (remove x s)forall x : X.t, Sorted X.lt (a :: s) -> Sorted X.lt match X.compare x a with | Eq => s | Lt => a :: s | Gt => a :: remove x s endforall (s : t) (x y : elt), Ok s -> In y (remove x s) <-> In y s /\ ~ X.eq y xforall (s : t) (x y : elt), Ok s -> In y (remove x s) <-> In y s /\ ~ X.eq y xx, y:eltHs:Ok nilIn y nil <-> In y nil /\ ~ X.eq y xa:elts:list eltIHs:forall x0 y0 : elt, Ok s -> In y0 (remove x0 s) <-> In y0 s /\ ~ X.eq y0 x0x, y:eltHs:Ok (a :: s)In y match X.compare x a with | Eq => s | Lt => a :: s | Gt => a :: remove x s end <-> In y (a :: s) /\ ~ X.eq y xelim_compare x a; inv; rewrite !InA_cons, ?IHs; intuition; try sort_inf_in; try order. Qed.a:elts:list eltIHs:forall x0 y0 : elt, Ok s -> In y0 (remove x0 s) <-> In y0 s /\ ~ X.eq y0 x0x, y:eltHs:Ok (a :: s)In y match X.compare x a with | Eq => s | Lt => a :: s | Gt => a :: remove x s end <-> In y (a :: s) /\ ~ X.eq y xx:eltOk (singleton x)unfold singleton; simpl; auto. Qed.x:eltOk (singleton x)forall x y : elt, In y (singleton x) <-> X.eq y xunfold singleton; simpl; split; intros; inv; auto. Qed. Ltac induction2 := simple induction s; [ simpl; auto; try solve [ intros; inv ] | intros x l Hrec; simple induction s'; [ simpl; auto; try solve [ intros; inv ] | intros x' l' Hrec'; simpl; elim_compare x x'; intros; inv; auto ]].forall x y : elt, In y (singleton x) <-> X.eq y xforall (s s' : t) (a : elt), Ok s -> Ok s' -> Inf a s -> Inf a s' -> Inf a (union s s')induction2. Qed. Hint Resolve union_inf : core.forall (s s' : t) (a : elt), Ok s -> Ok s' -> Inf a s -> Inf a s' -> Inf a (union s s')s, s':tOk s -> Ok s' -> Ok (union s s')s, s':tOk s -> Ok s' -> Ok (union s s')forall s s' : t, Sorted X.lt s -> Sorted X.lt s' -> Sorted X.lt (union s s')s:tx:eltl:list eltHrec:forall s'0 : t, Sorted X.lt l -> Sorted X.lt s'0 -> Sorted X.lt (union l s'0)s':tx':eltl':list eltHrec':Sorted X.lt (x :: l) -> Sorted X.lt l' -> Sorted X.lt (union (x :: l) l')H:X.eq x x'H2:Sorted X.lt l'H3:Inf x' l'H1:Sorted X.lt lH4:Inf x lInf x (union l l')s:tx:eltl:list eltHrec:forall s'0 : t, Sorted X.lt l -> Sorted X.lt s'0 -> Sorted X.lt (union l s'0)s':tx':eltl':list eltHrec':Sorted X.lt (x :: l) -> Sorted X.lt l' -> Sorted X.lt (union (x :: l) l')H:X.lt x' xH2:Sorted X.lt l'H3:Inf x' l'H1:Sorted X.lt lH4:Inf x lInf x' ((fix union_aux (s'0 : t) : t := match s'0 with | nil => x :: l | x'0 :: l'0 => match X.compare x x'0 with | Eq => x :: union l l'0 | Lt => x :: union l s'0 | Gt => x'0 :: union_aux l'0 end end) l')change (Inf x' (union (x :: l) l')); auto. Qed.s:tx:eltl:list eltHrec:forall s'0 : t, Sorted X.lt l -> Sorted X.lt s'0 -> Sorted X.lt (union l s'0)s':tx':eltl':list eltHrec':Sorted X.lt (x :: l) -> Sorted X.lt l' -> Sorted X.lt (union (x :: l) l')H:X.lt x' xH2:Sorted X.lt l'H3:Inf x' l'H1:Sorted X.lt lH4:Inf x lInf x' ((fix union_aux (s'0 : t) : t := match s'0 with | nil => x :: l | x'0 :: l'0 => match X.compare x x'0 with | Eq => x :: union l l'0 | Lt => x :: union l s'0 | Gt => x'0 :: union_aux l'0 end end) l')forall (s s' : t) (x : elt), Ok s -> Ok s' -> In x (union s s') <-> In x s \/ In x s'induction2; try rewrite ?InA_cons, ?Hrec, ?Hrec'; intuition; inv; auto. Qed.forall (s s' : t) (x : elt), Ok s -> Ok s' -> In x (union s s') <-> In x s \/ In x s'forall (s s' : t) (a : elt), Ok s -> Ok s' -> Inf a s -> Inf a s' -> Inf a (inter s s')forall (s s' : t) (a : elt), Ok s -> Ok s' -> Inf a s -> Inf a s' -> Inf a (inter s s')s:tx:eltl:list eltHrec:forall (s'0 : t) (a0 : elt), Ok l -> Ok s'0 -> Inf a0 l -> Inf a0 s'0 -> Inf a0 (inter l s'0)s':tx':eltl':list eltHrec':forall a0 : elt, Ok (x :: l) -> Ok l' -> Inf a0 (x :: l) -> Inf a0 l' -> Inf a0 (inter (x :: l) l')H:X.lt x x'a:eltH2:Sorted X.lt l'H3:Inf x' l'H4:Sorted X.lt lH5:Inf x lH6:X.lt a x'H1:X.lt a xInf a (inter l (x' :: l'))s:tx:eltl:list eltHrec:forall (s'0 : t) (a0 : elt), Ok l -> Ok s'0 -> Inf a0 l -> Inf a0 s'0 -> Inf a0 (inter l s'0)s':tx':eltl':list eltHrec':forall a0 : elt, Ok (x :: l) -> Ok l' -> Inf a0 (x :: l) -> Inf a0 l' -> Inf a0 (inter (x :: l) l')H:X.lt x' xa:eltH2:Sorted X.lt l'H3:Inf x' l'H4:Sorted X.lt lH5:Inf x lH6:X.lt a x'H1:X.lt a xInf a ((fix inter_aux (s'0 : t) : t := match s'0 with | nil => nil | x'0 :: l'0 => match X.compare x x'0 with | Eq => x :: inter l l'0 | Lt => inter l s'0 | Gt => inter_aux l'0 end end) l')s:tx:eltl:list eltHrec:forall (s'0 : t) (a0 : elt), Ok l -> Ok s'0 -> Inf a0 l -> Inf a0 s'0 -> Inf a0 (inter l s'0)s':tx':eltl':list eltHrec':forall a0 : elt, Ok (x :: l) -> Ok l' -> Inf a0 (x :: l) -> Inf a0 l' -> Inf a0 (inter (x :: l) l')H:X.lt x' xa:eltH2:Sorted X.lt l'H3:Inf x' l'H4:Sorted X.lt lH5:Inf x lH6:X.lt a x'H1:X.lt a xInf a ((fix inter_aux (s'0 : t) : t := match s'0 with | nil => nil | x'0 :: l'0 => match X.compare x x'0 with | Eq => x :: inter l l'0 | Lt => inter l s'0 | Gt => inter_aux l'0 end end) l')apply Inf_lt with x'; auto. Qed. Hint Resolve inter_inf : core.s:tx:eltl:list eltHrec:forall (s'0 : t) (a0 : elt), Ok l -> Ok s'0 -> Inf a0 l -> Inf a0 s'0 -> Inf a0 (inter l s'0)s':tx':eltl':list eltHrec':forall a0 : elt, Ok (x :: l) -> Ok l' -> Inf a0 (x :: l) -> Inf a0 l' -> Inf a0 (inter (x :: l) l')H:X.lt x' xa:eltH2:Sorted X.lt l'H3:Inf x' l'H4:Sorted X.lt lH5:Inf x lH6:X.lt a x'H1:X.lt a xInf a l's, s':tOk s -> Ok s' -> Ok (inter s s')s, s':tOk s -> Ok s' -> Ok (inter s s')forall s s' : t, Sorted X.lt s -> Sorted X.lt s' -> Sorted X.lt (inter s s')s:tx:eltl:list eltHrec:forall s'0 : t, Sorted X.lt l -> Sorted X.lt s'0 -> Sorted X.lt (inter l s'0)s':tx':eltl':list eltHrec':Sorted X.lt (x :: l) -> Sorted X.lt l' -> Sorted X.lt (inter (x :: l) l')H:X.eq x x'H2:Sorted X.lt l'H3:Inf x' l'H1:Sorted X.lt lH4:Inf x lSorted X.lt (x :: inter l l')apply Inf_eq with x'; auto; apply inter_inf; auto; apply Inf_eq with x; auto. Qed.s:tx:eltl:list eltHrec:forall s'0 : t, Sorted X.lt l -> Sorted X.lt s'0 -> Sorted X.lt (inter l s'0)s':tx':eltl':list eltHrec':Sorted X.lt (x :: l) -> Sorted X.lt l' -> Sorted X.lt (inter (x :: l) l')H:X.eq x x'H2:Sorted X.lt l'H3:Inf x' l'H1:Sorted X.lt lH4:Inf x lInf x (inter l l')forall (s s' : t) (x : elt), Ok s -> Ok s' -> In x (inter s s') <-> In x s /\ In x s'induction2; try rewrite ?InA_cons, ?Hrec, ?Hrec'; intuition; inv; auto; try sort_inf_in; try order. Qed.forall (s s' : t) (x : elt), Ok s -> Ok s' -> In x (inter s s') <-> In x s /\ In x s'forall s s' : t, Ok s -> Ok s' -> forall a : elt, Inf a s -> Inf a s' -> Inf a (diff s s')forall s s' : t, Ok s -> Ok s' -> forall a : elt, Inf a s -> Inf a s' -> Inf a (diff s s')forall s s' : t, Sorted X.lt s -> Sorted X.lt s' -> forall a : elt, Inf a s -> Inf a s' -> Inf a (diff s s')s:tx:eltl:list eltHrec:forall s'0 : t, Sorted X.lt l -> Sorted X.lt s'0 -> forall a0 : elt, Inf a0 l -> Inf a0 s'0 -> Inf a0 (diff l s'0)s':tx':eltl':list eltHrec':Sorted X.lt (x :: l) -> Sorted X.lt l' -> forall a0 : elt, Inf a0 (x :: l) -> Inf a0 l' -> Inf a0 (diff (x :: l) l')H:X.eq x x'a:eltH4:Sorted X.lt l'H5:Inf x' l'H1:Sorted X.lt lH6:Inf x lH0:X.lt a x'H3:X.lt a xInf a (diff l l')s:tx:eltl:list eltHrec:forall s'0 : t, Sorted X.lt l -> Sorted X.lt s'0 -> forall a0 : elt, Inf a0 l -> Inf a0 s'0 -> Inf a0 (diff l s'0)s':tx':eltl':list eltHrec':Sorted X.lt (x :: l) -> Sorted X.lt l' -> forall a0 : elt, Inf a0 (x :: l) -> Inf a0 l' -> Inf a0 (diff (x :: l) l')H:X.lt x' xa:eltH4:Sorted X.lt l'H5:Inf x' l'H1:Sorted X.lt lH6:Inf x lH0:X.lt a x'H3:X.lt a xInf a ((fix diff_aux (s'0 : t) : t := match s'0 with | nil => x :: l | x'0 :: l'0 => match X.compare x x'0 with | Eq => diff l l'0 | Lt => x :: diff l s'0 | Gt => diff_aux l'0 end end) l')s:tx:eltl:list eltHrec:forall s'0 : t, Sorted X.lt l -> Sorted X.lt s'0 -> forall a0 : elt, Inf a0 l -> Inf a0 s'0 -> Inf a0 (diff l s'0)s':tx':eltl':list eltHrec':Sorted X.lt (x :: l) -> Sorted X.lt l' -> forall a0 : elt, Inf a0 (x :: l) -> Inf a0 l' -> Inf a0 (diff (x :: l) l')H:X.eq x x'a:eltH4:Sorted X.lt l'H5:Inf x' l'H1:Sorted X.lt lH6:Inf x lH0:X.lt a x'H3:X.lt a xInf a ls:tx:eltl:list eltHrec:forall s'0 : t, Sorted X.lt l -> Sorted X.lt s'0 -> forall a0 : elt, Inf a0 l -> Inf a0 s'0 -> Inf a0 (diff l s'0)s':tx':eltl':list eltHrec':Sorted X.lt (x :: l) -> Sorted X.lt l' -> forall a0 : elt, Inf a0 (x :: l) -> Inf a0 l' -> Inf a0 (diff (x :: l) l')H:X.eq x x'a:eltH4:Sorted X.lt l'H5:Inf x' l'H1:Sorted X.lt lH6:Inf x lH0:X.lt a x'H3:X.lt a xInf a l's:tx:eltl:list eltHrec:forall s'0 : t, Sorted X.lt l -> Sorted X.lt s'0 -> forall a0 : elt, Inf a0 l -> Inf a0 s'0 -> Inf a0 (diff l s'0)s':tx':eltl':list eltHrec':Sorted X.lt (x :: l) -> Sorted X.lt l' -> forall a0 : elt, Inf a0 (x :: l) -> Inf a0 l' -> Inf a0 (diff (x :: l) l')H:X.lt x' xa:eltH4:Sorted X.lt l'H5:Inf x' l'H1:Sorted X.lt lH6:Inf x lH0:X.lt a x'H3:X.lt a xInf a ((fix diff_aux (s'0 : t) : t := match s'0 with | nil => x :: l | x'0 :: l'0 => match X.compare x x'0 with | Eq => diff l l'0 | Lt => x :: diff l s'0 | Gt => diff_aux l'0 end end) l')s:tx:eltl:list eltHrec:forall s'0 : t, Sorted X.lt l -> Sorted X.lt s'0 -> forall a0 : elt, Inf a0 l -> Inf a0 s'0 -> Inf a0 (diff l s'0)s':tx':eltl':list eltHrec':Sorted X.lt (x :: l) -> Sorted X.lt l' -> forall a0 : elt, Inf a0 (x :: l) -> Inf a0 l' -> Inf a0 (diff (x :: l) l')H:X.eq x x'a:eltH4:Sorted X.lt l'H5:Inf x' l'H1:Sorted X.lt lH6:Inf x lH0:X.lt a x'H3:X.lt a xInf a l's:tx:eltl:list eltHrec:forall s'0 : t, Sorted X.lt l -> Sorted X.lt s'0 -> forall a0 : elt, Inf a0 l -> Inf a0 s'0 -> Inf a0 (diff l s'0)s':tx':eltl':list eltHrec':Sorted X.lt (x :: l) -> Sorted X.lt l' -> forall a0 : elt, Inf a0 (x :: l) -> Inf a0 l' -> Inf a0 (diff (x :: l) l')H:X.lt x' xa:eltH4:Sorted X.lt l'H5:Inf x' l'H1:Sorted X.lt lH6:Inf x lH0:X.lt a x'H3:X.lt a xInf a ((fix diff_aux (s'0 : t) : t := match s'0 with | nil => x :: l | x'0 :: l'0 => match X.compare x x'0 with | Eq => diff l l'0 | Lt => x :: diff l s'0 | Gt => diff_aux l'0 end end) l')s:tx:eltl:list eltHrec:forall s'0 : t, Sorted X.lt l -> Sorted X.lt s'0 -> forall a0 : elt, Inf a0 l -> Inf a0 s'0 -> Inf a0 (diff l s'0)s':tx':eltl':list eltHrec':Sorted X.lt (x :: l) -> Sorted X.lt l' -> forall a0 : elt, Inf a0 (x :: l) -> Inf a0 l' -> Inf a0 (diff (x :: l) l')H:X.lt x' xa:eltH4:Sorted X.lt l'H5:Inf x' l'H1:Sorted X.lt lH6:Inf x lH0:X.lt a x'H3:X.lt a xInf a ((fix diff_aux (s'0 : t) : t := match s'0 with | nil => x :: l | x'0 :: l'0 => match X.compare x x'0 with | Eq => diff l l'0 | Lt => x :: diff l s'0 | Gt => diff_aux l'0 end end) l')apply Inf_lt with x'; auto. Qed. Hint Resolve diff_inf : core.s:tx:eltl:list eltHrec:forall s'0 : t, Sorted X.lt l -> Sorted X.lt s'0 -> forall a0 : elt, Inf a0 l -> Inf a0 s'0 -> Inf a0 (diff l s'0)s':tx':eltl':list eltHrec':Sorted X.lt (x :: l) -> Sorted X.lt l' -> forall a0 : elt, Inf a0 (x :: l) -> Inf a0 l' -> Inf a0 (diff (x :: l) l')H:X.lt x' xa:eltH4:Sorted X.lt l'H5:Inf x' l'H1:Sorted X.lt lH6:Inf x lH0:X.lt a x'H3:X.lt a xInf a l's, s':tOk s -> Ok s' -> Ok (diff s s')s, s':tOk s -> Ok s' -> Ok (diff s s')induction2. Qed.forall s s' : t, Sorted X.lt s -> Sorted X.lt s' -> Sorted X.lt (diff s s')forall (s s' : t) (x : elt), Ok s -> Ok s' -> In x (diff s s') <-> In x s /\ ~ In x s'forall (s s' : t) (x : elt), Ok s -> Ok s' -> In x (diff s s') <-> In x s /\ ~ In x s'right; intuition; inv; auto. Qed.s:tx:eltl:list eltHrec:forall (s'0 : t) (x1 : elt), Ok l -> Ok s'0 -> In x1 (diff l s'0) <-> In x1 l /\ (In x1 s'0 -> False)s':tx':eltl':list eltHrec':forall x1 : elt, Ok (x :: l) -> Ok l' -> In x1 (diff (x :: l) l') <-> In x1 (x :: l) /\ (In x1 l' -> False)H:X.lt x x'x0:eltH0:Sorted X.lt l'H1:Inf x' l'H2:Sorted X.lt lH3:Inf x lH4:In x0 lH5:X.eq x0 x' -> FalseH7:In x0 l' -> FalseH6:X.lt x x0X.eq x0 x \/ In x0 l /\ (In x0 (x' :: l') -> False)forall s s' : t, Ok s -> Ok s' -> equal s s' = true <-> Equal s s'forall s s' : t, Ok s -> Ok s' -> equal s s' = true <-> Equal s s'Hs, Hs':Ok niltrue = true <-> Equal nil nilx':elts':list eltHs:Ok nilHs':Ok (x' :: s')false = true <-> Equal nil (x' :: s')x:elts:list eltIH:forall s' : t, Ok s -> Ok s' -> equal s s' = true <-> Equal s s'Hs:Ok (x :: s)Hs':Ok nilfalse = true <-> Equal (x :: s) nilx:elts:list eltIH:forall s'0 : t, Ok s -> Ok s'0 -> equal s s'0 = true <-> Equal s s'0x':elts':list eltHs:Ok (x :: s)Hs':Ok (x' :: s')match X.compare x x' with | Eq => equal s s' | _ => false end = true <-> Equal (x :: s) (x' :: s')x':elts':list eltHs:Ok nilHs':Ok (x' :: s')false = true <-> Equal nil (x' :: s')x:elts:list eltIH:forall s' : t, Ok s -> Ok s' -> equal s s' = true <-> Equal s s'Hs:Ok (x :: s)Hs':Ok nilfalse = true <-> Equal (x :: s) nilx:elts:list eltIH:forall s'0 : t, Ok s -> Ok s'0 -> equal s s'0 = true <-> Equal s s'0x':elts':list eltHs:Ok (x :: s)Hs':Ok (x' :: s')match X.compare x x' with | Eq => equal s s' | _ => false end = true <-> Equal (x :: s) (x' :: s')x':elts':list eltHs:Ok nilHs':Ok (x' :: s')H:false = trueEqual nil (x' :: s')x':elts':list eltHs:Ok nilHs':Ok (x' :: s')H:Equal nil (x' :: s')false = truex:elts:list eltIH:forall s' : t, Ok s -> Ok s' -> equal s s' = true <-> Equal s s'Hs:Ok (x :: s)Hs':Ok nilfalse = true <-> Equal (x :: s) nilx:elts:list eltIH:forall s'0 : t, Ok s -> Ok s'0 -> equal s s'0 = true <-> Equal s s'0x':elts':list eltHs:Ok (x :: s)Hs':Ok (x' :: s')match X.compare x x' with | Eq => equal s s' | _ => false end = true <-> Equal (x :: s) (x' :: s')x':elts':list eltHs:Ok nilHs':Ok (x' :: s')H:Equal nil (x' :: s')false = truex:elts:list eltIH:forall s' : t, Ok s -> Ok s' -> equal s s' = true <-> Equal s s'Hs:Ok (x :: s)Hs':Ok nilfalse = true <-> Equal (x :: s) nilx:elts:list eltIH:forall s'0 : t, Ok s -> Ok s'0 -> equal s s'0 = true <-> Equal s s'0x':elts':list eltHs:Ok (x :: s)Hs':Ok (x' :: s')match X.compare x x' with | Eq => equal s s' | _ => false end = true <-> Equal (x :: s) (x' :: s')x':elts':list eltHs:Ok nilHs':Ok (x' :: s')H:Equal nil (x' :: s')H0:In x' nilfalse = truex:elts:list eltIH:forall s' : t, Ok s -> Ok s' -> equal s s' = true <-> Equal s s'Hs:Ok (x :: s)Hs':Ok nilfalse = true <-> Equal (x :: s) nilx:elts:list eltIH:forall s'0 : t, Ok s -> Ok s'0 -> equal s s'0 = true <-> Equal s s'0x':elts':list eltHs:Ok (x :: s)Hs':Ok (x' :: s')match X.compare x x' with | Eq => equal s s' | _ => false end = true <-> Equal (x :: s) (x' :: s')x:elts:list eltIH:forall s' : t, Ok s -> Ok s' -> equal s s' = true <-> Equal s s'Hs:Ok (x :: s)Hs':Ok nilfalse = true <-> Equal (x :: s) nilx:elts:list eltIH:forall s'0 : t, Ok s -> Ok s'0 -> equal s s'0 = true <-> Equal s s'0x':elts':list eltHs:Ok (x :: s)Hs':Ok (x' :: s')match X.compare x x' with | Eq => equal s s' | _ => false end = true <-> Equal (x :: s) (x' :: s')x:elts:list eltIH:forall s' : t, Ok s -> Ok s' -> equal s s' = true <-> Equal s s'Hs:Ok (x :: s)Hs':Ok nilH:false = trueEqual (x :: s) nilx:elts:list eltIH:forall s' : t, Ok s -> Ok s' -> equal s s' = true <-> Equal s s'Hs:Ok (x :: s)Hs':Ok nilH:Equal (x :: s) nilfalse = truex:elts:list eltIH:forall s'0 : t, Ok s -> Ok s'0 -> equal s s'0 = true <-> Equal s s'0x':elts':list eltHs:Ok (x :: s)Hs':Ok (x' :: s')match X.compare x x' with | Eq => equal s s' | _ => false end = true <-> Equal (x :: s) (x' :: s')x:elts:list eltIH:forall s' : t, Ok s -> Ok s' -> equal s s' = true <-> Equal s s'Hs:Ok (x :: s)Hs':Ok nilH:Equal (x :: s) nilfalse = truex:elts:list eltIH:forall s'0 : t, Ok s -> Ok s'0 -> equal s s'0 = true <-> Equal s s'0x':elts':list eltHs:Ok (x :: s)Hs':Ok (x' :: s')match X.compare x x' with | Eq => equal s s' | _ => false end = true <-> Equal (x :: s) (x' :: s')x:elts:list eltIH:forall s' : t, Ok s -> Ok s' -> equal s s' = true <-> Equal s s'Hs:Ok (x :: s)Hs':Ok nilH:Equal (x :: s) nilH0:In x nilfalse = truex:elts:list eltIH:forall s'0 : t, Ok s -> Ok s'0 -> equal s s'0 = true <-> Equal s s'0x':elts':list eltHs:Ok (x :: s)Hs':Ok (x' :: s')match X.compare x x' with | Eq => equal s s' | _ => false end = true <-> Equal (x :: s) (x' :: s')x:elts:list eltIH:forall s'0 : t, Ok s -> Ok s'0 -> equal s s'0 = true <-> Equal s s'0x':elts':list eltHs:Ok (x :: s)Hs':Ok (x' :: s')match X.compare x x' with | Eq => equal s s' | _ => false end = true <-> Equal (x :: s) (x' :: s')x:elts:list eltIH:forall s'0 : t, Ok s -> Ok s'0 -> equal s s'0 = true <-> Equal s s'0x':elts':list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x smatch X.compare x x' with | Eq => equal s s' | _ => false end = true <-> Equal (x :: s) (x' :: s')(* x=x' *)x:elts:list eltIH:forall s'0 : t, Ok s -> Ok s'0 -> equal s s'0 = true <-> Equal s s'0x':elts':list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.eq x x'equal s s' = true <-> Equal (x :: s) (x' :: s')x:elts:list eltIH:forall s'0 : t, Ok s -> Ok s'0 -> equal s s'0 = true <-> Equal s s'0x':elts':list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x x'false = true <-> Equal (x :: s) (x' :: s')x:elts:list eltIH:forall s'0 : t, Ok s -> Ok s'0 -> equal s s'0 = true <-> Equal s s'0x':elts':list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x' xfalse = true <-> Equal (x :: s) (x' :: s')x:elts:list eltIH:forall s'0 : t, Ok s -> Ok s'0 -> equal s s'0 = true <-> Equal s s'0x':elts':list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.eq x x'Equal s s' <-> Equal (x :: s) (x' :: s')x:elts:list eltIH:forall s'0 : t, Ok s -> Ok s'0 -> equal s s'0 = true <-> Equal s s'0x':elts':list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x x'false = true <-> Equal (x :: s) (x' :: s')x:elts:list eltIH:forall s'0 : t, Ok s -> Ok s'0 -> equal s s'0 = true <-> Equal s s'0x':elts':list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x' xfalse = true <-> Equal (x :: s) (x' :: s')x:elts:list eltIH:forall s'0 : t, Ok s -> Ok s'0 -> equal s s'0 = true <-> Equal s s'0x':elts':list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.eq x x'y:eltE:In y s <-> In y s'In y (x :: s) <-> In y (x' :: s')x:elts:list eltIH:forall s'0 : t, Ok s -> Ok s'0 -> equal s s'0 = true <-> Equal s s'0x':elts':list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.eq x x'y:eltE:In y (x :: s) <-> In y (x' :: s')In y s <-> In y s'x:elts:list eltIH:forall s'0 : t, Ok s -> Ok s'0 -> equal s s'0 = true <-> Equal s s'0x':elts':list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x x'false = true <-> Equal (x :: s) (x' :: s')x:elts:list eltIH:forall s'0 : t, Ok s -> Ok s'0 -> equal s s'0 = true <-> Equal s s'0x':elts':list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x' xfalse = true <-> Equal (x :: s) (x' :: s')x:elts:list eltIH:forall s'0 : t, Ok s -> Ok s'0 -> equal s s'0 = true <-> Equal s s'0x':elts':list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.eq x x'y:eltE:In y (x :: s) <-> In y (x' :: s')In y s <-> In y s'x:elts:list eltIH:forall s'0 : t, Ok s -> Ok s'0 -> equal s s'0 = true <-> Equal s s'0x':elts':list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x x'false = true <-> Equal (x :: s) (x' :: s')x:elts:list eltIH:forall s'0 : t, Ok s -> Ok s'0 -> equal s s'0 = true <-> Equal s s'0x':elts':list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x' xfalse = true <-> Equal (x :: s) (x' :: s')x:elts:list eltIH:forall s'0 : t, Ok s -> Ok s'0 -> equal s s'0 = true <-> Equal s s'0x':elts':list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.eq x x'y:eltE:X.eq y x' \/ In y s <-> X.eq y x' \/ In y s'In y s <-> In y s'x:elts:list eltIH:forall s'0 : t, Ok s -> Ok s'0 -> equal s s'0 = true <-> Equal s s'0x':elts':list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x x'false = true <-> Equal (x :: s) (x' :: s')x:elts:list eltIH:forall s'0 : t, Ok s -> Ok s'0 -> equal s s'0 = true <-> Equal s s'0x':elts':list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x' xfalse = true <-> Equal (x :: s) (x' :: s')(* x<x' *)x:elts:list eltIH:forall s'0 : t, Ok s -> Ok s'0 -> equal s s'0 = true <-> Equal s s'0x':elts':list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x x'false = true <-> Equal (x :: s) (x' :: s')x:elts:list eltIH:forall s'0 : t, Ok s -> Ok s'0 -> equal s s'0 = true <-> Equal s s'0x':elts':list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x' xfalse = true <-> Equal (x :: s) (x' :: s')x:elts:list eltIH:forall s'0 : t, Ok s -> Ok s'0 -> equal s s'0 = true <-> Equal s s'0x':elts':list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x x'E:false = trueEqual (x :: s) (x' :: s')x:elts:list eltIH:forall s'0 : t, Ok s -> Ok s'0 -> equal s s'0 = true <-> Equal s s'0x':elts':list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x x'E:Equal (x :: s) (x' :: s')false = truex:elts:list eltIH:forall s'0 : t, Ok s -> Ok s'0 -> equal s s'0 = true <-> Equal s s'0x':elts':list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x' xfalse = true <-> Equal (x :: s) (x' :: s')x:elts:list eltIH:forall s'0 : t, Ok s -> Ok s'0 -> equal s s'0 = true <-> Equal s s'0x':elts':list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x x'E:Equal (x :: s) (x' :: s')false = truex:elts:list eltIH:forall s'0 : t, Ok s -> Ok s'0 -> equal s s'0 = true <-> Equal s s'0x':elts':list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x' xfalse = true <-> Equal (x :: s) (x' :: s')x:elts:list eltIH:forall s'0 : t, Ok s -> Ok s'0 -> equal s s'0 = true <-> Equal s s'0x':elts':list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x x'E:Equal (x :: s) (x' :: s')H3:In x (x' :: s')false = truex:elts:list eltIH:forall s'0 : t, Ok s -> Ok s'0 -> equal s s'0 = true <-> Equal s s'0x':elts':list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x' xfalse = true <-> Equal (x :: s) (x' :: s')(* x>x' *)x:elts:list eltIH:forall s'0 : t, Ok s -> Ok s'0 -> equal s s'0 = true <-> Equal s s'0x':elts':list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x' xfalse = true <-> Equal (x :: s) (x' :: s')x:elts:list eltIH:forall s'0 : t, Ok s -> Ok s'0 -> equal s s'0 = true <-> Equal s s'0x':elts':list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x' xE:false = trueEqual (x :: s) (x' :: s')x:elts:list eltIH:forall s'0 : t, Ok s -> Ok s'0 -> equal s s'0 = true <-> Equal s s'0x':elts':list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x' xE:Equal (x :: s) (x' :: s')false = truex:elts:list eltIH:forall s'0 : t, Ok s -> Ok s'0 -> equal s s'0 = true <-> Equal s s'0x':elts':list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x' xE:Equal (x :: s) (x' :: s')false = trueinv; try sort_inf_in; order. Qed.x:elts:list eltIH:forall s'0 : t, Ok s -> Ok s'0 -> equal s s'0 = true <-> Equal s s'0x':elts':list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x' xE:Equal (x :: s) (x' :: s')H3:In x' (x :: s)false = trueforall s s' : t, Ok s -> Ok s' -> subset s s' = true <-> Subset s s'forall s s' : t, Ok s -> Ok s' -> subset s s' = true <-> Subset s s's':tforall s : t, Ok s -> Ok s' -> subset s s' = true <-> Subset s s'Hs, Hs':Ok niltrue = true <-> Subset nil nilx:elts:list eltHs:Ok (x :: s)Hs':Ok nilfalse = true <-> Subset (x :: s) nilx':elts':list eltIH:forall s : t, Ok s -> Ok s' -> subset s s' = true <-> Subset s s'Hs:Ok nilHs':Ok (x' :: s')true = true <-> Subset nil (x' :: s')x':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltHs:Ok (x :: s)Hs':Ok (x' :: s')match X.compare x x' with | Eq => subset s s' | Lt => false | Gt => subset (x :: s) s' end = true <-> Subset (x :: s) (x' :: s')x:elts:list eltHs:Ok (x :: s)Hs':Ok nilfalse = true <-> Subset (x :: s) nilx':elts':list eltIH:forall s : t, Ok s -> Ok s' -> subset s s' = true <-> Subset s s'Hs:Ok nilHs':Ok (x' :: s')true = true <-> Subset nil (x' :: s')x':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltHs:Ok (x :: s)Hs':Ok (x' :: s')match X.compare x x' with | Eq => subset s s' | Lt => false | Gt => subset (x :: s) s' end = true <-> Subset (x :: s) (x' :: s')x:elts:list eltHs:Ok (x :: s)Hs':Ok nilH:false = trueSubset (x :: s) nilx:elts:list eltHs:Ok (x :: s)Hs':Ok nilH:Subset (x :: s) nilfalse = truex':elts':list eltIH:forall s : t, Ok s -> Ok s' -> subset s s' = true <-> Subset s s'Hs:Ok nilHs':Ok (x' :: s')true = true <-> Subset nil (x' :: s')x':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltHs:Ok (x :: s)Hs':Ok (x' :: s')match X.compare x x' with | Eq => subset s s' | Lt => false | Gt => subset (x :: s) s' end = true <-> Subset (x :: s) (x' :: s')x:elts:list eltHs:Ok (x :: s)Hs':Ok nilH:Subset (x :: s) nilfalse = truex':elts':list eltIH:forall s : t, Ok s -> Ok s' -> subset s s' = true <-> Subset s s'Hs:Ok nilHs':Ok (x' :: s')true = true <-> Subset nil (x' :: s')x':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltHs:Ok (x :: s)Hs':Ok (x' :: s')match X.compare x x' with | Eq => subset s s' | Lt => false | Gt => subset (x :: s) s' end = true <-> Subset (x :: s) (x' :: s')x:elts:list eltHs:Ok (x :: s)Hs':Ok nilH:Subset (x :: s) nilH0:In x nilfalse = truex':elts':list eltIH:forall s : t, Ok s -> Ok s' -> subset s s' = true <-> Subset s s'Hs:Ok nilHs':Ok (x' :: s')true = true <-> Subset nil (x' :: s')x':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltHs:Ok (x :: s)Hs':Ok (x' :: s')match X.compare x x' with | Eq => subset s s' | Lt => false | Gt => subset (x :: s) s' end = true <-> Subset (x :: s) (x' :: s')x':elts':list eltIH:forall s : t, Ok s -> Ok s' -> subset s s' = true <-> Subset s s'Hs:Ok nilHs':Ok (x' :: s')true = true <-> Subset nil (x' :: s')x':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltHs:Ok (x :: s)Hs':Ok (x' :: s')match X.compare x x' with | Eq => subset s s' | Lt => false | Gt => subset (x :: s) s' end = true <-> Subset (x :: s) (x' :: s')x':elts':list eltIH:forall s : t, Ok s -> Ok s' -> subset s s' = true <-> Subset s s'Hs:Ok nilHs':Ok (x' :: s')H:true = truea:eltH0:In a nilIn a (x' :: s')x':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltHs:Ok (x :: s)Hs':Ok (x' :: s')match X.compare x x' with | Eq => subset s s' | Lt => false | Gt => subset (x :: s) s' end = true <-> Subset (x :: s) (x' :: s')x':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltHs:Ok (x :: s)Hs':Ok (x' :: s')match X.compare x x' with | Eq => subset s s' | Lt => false | Gt => subset (x :: s) s' end = true <-> Subset (x :: s) (x' :: s')x':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x smatch X.compare x x' with | Eq => subset s s' | Lt => false | Gt => subset (x :: s) s' end = true <-> Subset (x :: s) (x' :: s')(* x=x' *)x':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.eq x x'subset s s' = true <-> Subset (x :: s) (x' :: s')x':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x x'false = true <-> Subset (x :: s) (x' :: s')x':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x' xsubset (x :: s) s' = true <-> Subset (x :: s) (x' :: s')x':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.eq x x'Subset s s' <-> Subset (x :: s) (x' :: s')x':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x x'false = true <-> Subset (x :: s) (x' :: s')x':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x' xsubset (x :: s) s' = true <-> Subset (x :: s) (x' :: s')x':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.eq x x'y:eltS:In y s -> In y s'In y (x :: s) -> In y (x' :: s')x':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.eq x x'y:eltS:In y (x :: s) -> In y (x' :: s')In y s -> In y s'x':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x x'false = true <-> Subset (x :: s) (x' :: s')x':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x' xsubset (x :: s) s' = true <-> Subset (x :: s) (x' :: s')x':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.eq x x'y:eltS:In y s -> In y s'X.eq y x' \/ In y s -> X.eq y x' \/ In y s'x':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.eq x x'y:eltS:In y (x :: s) -> In y (x' :: s')In y s -> In y s'x':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x x'false = true <-> Subset (x :: s) (x' :: s')x':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x' xsubset (x :: s) s' = true <-> Subset (x :: s) (x' :: s')x':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.eq x x'y:eltS:In y (x :: s) -> In y (x' :: s')In y s -> In y s'x':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x x'false = true <-> Subset (x :: s) (x' :: s')x':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x' xsubset (x :: s) s' = true <-> Subset (x :: s) (x' :: s')x':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.eq x x'y:eltS:X.eq y x' \/ In y s -> X.eq y x' \/ In y s'In y s -> In y s'x':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x x'false = true <-> Subset (x :: s) (x' :: s')x':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x' xsubset (x :: s) s' = true <-> Subset (x :: s) (x' :: s')(* x<x' *)x':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x x'false = true <-> Subset (x :: s) (x' :: s')x':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x' xsubset (x :: s) s' = true <-> Subset (x :: s) (x' :: s')x':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x x'S:false = trueSubset (x :: s) (x' :: s')x':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x x'S:Subset (x :: s) (x' :: s')false = truex':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x' xsubset (x :: s) s' = true <-> Subset (x :: s) (x' :: s')x':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x x'S:Subset (x :: s) (x' :: s')false = truex':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x' xsubset (x :: s) s' = true <-> Subset (x :: s) (x' :: s')x':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x x'S:Subset (x :: s) (x' :: s')H3:In x (x' :: s')false = truex':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x' xsubset (x :: s) s' = true <-> Subset (x :: s) (x' :: s')(* x>x' *)x':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x' xsubset (x :: s) s' = true <-> Subset (x :: s) (x' :: s')x':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x' xSubset (x :: s) s' <-> Subset (x :: s) (x' :: s')x':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x' xy:eltS:In y (x :: s) -> In y s'In y (x :: s) -> In y (x' :: s')x':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x' xy:eltS:In y (x :: s) -> In y (x' :: s')In y (x :: s) -> In y s'x':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x' xy:eltS:In y (x :: s) -> In y s'X.eq y x \/ In y s -> X.eq y x' \/ In y s'x':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x' xy:eltS:In y (x :: s) -> In y (x' :: s')In y (x :: s) -> In y s'x':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x' xy:eltS:In y (x :: s) -> In y (x' :: s')In y (x :: s) -> In y s'x':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x' xy:eltS:X.eq y x \/ In y s -> X.eq y x' \/ In y s'In y (x :: s) -> In y s'intuition; try sort_inf_in; order. Qed.x':elts':list eltIH:forall s0 : t, Ok s0 -> Ok s' -> subset s0 s' = true <-> Subset s0 s'x:elts:list eltH:Sorted X.lt s'H0:Inf x' s'H1:Sorted X.lt sH2:Inf x sC:X.lt x' xy:eltS:X.eq y x \/ In y s -> X.eq y x' \/ In y s'X.eq y x \/ In y s -> In y s'Ok emptyconstructors. Qed.Ok emptyEmpty emptyunfold Empty, empty; intuition; inv. Qed.Empty emptyforall s : t, is_empty s = true <-> Empty sforall s : t, is_empty s = true <-> Empty strue = true <-> Empty nilx:elts:list eltfalse = true <-> Empty (x :: s)true = true -> Empty nilx:elts:list eltfalse = true <-> Empty (x :: s)x:eltH:In x nilFalsex:elts:list eltfalse = true <-> Empty (x :: s)x:elts:list eltfalse = true <-> Empty (x :: s)x:elts:list eltfalse = true -> Empty (x :: s)x:elts:list eltEmpty (x :: s) -> false = truex:elts:list eltEmpty (x :: s) -> false = trueelim (H x); auto. Qed.x:elts:list eltH:Empty (x :: s)false = trueforall (s : t) (x : elt), In x (elements s) <-> In x sintuition. Qed.forall (s : t) (x : elt), In x (elements s) <-> In x sforall s : t, Ok s -> Sorted X.lt (elements s)intro s; repeat rewrite <- isok_iff; auto. Qed.forall s : t, Ok s -> Sorted X.lt (elements s)forall s : t, Ok s -> NoDupA X.eq (elements s)intro s; repeat rewrite <- isok_iff; auto. Qed.forall s : t, Ok s -> NoDupA X.eq (elements s)forall (s : t) (x : elt), min_elt s = Some x -> In x sdestruct s; simpl; inversion 1; auto. Qed.forall (s : t) (x : elt), min_elt s = Some x -> In x sforall (s : t) (x y : elt), Ok s -> min_elt s = Some x -> In y s -> ~ X.lt y xforall (s : t) (x y : elt), Ok s -> min_elt s = Some x -> In y s -> ~ X.lt y xintros; inv; try sort_inf_in; order. Qed.s:list eltIH:forall x y0 : elt, Ok s -> min_elt s = Some x -> In y0 s -> ~ X.lt y0 xx0, y:eltH:Some x0 = Some x0Hs:Ok (x0 :: s)In y (x0 :: s) -> ~ X.lt y x0forall s : t, min_elt s = None -> Empty sforall s : t, min_elt s = None -> Empty sH:None = Nonea:eltH0:In a nilFalsee:elts:list eltH:Some e = Nonea:eltH0:In a (e :: s)Falsediscriminate. Qed.e:elts:list eltH:Some e = Nonea:eltH0:In a (e :: s)Falseforall (s : t) (x : elt), max_elt s = Some x -> In x sforall (s : t) (x : elt), max_elt s = Some x -> In x sforall x : elt, max_elt nil = Some x -> In x nilx:elts:list eltIH:forall x0 : elt, max_elt s = Some x0 -> In x0 sforall x0 : elt, max_elt (x :: s) = Some x0 -> In x0 (x :: s)x:elts:list eltIH:forall x0 : elt, max_elt s = Some x0 -> In x0 sforall x0 : elt, max_elt (x :: s) = Some x0 -> In x0 (x :: s)x:eltIH:forall x0 : elt, max_elt nil = Some x0 -> In x0 nilforall x0 : elt, max_elt (x :: nil) = Some x0 -> In x0 (x :: nil)x, y:elts:list eltIH:forall x0 : elt, max_elt (y :: s) = Some x0 -> In x0 (y :: s)forall x0 : elt, max_elt (x :: y :: s) = Some x0 -> In x0 (x :: y :: s)x:eltIH:forall x0 : elt, max_elt nil = Some x0 -> In x0 nilforall x0 : elt, Some x = Some x0 -> In x0 (x :: nil)x, y:elts:list eltIH:forall x0 : elt, max_elt (y :: s) = Some x0 -> In x0 (y :: s)forall x0 : elt, max_elt (x :: y :: s) = Some x0 -> In x0 (x :: y :: s)right; apply IH; auto. Qed.x, y:elts:list eltIH:forall x0 : elt, max_elt (y :: s) = Some x0 -> In x0 (y :: s)forall x0 : elt, max_elt (x :: y :: s) = Some x0 -> In x0 (x :: y :: s)forall (s : t) (x y : elt), Ok s -> max_elt s = Some x -> In y s -> ~ X.lt x yforall (s : t) (x y : elt), Ok s -> max_elt s = Some x -> In y s -> ~ X.lt x yforall x y : elt, Ok nil -> max_elt nil = Some x -> In y nil -> ~ X.lt x ya:elts:list eltIH:forall x y : elt, Ok s -> max_elt s = Some x -> In y s -> ~ X.lt x yforall x y : elt, Ok (a :: s) -> max_elt (a :: s) = Some x -> In y (a :: s) -> ~ X.lt x ya:elts:list eltIH:forall x y : elt, Ok s -> max_elt s = Some x -> In y s -> ~ X.lt x yforall x y : elt, Ok (a :: s) -> max_elt (a :: s) = Some x -> In y (a :: s) -> ~ X.lt x ya:eltIH:forall x y : elt, Ok nil -> max_elt nil = Some x -> In y nil -> ~ X.lt x yforall x y : elt, Ok (a :: nil) -> max_elt (a :: nil) = Some x -> In y (a :: nil) -> ~ X.lt x ya, b:elts:list eltIH:forall x y : elt, Ok (b :: s) -> max_elt (b :: s) = Some x -> In y (b :: s) -> ~ X.lt x yforall x y : elt, Ok (a :: b :: s) -> max_elt (a :: b :: s) = Some x -> In y (a :: b :: s) -> ~ X.lt x yIH:forall x0 y0 : elt, Ok nil -> max_elt nil = Some x0 -> In y0 nil -> ~ X.lt x0 y0x, y:eltH:max_elt (x :: nil) = Some xHs:Ok (x :: nil)In y (x :: nil) -> ~ X.lt x ya, b:elts:list eltIH:forall x y : elt, Ok (b :: s) -> max_elt (b :: s) = Some x -> In y (b :: s) -> ~ X.lt x yforall x y : elt, Ok (a :: b :: s) -> max_elt (a :: b :: s) = Some x -> In y (a :: b :: s) -> ~ X.lt x ya, b:elts:list eltIH:forall x y : elt, Ok (b :: s) -> max_elt (b :: s) = Some x -> In y (b :: s) -> ~ X.lt x yforall x y : elt, Ok (a :: b :: s) -> max_elt (a :: b :: s) = Some x -> In y (a :: b :: s) -> ~ X.lt x ya, b:elts:list eltIH:forall x0 y0 : elt, Ok (b :: s) -> max_elt (b :: s) = Some x0 -> In y0 (b :: s) -> ~ X.lt x0 y0x, y:eltHs:Ok (a :: b :: s)H:max_elt (a :: b :: s) = Some xH0:In y (a :: b :: s)~ X.lt x ya, b:elts:list eltIH:forall x0 y0 : elt, Ok (b :: s) -> max_elt (b :: s) = Some x0 -> In y0 (b :: s) -> ~ X.lt x0 y0x, y:eltH:max_elt (a :: b :: s) = Some xH1:X.eq y aH3:Sorted X.lt sH4:Inf b sH0:X.lt a b~ X.lt x ya, b:elts:list eltIH:forall x0 y0 : elt, Ok (b :: s) -> max_elt (b :: s) = Some x0 -> In y0 (b :: s) -> ~ X.lt x0 y0x, y:eltH:max_elt (a :: b :: s) = Some xH1:X.eq y aH3:Sorted X.lt sH4:Inf b sH0:X.lt a bH2:~ X.lt x b~ X.lt x yorder. Qed.a, b:elts:list eltIH:forall x0 y0 : elt, Ok (b :: s) -> max_elt (b :: s) = Some x0 -> In y0 (b :: s) -> ~ X.lt x0 y0x, y:eltH:max_elt (a :: b :: s) = Some xH1:X.eq y aH3:Sorted X.lt sH4:Inf b sH0:X.lt a bH2:~ X.lt x bH5:X.lt a b~ X.lt x yforall s : t, max_elt s = None -> Empty sforall s : t, max_elt s = None -> Empty smax_elt nil = None -> Empty nila:elts:list eltIH:max_elt s = None -> Empty smax_elt (a :: s) = None -> Empty (a :: s)a:elts:list eltIH:max_elt s = None -> Empty smax_elt (a :: s) = None -> Empty (a :: s)a:eltIH:max_elt nil = None -> Empty nilmax_elt (a :: nil) = None -> Empty (a :: nil)a, b:elts:list eltIH:max_elt (b :: s) = None -> Empty (b :: s)max_elt (a :: b :: s) = None -> Empty (a :: b :: s)intros; elim IH with b; auto. Qed. Definition choose_spec1 : forall (s : t) (x : elt), choose s = Some x -> In x s := min_elt_spec1. Definition choose_spec2 : forall s : t, choose s = None -> Empty s := min_elt_spec3.a, b:elts:list eltIH:max_elt (b :: s) = None -> Empty (b :: s)max_elt (a :: b :: s) = None -> Empty (a :: b :: s)forall (s s' : t) (x x' : elt), Ok s -> Ok s' -> choose s = Some x -> choose s' = Some x' -> Equal s s' -> X.eq x x'forall (s s' : t) (x x' : elt), Ok s -> Ok s' -> choose s = Some x -> choose s' = Some x' -> Equal s s' -> X.eq x x's, s':tx, x':eltHs:Ok sHs':Ok s'Hx:min_elt s = Some xHx':min_elt s' = Some x'H:Equal s s'X.eq x x's, s':tx, x':eltHs:Ok sHs':Ok s'Hx:min_elt s = Some xHx':min_elt s' = Some x'H:Equal s s'~ X.lt x x's, s':tx, x':eltHs:Ok sHs':Ok s'Hx:min_elt s = Some xHx':min_elt s' = Some x'H:Equal s s'H0:~ X.lt x x'X.eq x x's, s':tx, x':eltHs:Ok sHs':Ok s'Hx:min_elt s = Some xHx':min_elt s' = Some x'H:Equal s s'In x s's, s':tx, x':eltHs:Ok sHs':Ok s'Hx:min_elt s = Some xHx':min_elt s' = Some x'H:Equal s s'H0:~ X.lt x x'X.eq x x's, s':tx, x':eltHs:Ok sHs':Ok s'Hx:min_elt s = Some xHx':min_elt s' = Some x'H:Equal s s'H0:~ X.lt x x'X.eq x x's, s':tx, x':eltHs:Ok sHs':Ok s'Hx:min_elt s = Some xHx':min_elt s' = Some x'H:Equal s s'H0:~ X.lt x x'~ X.lt x' xs, s':tx, x':eltHs:Ok sHs':Ok s'Hx:min_elt s = Some xHx':min_elt s' = Some x'H:Equal s s'H0:~ X.lt x x'H1:~ X.lt x' xX.eq x x's, s':tx, x':eltHs:Ok sHs':Ok s'Hx:min_elt s = Some xHx':min_elt s' = Some x'H:Equal s s'H0:~ X.lt x x'In x' ss, s':tx, x':eltHs:Ok sHs':Ok s'Hx:min_elt s = Some xHx':min_elt s' = Some x'H:Equal s s'H0:~ X.lt x x'H1:~ X.lt x' xX.eq x x'order. Qed.s, s':tx, x':eltHs:Ok sHs':Ok s'Hx:min_elt s = Some xHx':min_elt s' = Some x'H:Equal s s'H0:~ X.lt x x'H1:~ X.lt x' xX.eq x x'forall (s : t) (A : Type) (i : A) (f : elt -> A -> A), fold f s i = fold_left (flip f) (elements s) ireflexivity. Qed.forall (s : t) (A : Type) (i : A) (f : elt -> A -> A), fold f s i = fold_left (flip f) (elements s) iforall s : t, Ok s -> cardinal s = length (elements s)auto. Qed.forall s : t, Ok s -> cardinal s = length (elements s)forall (s : t) (x : elt) (f : elt -> bool), Ok s -> Inf x s -> Inf x (filter f s)forall (s : t) (x : elt) (f : elt -> bool), Ok s -> Inf x s -> Inf x (filter f s)s:tforall x : elt, (elt -> bool) -> Ok nil -> Inf x nil -> Inf x nils:tforall (a : elt) (l : list elt), (forall (x : elt) (f : elt -> bool), Ok l -> Inf x l -> Inf x (filter f l)) -> forall (x : elt) (f : elt -> bool), Ok (a :: l) -> Inf x (a :: l) -> Inf x (if f a then a :: filter f l else filter f l)s:tforall (a : elt) (l : list elt), (forall (x : elt) (f : elt -> bool), Ok l -> Inf x l -> Inf x (filter f l)) -> forall (x : elt) (f : elt -> bool), Ok (a :: l) -> Inf x (a :: l) -> Inf x (if f a then a :: filter f l else filter f l)s:tx:eltl:list eltHrec:forall (x0 : elt) (f0 : elt -> bool), Ok l -> Inf x0 l -> Inf x0 (filter f0 l)a:eltf:elt -> boolH:Sorted X.lt lH0:Inf x lH1:X.lt a xInf a (if f x then x :: filter f l else filter f l)s:tx:eltl:list eltHrec:forall (x0 : elt) (f0 : elt -> bool), Ok l -> Inf x0 l -> Inf x0 (filter f0 l)a:eltf:elt -> boolH:Sorted X.lt lH0:Inf x lH1:X.lt a xInf a (filter f l)apply Inf_lt with x; auto. Qed.s:tx:eltl:list eltHrec:forall (x0 : elt) (f0 : elt -> bool), Ok l -> Inf x0 l -> Inf x0 (filter f0 l)a:eltf:elt -> boolH:Sorted X.lt lH0:Inf x lH1:X.lt a xInf a ls:tf:elt -> boolOk s -> Ok (filter f s)s:tf:elt -> boolOk s -> Ok (filter f s)forall (s : t) (f : elt -> bool), Sorted X.lt s -> Sorted X.lt (filter f s)s:t(elt -> bool) -> Sorted X.lt nil -> Sorted X.lt nils:tforall (a : elt) (l : list elt), (forall f : elt -> bool, Sorted X.lt l -> Sorted X.lt (filter f l)) -> forall f : elt -> bool, Sorted X.lt (a :: l) -> Sorted X.lt (if f a then a :: filter f l else filter f l)s:tforall (a : elt) (l : list elt), (forall f : elt -> bool, Sorted X.lt l -> Sorted X.lt (filter f l)) -> forall f : elt -> bool, Sorted X.lt (a :: l) -> Sorted X.lt (if f a then a :: filter f l else filter f l)s:tx:eltl:list eltHrec:forall f0 : elt -> bool, Sorted X.lt l -> Sorted X.lt (filter f0 l)f:elt -> boolH:Sorted X.lt lH0:Inf x lSorted X.lt (if f x then x :: filter f l else filter f l)s:tx:eltl:list eltHrec:forall f0 : elt -> bool, Sorted X.lt l -> Sorted X.lt (filter f0 l)f:elt -> boolH:Sorted X.lt lH0:Inf x lSorted X.lt (x :: filter f l)apply filter_inf; auto. Qed.s:tx:eltl:list eltHrec:forall f0 : elt -> bool, Sorted X.lt l -> Sorted X.lt (filter f0 l)f:elt -> boolH:Sorted X.lt lH0:Inf x lInf x (filter f l)forall (s : t) (x : elt) (f : elt -> bool), Proper (X.eq ==> eq) f -> In x (filter f s) <-> In x s /\ f x = trueforall (s : t) (x : elt) (f : elt -> bool), Proper (X.eq ==> eq) f -> In x (filter f s) <-> In x s /\ f x = truex:eltf:elt -> boolH:Proper (X.eq ==> eq) fIn x nil <-> In x nil /\ f x = truea:elts:list eltIHs:forall (x0 : elt) (f0 : elt -> bool), Proper (X.eq ==> eq) f0 -> In x0 (filter f0 s) <-> In x0 s /\ f0 x0 = truex:eltf:elt -> boolH:Proper (X.eq ==> eq) fIn x (if f a then a :: filter f s else filter f s) <-> In x (a :: s) /\ f x = truea:elts:list eltIHs:forall (x0 : elt) (f0 : elt -> bool), Proper (X.eq ==> eq) f0 -> In x0 (filter f0 s) <-> In x0 s /\ f0 x0 = truex:eltf:elt -> boolH:Proper (X.eq ==> eq) fIn x (if f a then a :: filter f s else filter f s) <-> In x (a :: s) /\ f x = truea:elts:list eltIHs:forall (x0 : elt) (f0 : elt -> bool), Proper (X.eq ==> eq) f0 -> In x0 (filter f0 s) <-> In x0 s /\ f0 x0 = truex:eltf:elt -> boolH:Proper (X.eq ==> eq) fF:f a = trueH1:X.eq x af x = truea:elts:list eltIHs:forall (x0 : elt) (f0 : elt -> bool), Proper (X.eq ==> eq) f0 -> In x0 (filter f0 s) <-> In x0 s /\ f0 x0 = truex:eltf:elt -> boolH:Proper (X.eq ==> eq) fF:f a = falseH2:f x = trueH0:X.eq x aIn x ssetoid_replace a with x in F; auto; congruence. Qed.a:elts:list eltIHs:forall (x0 : elt) (f0 : elt -> bool), Proper (X.eq ==> eq) f0 -> In x0 (filter f0 s) <-> In x0 s /\ f0 x0 = truex:eltf:elt -> boolH:Proper (X.eq ==> eq) fF:f a = falseH2:f x = trueH0:X.eq x aIn x sforall (s : t) (f : elt -> bool), Proper (X.eq ==> eq) f -> for_all f s = true <-> For_all (fun x : elt => f x = true) sforall (s : t) (f : elt -> bool), Proper (X.eq ==> eq) f -> for_all f s = true <-> For_all (fun x : elt => f x = true) sf:elt -> boolH:Proper (X.eq ==> eq) ftrue = true <-> (forall x : X.t, In x nil -> f x = true)a:elts:list eltIHs:forall f0 : elt -> bool, Proper (X.eq ==> eq) f0 -> for_all f0 s = true <-> (forall x : X.t, In x s -> f0 x = true)f:elt -> boolH:Proper (X.eq ==> eq) f(if f a then for_all f s else false) = true <-> (forall x : X.t, In x (a :: s) -> f x = true)f:elt -> boolH:Proper (X.eq ==> eq) fH0:true = truex:X.tH1:In x nilf x = truea:elts:list eltIHs:forall f0 : elt -> bool, Proper (X.eq ==> eq) f0 -> for_all f0 s = true <-> (forall x : X.t, In x s -> f0 x = true)f:elt -> boolH:Proper (X.eq ==> eq) f(if f a then for_all f s else false) = true <-> (forall x : X.t, In x (a :: s) -> f x = true)a:elts:list eltIHs:forall f0 : elt -> bool, Proper (X.eq ==> eq) f0 -> for_all f0 s = true <-> (forall x : X.t, In x s -> f0 x = true)f:elt -> boolH:Proper (X.eq ==> eq) f(if f a then for_all f s else false) = true <-> (forall x : X.t, In x (a :: s) -> f x = true)a:elts:list eltIHs:forall f0 : elt -> bool, Proper (X.eq ==> eq) f0 -> for_all f0 s = true <-> (forall x : X.t, In x s -> f0 x = true)f:elt -> boolH:Proper (X.eq ==> eq) fF:f a = truefor_all f s = true <-> (forall x : X.t, In x (a :: s) -> f x = true)a:elts:list eltIHs:forall f0 : elt -> bool, Proper (X.eq ==> eq) f0 -> for_all f0 s = true <-> (forall x : X.t, In x s -> f0 x = true)f:elt -> boolH:Proper (X.eq ==> eq) fF:f a = falsefalse = true <-> (forall x : X.t, In x (a :: s) -> f x = true)a:elts:list eltIHs:forall f0 : elt -> bool, Proper (X.eq ==> eq) f0 -> for_all f0 s = true <-> (forall x : X.t, In x s -> f0 x = true)f:elt -> boolH:Proper (X.eq ==> eq) fF:f a = true(forall x : X.t, In x s -> f x = true) <-> (forall x : X.t, In x (a :: s) -> f x = true)a:elts:list eltIHs:forall f0 : elt -> bool, Proper (X.eq ==> eq) f0 -> for_all f0 s = true <-> (forall x : X.t, In x s -> f0 x = true)f:elt -> boolH:Proper (X.eq ==> eq) fF:f a = falsefalse = true <-> (forall x : X.t, In x (a :: s) -> f x = true)a:elts:list eltIHs:forall f0 : elt -> bool, Proper (X.eq ==> eq) f0 -> for_all f0 s = true <-> (forall x0 : X.t, In x0 s -> f0 x0 = true)f:elt -> boolH:Proper (X.eq ==> eq) fF:f a = trueH0:forall x0 : X.t, In x0 s -> f x0 = truex:X.tH1:In x (a :: s)f x = truea:elts:list eltIHs:forall f0 : elt -> bool, Proper (X.eq ==> eq) f0 -> for_all f0 s = true <-> (forall x : X.t, In x s -> f0 x = true)f:elt -> boolH:Proper (X.eq ==> eq) fF:f a = falsefalse = true <-> (forall x : X.t, In x (a :: s) -> f x = true)a:elts:list eltIHs:forall f0 : elt -> bool, Proper (X.eq ==> eq) f0 -> for_all f0 s = true <-> (forall x0 : X.t, In x0 s -> f0 x0 = true)f:elt -> boolH:Proper (X.eq ==> eq) fF:f a = trueH0:forall x0 : X.t, In x0 s -> f x0 = truex:X.tH2:X.eq x af x = truea:elts:list eltIHs:forall f0 : elt -> bool, Proper (X.eq ==> eq) f0 -> for_all f0 s = true <-> (forall x : X.t, In x s -> f0 x = true)f:elt -> boolH:Proper (X.eq ==> eq) fF:f a = falsefalse = true <-> (forall x : X.t, In x (a :: s) -> f x = true)a:elts:list eltIHs:forall f0 : elt -> bool, Proper (X.eq ==> eq) f0 -> for_all f0 s = true <-> (forall x : X.t, In x s -> f0 x = true)f:elt -> boolH:Proper (X.eq ==> eq) fF:f a = falsefalse = true <-> (forall x : X.t, In x (a :: s) -> f x = true)a:elts:list eltIHs:forall f0 : elt -> bool, Proper (X.eq ==> eq) f0 -> for_all f0 s = true <-> (forall x : X.t, In x s -> f0 x = true)f:elt -> boolH:Proper (X.eq ==> eq) fF:f a = falseH':false = trueforall x : X.t, In x (a :: s) -> f x = truea:elts:list eltIHs:forall f0 : elt -> bool, Proper (X.eq ==> eq) f0 -> for_all f0 s = true <-> (forall x : X.t, In x s -> f0 x = true)f:elt -> boolH:Proper (X.eq ==> eq) fF:f a = falseH':forall x : X.t, In x (a :: s) -> f x = truefalse = truerewrite H' in F; auto. Qed.a:elts:list eltIHs:forall f0 : elt -> bool, Proper (X.eq ==> eq) f0 -> for_all f0 s = true <-> (forall x : X.t, In x s -> f0 x = true)f:elt -> boolH:Proper (X.eq ==> eq) fF:f a = falseH':forall x : X.t, In x (a :: s) -> f x = truefalse = trueforall (s : t) (f : elt -> bool), Proper (X.eq ==> eq) f -> exists_ f s = true <-> Exists (fun x : elt => f x = true) sforall (s : t) (f : elt -> bool), Proper (X.eq ==> eq) f -> exists_ f s = true <-> Exists (fun x : elt => f x = true) sf:elt -> boolH:Proper (X.eq ==> eq) ffalse = true <-> (exists x : X.t, In x nil /\ f x = true)a:elts:list eltIHs:forall f0 : elt -> bool, Proper (X.eq ==> eq) f0 -> exists_ f0 s = true <-> (exists x : X.t, In x s /\ f0 x = true)f:elt -> boolH:Proper (X.eq ==> eq) f(if f a then true else exists_ f s) = true <-> (exists x : X.t, In x (a :: s) /\ f x = true)f:elt -> boolH:Proper (X.eq ==> eq) fH0:false = trueexists x : X.t, In x nil /\ f x = truef:elt -> boolH:Proper (X.eq ==> eq) fx:X.tH0:In x nilH1:f x = truefalse = truea:elts:list eltIHs:forall f0 : elt -> bool, Proper (X.eq ==> eq) f0 -> exists_ f0 s = true <-> (exists x : X.t, In x s /\ f0 x = true)f:elt -> boolH:Proper (X.eq ==> eq) f(if f a then true else exists_ f s) = true <-> (exists x : X.t, In x (a :: s) /\ f x = true)f:elt -> boolH:Proper (X.eq ==> eq) fx:X.tH0:In x nilH1:f x = truefalse = truea:elts:list eltIHs:forall f0 : elt -> bool, Proper (X.eq ==> eq) f0 -> exists_ f0 s = true <-> (exists x : X.t, In x s /\ f0 x = true)f:elt -> boolH:Proper (X.eq ==> eq) f(if f a then true else exists_ f s) = true <-> (exists x : X.t, In x (a :: s) /\ f x = true)a:elts:list eltIHs:forall f0 : elt -> bool, Proper (X.eq ==> eq) f0 -> exists_ f0 s = true <-> (exists x : X.t, In x s /\ f0 x = true)f:elt -> boolH:Proper (X.eq ==> eq) f(if f a then true else exists_ f s) = true <-> (exists x : X.t, In x (a :: s) /\ f x = true)a:elts:list eltIHs:forall f0 : elt -> bool, Proper (X.eq ==> eq) f0 -> exists_ f0 s = true <-> (exists x : X.t, In x s /\ f0 x = true)f:elt -> boolH:Proper (X.eq ==> eq) fF:f a = truetrue = true <-> (exists x : X.t, In x (a :: s) /\ f x = true)a:elts:list eltIHs:forall f0 : elt -> bool, Proper (X.eq ==> eq) f0 -> exists_ f0 s = true <-> (exists x : X.t, In x s /\ f0 x = true)f:elt -> boolH:Proper (X.eq ==> eq) fF:f a = falseexists_ f s = true <-> (exists x : X.t, In x (a :: s) /\ f x = true)a:elts:list eltIHs:forall f0 : elt -> bool, Proper (X.eq ==> eq) f0 -> exists_ f0 s = true <-> (exists x : X.t, In x s /\ f0 x = true)f:elt -> boolH:Proper (X.eq ==> eq) fF:f a = falseexists_ f s = true <-> (exists x : X.t, In x (a :: s) /\ f x = true)a:elts:list eltIHs:forall f0 : elt -> bool, Proper (X.eq ==> eq) f0 -> exists_ f0 s = true <-> (exists x : X.t, In x s /\ f0 x = true)f:elt -> boolH:Proper (X.eq ==> eq) fF:f a = false(exists x : X.t, In x s /\ f x = true) <-> (exists x : X.t, In x (a :: s) /\ f x = true)a:elts:list eltIHs:forall f0 : elt -> bool, Proper (X.eq ==> eq) f0 -> exists_ f0 s = true <-> (exists x0 : X.t, In x0 s /\ f0 x0 = true)f:elt -> boolH:Proper (X.eq ==> eq) fF:f a = falsex:X.tH0:In x (a :: s)H1:f x = trueexists x0 : X.t, In x0 s /\ f x0 = truea:elts:list eltIHs:forall f0 : elt -> bool, Proper (X.eq ==> eq) f0 -> exists_ f0 s = true <-> (exists x0 : X.t, In x0 s /\ f0 x0 = true)f:elt -> boolH:Proper (X.eq ==> eq) fF:f a = falsex:X.tH1:f x = trueH2:X.eq x aexists x0 : X.t, In x0 s /\ f x0 = truea:elts:list eltIHs:forall f0 : elt -> bool, Proper (X.eq ==> eq) f0 -> exists_ f0 s = true <-> (exists x0 : X.t, In x0 s /\ f0 x0 = true)f:elt -> boolH:Proper (X.eq ==> eq) fF:f a = falsex:X.tH1:f x = trueH2:In x sexists x0 : X.t, In x0 s /\ f x0 = trueexists x; auto. Qed.a:elts:list eltIHs:forall f0 : elt -> bool, Proper (X.eq ==> eq) f0 -> exists_ f0 s = true <-> (exists x0 : X.t, In x0 s /\ f0 x0 = true)f:elt -> boolH:Proper (X.eq ==> eq) fF:f a = falsex:X.tH1:f x = trueH2:In x sexists x0 : X.t, In x0 s /\ f x0 = trueforall (s : t) (f : elt -> bool) (x : elt), Ok s -> Inf x s -> Inf x (fst (partition f s))forall (s : t) (f : elt -> bool) (x : elt), Ok s -> Inf x s -> Inf x (fst (partition f s))forall (s : t) (f : elt -> bool) (x : elt), Sorted X.lt s -> Inf x s -> Inf x (fst (partition f s))s:t(elt -> bool) -> forall x : elt, Sorted X.lt nil -> Inf x nil -> Inf x nils:tforall (a : elt) (l : list elt), (forall (f : elt -> bool) (x : elt), Sorted X.lt l -> Inf x l -> Inf x (fst (partition f l))) -> forall (f : elt -> bool) (x : elt), Sorted X.lt (a :: l) -> Inf x (a :: l) -> Inf x (fst (let (s1, s2) := partition f l in if f a then (a :: s1, s2) else (s1, a :: s2)))s:tforall (a : elt) (l : list elt), (forall (f : elt -> bool) (x : elt), Sorted X.lt l -> Inf x l -> Inf x (fst (partition f l))) -> forall (f : elt -> bool) (x : elt), Sorted X.lt (a :: l) -> Inf x (a :: l) -> Inf x (fst (let (s1, s2) := partition f l in if f a then (a :: s1, s2) else (s1, a :: s2)))s:tx:eltl:list eltHrec:forall (f0 : elt -> bool) (x0 : elt), Sorted X.lt l -> Inf x0 l -> Inf x0 (fst (partition f0 l))f:elt -> boola:eltH:Sorted X.lt lH0:Inf x lH1:X.lt a xInf a (fst (let (s1, s2) := partition f l in if f x then (x :: s1, s2) else (s1, x :: s2)))s:tx:eltl:list eltHrec:forall (f0 : elt -> bool) (x0 : elt), Sorted X.lt l -> Inf x0 l -> Inf x0 (fst (partition f0 l))f:elt -> boola:eltH:Sorted X.lt lH0:Inf x lH1:X.lt a x(Inf a l -> Inf a (fst (partition f l))) -> Inf a (fst (let (s1, s2) := partition f l in if f x then (x :: s1, s2) else (s1, x :: s2)))s:tx:eltl:list eltHrec:forall (f0 : elt -> bool) (x0 : elt), Sorted X.lt l -> Inf x0 l -> Inf x0 (fst (partition f0 l))f:elt -> boola:eltH:Sorted X.lt lH0:Inf x lH1:X.lt a xforall t0 : t, t -> (Inf a l -> Inf a t0) -> Inf a (x :: t0)s:tx:eltl:list eltHrec:forall (f0 : elt -> bool) (x0 : elt), Sorted X.lt l -> Inf x0 l -> Inf x0 (fst (partition f0 l))f:elt -> boola:eltH:Sorted X.lt lH0:Inf x lH1:X.lt a xforall t0 : t, t -> (Inf a l -> Inf a t0) -> Inf a t0intros; apply H2; apply Inf_lt with x; auto. Qed.s:tx:eltl:list eltHrec:forall (f0 : elt -> bool) (x0 : elt), Sorted X.lt l -> Inf x0 l -> Inf x0 (fst (partition f0 l))f:elt -> boola:eltH:Sorted X.lt lH0:Inf x lH1:X.lt a xforall t0 : t, t -> (Inf a l -> Inf a t0) -> Inf a t0forall (s : t) (f : elt -> bool) (x : elt), Ok s -> Inf x s -> Inf x (snd (partition f s))forall (s : t) (f : elt -> bool) (x : elt), Ok s -> Inf x s -> Inf x (snd (partition f s))forall (s : t) (f : elt -> bool) (x : elt), Sorted X.lt s -> Inf x s -> Inf x (snd (partition f s))s:t(elt -> bool) -> forall x : elt, Sorted X.lt nil -> Inf x nil -> Inf x nils:tforall (a : elt) (l : list elt), (forall (f : elt -> bool) (x : elt), Sorted X.lt l -> Inf x l -> Inf x (snd (partition f l))) -> forall (f : elt -> bool) (x : elt), Sorted X.lt (a :: l) -> Inf x (a :: l) -> Inf x (snd (let (s1, s2) := partition f l in if f a then (a :: s1, s2) else (s1, a :: s2)))s:tforall (a : elt) (l : list elt), (forall (f : elt -> bool) (x : elt), Sorted X.lt l -> Inf x l -> Inf x (snd (partition f l))) -> forall (f : elt -> bool) (x : elt), Sorted X.lt (a :: l) -> Inf x (a :: l) -> Inf x (snd (let (s1, s2) := partition f l in if f a then (a :: s1, s2) else (s1, a :: s2)))s:tx:eltl:list eltHrec:forall (f0 : elt -> bool) (x0 : elt), Sorted X.lt l -> Inf x0 l -> Inf x0 (snd (partition f0 l))f:elt -> boola:eltH:Sorted X.lt lH0:Inf x lH1:X.lt a xInf a (snd (let (s1, s2) := partition f l in if f x then (x :: s1, s2) else (s1, x :: s2)))s:tx:eltl:list eltHrec:forall (f0 : elt -> bool) (x0 : elt), Sorted X.lt l -> Inf x0 l -> Inf x0 (snd (partition f0 l))f:elt -> boola:eltH:Sorted X.lt lH0:Inf x lH1:X.lt a x(Inf a l -> Inf a (snd (partition f l))) -> Inf a (snd (let (s1, s2) := partition f l in if f x then (x :: s1, s2) else (s1, x :: s2)))s:tx:eltl:list eltHrec:forall (f0 : elt -> bool) (x0 : elt), Sorted X.lt l -> Inf x0 l -> Inf x0 (snd (partition f0 l))f:elt -> boola:eltH:Sorted X.lt lH0:Inf x lH1:X.lt a xt -> forall t1 : t, (Inf a l -> Inf a t1) -> Inf a t1s:tx:eltl:list eltHrec:forall (f0 : elt -> bool) (x0 : elt), Sorted X.lt l -> Inf x0 l -> Inf x0 (snd (partition f0 l))f:elt -> boola:eltH:Sorted X.lt lH0:Inf x lH1:X.lt a xt -> forall t1 : t, (Inf a l -> Inf a t1) -> Inf a (x :: t1)auto. Qed.s:tx:eltl:list eltHrec:forall (f0 : elt -> bool) (x0 : elt), Sorted X.lt l -> Inf x0 l -> Inf x0 (snd (partition f0 l))f:elt -> boola:eltH:Sorted X.lt lH0:Inf x lH1:X.lt a xt -> forall t1 : t, (Inf a l -> Inf a t1) -> Inf a (x :: t1)s:tf:elt -> boolOk s -> Ok (fst (partition f s))s:tf:elt -> boolOk s -> Ok (fst (partition f s))forall (s : t) (f : elt -> bool), Sorted X.lt s -> Sorted X.lt (fst (partition f s))s:t(elt -> bool) -> Sorted X.lt nil -> Sorted X.lt nils:tforall (a : elt) (l : list elt), (forall f : elt -> bool, Sorted X.lt l -> Sorted X.lt (fst (partition f l))) -> forall f : elt -> bool, Sorted X.lt (a :: l) -> Sorted X.lt (fst (let (s1, s2) := partition f l in if f a then (a :: s1, s2) else (s1, a :: s2)))s:tforall (a : elt) (l : list elt), (forall f : elt -> bool, Sorted X.lt l -> Sorted X.lt (fst (partition f l))) -> forall f : elt -> bool, Sorted X.lt (a :: l) -> Sorted X.lt (fst (let (s1, s2) := partition f l in if f a then (a :: s1, s2) else (s1, a :: s2)))s:tx:eltl:list eltHrec:forall f0 : elt -> bool, Sorted X.lt l -> Sorted X.lt (fst (partition f0 l))f:elt -> boolH:Sorted X.lt lH0:Inf x lSorted X.lt (fst (let (s1, s2) := partition f l in if f x then (x :: s1, s2) else (s1, x :: s2)))case (f x); case (partition f l); simpl; auto. Qed.s:tx:eltl:list eltHrec:forall f0 : elt -> bool, Sorted X.lt l -> Sorted X.lt (fst (partition f0 l))f:elt -> boolH:Sorted X.lt lH0:Inf x l(Ok l -> Inf x l -> Inf x (fst (partition f l))) -> Sorted X.lt (fst (partition f l)) -> Sorted X.lt (fst (let (s1, s2) := partition f l in if f x then (x :: s1, s2) else (s1, x :: s2)))s:tf:elt -> boolOk s -> Ok (snd (partition f s))s:tf:elt -> boolOk s -> Ok (snd (partition f s))forall (s : t) (f : elt -> bool), Sorted X.lt s -> Sorted X.lt (snd (partition f s))s:t(elt -> bool) -> Sorted X.lt nil -> Sorted X.lt nils:tforall (a : elt) (l : list elt), (forall f : elt -> bool, Sorted X.lt l -> Sorted X.lt (snd (partition f l))) -> forall f : elt -> bool, Sorted X.lt (a :: l) -> Sorted X.lt (snd (let (s1, s2) := partition f l in if f a then (a :: s1, s2) else (s1, a :: s2)))s:tforall (a : elt) (l : list elt), (forall f : elt -> bool, Sorted X.lt l -> Sorted X.lt (snd (partition f l))) -> forall f : elt -> bool, Sorted X.lt (a :: l) -> Sorted X.lt (snd (let (s1, s2) := partition f l in if f a then (a :: s1, s2) else (s1, a :: s2)))s:tx:eltl:list eltHrec:forall f0 : elt -> bool, Sorted X.lt l -> Sorted X.lt (snd (partition f0 l))f:elt -> boolH:Sorted X.lt lH0:Inf x lSorted X.lt (snd (let (s1, s2) := partition f l in if f x then (x :: s1, s2) else (s1, x :: s2)))case (f x); case (partition f l); simpl; auto. Qed.s:tx:eltl:list eltHrec:forall f0 : elt -> bool, Sorted X.lt l -> Sorted X.lt (snd (partition f0 l))f:elt -> boolH:Sorted X.lt lH0:Inf x l(Ok l -> Inf x l -> Inf x (snd (partition f l))) -> Sorted X.lt (snd (partition f l)) -> Sorted X.lt (snd (let (s1, s2) := partition f l in if f x then (x :: s1, s2) else (s1, x :: s2)))forall (s : t) (f : elt -> bool), Proper (X.eq ==> eq) f -> Equal (fst (partition f s)) (filter f s)forall (s : t) (f : elt -> bool), Proper (X.eq ==> eq) f -> Equal (fst (partition f s)) (filter f s)s:tforall f : elt -> bool, Proper (X.eq ==> eq) f -> forall a : elt, In a nil <-> In a nils:tforall (a : elt) (l : list elt), (forall f : elt -> bool, Proper (X.eq ==> eq) f -> forall a0 : elt, In a0 (fst (partition f l)) <-> In a0 (filter f l)) -> forall f : elt -> bool, Proper (X.eq ==> eq) f -> forall a0 : elt, In a0 (fst (let (s1, s2) := partition f l in if f a then (a :: s1, s2) else (s1, a :: s2))) <-> In a0 (if f a then a :: filter f l else filter f l)s:tforall (a : elt) (l : list elt), (forall f : elt -> bool, Proper (X.eq ==> eq) f -> forall a0 : elt, In a0 (fst (partition f l)) <-> In a0 (filter f l)) -> forall f : elt -> bool, Proper (X.eq ==> eq) f -> forall a0 : elt, In a0 (fst (let (s1, s2) := partition f l in if f a then (a :: s1, s2) else (s1, a :: s2))) <-> In a0 (if f a then a :: filter f l else filter f l)s:tx:eltl:list eltHrec:forall f0 : elt -> bool, Proper (X.eq ==> eq) f0 -> forall a : elt, In a (fst (partition f0 l)) <-> In a (filter f0 l)f:elt -> boolHf:Proper (X.eq ==> eq) fforall a : elt, In a (fst (let (s1, s2) := partition f l in if f x then (x :: s1, s2) else (s1, x :: s2))) <-> In a (if f x then x :: filter f l else filter f l)s:tx:eltl:list eltf:elt -> boolHf:Proper (X.eq ==> eq) f(forall a : elt, In a (fst (partition f l)) <-> In a (filter f l)) -> forall a : elt, In a (fst (let (s1, s2) := partition f l in if f x then (x :: s1, s2) else (s1, x :: s2))) <-> In a (if f x then x :: filter f l else filter f l)s:tx:eltl:list eltf:elt -> boolHf:Proper (X.eq ==> eq) fs1, s2:tH:forall a0 : elt, In a0 s1 <-> In a0 (filter f l)a:eltIn a (fst (if f x then (x :: s1, s2) else (s1, x :: s2))) <-> In a (if f x then x :: filter f l else filter f l)s:tx:eltl:list eltf:elt -> boolHf:Proper (X.eq ==> eq) fs1, s2:tH:forall a0 : elt, In a0 s1 <-> In a0 (filter f l)a:eltIn a (x :: s1) <-> In a (x :: filter f l)s:tx:eltl:list eltf:elt -> boolHf:Proper (X.eq ==> eq) fs1, s2:tH:forall a0 : elt, In a0 s1 <-> In a0 (filter f l)a:eltH1:In a s1In a (x :: filter f l)s:tx:eltl:list eltf:elt -> boolHf:Proper (X.eq ==> eq) fs1, s2:tH:forall a0 : elt, In a0 s1 <-> In a0 (filter f l)a:eltH1:In a (filter f l)In a (x :: s1)constructor 2; rewrite H; auto. Qed.s:tx:eltl:list eltf:elt -> boolHf:Proper (X.eq ==> eq) fs1, s2:tH:forall a0 : elt, In a0 s1 <-> In a0 (filter f l)a:eltH1:In a (filter f l)In a (x :: s1)forall (s : t) (f : elt -> bool), Proper (X.eq ==> eq) f -> Equal (snd (partition f s)) (filter (fun x : elt => negb (f x)) s)forall (s : t) (f : elt -> bool), Proper (X.eq ==> eq) f -> Equal (snd (partition f s)) (filter (fun x : elt => negb (f x)) s)s:tforall f : elt -> bool, Proper (X.eq ==> eq) f -> forall a : elt, In a nil <-> In a nils:tforall (a : elt) (l : list elt), (forall f : elt -> bool, Proper (X.eq ==> eq) f -> forall a0 : elt, In a0 (snd (partition f l)) <-> In a0 (filter (fun x : elt => negb (f x)) l)) -> forall f : elt -> bool, Proper (X.eq ==> eq) f -> forall a0 : elt, In a0 (snd (let (s1, s2) := partition f l in if f a then (a :: s1, s2) else (s1, a :: s2))) <-> In a0 (if negb (f a) then a :: filter (fun x : elt => negb (f x)) l else filter (fun x : elt => negb (f x)) l)s:tforall (a : elt) (l : list elt), (forall f : elt -> bool, Proper (X.eq ==> eq) f -> forall a0 : elt, In a0 (snd (partition f l)) <-> In a0 (filter (fun x : elt => negb (f x)) l)) -> forall f : elt -> bool, Proper (X.eq ==> eq) f -> forall a0 : elt, In a0 (snd (let (s1, s2) := partition f l in if f a then (a :: s1, s2) else (s1, a :: s2))) <-> In a0 (if negb (f a) then a :: filter (fun x : elt => negb (f x)) l else filter (fun x : elt => negb (f x)) l)s:tx:eltl:list eltHrec:forall f0 : elt -> bool, Proper (X.eq ==> eq) f0 -> forall a : elt, In a (snd (partition f0 l)) <-> In a (filter (fun x0 : elt => negb (f0 x0)) l)f:elt -> boolHf:Proper (X.eq ==> eq) fforall a : elt, In a (snd (let (s1, s2) := partition f l in if f x then (x :: s1, s2) else (s1, x :: s2))) <-> In a (if negb (f x) then x :: filter (fun x0 : elt => negb (f x0)) l else filter (fun x0 : elt => negb (f x0)) l)s:tx:eltl:list eltf:elt -> boolHf:Proper (X.eq ==> eq) f(forall a : elt, In a (snd (partition f l)) <-> In a (filter (fun x0 : elt => negb (f x0)) l)) -> forall a : elt, In a (snd (let (s1, s2) := partition f l in if f x then (x :: s1, s2) else (s1, x :: s2))) <-> In a (if negb (f x) then x :: filter (fun x0 : elt => negb (f x0)) l else filter (fun x0 : elt => negb (f x0)) l)s:tx:eltl:list eltf:elt -> boolHf:Proper (X.eq ==> eq) fs1, s2:tH:forall a0 : elt, In a0 s2 <-> In a0 (filter (fun x0 : elt => negb (f x0)) l)a:eltIn a (snd (if f x then (x :: s1, s2) else (s1, x :: s2))) <-> In a (if negb (f x) then x :: filter (fun x0 : elt => negb (f x0)) l else filter (fun x0 : elt => negb (f x0)) l)s:tx:eltl:list eltf:elt -> boolHf:Proper (X.eq ==> eq) fs1, s2:tH:forall a0 : elt, In a0 s2 <-> In a0 (filter (fun x0 : elt => negb (f x0)) l)a:eltIn a (x :: s2) <-> In a (x :: filter (fun x0 : elt => negb (f x0)) l)s:tx:eltl:list eltf:elt -> boolHf:Proper (X.eq ==> eq) fs1, s2:tH:forall a0 : elt, In a0 s2 <-> In a0 (filter (fun x0 : elt => negb (f x0)) l)a:eltH1:In a s2In a (x :: filter (fun x0 : elt => negb (f x0)) l)s:tx:eltl:list eltf:elt -> boolHf:Proper (X.eq ==> eq) fs1, s2:tH:forall a0 : elt, In a0 s2 <-> In a0 (filter (fun x0 : elt => negb (f x0)) l)a:eltH1:In a (filter (fun x0 : elt => negb (f x0)) l)In a (x :: s2)constructor 2; rewrite H; auto. Qed. End ForNotations. Definition In := InA X.eq.s:tx:eltl:list eltf:elt -> boolHf:Proper (X.eq ==> eq) fs1, s2:tH:forall a0 : elt, In a0 s2 <-> In a0 (filter (fun x0 : elt => negb (f x0)) l)a:eltH1:In a (filter (fun x0 : elt => negb (f x0)) l)In a (x :: s2)Proper (X.eq ==> eq ==> iff) Inrepeat red; intros; rewrite H, H0; auto. Qed. Module L := MakeListOrdering X. Definition eq := L.eq. Definition eq_equiv := L.eq_equiv. Definition lt l1 l2 := exists l1' l2', Ok l1' /\ Ok l2' /\ eq l1 l1' /\ eq l2 l2' /\ L.lt l1' l2'.Proper (X.eq ==> eq ==> iff) InStrictOrder ltStrictOrder ltIrreflexive ltTransitive lts:list X.ts1, s2:tB1:Ok s1B2:Ok s2E1:eq s s1E2:eq s s2L:L.lt s1 s2FalseTransitive lts:list X.ts1, s2:tB1:Sorted X.lt s1B2:Sorted X.lt s2E1:eq s s1E2:eq s s2L:L.lt s1 s2FalseTransitive lts:list X.ts1, s2:tB1:Sorted X.lt s1B2:Sorted X.lt s2E1:eq s s1E2:eq s s2L:L.lt s1 s2eqlistA X.eq s1 s2s:list X.ts1, s2:tB1:Sorted X.lt s1B2:Sorted X.lt s2E1:eq s s1E2:eq s s2L:L.lt s1 s2H:eqlistA X.eq s1 s2FalseTransitive lts:list X.ts1, s2:tB1:Sorted X.lt s1B2:Sorted X.lt s2E1:eq s s1E2:eq s s2L:L.lt s1 s2equivlistA X.eq s1 s2s:list X.ts1, s2:tB1:Sorted X.lt s1B2:Sorted X.lt s2E1:eq s s1E2:eq s s2L:L.lt s1 s2H:eqlistA X.eq s1 s2FalseTransitive lts:list X.ts1, s2:tB1:Sorted X.lt s1B2:Sorted X.lt s2E1:eq s s1E2:eq s s2L:L.lt s1 s2equivlistA X.eq s1 ss:list X.ts1, s2:tB1:Sorted X.lt s1B2:Sorted X.lt s2E1:eq s s1E2:eq s s2L:L.lt s1 s2H:eqlistA X.eq s1 s2FalseTransitive lts:list X.ts1, s2:tB1:Sorted X.lt s1B2:Sorted X.lt s2E1:eq s s1E2:eq s s2L:L.lt s1 s2H:eqlistA X.eq s1 s2FalseTransitive lts:list X.ts1, s2:tB1:Sorted X.lt s1B2:Sorted X.lt s2E1:eq s s1E2:eq s s2L:L.lt s2 s2H:eqlistA X.eq s1 s2FalseTransitive ltTransitive lts1, s2, s3:list X.ts1', s2':tB1:Ok s1'B2:Ok s2'E1:eq s1 s1'E2:eq s2 s2'L12:L.lt s1' s2's2'', s3':tB2':Ok s2''B3:Ok s3'E2':eq s2 s2''E3:eq s3 s3'L23:L.lt s2'' s3'lt s1 s3s1, s2, s3:list X.ts1', s2':tB1:Ok s1'B2:Ok s2'E1:eq s1 s1'E2:eq s2 s2'L12:L.lt s1' s2's2'', s3':tB2':Ok s2''B3:Ok s3'E2':eq s2 s2''E3:eq s3 s3'L23:L.lt s2'' s3'Ok s1' /\ Ok s3' /\ eq s1 s1' /\ eq s3 s3' /\ L.lt s1' s3's1, s2, s3:list X.ts1', s2':tB1:Sorted X.lt s1'B2:Sorted X.lt s2'E1:eq s1 s1'E2:eq s2 s2'L12:L.lt s1' s2's2'', s3':tB2':Sorted X.lt s2''B3:Sorted X.lt s3'E2':eq s2 s2''E3:eq s3 s3'L23:L.lt s2'' s3'Sorted X.lt s1' /\ Sorted X.lt s3' /\ eq s1 s1' /\ eq s3 s3' /\ L.lt s1' s3's1, s2, s3:list X.ts1', s2':tB1:Sorted X.lt s1'B2:Sorted X.lt s2'E1:eq s1 s1'E2:eq s2 s2'L12:L.lt s1' s2's2'', s3':tB2':Sorted X.lt s2''B3:Sorted X.lt s3'E2':eq s2 s2''E3:eq s3 s3'L23:L.lt s2'' s3'L.lt s1' s3's1, s2, s3:list X.ts1', s2':tB1:Sorted X.lt s1'B2:Sorted X.lt s2'E1:eq s1 s1'E2:eq s2 s2'L12:L.lt s1' s2's2'', s3':tB2':Sorted X.lt s2''B3:Sorted X.lt s3'E2':eq s2 s2''E3:eq s3 s3'L23:L.lt s2'' s3'eqlistA X.eq s2' s2''s1, s2, s3:list X.ts1', s2':tB1:Sorted X.lt s1'B2:Sorted X.lt s2'E1:eq s1 s1'E2:eq s2 s2'L12:L.lt s1' s2's2'', s3':tB2':Sorted X.lt s2''B3:Sorted X.lt s3'E2':eq s2 s2''E3:eq s3 s3'L23:L.lt s2'' s3'H:eqlistA X.eq s2' s2''L.lt s1' s3's1, s2, s3:list X.ts1', s2':tB1:Sorted X.lt s1'B2:Sorted X.lt s2'E1:eq s1 s1'E2:eq s2 s2'L12:L.lt s1' s2's2'', s3':tB2':Sorted X.lt s2''B3:Sorted X.lt s3'E2':eq s2 s2''E3:eq s3 s3'L23:L.lt s2'' s3'equivlistA X.eq s2' s2''s1, s2, s3:list X.ts1', s2':tB1:Sorted X.lt s1'B2:Sorted X.lt s2'E1:eq s1 s1'E2:eq s2 s2'L12:L.lt s1' s2's2'', s3':tB2':Sorted X.lt s2''B3:Sorted X.lt s3'E2':eq s2 s2''E3:eq s3 s3'L23:L.lt s2'' s3'H:eqlistA X.eq s2' s2''L.lt s1' s3's1, s2, s3:list X.ts1', s2':tB1:Sorted X.lt s1'B2:Sorted X.lt s2'E1:eq s1 s1'E2:eq s2 s2'L12:L.lt s1' s2's2'', s3':tB2':Sorted X.lt s2''B3:Sorted X.lt s3'E2':eq s2 s2''E3:eq s3 s3'L23:L.lt s2'' s3'equivlistA X.eq s2' s2s1, s2, s3:list X.ts1', s2':tB1:Sorted X.lt s1'B2:Sorted X.lt s2'E1:eq s1 s1'E2:eq s2 s2'L12:L.lt s1' s2's2'', s3':tB2':Sorted X.lt s2''B3:Sorted X.lt s3'E2':eq s2 s2''E3:eq s3 s3'L23:L.lt s2'' s3'H:eqlistA X.eq s2' s2''L.lt s1' s3's1, s2, s3:list X.ts1', s2':tB1:Sorted X.lt s1'B2:Sorted X.lt s2'E1:eq s1 s1'E2:eq s2 s2'L12:L.lt s1' s2's2'', s3':tB2':Sorted X.lt s2''B3:Sorted X.lt s3'E2':eq s2 s2''E3:eq s3 s3'L23:L.lt s2'' s3'H:eqlistA X.eq s2' s2''L.lt s1' s3'rewrite H; auto. Qed.s1, s2, s3:list X.ts1', s2':tB1:Sorted X.lt s1'B2:Sorted X.lt s2'E1:eq s1 s1'E2:eq s2 s2'L12:L.lt s1' s2's2'', s3':tB2':Sorted X.lt s2''B3:Sorted X.lt s3'E2':eq s2 s2''E3:eq s3 s3'L23:L.lt s2'' s3'H:eqlistA X.eq s2' s2''L.lt s2' s3'Proper (eq ==> eq ==> iff) ltProper (eq ==> eq ==> iff) lts1, s2:list X.tE12:eq s1 s2s3, s4:list X.tE34:eq s3 s4lt s1 s3 <-> lt s2 s4s1, s2:list X.tE12:eq s1 s2s3, s4:list X.tE34:eq s3 s4lt s1 s3 -> lt s2 s4s1, s2:list X.tE12:eq s1 s2s3, s4:list X.tE34:eq s3 s4lt s2 s4 -> lt s1 s3s1, s2:list X.tE12:eq s1 s2s3, s4:list X.tE34:eq s3 s4s1', s3':tB1:Ok s1'B3:Ok s3'E1:eq s1 s1'E3:eq s3 s3'LT:L.lt s1' s3'lt s2 s4s1, s2:list X.tE12:eq s1 s2s3, s4:list X.tE34:eq s3 s4lt s2 s4 -> lt s1 s3s1, s2:list X.tE12:eq s1 s2s3, s4:list X.tE34:eq s3 s4s1', s3':tB1:Ok s1'B3:Ok s3'E1:eq s1 s1'E3:eq s3 s3'LT:L.lt s1' s3'eq s2 s1' /\ eq s4 s3' /\ L.lt s1' s3's1, s2:list X.tE12:eq s1 s2s3, s4:list X.tE34:eq s3 s4lt s2 s4 -> lt s1 s3s1, s2:list X.tE12:eq s1 s2s3, s4:list X.tE34:eq s3 s4s1', s3':tB1:Ok s1'B3:Ok s3'E1:eq s1 s1'E3:eq s3 s3'LT:L.lt s1' s3'eq s2 s1's1, s2:list X.tE12:eq s1 s2s3, s4:list X.tE34:eq s3 s4s1', s3':tB1:Ok s1'B3:Ok s3'E1:eq s1 s1'E3:eq s3 s3'LT:L.lt s1' s3'eq s4 s3' /\ L.lt s1' s3's1, s2:list X.tE12:eq s1 s2s3, s4:list X.tE34:eq s3 s4lt s2 s4 -> lt s1 s3s1, s2:list X.tE12:eq s1 s2s3, s4:list X.tE34:eq s3 s4s1', s3':tB1:Ok s1'B3:Ok s3'E1:eq s1 s1'E3:eq s3 s3'LT:L.lt s1' s3'eq s2 s1s1, s2:list X.tE12:eq s1 s2s3, s4:list X.tE34:eq s3 s4s1', s3':tB1:Ok s1'B3:Ok s3'E1:eq s1 s1'E3:eq s3 s3'LT:L.lt s1' s3'eq s4 s3' /\ L.lt s1' s3's1, s2:list X.tE12:eq s1 s2s3, s4:list X.tE34:eq s3 s4lt s2 s4 -> lt s1 s3s1, s2:list X.tE12:eq s1 s2s3, s4:list X.tE34:eq s3 s4s1', s3':tB1:Ok s1'B3:Ok s3'E1:eq s1 s1'E3:eq s3 s3'LT:L.lt s1' s3'eq s4 s3' /\ L.lt s1' s3's1, s2:list X.tE12:eq s1 s2s3, s4:list X.tE34:eq s3 s4lt s2 s4 -> lt s1 s3s1, s2:list X.tE12:eq s1 s2s3, s4:list X.tE34:eq s3 s4s1', s3':tB1:Ok s1'B3:Ok s3'E1:eq s1 s1'E3:eq s3 s3'LT:L.lt s1' s3'eq s4 s3's1, s2:list X.tE12:eq s1 s2s3, s4:list X.tE34:eq s3 s4lt s2 s4 -> lt s1 s3s1, s2:list X.tE12:eq s1 s2s3, s4:list X.tE34:eq s3 s4s1', s3':tB1:Ok s1'B3:Ok s3'E1:eq s1 s1'E3:eq s3 s3'LT:L.lt s1' s3'eq s4 s3s1, s2:list X.tE12:eq s1 s2s3, s4:list X.tE34:eq s3 s4lt s2 s4 -> lt s1 s3s1, s2:list X.tE12:eq s1 s2s3, s4:list X.tE34:eq s3 s4lt s2 s4 -> lt s1 s3s1, s2:list X.tE12:eq s1 s2s3, s4:list X.tE34:eq s3 s4s1', s3':tB1:Ok s1'B3:Ok s3'E1:eq s2 s1'E3:eq s4 s3'LT:L.lt s1' s3'lt s1 s3s1, s2:list X.tE12:eq s1 s2s3, s4:list X.tE34:eq s3 s4s1', s3':tB1:Ok s1'B3:Ok s3'E1:eq s2 s1'E3:eq s4 s3'LT:L.lt s1' s3'eq s1 s1' /\ eq s3 s3' /\ L.lt s1' s3's1, s2:list X.tE12:eq s1 s2s3, s4:list X.tE34:eq s3 s4s1', s3':tB1:Ok s1'B3:Ok s3'E1:eq s2 s1'E3:eq s4 s3'LT:L.lt s1' s3'eq s1 s1's1, s2:list X.tE12:eq s1 s2s3, s4:list X.tE34:eq s3 s4s1', s3':tB1:Ok s1'B3:Ok s3'E1:eq s2 s1'E3:eq s4 s3'LT:L.lt s1' s3'eq s3 s3' /\ L.lt s1' s3's1, s2:list X.tE12:eq s1 s2s3, s4:list X.tE34:eq s3 s4s1', s3':tB1:Ok s1'B3:Ok s3'E1:eq s2 s1'E3:eq s4 s3'LT:L.lt s1' s3'eq s3 s3' /\ L.lt s1' s3'transitivity s4; auto. Qed.s1, s2:list X.tE12:eq s1 s2s3, s4:list X.tE34:eq s3 s4s1', s3':tB1:Ok s1'B3:Ok s3'E1:eq s2 s1'E3:eq s4 s3'LT:L.lt s1' s3'eq s3 s3'forall s s' : list X.t, CompSpec eq L.lt s s' (compare s s')forall s s' : list X.t, CompSpec eq L.lt s s' (compare s s')elim_compare x x'; auto. Qed.x:X.ts:list X.tIH:forall s'0 : list X.t, CompSpec eq L.lt s s'0 (compare s s'0)x':X.ts':list X.tCompSpec eq L.lt (x :: s) (x' :: s') match X.compare x x' with | Eq => compare s s' | Lt => Lt | Gt => Gt endforall s s' : t, Ok s -> Ok s' -> CompSpec eq lt s s' (compare s s')forall s s' : t, Ok s -> Ok s' -> CompSpec eq lt s s' (compare s s')s, s':tHs:Ok sHs':Ok s'CompSpec eq lt s s' (compare s s')s, s':tHs:Ok sHs':Ok s'H:L.lt s s'lt s s's, s':tHs:Ok sHs':Ok s'H:L.lt s' slt s' sexists s', s; repeat split; auto using @ok. Qed. End MakeRaw.s, s':tHs:Ok sHs':Ok s'H:L.lt s' slt s' s
Encapsulation
Module Make (X: OrderedType) <: S with Module E := X. Module Raw := MakeRaw X. Include Raw2Sets X Raw. End Make.
For this specific implementation, eq coincides with Leibniz equality
Require Eqdep_dec. Module Type OrderedTypeWithLeibniz. Include OrderedType. Parameter eq_leibniz : forall x y, eq x y -> x = y. End OrderedTypeWithLeibniz. Module Type SWithLeibniz. Declare Module E : OrderedTypeWithLeibniz. Include SetsOn E. Parameter eq_leibniz : forall x y, eq x y -> x = y. End SWithLeibniz. Module MakeWithLeibniz (X: OrderedTypeWithLeibniz) <: SWithLeibniz with Module E := X. Module E := X. Module Raw := MakeRaw X. Include Raw2SetsOn X Raw.forall xs ys : list X.t, eqlistA X.eq xs ys -> xs = ysforall xs ys : list X.t, eqlistA X.eq xs ys -> xs = ysH:eqlistA X.eq nil nilnil = nilx:X.txs:list X.tIHxs:forall ys0 : list X.t, eqlistA X.eq xs ys0 -> xs = ys0y:X.tys:list X.tH:eqlistA X.eq (x :: xs) (y :: ys)x0, x':X.tl, l':list X.tH3:X.eq x yH5:eqlistA X.eq xs ysH0:x0 = xH1:l = xsH2:x' = yH4:l' = ysx :: xs = y :: ysx:X.txs:list X.tIHxs:forall ys0 : list X.t, eqlistA X.eq xs ys0 -> xs = ys0y:X.tys:list X.tH:eqlistA X.eq (x :: xs) (y :: ys)x0, x':X.tl, l':list X.tH3:X.eq x yH5:eqlistA X.eq xs ysH0:x0 = xH1:l = xsH2:x' = yH4:l' = ysx :: xs = y :: ysx:X.txs:list X.tIHxs:forall ys0 : list X.t, eqlistA X.eq xs ys0 -> xs = ys0y:X.tys:list X.tH:eqlistA X.eq (x :: xs) (y :: ys)x0, x':X.tl, l':list X.tH3:X.eq x yH5:eqlistA X.eq xs ysH0:x0 = xH1:l = xsH2:x' = yH4:l' = ysx = yx:X.txs:list X.tIHxs:forall ys0 : list X.t, eqlistA X.eq xs ys0 -> xs = ys0y:X.tys:list X.tH:eqlistA X.eq (x :: xs) (y :: ys)x0, x':X.tl, l':list X.tH3:X.eq x yH5:eqlistA X.eq xs ysH0:x0 = xH1:l = xsH2:x' = yH4:l' = ysxs = ysapply IHxs; subst; assumption. Qed.x:X.txs:list X.tIHxs:forall ys0 : list X.t, eqlistA X.eq xs ys0 -> xs = ys0y:X.tys:list X.tH:eqlistA X.eq (x :: xs) (y :: ys)x0, x':X.tl, l':list X.tH3:X.eq x yH5:eqlistA X.eq xs ysH0:x0 = xH1:l = xsH2:x' = yH4:l' = ysxs = ysforall s s' : t, eq s s' -> s = s'forall s s' : t, eq s s' -> s = s'xs:Raw.tHxs:Raw.Ok xsys:Raw.tHys:Raw.Ok ysHeq:eq {| this := xs; is_ok := Hxs |} {| this := ys; is_ok := Hys |}{| this := xs; is_ok := Hxs |} = {| this := ys; is_ok := Hys |}xs:Raw.tHxs:Raw.Ok xsys:Raw.tHys:Raw.Ok ysHeq:equivlistA X.eq xs ys{| this := xs; is_ok := Hxs |} = {| this := ys; is_ok := Hys |}xs:Raw.tHxs:Raw.Ok xsys:Raw.tHys:Raw.Ok ysHeq:equivlistA X.eq xs yseqlistA X.eq xs ysxs:Raw.tHxs:Raw.Ok xsys:Raw.tHys:Raw.Ok ysHeq:equivlistA X.eq xs ysH:eqlistA X.eq xs ys{| this := xs; is_ok := Hxs |} = {| this := ys; is_ok := Hys |}xs:Raw.tHxs:Sorted X.lt xsys:Raw.tHys:Sorted X.lt ysHeq:equivlistA X.eq xs yseqlistA X.eq xs ysxs:Raw.tHxs:Raw.Ok xsys:Raw.tHys:Raw.Ok ysHeq:equivlistA X.eq xs ysH:eqlistA X.eq xs ys{| this := xs; is_ok := Hxs |} = {| this := ys; is_ok := Hys |}xs:Raw.tHxs:Raw.Ok xsys:Raw.tHys:Raw.Ok ysHeq:equivlistA X.eq xs ysH:eqlistA X.eq xs ys{| this := xs; is_ok := Hxs |} = {| this := ys; is_ok := Hys |}xs:Raw.tHxs:Raw.Ok xsys:Raw.tHys:Raw.Ok ysHeq:equivlistA X.eq xs ysH:xs = ys{| this := xs; is_ok := Hxs |} = {| this := ys; is_ok := Hys |}xs:Raw.tHxs:Raw.Ok xsHeq:equivlistA X.eq xs xsHys:Raw.Ok xs{| this := xs; is_ok := Hxs |} = {| this := xs; is_ok := Hys |}xs:Raw.tHxs:Raw.Ok xsHeq:equivlistA X.eq xs xsHys:Raw.Ok xsHxs = Hysintros x y; destruct (bool_dec x y); tauto. Qed. End MakeWithLeibniz.xs:Raw.tHxs:Raw.Ok xsHeq:equivlistA X.eq xs xsHys:Raw.Ok xsforall x y : bool, x = y \/ x <> y