{-# OPTIONS --cubical-compatible --safe #-} module finiteSetUtil where open import Data.Nat hiding ( _≟_ ) open import Data.Fin renaming ( _<_ to _<<_ ; _>_ to _f>_ ; _≟_ to _f≟_ ) hiding (_≤_ ; pred ) open import Data.Fin.Properties hiding ( <-trans ; ≤-trans ; ≤-refl ; <-irrelevant ) renaming ( <-cmp to <-fcmp ) open import Data.Empty open import Relation.Nullary open import Relation.Binary.Definitions open import Relation.Binary.PropositionalEquality open import logic open import nat open import finiteSet open import fin open import Data.Nat.Properties as NP hiding ( _≟_ ) record Found ( Q : Set ) (p : Q → Bool ) : Set where field found-q : Q found-p : p found-q ≡ true open Bijection open import Axiom.Extensionality.Propositional open import Level hiding (suc ; zero) module _ {Q : Set } (F : FiniteSet Q) where open FiniteSet F equal?-refl : { x : Q } → equal? x x ≡ true equal?-refl {x} with F←Q x ≟ F←Q x ... | yes eq = refl ... | no ne = ⊥-elim (ne refl) equal→refl : { x y : Q } → equal? x y ≡ true → x ≡ y equal→refl {q0} {q1} eq with F←Q q0 ≟ F←Q q1 equal→refl {q0} {q1} refl | yes eq = begin q0 ≡⟨ sym ( finiso→ q0) ⟩ Q←F (F←Q q0) ≡⟨ cong (λ k → Q←F k ) eq ⟩ Q←F (F←Q q1) ≡⟨ finiso→ q1 ⟩ q1 ∎ where open ≡-Reasoning eqP : (x y : Q) → Dec ( x ≡ y ) eqP x y with F←Q x ≟ F←Q y ... | yes eq = yes (subst₂ (λ j k → j ≡ k ) (finiso→ x) (finiso→ y) (cong Q←F eq) ) ... | no n = no (λ eq → n (cong F←Q eq)) End : (m : ℕ ) → (p : Q → Bool ) → Set End m p = (i : Fin finite) → m ≤ toℕ i → p (Q←F i ) ≡ false first-end : ( p : Q → Bool ) → End finite p first-end p i i>n = ⊥-elim (nat-≤> i>n (fin ¬a ¬b c = ⊥-elim ( nat-≤> m 1 -- theses are duplicates -- actualy it is duplicate phase2 : { Q : Set } (finq : FiniteSet Q) (q : Q) (qs : List Q ) → Bool phase2 finq q [] = false phase2 finq q (x ∷ qs) with equal? finq q x ... | true = true ... | false = phase2 finq q qs phase1 : { Q : Set } (finq : FiniteSet Q) (q : Q) (qs : List Q ) → Bool phase1 finq q [] = false phase1 finq q (x ∷ qs) with equal? finq q x ... | true = phase2 finq q qs ... | false = phase1 finq q qs dup-in-list : { Q : Set } (finq : FiniteSet Q) (q : Q) (qs : List Q ) → Bool dup-in-list {Q} finq q qs = phase1 finq q qs -- -- if length of the list is longer than kinds of a finite set, there is a duplicate -- prove this based on the theorem on Data.Fin -- dup-in-list+fin : { Q : Set } (finq : FiniteSet Q) → (q : Q) (qs : List Q ) → fin-dup-in-list (F←Q finq q) (map (F←Q finq) qs) ≡ true → dup-in-list finq q qs ≡ true dup-in-list+fin {Q} finq q qs p = i-phase1 qs p where i-phase2 : (qs : List Q) → fin-phase2 (F←Q finq q) (map (F←Q finq) qs) ≡ true → phase2 finq q qs ≡ true i-phase2 (x ∷ qs) p with equal? finq q x in eq | <-fcmp (F←Q finq q) (F←Q finq x) ... | true | t = refl ... | false | tri< a ¬b ¬c = i-phase2 qs p ... | false | tri≈ ¬a b ¬c = ⊥-elim (¬-bool eq (subst₂ (λ j k → equal? finq j k ≡ true) (finiso→ finq q) (subst (λ k → Q←F finq k ≡ x) (sym b) (finiso→ finq x)) ( equal?-refl finq ))) ... | false | tri> ¬a ¬b c = i-phase2 qs p i-phase1 : (qs : List Q) → fin-phase1 (F←Q finq q) (map (F←Q finq) qs) ≡ true → phase1 finq q qs ≡ true i-phase1 (x ∷ qs) p with equal? finq q x in eq | <-fcmp (F←Q finq q) (F←Q finq x) ... | true | tri< a ¬b ¬c = ⊥-elim ( nat-≡< (cong (λ x → toℕ (F←Q finq x)) ( equal→refl finq eq )) a ) ... | true | tri≈ ¬a b ¬c = i-phase2 qs p ... | true | tri> ¬a ¬b c = ⊥-elim ( nat-≡< (cong (λ x → toℕ (F←Q finq x)) (sym ( equal→refl finq eq ))) c ) ... | false | tri< a ¬b ¬c = i-phase1 qs p ... | false | tri≈ ¬a b ¬c = ⊥-elim (¬-bool eq (subst₂ (λ j k → equal? finq j k ≡ true) (finiso→ finq q) (subst (λ k → Q←F finq k ≡ x) (sym b) (finiso→ finq x)) ( equal?-refl finq ))) ... | false | tri> ¬a ¬b c = i-phase1 qs p record Dup-in-list {Q : Set } (finq : FiniteSet Q) (qs : List Q) : Set where field dup : Q is-dup : dup-in-list finq dup qs ≡ true dup-in-list>n : {Q : Set } → (finq : FiniteSet Q) → (qs : List Q) → (len> : length qs > finite finq ) → Dup-in-list finq qs dup-in-list>n {Q} finq qs lt = record { dup = Q←F finq (FDup-in-list.dup dl) ; is-dup = dup-in-list+fin finq (Q←F finq (FDup-in-list.dup dl)) qs dl01 } where maplen : (qs : List Q) → length (map (F←Q finq) qs) ≡ length qs maplen [] = refl maplen (x ∷ qs) = cong suc (maplen qs) dl : FDup-in-list (finite finq ) (map (F←Q finq) qs) dl = fin-dup-in-list>n (map (F←Q finq) qs) (subst (λ k → k > finite finq ) (sym (maplen qs)) lt) dl01 : fin-dup-in-list (F←Q finq (Q←F finq (FDup-in-list.dup dl))) (map (F←Q finq) qs) ≡ true dl01 = subst (λ k → fin-dup-in-list k (map (F←Q finq) qs) ≡ true ) (sym (finiso← finq _)) ( FDup-in-list.is-dup dl ) open import bijection using ( InjectiveF ; Is ) -- open import Relation.Binary.HeterogeneousEquality as HE using (_≅_ ) inject-fin : {A B : Set} (fa : FiniteSet A ) → (fi : InjectiveF B A) → (is-B : (a : A ) → Dec (Is B A (InjectiveF.f fi) a) ) → FiniteSet B inject-fin {A} {B} fa fi is-B with finite fa in eq1 ... | zero = record { finite = 0 ; Q←F = λ () ; F←Q = λ b → ⊥-elim ( lem00 b) ; finiso→ = λ b → ⊥-elim ( lem00 b) ; finiso← = λ () } where lem00 : ( b : B) → ⊥ lem00 b with subst (λ k → Fin k ) eq1 (F←Q fa (InjectiveF.f fi b)) ... | () ... | suc pfa = record { finite = maxb ; Q←F = λ fb → CountB.b (cb00 _ (fin ¬a ¬b c with is-B (Q←F fa (fromℕ< c)) ... | yes isb = suc (count-B n) ... | no nisb = count-B n record CountB (n : ℕ) : Set where field b : B cb : ℕ b=cn : cb ≡ toℕ (F←Q fa (f b)) cb=n : count-B cb ≡ suc n cb-inject : (cb1 : ℕ) → (c1 ¬a ¬b c with is-B (Q←F fa (fromℕ< c)) | is-B (Q←F fa ( fromℕ< {0} 0 ¬a ¬b c = ⊥-elim ( ¬a a ) ... | tri< a ¬b ¬c | tri≈ ¬a b ¬c₁ = ⊥-elim (nat-≡< b (<-trans a a ¬a ¬b₁ c = ⊥-elim (nat-<> a (<-trans a ¬a ¬b c = ⊥-elim ( ¬c c ) ... | tri≈ ¬a b ¬c | tri≈ ¬a₁ b₁ ¬c₁ = ⊥-elim (nat-≡< (sym b) (subst (λ k → _ < k ) (sym b₁) a ¬a₁ ¬b c = ⊥-elim (nat-≡< (sym b) (<-trans a ¬a ¬b c | tri< a ¬b₁ ¬c = ⊥-elim (nat-≤> a (<-transʳ c a ¬a ¬b c | tri≈ ¬a₁ b ¬c with is-B (Q←F fa (fromℕ< c)) ... | yes isb = refl-≤≡ (sym lem14) where lem14 : count-B (suc i) ≡ suc (count-B i) lem14 with <-cmp (finite fa) (suc i) ... | tri< a₂ ¬b₂ ¬c₂ = ⊥-elim (¬c₂ c) ... | tri≈ ¬a₂ b₂ ¬c₂ = ⊥-elim (¬c₂ c) ... | tri> ¬a₂ ¬b₂ c₂ with is-B (Q←F fa ( fromℕ< c₂ )) ... | yes isb = refl ... | no ne = ⊥-elim (ne record {a = Is.a isb ; fa=c = trans (Is.fa=c isb) (cong (λ k → Q←F fa k) (lemma10 refl )) } ) ... | no nisb = refl-≤≡ (sym lem14) where lem14 : count-B (suc i) ≡ count-B i lem14 with <-cmp (finite fa) (suc i) ... | tri< a₂ ¬b₂ ¬c₂ = ⊥-elim (¬c₂ c) ... | tri≈ ¬a₂ b₂ ¬c₂ = ⊥-elim (¬c₂ c) ... | tri> ¬a₂ ¬b₂ c₂ with is-B (Q←F fa ( fromℕ< c₂ )) ... | yes isb = ⊥-elim (nisb record {a = Is.a isb ; fa=c = trans (Is.fa=c isb) (cong (λ k → Q←F fa k) (lemma10 refl )) } ) ... | no ne = refl lem01 (suc i) | tri> ¬a ¬b c | tri> ¬a₁ ¬b₁ c₁ with is-B (Q←F fa (fromℕ< c)) | is-B (Q←F fa (fromℕ< c₁)) ... | yes isb0 | yes isb1 = ≤-trans (refl-≤≡ (sym lem14)) a≤sa where lem14 : count-B (suc i) ≡ suc (count-B i) lem14 with <-cmp (finite fa) (suc i) ... | tri< a₂ ¬b₂ ¬c₂ = ⊥-elim (¬c₂ c) ... | tri≈ ¬a₂ b₂ ¬c₂ = ⊥-elim (¬c₂ c) ... | tri> ¬a₂ ¬b₂ c₂ with is-B (Q←F fa ( fromℕ< c₂ )) ... | no ne = ⊥-elim (ne record {a = Is.a isb0 ; fa=c = trans (Is.fa=c isb0) (cong (λ k → Q←F fa k) (lemma10 refl )) } ) ... | yes isb = refl ... | yes isb0 | no nisb1 = refl-≤≡ (sym lem14) where lem14 : count-B (suc i) ≡ suc (count-B i) lem14 with <-cmp (finite fa) (suc i) ... | tri< a₂ ¬b₂ ¬c₂ = ⊥-elim (¬c₂ c) ... | tri≈ ¬a₂ b₂ ¬c₂ = ⊥-elim (¬c₂ c) ... | tri> ¬a₂ ¬b₂ c₂ with is-B (Q←F fa ( fromℕ< c₂ )) ... | no ne = ⊥-elim (ne record {a = Is.a isb0 ; fa=c = trans (Is.fa=c isb0) (cong (λ k → Q←F fa k) (lemma10 refl )) } ) ... | yes isb = refl ... | no nisb0 | yes isb1 = ≤-trans (refl-≤≡ (sym lem14)) a≤sa where lem14 : count-B (suc i) ≡ count-B i lem14 with <-cmp (finite fa) (suc i) ... | tri< a₂ ¬b₂ ¬c₂ = ⊥-elim (¬c₂ c) ... | tri≈ ¬a₂ b₂ ¬c₂ = ⊥-elim (¬c₂ c) ... | tri> ¬a₂ ¬b₂ c₂ with is-B (Q←F fa ( fromℕ< c₂ )) ... | no ne = refl ... | yes isb = ⊥-elim (nisb0 record {a = Is.a isb ; fa=c = trans (Is.fa=c isb) (cong (λ k → Q←F fa k) (lemma10 refl )) } ) ... | no nisb0 | no nisb1 = refl-≤≡ (sym lem14) where lem14 : count-B (suc i) ≡ count-B i lem14 with <-cmp (finite fa) (suc i) ... | tri< a₂ ¬b₂ ¬c₂ = ⊥-elim (¬c₂ c) ... | tri≈ ¬a₂ b₂ ¬c₂ = ⊥-elim (¬c₂ c) ... | tri> ¬a₂ ¬b₂ c₂ with is-B (Q←F fa ( fromℕ< c₂ )) ... | no ne = refl ... | yes isb = ⊥-elim (nisb0 record {a = Is.a isb ; fa=c = trans (Is.fa=c isb) (cong (λ k → Q←F fa k) (lemma10 refl )) } ) lem31 : (b : B) → 0 < count-B (toℕ (F←Q fa (f b))) lem31 b = lem32 (toℕ (F←Q fa (f b))) refl where lem32 : (i : ℕ) → toℕ (F←Q fa (f b)) ≡ i → 0 < count-B i lem32 zero eq with is-B (Q←F fa ( fromℕ< {0} 0 ¬a ¬b c with is-B (Q←F fa (fromℕ< c)) ... | yes isb = s≤s z≤n ... | no nisb = ⊥-elim ( nisb record { a = b ; fa=c = lem33 } ) where lem33 : f b ≡ Q←F fa ( fromℕ< c) lem33 = begin f b ≡⟨ sym (finiso→ fa _) ⟩ Q←F fa ( F←Q fa (f b)) ≡⟨ sym (cong (λ k → Q←F fa k) ( fromℕ<-toℕ _ (fin ¬a ¬b c with is-B (Q←F fa ( fromℕ< 0 ¬a ¬b c with is-B (Q←F fa (fromℕ< c)) ... | yes _ = refl ... | no nisa = ⊥-elim ( nisa record { a = Is.a bj ; fa=c = lem26 } ) where lem26 : f (Is.a bj) ≡ Q←F fa (fromℕ< c) lem26 = trans (Is.fa=c bj) (cong (Q←F fa) (fromℕ<-cong _ _ refl j ¬a ¬b c₁ = ⊥-elim (nat-≡< (sym eq) ( lem20 j i c₁ j ¬a ¬b c with is-B (Q←F fa (fromℕ< c)) ... | no nisb = lem09 i (suc j) (s≤s le) eq ... | yes isb with ≤-∨ (s≤s le) ... | case1 eq2 = record { b = Is.a isb ; cb = suc i ; b=cn = lem11 ; cb=n = trans lem14 (sym (trans eq2 eq )) ; cb-inject = λ cb1 c1 ¬a₂ ¬b₂ c₂ with is-B (Q←F fa ( fromℕ< c₂ )) ... | yes isb = refl ... | no ne = ⊥-elim (ne record {a = Is.a isb ; fa=c = trans (Is.fa=c isb) (cong (λ k → Q←F fa k) (lemma10 refl )) } ) lem11 : suc i ≡ toℕ (F←Q fa (f (Is.a isb))) lem11 = begin suc i ≡⟨ sym ( toℕ-fromℕ< c) ⟩ toℕ (fromℕ< c) ≡⟨ cong toℕ (sym (finiso← fa _)) ⟩ toℕ (F←Q fa (Q←F fa (fromℕ< c ))) ≡⟨ cong (λ k → toℕ ((F←Q fa k))) (sym (Is.fa=c isb)) ⟩ toℕ (F←Q fa (f (Is.a isb))) ∎ where open ≡-Reasoning ... | case2 (s≤s lt) = lem09 i j lt (cong pred eq) iso0 : (x : Fin maxb) → fromℕ< (cb