module Vec.Relation.FirstOrNot where
open import Level
open import Function
open import Data.Bool
open import Data.Product
open import Data.Maybe as Maybe
open import Data.Nat
open import Data.Fin
open import Data.Vec as Vec
open import Relation.Nullary
private variable
ℓ ℓ1 : Level
A : Set ℓ
a : A
b : Bool
n : ℕ
P : A → Set ℓ
xs : Vec A n
data FirstOrNot {A : Set ℓ} (P : A → Set ℓ1) : Vec A n → Bool → Set (ℓ Level.⊔ ℓ1) where
notHere : FirstOrNot P [] false
here : (p : P a) (xs : Vec A n) → FirstOrNot P (a ∷ xs) true
there : (¬p : ¬ P a) {xs : Vec A n} (firstOrNot : FirstOrNot P xs b) → FirstOrNot P (a ∷ xs) b
FirstOrNotΣ : {A : Set ℓ} (P : A → Set ℓ1) (xs : Vec A n) → Set (ℓ Level.⊔ ℓ1)
FirstOrNotΣ P xs = Σ Bool $ FirstOrNot P xs
firstOrNotPosition : ∀ {xs : Vec A n} → FirstOrNot P xs true → Fin n
firstOrNotPosition (here p xs) = Fin.zero
firstOrNotPosition (there ¬p xs) = Fin.suc (firstOrNotPosition xs)
firstOrNotPositionMaybe : ∀ {xs : Vec A n} → FirstOrNot P xs b → Maybe $ Fin n
firstOrNotPositionMaybe {b = false} fxs = nothing
firstOrNotPositionMaybe {b = true} fxs = just $ firstOrNotPosition fxs
vReflect : (P : A → Set ℓ) → ℕ → Set _
vReflect P n = Vec (Σ[ x ∈ _ ] Σ[ b ∈ Bool ] Reflects (P x) b) n
boolVec→firstOrNot : (P : A → Set ℓ) (xs : vReflect P n) → FirstOrNotΣ P $ Vec.map proj₁ xs
boolVec→firstOrNot P [] = false , notHere
boolVec→firstOrNot P ((x , false , ofⁿ ¬p) ∷ xs) = _ , there ¬p (boolVec→firstOrNot P xs .proj₂)
boolVec→firstOrNot P ((x , true , ofʸ p) ∷ xs) = true , here p (Vec.map proj₁ xs)
firstOfVReflect : vReflect P n → Maybe $ Fin n
firstOfVReflect [] = nothing
firstOfVReflect ((_ , false , _) ∷ xs) = Maybe.map Fin.suc $ firstOfVReflect xs
firstOfVReflect ((_ , true , _) ∷ xs) = just $ Fin.zero
firstOrNotFromDec : (P? : ∀ a → Dec $ P a) (xs : Vec A n) → FirstOrNotΣ P xs
firstOrNotFromDec P? [] = _ , notHere
firstOrNotFromDec P? (x ∷ xs) with P? x
... | yes p = true , here p xs
... | no ¬p = _ , there ¬p (proj₂ $ firstOrNotFromDec P? xs)
firstTrue : Vec Bool n → Maybe $ Fin n
firstTrue [] = nothing
firstTrue (true ∷ xs) = just $ Fin.zero
firstTrue (false ∷ xs) = Maybe.map Fin.suc (firstTrue xs)