{-# OPTIONS --cubical-compatible --safe #-} module fin where open import Data.Fin hiding (_<_ ; _≤_ ; _>_ ; _+_ ) open import Data.Fin.Properties hiding (≤-trans ; <-trans ; ≤-refl ) renaming ( <-cmp to <-fcmp ) open import Data.Nat open import Data.Nat.Properties open import logic open import nat open import Relation.Binary.PropositionalEquality -- toℕ 0 → Data.Nat.pred (toℕ f) < n pred ¬a ¬b c = fin-phase2 q qs fin-phase1 : { n : ℕ } (q : Fin n) (qs : List (Fin n) ) → Bool -- find the first element fin-phase1 q [] = false fin-phase1 q (x ∷ qs) with <-fcmp q x ... | tri< a ¬b ¬c = fin-phase1 q qs ... | tri≈ ¬a b ¬c = fin-phase2 q qs ... | tri> ¬a ¬b c = fin-phase1 q qs fin-dup-in-list : { n : ℕ} (q : Fin n) (qs : List (Fin n) ) → Bool fin-dup-in-list {n} q qs = fin-phase1 q qs record FDup-in-list (n : ℕ ) (qs : List (Fin n)) : Set where field dup : Fin n is-dup : fin-dup-in-list dup qs ≡ true list-less : {n : ℕ } → List (Fin (suc n)) → List (Fin n) list-less [] = [] list-less {n} (i ∷ ls) with <-fcmp (fromℕ< a a (subst (λ k → toℕ i < suc k ) (sym fin ¬a ¬b c = xn : {n : ℕ } → (qs : List (Fin n)) → (len> : length qs > n ) → FDup-in-list n qs fin-dup-in-list>n {zero} [] () fin-dup-in-list>n {zero} (() ∷ qs) lt fin-dup-in-list>n {suc n} qs lt = fdup-phase0 where open import Level using ( Level ) -- make a dup from one level below fdup+1 : (qs : List (Fin (suc n))) (i : Fin n) → fin-dup-in-list (fromℕ< a a (subst (λ k → toℕ x < suc k ) (sym fin ¬a₁ ¬b c = f1-phase2 qs p (case2 q1) -- two fcmp is only different in the size of Fin, but to develop both f1-phase and list-less both fcmps are required f1-phase2 (x ∷ qs) p (case1 q1) | tri> ¬a ¬b c with <-fcmp i (fromℕ< (≤-trans c (fin≤n (fromℕ< a ¬a₁ ¬b₂ c₁ = ⊥-elim ( ¬a₁ (subst₂ (λ j k → j < k) (sym fin+1-toℕ) (toℕ-fromℕ< _) a )) ... | tri≈ ¬a₁ b ¬c | tri< a ¬b₁ ¬c₁ = ⊥-elim ( ¬a₁ (subst₂ (λ j k → j < k) fin+1-toℕ (sym (toℕ-fromℕ< _)) a )) ... | tri≈ ¬a₁ b ¬c | tri≈ ¬a₂ b₁ ¬c₁ = refl ... | tri≈ ¬a₁ b ¬c | tri> ¬a₂ ¬b₁ c₁ = ⊥-elim ( ¬c (subst₂ (λ j k → j > k) fin+1-toℕ (sym (toℕ-fromℕ< _)) c₁ )) ... | tri> ¬a₁ ¬b₁ c₁ | tri< a ¬b₂ ¬c = ⊥-elim ( ¬c (subst₂ (λ j k → j > k) (sym fin+1-toℕ) (toℕ-fromℕ< _) c₁ )) ... | tri> ¬a₁ ¬b₁ c₁ | tri≈ ¬a₂ b ¬c = ⊥-elim ( ¬c (subst₂ (λ j k → j > k) (sym fin+1-toℕ) (toℕ-fromℕ< _) c₁ )) ... | tri> ¬a₁ ¬b₁ c₁ | tri> ¬a₂ ¬b₂ c₂ = f1-phase2 qs p (case1 q1) f1-phase2 (x ∷ qs) p (case2 q1) with <-fcmp (fromℕ< a a (subst (λ k → toℕ x < suc k ) (sym fin ¬a₁ ¬b c = ⊥-elim ( ¬-bool q1 refl ) f1-phase2 (x ∷ qs) p (case2 q1) | tri> ¬a ¬b c with <-fcmp i (fromℕ< (≤-trans c (fin≤n (fromℕ< a ¬a₁ ¬b₂ c₁ = ⊥-elim ( ¬a₁ (subst₂ (λ j k → j < k) (sym fin+1-toℕ) (toℕ-fromℕ< _) a )) ... | tri≈ ¬a₁ b ¬c | tri< a ¬b₁ ¬c₁ = ⊥-elim ( ¬a₁ (subst₂ (λ j k → j < k) fin+1-toℕ (sym (toℕ-fromℕ< _)) a )) ... | tri≈ ¬a₁ b ¬c | tri≈ ¬a₂ b₁ ¬c₁ = refl ... | tri≈ ¬a₁ b ¬c | tri> ¬a₂ ¬b₁ c₁ = ⊥-elim ( ¬c (subst₂ (λ j k → j > k) fin+1-toℕ (sym (toℕ-fromℕ< _)) c₁ )) ... | tri> ¬a₁ ¬b₁ c₁ | tri< a ¬b₂ ¬c = ⊥-elim ( ¬c (subst₂ (λ j k → j > k) (sym fin+1-toℕ) (toℕ-fromℕ< _) c₁ )) ... | tri> ¬a₁ ¬b₁ c₁ | tri≈ ¬a₂ b ¬c = ⊥-elim ( ¬c (subst₂ (λ j k → j > k) (sym fin+1-toℕ) (toℕ-fromℕ< _) c₁ )) ... | tri> ¬a₁ ¬b₁ c₁ | tri> ¬a₂ ¬b₂ c₂ = f1-phase2 qs p (case2 q1 ) f1-phase1 : (qs : List (Fin (suc n)) ) → fin-phase1 i (list-less qs) ≡ true → (fin-phase1 (fromℕ< a a (subst (λ k → toℕ x < suc k ) (sym fin ¬a₁ ¬b c = f1-phase1 qs p (case2 q1) f1-phase1 (x ∷ qs) p (case1 q1) | tri> ¬a ¬b c with <-fcmp i (fromℕ< (≤-trans c (fin≤n (fromℕ< a ¬a₁ ¬b₂ c₁ = ⊥-elim ( ¬a₁ (subst₂ (λ j k → j < k) (sym fin+1-toℕ) (toℕ-fromℕ< _) a )) ... | tri≈ ¬a₁ b ¬c | tri< a ¬b₁ ¬c₁ = ⊥-elim ( ¬a₁ (subst₂ (λ j k → j < k) fin+1-toℕ (sym (toℕ-fromℕ< _)) a )) ... | tri≈ ¬a₁ b ¬c | tri≈ ¬a₂ b₁ ¬c₁ = f1-phase2 qs p (case1 q1) ... | tri≈ ¬a₁ b ¬c | tri> ¬a₂ ¬b₁ c₁ = ⊥-elim ( ¬c (subst₂ (λ j k → j > k) fin+1-toℕ (sym (toℕ-fromℕ< _)) c₁ )) ... | tri> ¬a₁ ¬b₁ c₁ | tri< a ¬b₂ ¬c = ⊥-elim ( ¬c (subst₂ (λ j k → j > k) (sym fin+1-toℕ) (toℕ-fromℕ< _) c₁ )) ... | tri> ¬a₁ ¬b₁ c₁ | tri≈ ¬a₂ b ¬c = ⊥-elim ( ¬c (subst₂ (λ j k → j > k) (sym fin+1-toℕ) (toℕ-fromℕ< _) c₁ )) ... | tri> ¬a₁ ¬b₁ c₁ | tri> ¬a₂ ¬b₂ c₂ = f1-phase1 qs p (case1 q1) f1-phase1 (x ∷ qs) p (case2 q1) with <-fcmp (fromℕ< a a (subst (λ k → toℕ x < suc k ) (sym fin ¬a ¬b c with <-fcmp i (fromℕ< (≤-trans c (fin≤n (fromℕ< a ¬a₁ ¬b₂ c₁ = ⊥-elim ( ¬a₁ (subst₂ (λ j k → j < k) (sym fin+1-toℕ) (toℕ-fromℕ< _) a )) ... | tri≈ ¬a₁ b ¬c | tri< a ¬b₁ ¬c₁ = ⊥-elim ( ¬a₁ (subst₂ (λ j k → j < k) fin+1-toℕ (sym (toℕ-fromℕ< _)) a )) ... | tri≈ ¬a₁ b ¬c | tri≈ ¬a₂ b₁ ¬c₁ = f1-phase2 qs p (case2 q1) ... | tri≈ ¬a₁ b ¬c | tri> ¬a₂ ¬b₁ c₁ = ⊥-elim ( ¬c (subst₂ (λ j k → j > k) fin+1-toℕ (sym (toℕ-fromℕ< _)) c₁ )) ... | tri> ¬a₁ ¬b₁ c₁ | tri< a ¬b₂ ¬c = ⊥-elim ( ¬c (subst₂ (λ j k → j > k) (sym fin+1-toℕ) (toℕ-fromℕ< _) c₁ )) ... | tri> ¬a₁ ¬b₁ c₁ | tri≈ ¬a₂ b ¬c = ⊥-elim ( ¬c (subst₂ (λ j k → j > k) (sym fin+1-toℕ) (toℕ-fromℕ< _) c₁ )) ... | tri> ¬a₁ ¬b₁ c₁ | tri> ¬a₂ ¬b₂ c₂ = f1-phase1 qs p (case2 q1) fdup-phase0 : FDup-in-list (suc n) qs fdup-phase0 with fin-dup-in-list (fromℕ< a suc n → fin-dup-in-list (fromℕ< a n1 → fin-phase2 (fromℕ< a a (subst (λ k → toℕ x < suc k ) (sym fin ¬a ¬b c = s≤s z≤n fl-phase2 (suc n1) (x ∷ qs) (s≤s lt) p with <-fcmp (fromℕ< a a (subst (λ k → toℕ x < suc k ) (sym fin ¬a ¬b c = s≤s ( fl-phase2 n1 qs lt p ) fl-phase1 : (n1 : ℕ) (qs : List (Fin (suc n))) → length qs > suc n1 → fin-phase1 (fromℕ< a a (subst (λ k → toℕ x < suc k ) (sym fin ¬a ¬b c = s≤s z≤n fl-phase1 (suc n1) (x ∷ qs) (s≤s lt) p with <-fcmp (fromℕ< a a (subst (λ k → toℕ x < suc k ) (sym fin ¬a ¬b c = s≤s ( fl-phase1 n1 qs lt p ) -- if the list without the max element is only one length shorter, we can recurse fdup : FDup-in-list n (list-less qs) fdup = fin-dup-in-list>n (list-less qs) (fless qs lt eq) --