1
------------------------------------------------------------------------
2
-- Definition of and lemmas related to "true infinitely often"
3
------------------------------------------------------------------------
5
module Data.Nat.InfinitelyOften where
8
open import Category.Monad
10
open import Data.Function
12
import Data.Nat.Properties as NatProp
13
open import Data.Product as Prod hiding (map)
14
open import Data.Sum hiding (map)
15
open import Relation.Binary.PropositionalEquality
16
open import Relation.Nullary
17
open import Relation.Nullary.Negation
18
open import Relation.Unary using (_∪_; _⊆_)
19
open RawMonad ¬¬-Monad
21
module NatLattice = DistributiveLattice NatProp.distributiveLattice
23
-- Only true finitely often.
26
Fin P = ∃ λ i → ∀ j → i ≤ j → ¬ P j
28
-- Fin is preserved by binary sums.
30
_∪-Fin_ : ∀ {P Q} → Fin P → Fin Q → Fin (P ∪ Q)
31
_∪-Fin_ {P} {Q} (i , ¬p) (j , ¬q) = (i ⊔ j , helper)
35
helper : ∀ k → i ⊔ j ≤ k → ¬ (P ∪ Q) k
36
helper k i⊔j≤k (inj₁ p) = ¬p k (begin
37
i ≤⟨ NatProp.m≤m⊔n i j ⟩
40
helper k i⊔j≤k (inj₂ q) = ¬q k (begin
41
j ≤⟨ NatProp.m≤m⊔n j i ⟩
42
j ⊔ i ≡⟨ NatLattice.∧-comm j i ⟩
46
-- A non-constructive definition of "true infinitely often".
51
-- Inf commutes with binary sums (in the double-negation monad).
53
commutes-with-∪ : ∀ {P Q} → Inf (P ∪ Q) → ¬ ¬ (Inf P ⊎ Inf Q)
56
(λ ¬p ¬q → ⊥-elim (p∪q (¬p ∪-Fin ¬q)))
57
<$> ¬[p⊎q] ∘ inj₁ ⊛ ¬[p⊎q] ∘ inj₂
61
map : ∀ {P Q} → P ⊆ Q → Inf P → Inf Q
62
map P⊆Q ¬fin = ¬fin ∘ Prod.map id (λ fin j i≤j → fin j i≤j ∘ P⊆Q)
64
-- Inf is upwards closed.
66
up : ∀ {P} n → Inf P → Inf (P ∘ _+_ n)
68
up {P} (suc n) = up n ∘ up₁
70
up₁ : Inf P → Inf (P ∘ suc)
71
up₁ ¬fin (i , fin) = ¬fin (suc i , helper)
73
helper : ∀ j → 1 + i ≤ j → ¬ P j
74
helper ._ (s≤s i≤j) = fin _ i≤j
78
witness : ∀ {P} → Inf P → ¬ ¬ ∃ P
79
witness ¬fin ¬p = ¬fin (0 , λ i _ Pi → ¬p (i , Pi))
81
-- Two different witnesses.
84
: ∀ {P} → Inf P → ¬ ¬ ∃₂ λ m n → m ≢ n × P m × P n
85
twoDifferentWitnesses inf =
86
witness inf >>= λ w₁ →
87
witness (up (1 + proj₁ w₁) inf) >>= λ w₂ →
88
return (_ , _ , NatProp.m≢1+m+n (proj₁ w₁) , proj₂ w₁ , proj₂ w₂)