open import Data.Bool hiding (_≤_; _≤?_)
open import Data.Empty
open import Data.Fin hiding (_<_)
open import Data.Fin.Properties
open import Function using (Inverseᵇ)
open import Data.List
open import Data.Nat hiding (_<_)
open import Data.Nat.Properties
open import Data.Product
open import Data.Sum
open import Data.Unit
open import Level using (0ℓ)
open import Relation.Binary.Core using (Rel)
open import Relation.Binary.Definitions
open import Relation.Binary.PropositionalEquality hiding ([_])
open ≡-Reasoning
open import Relation.Nullary
open import Data.Unit.Properties using (⊤-irrelevant)
open import Function
open import Eser.Fin
module Eser.Card where
data ℕ∞ : Set where
fin : ℕ → ℕ∞
∞ : ℕ∞
suc∞ : ℕ∞ → ℕ∞
suc∞ (fin n) = fin (suc n)
suc∞ ∞ = ∞
_<∞_ : Rel ℕ∞ 0ℓ
fin n <∞ fin m = n Data.Nat.< m
fin n <∞ ∞ = ⊤
∞ <∞ fin m = ⊥
∞ <∞ ∞ = ⊥
_<∞?_ : Decidable _<∞_
fin n <∞? fin m = n Data.Nat.<? m
fin n <∞? ∞ = true because (ofʸ tt)
∞ <∞? fin m = false because ofⁿ id
∞ <∞? ∞ = false because ofⁿ id
_<∞b_ : ℕ∞ → ℕ∞ → Bool
n <∞b m = does (m <∞? n)
<∞-irrel : Relation.Binary.Definitions.Irrelevant _<∞_
<∞-irrel {fin x} {fin y} = Data.Nat.Properties.≤-irrelevant
<∞-irrel {fin x} {∞} p q = refl
<∞-irrel {∞} {fin y} ()
<∞-irrel {∞} {∞} ()
cardToSet : ℕ∞ → Set
cardToSet (fin 0) = ⊥
cardToSet (fin (suc n)) = Fin (suc n)
cardToSet ∞ = ℕ
cardTo< : {n : ℕ∞} → Rel (cardToSet n) 0ℓ
cardTo< {fin 0} ()
cardTo< {fin (suc n)} = Data.Fin._<_
cardTo< {∞} = Data.Nat._<_
cardTo<Trans
: {n : ℕ∞}
→ Transitive (cardTo< {n})
cardTo<Trans {fin (ℕ.suc n)} = Data.Fin.Properties.<-trans
cardTo<Trans {∞} = Data.Nat.Properties.<-trans
leqSmallerTrans
: {c : ℕ∞}
→ {m n k : cardToSet c}
→ (m ≡ n ⊎ cardTo< m n)
→ cardTo< n k
→ cardTo< m k
leqSmallerTrans {_} {m} {n} {k} (inj₁ m≡n) n<k =
subst (λ x → cardTo< x k) (sym m≡n) n<k
leqSmallerTrans {fin (ℕ.suc x)} {m} {n} {k} (inj₂ m<n) n<k =
let m≤Sm : (toℕ m) Data.Nat.≤ ℕ.suc (toℕ m)
m≤Sm = Data.Nat.Properties.n≤1+n (toℕ m)
in
let Sm≤Sn : ℕ.suc (toℕ m) Data.Nat.≤ ℕ.suc (toℕ n)
Sm≤Sn = s≤s (Data.Nat.Properties.≤-trans m≤Sm m<n)
in
Data.Nat.Properties.≤-trans Sm≤Sn n<k
leqSmallerTrans {∞} {m} {n} {k} (inj₂ m<n) n<k =
Data.Nat.Properties.<-trans m<n n<k
cardToℕ
: {c : ℕ∞}
→ cardToSet c
→ ℕ
cardToℕ {∞} n = n
cardToℕ {fin (suc c)} n = toℕ n
cardToℕ-injective
: {c : ℕ∞}
→ {n m : cardToSet c}
→ cardToℕ n ≡ cardToℕ m
→ n ≡ m
cardToℕ-injective {fin (suc c)} {n} {m} H = Data.Fin.Properties.toℕ-injective H
cardToℕ-injective {∞} {n} {m} refl = refl
cardTo<Dec
: {c : ℕ∞}
→ Decidable (cardTo< {c})
cardTo<Dec {fin (ℕ.suc n)} = Data.Fin.Properties._<?_
cardTo<Dec {∞} = Data.Nat.Properties._<?_
n≢m→toℕ[n]≢toℕ[m]
: {k : ℕ}
→ {n m : Fin k}
→ n ≢ m
→ toℕ n ≢ toℕ m
n≢m→toℕ[n]≢toℕ[m] {suc k} {n} {m} n≢m toℕ[n]≡toℕ[m] =
let n≡m = toℕ-injective toℕ[n]≡toℕ[m] in
⊥-elim (n≢m n≡m)
n≮m→n≢m→m<n
: {c : ℕ∞}
→ {n m : cardToSet c}
→ ¬ (cardTo< n m)
→ n ≢ m
→ cardTo< m n
n≮m→n≢m→m<n {fin (suc x)} {n} {m} n≮m n≢m =
let m≤n = Data.Nat.Properties.≮⇒≥ n≮m in
let n≢m = n≢m→toℕ[n]≢toℕ[m] (n≢m) in
Data.Nat.Properties.≤∧≢⇒< m≤n (≢-sym n≢m)
n≮m→n≢m→m<n {∞} {n} {m} n≮m n≢m =
let m≤n = Data.Nat.Properties.≮⇒≥ n≮m in
Data.Nat.Properties.≤∧≢⇒< m≤n (≢-sym n≢m)
cardTo≤ : {n : ℕ∞} → Rel (cardToSet n) 0ℓ
cardTo≤ {fin 0} ()
cardTo≤ {fin (suc n)} = Data.Fin._≤_
cardTo≤ {∞} = Data.Nat._≤_
card≤to⊎
: {c : ℕ∞}
→ {n m : cardToSet c}
→ cardTo≤ {c} n m
→ (n ≡ m) ⊎ (cardTo< n m)
card≤to⊎ {∞} {n} {m} n≤m =
Data.Sum.swap (Data.Nat.Properties.m<1+n⇒m<n∨m≡n (s≤s n≤m))
card≤to⊎ {fin (suc c)} {n} {m} n≤m =
makeFin (Data.Sum.swap (Data.Nat.Properties.m<1+n⇒m<n∨m≡n (s≤s n≤m)))
where
makeFin
: (toℕ n ≡ toℕ m) ⊎ (toℕ n Data.Nat.< toℕ m)
→ (n ≡ m) ⊎ (cardTo< n m)
makeFin (inj₁ Tn≡Tm) = inj₁ (toℕ-injective Tn≡Tm)
makeFin (inj₂ Tn<Tm) = inj₂ Tn<Tm
cardToZero : (n : ℕ∞) → cardToSet (suc∞ n)
cardToZero (fin n) = Data.Fin.zero
cardToZero ∞ = Data.Nat.zero
cardToSuc : {n : ℕ∞} → (m : cardToSet n) → cardToSet (suc∞ n)
cardToSuc {fin 0} ()
cardToSuc {fin (suc n)} m = Data.Fin.suc m
cardToSuc {∞} m = Data.Nat.suc m
cardToPred : {n : ℕ∞} → (m : cardToSet n) → cardToSet n
cardToPred {fin 0} ()
cardToPred {fin (suc n)} zero = zero
cardToPred {fin (suc n)} (suc m) = inject₁ m
cardToPred {∞} zero = zero
cardToPred {∞} (suc m) = m
clipSuc : {n : ℕ} → Fin n → Fin n
clipSuc {suc n} m with n Data.Nat.≟ toℕ m
... | yes _ = m
... | no p = let q = negTransport p (lemma {n} {m}) in
lower₁ (suc m) q
where
lemma : {n : ℕ} {m : Fin (suc n)}
→ (suc n ≡ toℕ ( suc m))
→ (n ≡ toℕ m)
lemma {n} {m} r = Data.Nat.Properties.suc-injective r
negTransport : {A B : Set} → ¬ B → (A → B) → ¬ A
negTransport {A} {B} ¬B f a = ⊥-elim (¬B (f a))
cardToClipSuc : {n : ℕ∞} → (m : cardToSet n) → cardToSet n
cardToClipSuc {fin 0} ()
cardToClipSuc {fin (suc n)} m = clipSuc m
cardToClipSuc {∞} m = suc m
elToNonempty
: {c : ℕ∞}
→ cardToSet c
→ fin ℕ.zero <∞ c
elToNonempty {fin (ℕ.suc c)} i = s≤s z≤n
elToNonempty {∞} i = tt
smallerThanCard
: {c : ℕ∞}
→ (x : cardToSet c)
→ fin (cardToℕ x) <∞ c
smallerThanCard {fin (suc c)} x = toℕ<n {n = ℕ.suc c} x
smallerThanCard {∞} x = tt
ℕequalsCardToSetElem : {c : ℕ∞} → ℕ → (m : cardToSet c) → Set
ℕequalsCardToSetElem {fin (suc c)} n m = (toℕ m) ≡ n
ℕequalsCardToSetElem {∞} n m = n ≡ m
IsNotMax
: {c : ℕ∞}
→ (m : cardToSet c)
→ Set
IsNotMax {fin zero} ()
IsNotMax {fin (suc n)} m = m Data.Fin.< (fromℕ n)
IsNotMax {∞} n = ⊤
biggerToIsNotMax
: {c : ℕ∞}
→ {n m : cardToSet c}
→ cardTo< n m
→ IsNotMax n
biggerToIsNotMax {fin (suc c)} {n} {m} n<m =
let Sm≤Sc : ℕ.suc (toℕ m) Data.Nat.≤ ℕ.suc c
Sm≤Sc = toℕ<n m
in
let
m≤c : toℕ m Data.Nat.≤ c
m≤c = s≤s⁻¹ Sm≤Sc
in
let
c≡TFc : c ≡ toℕ (fromℕ c)
c≡TFc = sym (toℕ-fromℕ c)
in
let
m≤TFc : toℕ m Data.Nat.≤ (toℕ (fromℕ c))
m≤TFc = subst (λ x → toℕ m Data.Nat.≤ x) c≡TFc m≤c
in
Data.Nat.Properties.≤-trans n<m m≤TFc
biggerToIsNotMax {∞} {n} {m} n<m = tt
IsNotMax-irrel
: {c : ℕ∞}
→ (m : cardToSet c)
→ Relation.Nullary.Irrelevant (IsNotMax m)
IsNotMax-irrel {fin (suc c)} m = Data.Fin.Properties.<-irrelevant
IsNotMax-irrel {∞} m = ⊤-irrelevant
endoSuc
: {c : ℕ∞}
→ {n : cardToSet c}
→ (h : IsNotMax n)
→ cardToSet c
endoSuc {fin (suc c)} {n} h =
let sucn = Fin.suc n in
let meh = toℕ-fromℕ c in
let n<c = subst (λ x → suc (toℕ n) Data.Nat.≤ x) meh h in
let Sn<Sc = s≤s n<c in
lower {2+ c} {suc c} sucn Sn<Sc
endoSuc {∞} {n} h = ℕ.suc n
endoSucUnique
: {c : ℕ∞}
→ {n : cardToSet c}
→ (h₁ h₂ : IsNotMax n)
→ (endoSuc h₁ ≡ endoSuc h₂)
endoSucUnique {fin (suc c)} {n} h₁ h₂ = refl
endoSucUnique {∞} {n} h₁ h₂ = refl
endoSucPresvEquality
: {c : ℕ∞}
→ {a b : cardToSet c}
→ (a ≡ b)
→ (h : IsNotMax a)
→ (k : IsNotMax b)
→ endoSuc h ≡ endoSuc k
endoSucPresvEquality {fin ℕ.zero} {()}
endoSucPresvEquality {∞} {a} {b} refl tt tt = refl
endoSucPresvEquality {fin (ℕ.suc c)} {a} {a} refl h k =
let h≡k : h ≡ k
h≡k = IsNotMax-irrel a h k
in
cong endoSuc h≡k
endoSucLemma
: {c : ℕ}
→ (n : cardToSet (fin (ℕ.suc c)))
→ (h : IsNotMax n)
→ toℕ (endoSuc (s≤s h)) ≡ ℕ.suc (toℕ (endoSuc h))
endoSucLemma {suc c} n h = refl
endoSucNatSuc
: {n : cardToSet ∞}
→ (h : IsNotMax n)
→ endoSuc {∞} {n} h ≡ ℕ.suc n
endoSucNatSuc {n} h = refl
endoSucFinSuc
: {c : ℕ}
→ (n : Fin c)
→ (h : IsNotMax (inject₁ n))
→ endoSuc {fin (ℕ.suc c)} {inject₁ n} h ≡ Fin.suc n
endoSucFinSuc {c} zero (s≤s z≤n) = refl
endoSucFinSuc {ℕ.suc c} (Fin.suc n) (s≤s h) =
let rec : endoSuc h ≡ Fin.suc n
rec = endoSucFinSuc {c} n h
in
let H₁ : toℕ (endoSuc (s≤s h)) ≡ toℕ (Fin.suc (endoSuc h))
H₁ = endoSucLemma (inject₁ n) h
in
let H₂ : endoSuc (s≤s h) ≡ Fin.suc (endoSuc h)
H₂ = Data.Fin.Properties.toℕ-injective H₁
in
trans H₂ (cong Fin.suc rec)
endoSucBigger
: {c : ℕ∞}
→ {n : cardToSet c}
→ (h : IsNotMax n)
→ cardTo< n (endoSuc h)
endoSucBigger {fin (2+ c)} {zero} (s≤s z≤n) = s≤s z≤n
endoSucBigger {fin (suc c)} {suc n} h =
let h' : toℕ (suc n) Data.Nat.< c
h' = subst (λ x → toℕ (suc n) Data.Nat.< x) (toℕ-fromℕ c) h
in
let n≤n : toℕ n Data.Nat.≤ toℕ n
n≤n = Data.Nat.Properties.≤-refl
in
let STn≤STn : suc (toℕ n) Data.Nat.≤ suc (toℕ n)
STn≤STn = s≤s n≤n
in
let STn≤TLSn : suc (toℕ n) Data.Nat.≤ toℕ (lower (suc n) h')
STn≤TLSn = subst (λ x → suc (toℕ n) Data.Nat.≤ x)
(sym (toℕ-lower (suc n) h'))
STn≤STn
in
s≤s (subst (λ x → suc (toℕ n) Data.Nat.≤ x) refl STn≤TLSn )
endoSucBigger {∞} {zero} tt = s≤s z≤n
endoSucBigger {∞} {suc n} tt = s≤s (s≤s Data.Nat.Properties.≤-refl)
endoSucInjToNatSuc
: {c : ℕ}
→ {n : cardToSet (fin (ℕ.suc c))}
→ (h : IsNotMax n)
→ toℕ (endoSuc h) ≡ ℕ.suc (toℕ n)
endoSucInjToNatSuc {suc c} {zero} (s≤s z≤n) = refl
endoSucInjToNatSuc {suc c} {suc n} (s≤s h) =
let H = endoSucLemma {c} n h in
let rec = endoSucInjToNatSuc {c} {n} h in
let rec' = cong ℕ.suc rec in
trans H rec'
sucpredsuc≡suc
: {c : ℕ}
→ (n : Fin c)
→ ℕ.suc (toℕ (cardToPred {fin (ℕ.suc c)} (Fin.suc n))) ≡ toℕ (Fin.suc n)
sucpredsuc≡suc {c} n =
let sn≡sn = refl {x = toℕ (Fin.suc n)} in
let P = (λ x → x ≡ toℕ (Fin.suc n)) in
subst P (sym (toℕ-inject₁ (Fin.suc n))) sn≡sn
j<i<Sj-impossible
: {c : ℕ∞}
→ {i j : cardToSet c}
→ {h : IsNotMax j}
→ cardTo< i (endoSuc h)
→ cardTo< j i
→ ⊥
j<i<Sj-impossible {fin (ℕ.suc c)} {i} {j} {h} i<Sj j<i =
let SSj≤Si = s≤s j<i in
let SSj≤Sj = Data.Nat.Properties.≤-trans SSj≤Si i<Sj in
let H = endoSucInjToNatSuc {c} h in
let SSj≤Sj' = subst (λ x → 2+ (toℕ j) Data.Nat.≤ x) H SSj≤Sj in
let K = s≤s⁻¹ SSj≤Sj' in
1+n≰n {toℕ j} K
j<i<Sj-impossible {∞} {i} {j} {h} i<Sj j<i =
let SSj≤Si = s≤s j<i in
let SSj≤Sj = Data.Nat.Properties.≤-trans SSj≤Si i<Sj in
1+n≰n SSj≤Sj
<And≡Impossible
: {c : ℕ∞}
→ {n m : cardToSet c}
→ cardTo< n m
→ n ≡ m
→ ⊥
<And≡Impossible {∞} {n} {m} n<m n≡m = Data.Nat.Properties.<⇒≢ n<m n≡m
<And≡Impossible {fin (ℕ.suc c)} {n} {m} n<m n≡m =
Data.Nat.Properties.<⇒≢ n<m (cong toℕ n≡m)
aPredecIsNotMax
: {c : ℕ∞}
→ {n : cardToSet c}
→ (cardTo< (cardToPred n) n)
→ IsNotMax (cardToPred n)
aPredecIsNotMax {fin (ℕ.suc c)} {Fin.suc n} (s≤s pn<n) =
let sn≤c' = toℕ≤pred[n] {ℕ.suc c} (Fin.suc n) in
let P = λ x → toℕ (Fin.suc n) Data.Nat.≤ x in
let sn≤c = subst P (sym(toℕ-fromℕ c)) sn≤c' in
let spsn≡sn = sym(sucpredsuc≡suc n) in
subst (λ x → x Data.Nat.≤ toℕ (fromℕ c)) spsn≡sn sn≤c
aPredecIsNotMax {∞} {n} pn<n = tt
cardLower : {n : ℕ∞} → {m : cardToSet (suc∞ n)} → (IsNotMax m) → cardToSet n
cardLower {fin (suc n)} {m} notMax =
coe h (Data.Fin.lower m notMax)
where
h : Fin (toℕ (fromℕ ( ℕ.suc n))) ≡ Fin (ℕ.suc n)
h = cong (λ X → Fin X) (toℕ-fromℕ (ℕ.suc n))
coe : {A B : Set} → A ≡ B → A → B
coe p x = subst (λ A → A) p x
cardLower {∞} {m} notMax = m
cardInject : {n : ℕ∞} → (m : cardToSet n) → cardToSet (suc∞ n)
cardInject {fin (suc n)} m = inject₁ m
cardInject {∞} m = m
cardFrom<∞
: {c : ℕ∞}
→ {m : ℕ}
→ (fin m <∞ c)
→ Σ[ m' ∈ cardToSet c ](cardToℕ m' ≡ m)
cardFrom<∞ {fin (suc c)} {m} m<c = ( fromℕ< m<c , toℕ-fromℕ< m<c)
cardFrom<∞ {∞} {m} m<c = (m , refl)
cardToDecidableEq
: (c : ℕ∞)
→ DecidableEquality (cardToSet c)
cardToDecidableEq (fin (suc c)) = Data.Fin._≟_
cardToDecidableEq ∞ = Data.Nat._≟_
nonzeroCardToZeroElem : {n : ℕ∞} → (fin ℕ.zero <∞ n) → cardToSet n
nonzeroCardToZeroElem {fin zero} ()
nonzeroCardToZeroElem {fin (suc n)} (s≤s z≤n) = Data.Fin.zero
nonzeroCardToZeroElem {∞} _ = Data.Nat.zero
zeroElemToNatZero
: {c : ℕ}
→ (h : fin ℕ.zero <∞ (fin (ℕ.suc c)))
→ toℕ (nonzeroCardToZeroElem h) ≡ ℕ.zero
zeroElemToNatZero {c} (s≤s z≤n) = refl
nothingIs<0
: {c : ℕ∞}
→ (n : cardToSet c)
→ (h : fin ℕ.zero <∞ c)
→ ¬ (cardTo< n (nonzeroCardToZeroElem h))
nothingIs<0 {fin (ℕ.suc c)} n h n<0 =
let nonzeroh≡0 = zeroElemToNatZero {c} h in
let n<0' = subst (λ x → ℕ.suc (toℕ n) Data.Nat.≤ x) nonzeroh≡0 n<0 in
n≮0 n<0'
nothingIs<0 {∞} n h n<0 = n≮0 n<0
inhToNonzero
: {n : ℕ∞}
→ (i : cardToSet n)
→ fin ℕ.zero <∞ n
inhToNonzero {fin zero} ()
inhToNonzero {fin (suc n)} _ = z<s
inhToNonzero {∞} _ = tt
cardInhToZero : {n : ℕ∞} → cardToSet n → cardToSet n
cardInhToZero {fin (ℕ.suc n)} m = Fin.zero
cardInhToZero {∞} _ = Data.Nat.zero
cardTo0<1
: {n : ℕ∞}
→ (m : cardToSet n)
→ cardTo< (cardInject (cardInhToZero m)) (cardToClipSuc (cardToZero n))
cardTo0<1 {fin 0} ()
cardTo0<1 {fin (suc n)} m = z<s
cardTo0<1 {∞} m = z<s
cardTo0<1'
: {n : ℕ∞}
→ (0<n : fin ℕ.zero <∞ n)
→ cardTo< (cardInject (nonzeroCardToZeroElem 0<n))
(cardToClipSuc (cardToZero n))
cardTo0<1' {fin 0} ()
cardTo0<1' {fin (suc n)} (s≤s z≤n) =
let toNinjZero = nonzeroCardToZeroElem {fin (suc n)} (s≤s z≤n) in
let toNZero = sym (toℕ-inject₁ toNinjZero) in
subst (λ x → suc x Data.Nat.≤ suc zero) toNZero (s≤s z≤n)
cardTo0<1' {∞} _ = z<s
thereIsOneZero
: {n : ℕ∞}
→ (i : cardToSet n)
→ (0<n : fin ℕ.zero <∞ n)
→ (cardInhToZero i ≡ nonzeroCardToZeroElem 0<n)
thereIsOneZero {fin zero} ()
thereIsOneZero {fin (suc n)} i (z<s) = refl
thereIsOneZero {∞} i 0<n = refl
thereIsOneZero'
: {n : ℕ∞}
→ (h h' : fin ℕ.zero <∞ n)
→ nonzeroCardToZeroElem h ≡ nonzeroCardToZeroElem h'
thereIsOneZero' {fin (suc n)} (s≤s z≤n) (s≤s z≤n) = refl
thereIsOneZero' {∞} h h' = refl
sucZeroIsOneInℕ
: (c : ℕ∞)
→ (ℕ.suc $ cardToℕ (cardToZero c)) ≡ 1
sucZeroIsOneInℕ (fin c) = refl
sucZeroIsOneInℕ ∞ = refl
ℕSucCardToSucComm
: {n : ℕ}
→ (i : cardToSet (fin n))
→ toℕ (cardToSuc i) ≡ ℕ.suc (toℕ (cardInject i))
ℕSucCardToSucComm {ℕ.suc n} i = begin
toℕ (cardToSuc i)
≡⟨ refl ⟩
ℕ.suc (toℕ i)
≡⟨ cong ℕ.suc (sym (toℕ-inject₁ i)) ⟩
ℕ.suc (toℕ (cardInject i))
∎
card<s→≤
: {n : ℕ∞}
→ {i j : cardToSet n}
→ (cardTo< (cardInject j) (cardToSuc i) )
→ (cardTo≤ j i)
card<s→≤ {fin (ℕ.suc n)} {i} {j} j<si =
let h = ℕSucCardToSucComm i in
let P = (λ x → ℕ.suc (toℕ (cardInject j)) Data.Nat.≤ x) in
let sjℕ≤si = subst P h j<si in
let jℕ≤i = ≤-pred sjℕ≤si in
let hj = toℕ-inject₁ j in
let hi = toℕ-inject₁ i in
let j≤i' = subst (λ x → x Data.Nat.≤ (toℕ (inject₁ i))) hj jℕ≤i in
let j≤i = subst (λ x → toℕ j Data.Nat.≤ x) hi j≤i' in
j≤i
card<s→≤ {∞} {i} {j} i<j = ≤-pred i<j