Built with Alectryon, running Coq+SerAPI v8.10.0+0.7.0. Coq sources are in this panel; goals and messages will appear in the other. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑ Ctrl+↓ to navigate, Ctrl+🖱️ to focus.
(************************************************************************) (* * The Coq Proof Assistant / The Coq Development Team *) (* v * INRIA, CNRS and contributors - Copyright 1999-2018 *) (* <O___,, * (see CREDITS file for the list of authors) *) (* \VV/ **************************************************************) (* // * This file is distributed under the terms of the *) (* * GNU Lesser General Public License Version 2.1 *) (* * (see LICENSE file for the text of the license) *) (************************************************************************) Require Import Le. Require Import Lt. Local Open Scope nat_scope. Implicit Types k l p q r : nat. Section Between. Variables P Q : nat -> Prop.
The between type expresses the concept
∀ i: nat, k ≤ i < l → P i..
Inductive between k : nat -> Prop := | bet_emp : between k k | bet_S : forall l, between k l -> P l -> between k (S l). Hint Constructors between: arith.P, Q:nat -> Propforall k l : nat, l = k -> between k lintros * ->; auto with arith. Qed. Hint Resolve bet_eq: arith.P, Q:nat -> Propforall k l : nat, l = k -> between k lP, Q:nat -> Propforall k l : nat, between k l -> k <= linduction 1; auto with arith. Qed. Hint Immediate between_le: arith.P, Q:nat -> Propforall k l : nat, between k l -> k <= lP, Q:nat -> Propforall k l : nat, between k l -> S k <= l -> between (S k) linduction 1 as [|* [|]]; auto with arith. Qed. Hint Resolve between_Sk_l: arith.P, Q:nat -> Propforall k l : nat, between k l -> S k <= l -> between (S k) lP, Q:nat -> Propforall k l m : nat, k <= l -> l <= m -> between k m -> between l minduction 1; auto with arith. Qed.P, Q:nat -> Propforall k l m : nat, k <= l -> l <= m -> between k m -> between l m
The exists_between type expresses the concept
∃ i: nat, k ≤ i < l ∧ Q i.
Inductive exists_between k : nat -> Prop := | exists_S : forall l, exists_between k l -> exists_between k (S l) | exists_le : forall l, k <= l -> Q l -> exists_between k (S l). Hint Constructors exists_between: arith.P, Q:nat -> Propforall k l : nat, exists_between k l -> S k <= linduction 1; auto with arith. Qed.P, Q:nat -> Propforall k l : nat, exists_between k l -> S k <= lProof exists_le_S. Hint Immediate exists_le_S exists_lt: arith.P, Q:nat -> Propforall k l : nat, exists_between k l -> k < lP, Q:nat -> Propforall k l : nat, exists_between k (S l) -> k <= lintros; apply le_S_n; auto with arith. Qed. Hint Immediate exists_S_le: arith. Definition in_int p q r := p <= r /\ r < q.P, Q:nat -> Propforall k l : nat, exists_between k (S l) -> k <= lP, Q:nat -> Propforall p q r : nat, p <= r -> r < q -> in_int p q rsplit; assumption. Qed. Hint Resolve in_int_intro: arith.P, Q:nat -> Propforall p q r : nat, p <= r -> r < q -> in_int p q rP, Q:nat -> Propforall p q r : nat, in_int p q r -> p < qP, Q:nat -> Propforall p q r : nat, in_int p q r -> p < qeapply le_lt_trans; eassumption. Qed.P, Q:nat -> Propp, q, r:natH:p <= rH0:r < qp < qP, Q:nat -> Propforall p q r : nat, in_int p (S q) r -> in_int p q r \/ r = qP, Q:nat -> Propforall p q r : nat, in_int p (S q) r -> in_int p q r \/ r = qdestruct (le_lt_or_eq r q); auto with arith. Qed.P, Q:nat -> Propp, q, r:natH:p <= rH0:r < S qin_int p q r \/ r = qP, Q:nat -> Propforall p q r : nat, in_int p q r -> in_int p (S q) rintros * []; auto with arith. Qed. Hint Resolve in_int_S: arith.P, Q:nat -> Propforall p q r : nat, in_int p q r -> in_int p (S q) rP, Q:nat -> Propforall p q r : nat, in_int (S p) q r -> in_int p q rintros * []; auto with arith. Qed. Hint Immediate in_int_Sp_q: arith.P, Q:nat -> Propforall p q r : nat, in_int (S p) q r -> in_int p q rP, Q:nat -> Propforall k l : nat, between k l -> forall r : nat, in_int k l r -> P rP, Q:nat -> Propforall k l : nat, between k l -> forall r : nat, in_int k l r -> P rP, Q:nat -> Propk, r:natH:in_int k k rP rP, Q:nat -> Propk, l:natH:between k lH0:P lIHbetween:forall r0 : nat, in_int k l r0 -> P r0r:natH1:in_int k (S l) rP rP, Q:nat -> Propk, r:natH:in_int k k rP rP, Q:nat -> Propk, r:natH:in_int k k r~ k < kP, Q:nat -> Propk, r:natH:in_int k k rk < kauto with arith.P, Q:nat -> Propk, r:natH:in_int k k r~ k < keapply in_int_lt; eassumption.P, Q:nat -> Propk, r:natH:in_int k k rk < kdestruct (in_int_p_Sq k l r) as [| ->]; auto with arith. Qed.P, Q:nat -> Propk, l:natH:between k lH0:P lIHbetween:forall r0 : nat, in_int k l r0 -> P r0r:natH1:in_int k (S l) rP rP, Q:nat -> Propforall k l : nat, k <= l -> (forall r : nat, in_int k l r -> P r) -> between k linduction 1; auto with arith. Qed.P, Q:nat -> Propforall k l : nat, k <= l -> (forall r : nat, in_int k l r -> P r) -> between k lP, Q:nat -> Propforall k l : nat, exists_between k l -> exists2 m : nat, in_int k l m & Q mP, Q:nat -> Propforall k l : nat, exists_between k l -> exists2 m : nat, in_int k l m & Q mP, Q:nat -> Propk, l:natH:exists_between k lp:natH0:in_int k l pH1:Q pexists2 m : nat, in_int k (S l) m & Q mP, Q:nat -> Propk, l:natH:k <= lH0:Q lexists2 m : nat, in_int k (S l) m & Q mexists p; auto with arith.P, Q:nat -> Propk, l:natH:exists_between k lp:natH0:in_int k l pH1:Q pexists2 m : nat, in_int k (S l) m & Q mexists l; auto with arith. Qed.P, Q:nat -> Propk, l:natH:k <= lH0:Q lexists2 m : nat, in_int k (S l) m & Q mP, Q:nat -> Propforall k l r : nat, in_int k l r -> Q r -> exists_between k lP, Q:nat -> Propforall k l r : nat, in_int k l r -> Q r -> exists_between k linduction lt_r_l; auto with arith. Qed.P, Q:nat -> Propk, l, r:natH:k <= rlt_r_l:r < lH0:Q rexists_between k lP, Q:nat -> Propforall k l : nat, k <= l -> (forall n : nat, in_int k l n -> P n \/ Q n) -> between k l \/ exists_between k lP, Q:nat -> Propforall k l : nat, k <= l -> (forall n : nat, in_int k l n -> P n \/ Q n) -> between k l \/ exists_between k lP, Q:nat -> Propk:nat(forall n : nat, in_int k k n -> P n \/ Q n) -> between k k \/ exists_between k kP, Q:nat -> Propk, m:natH:k <= mIHle:(forall n : nat, in_int k m n -> P n \/ Q n) -> between k m \/ exists_between k m(forall n : nat, in_int k (S m) n -> P n \/ Q n) -> between k (S m) \/ exists_between k (S m)auto with arith.P, Q:nat -> Propk:nat(forall n : nat, in_int k k n -> P n \/ Q n) -> between k k \/ exists_between k kP, Q:nat -> Propk, m:natH:k <= mIHle:(forall n : nat, in_int k m n -> P n \/ Q n) -> between k m \/ exists_between k m(forall n : nat, in_int k (S m) n -> P n \/ Q n) -> between k (S m) \/ exists_between k (S m)P, Q:nat -> Propk, m:natH:k <= mIHle:(forall n : nat, in_int k m n -> P n \/ Q n) -> between k m \/ exists_between k mP_or_Q:forall n : nat, in_int k (S m) n -> P n \/ Q nbetween k (S m) \/ exists_between k (S m)destruct (P_or_Q m); auto with arith. Qed.P, Q:nat -> Propk, m:natH:k <= mP_or_Q:forall n : nat, in_int k (S m) n -> P n \/ Q nH0:between k mbetween k (S m) \/ exists_between k (S m)P, Q:nat -> Propforall k l : nat, between k l -> (forall n : nat, in_int k l n -> P n -> ~ Q n) -> ~ exists_between k lP, Q:nat -> Propforall k l : nat, between k l -> (forall n : nat, in_int k l n -> P n -> ~ Q n) -> ~ exists_between k lP, Q:nat -> Propk:natH:forall n : nat, in_int k k n -> P n -> ~ Q nH0:exists_between k kFalseP, Q:nat -> Propk, l:natH:between k lH0:P lIHbetween:(forall n : nat, in_int k l n -> P n -> ~ Q n) -> ~ exists_between k lH1:forall n : nat, in_int k (S l) n -> P n -> ~ Q nH2:exists_between k (S l)Falseabsurd (k < k); auto with arith.P, Q:nat -> Propk:natH:forall n : nat, in_int k k n -> P n -> ~ Q nH0:exists_between k kFalseP, Q:nat -> Propk, l:natH:between k lH0:P lIHbetween:(forall n : nat, in_int k l n -> P n -> ~ Q n) -> ~ exists_between k lH1:forall n : nat, in_int k (S l) n -> P n -> ~ Q nH2:exists_between k (S l)FalseP, Q:nat -> Propk, l:natH:between k lH0:P lIHbetween:(forall n : nat, in_int k l n -> P n -> ~ Q n) -> ~ exists_between k lH1:forall n : nat, in_int k (S l) n -> P n -> ~ Q nH2:exists_between k (S l)~ Q lP, Q:nat -> Propk, l:natH:between k lH0:P lIHbetween:(forall n : nat, in_int k l n -> P n -> ~ Q n) -> ~ exists_between k lH1:forall n : nat, in_int k (S l) n -> P n -> ~ Q nH2:exists_between k (S l)Q lauto with arith.P, Q:nat -> Propk, l:natH:between k lH0:P lIHbetween:(forall n : nat, in_int k l n -> P n -> ~ Q n) -> ~ exists_between k lH1:forall n : nat, in_int k (S l) n -> P n -> ~ Q nH2:exists_between k (S l)~ Q lP, Q:nat -> Propk, l:natH:between k lH0:P lIHbetween:(forall n : nat, in_int k l n -> P n -> ~ Q n) -> ~ exists_between k lH1:forall n : nat, in_int k (S l) n -> P n -> ~ Q nH2:exists_between k (S l)Q lP, Q:nat -> Propk, l:natH:between k lH0:P lIHbetween:(forall n : nat, in_int k l n -> P n -> ~ Q n) -> ~ exists_between k lH1:forall n : nat, in_int k (S l) n -> P n -> ~ Q nH2:exists_between k (S l)exists_between k (S l)P, Q:nat -> Propk, l:natH:between k lH0:P lIHbetween:(forall n : nat, in_int k l n -> P n -> ~ Q n) -> ~ exists_between k lH1:forall n : nat, in_int k (S l) n -> P n -> ~ Q nH2:exists_between k (S l)l':natH3:k <= l'H4:l' < S lH5:Q l'Q lauto with arith.P, Q:nat -> Propk, l:natH:between k lH0:P lIHbetween:(forall n : nat, in_int k l n -> P n -> ~ Q n) -> ~ exists_between k lH1:forall n : nat, in_int k (S l) n -> P n -> ~ Q nH2:exists_between k (S l)exists_between k (S l)P, Q:nat -> Propk, l:natH:between k lH0:P lIHbetween:(forall n : nat, in_int k l n -> P n -> ~ Q n) -> ~ exists_between k lH1:forall n : nat, in_int k (S l) n -> P n -> ~ Q nH2:exists_between k (S l)l':natH3:k <= l'H4:l' < S lH5:Q l'Q lP, Q:nat -> Propk, l:natH:between k lH0:P lIHbetween:(forall n : nat, in_int k l n -> P n -> ~ Q n) -> ~ exists_between k lH1:forall n : nat, in_int k (S l) n -> P n -> ~ Q nH2:exists_between k (S l)l':natH3:k <= l'H4:l' < S lH5:Q l'Q l'P, Q:nat -> Propk, l:natH:between k lH0:P lIHbetween:(forall n : nat, in_int k l n -> P n -> ~ Q n) -> ~ exists_between k lH1:forall n : nat, in_int k (S l) n -> P n -> ~ Q nH2:exists_between k (S l)l':natH3:k <= l'H4:l' < S lH5:Q l'l' = ltrivial.P, Q:nat -> Propk, l:natH:between k lH0:P lIHbetween:(forall n : nat, in_int k l n -> P n -> ~ Q n) -> ~ exists_between k lH1:forall n : nat, in_int k (S l) n -> P n -> ~ Q nH2:exists_between k (S l)l':natH3:k <= l'H4:l' < S lH5:Q l'Q l'P, Q:nat -> Propk, l:natH:between k lH0:P lIHbetween:(forall n : nat, in_int k l n -> P n -> ~ Q n) -> ~ exists_between k lH1:forall n : nat, in_int k (S l) n -> P n -> ~ Q nH2:exists_between k (S l)l':natH3:k <= l'H4:l' < S lH5:Q l'l' = lP, Q:nat -> Propk, l:natH:between k lH0:P lIHbetween:(forall n : nat, in_int k l n -> P n -> ~ Q n) -> ~ exists_between k lH1:forall n : nat, in_int k (S l) n -> P n -> ~ Q nH2:exists_between k (S l)l':natH3:k <= l'H4:l' < S lH5:Q l'H6:l' < ll' = lP, Q:nat -> Propk, l:natH:between k lH0:P lIHbetween:(forall n : nat, in_int k l n -> P n -> ~ Q n) -> ~ exists_between k lH1:forall n : nat, in_int k (S l) n -> P n -> ~ Q nH2:exists_between k (S l)l':natH3:k <= l'H4:l' < S lH5:Q l'H6:l' < l~ exists_between k lP, Q:nat -> Propk, l:natH:between k lH0:P lIHbetween:(forall n : nat, in_int k l n -> P n -> ~ Q n) -> ~ exists_between k lH1:forall n : nat, in_int k (S l) n -> P n -> ~ Q nH2:exists_between k (S l)l':natH3:k <= l'H4:l' < S lH5:Q l'H6:l' < lexists_between k lauto with arith.P, Q:nat -> Propk, l:natH:between k lH0:P lIHbetween:(forall n : nat, in_int k l n -> P n -> ~ Q n) -> ~ exists_between k lH1:forall n : nat, in_int k (S l) n -> P n -> ~ Q nH2:exists_between k (S l)l':natH3:k <= l'H4:l' < S lH5:Q l'H6:l' < l~ exists_between k leapply in_int_exists; eauto with arith. Qed. Inductive P_nth (init:nat) : nat -> nat -> Prop := | nth_O : P_nth init init 0 | nth_S : forall k l (n:nat), P_nth init k n -> between (S k) l -> Q l -> P_nth init l (S n).P, Q:nat -> Propk, l:natH:between k lH0:P lIHbetween:(forall n : nat, in_int k l n -> P n -> ~ Q n) -> ~ exists_between k lH1:forall n : nat, in_int k (S l) n -> P n -> ~ Q nH2:exists_between k (S l)l':natH3:k <= l'H4:l' < S lH5:Q l'H6:l' < lexists_between k lP, Q:nat -> Propforall init l n : nat, P_nth init l n -> init <= lP, Q:nat -> Propforall init l n : nat, P_nth init l n -> init <= lP, Q:nat -> Propinit:natinit <= initP, Q:nat -> Propinit, k, l, n:natH:P_nth init k nH0:between (S k) lH1:Q lIHP_nth:init <= kinit <= lauto with arith.P, Q:nat -> Propinit:natinit <= initeapply le_trans; eauto with arith. Qed. Definition eventually (n:nat) := exists2 k : nat, k <= n & Q k.P, Q:nat -> Propinit, k, l, n:natH:P_nth init k nH0:between (S k) lH1:Q lIHP_nth:init <= kinit <= lP, Q:nat -> Propeventually 0 -> Q 0P, Q:nat -> Propeventually 0 -> Q 0replace 0 with x; auto with arith. Qed. End Between. Hint Resolve nth_O bet_S bet_emp bet_eq between_Sk_l exists_S exists_le in_int_S in_int_intro: arith. Hint Immediate in_int_Sp_q exists_le_S exists_S_le: arith.P, Q:nat -> Propx:natH:x <= 0H0:Q xQ 0