{-# OPTIONS --safe #-}
module Prelude.Irrelevance where
open import Prelude.Init
open import Prelude.Decidable
open import Prelude.Anyable
≡-irrelevant : ∀ {A : Type} {x y : A} → Irrelevant (x ≡ y)
≡-irrelevant refl refl = refl
T-irrelevant : ∀ {b} → Irrelevant (T b)
T-irrelevant {false} ()
T-irrelevant {true}  _ _ = refl
private variable A : Type ℓ
private data ∅ : Type where
record ·⊥ : Type where
  field .absurd : ∅
·⊥-elim : ·⊥ → A
·⊥-elim ()
·⊥⇒⊥ = (·⊥ → ⊥) ∋ ·⊥-elim
⊥⇒·⊥ = (⊥ → ·⊥) ∋ ⊥-elim
·⊥⇔⊥ = (·⊥ ↔ ⊥) ∋ ·⊥⇒⊥ , ⊥⇒·⊥
infix 3 ·¬_
·¬_ : Type ℓ → Type ℓ
·¬_ A = A → ·⊥
·¬-irrelevant : Irrelevant (·¬ A)
·¬-irrelevant _ _ = refl
·¬⇒¬ : ·¬ A → ¬ A
·¬⇒¬ ¬p = ·⊥-elim ∘ ¬p
¬⇒·¬ : ¬ A → ·¬ A
¬⇒·¬ ¬p = ⊥-elim ∘ ¬p
instance
  Dec-·⊥ : ·⊥ ⁇
  Dec-·⊥ .dec = no λ ()
private variable P : Pred A ℓ′
AnyFirst : ∀ {A : Type ℓ} → Pred A ℓ′ → Pred (List A) _
AnyFirst P = First (·¬_ ∘ P) P
module _ {a p} {A : Set a} where
  ·∁ : Pred A ℓ′ → Pred A ℓ′
  (·∁ P) x = ·¬ P x
  import Relation.Nullary.Decidable as Dec
  module _ {P : Pred A p} where
    AnyFirst-irrelevant : Irrelevant¹ P → Irrelevant¹ (AnyFirst P)
    AnyFirst-irrelevant = L.First.irrelevant (·⊥-elim ∘₂ _$_) ·¬-irrelevant
    first? : Decidable¹ P → Decidable¹ (First P (·∁ P))
    first? P? xs = mapDec (L.First.map id ¬⇒·¬) (L.First.map id ·¬⇒¬)
                          (L.First.first? P? xs)
    cofirst? : Decidable¹ P → Decidable¹ (First (·∁ P) P)
    cofirst? P? xs = mapDec (L.First.map ¬⇒·¬ id)  (L.First.map ·¬⇒¬ id)
                            (L.First.cofirst? P? xs)
instance
  Dec-AnyFirst : ⦃ P ⁇¹ ⦄ → AnyFirst P ⁇¹
  Dec-AnyFirst .dec = cofirst? dec¹ _
module _ {A : Type ℓ} {P : A → Type} where
  private variable xs : List A
  AnyFirst⇒Any : AnyFirst P xs → Any P xs
  AnyFirst⇒Any = L.First.toAny
  firstIndex : AnyFirst P xs → Fin (length xs)
  firstIndex = L.Any.index ∘ AnyFirst⇒Any
  module _ ⦃ _ : P ⁇¹ ⦄ where
    Any⇒AnyFirst : Any P xs → AnyFirst P xs
    Any⇒AnyFirst (here px) = First.[ px ]
    Any⇒AnyFirst (there p) with ¿ P _ ¿
    ... | yes px = First.[ px ]
    ... | no ¬px = ¬⇒·¬ ¬px ∷ Any⇒AnyFirst p