module CoverageCheck.Data.List.Relation where
open import Haskell.Prelude hiding (All; Any; a; b; e)
open import Haskell.Data.Bifunctor
open import Haskell.Extra.Dec
open import Haskell.Extra.Erase
open import Haskell.Extra.Nat
open import Haskell.Extra.Sigma
open import Haskell.Extra.Refinement
open import Haskell.Law.Eq
open import Haskell.Law.Eq.Instances
open import Haskell.Law.Equality
open import CoverageCheck.Extra.Negation
open import CoverageCheck.Extra.DecP
private
variable
@0 e e' : Type
a b : @0 e → Type
@0 x y : e
@0 xs ys : List e
n : Nat
infixr 5 _∷_
data IsNth (@0 x : e) : (@0 xs : List e) → Nat → Type where
isZero : x ≡ y → IsNth x (y ∷ xs) zero
isSuc : IsNth x xs n → IsNth x (y ∷ xs) (suc n)
In : (@0 x : e) (@0 xs : List e) → Type
In x xs = ∃ Nat λ n → IsNth x xs n
{-# COMPILE AGDA2HS In inline #-}
pattern InHere = zero ⟨ isZero refl ⟩
inHere : In x (x ∷ xs)
inHere = InHere
{-# COMPILE AGDA2HS inHere inline #-}
pattern InThere n h = suc n ⟨ isSuc h ⟩
inThere : In x xs → In x (y ∷ xs)
inThere (n ⟨ h ⟩) = InThere n h
{-# COMPILE AGDA2HS inThere #-}
¬In[] : {@0 x : e} → ¬ In x []
¬In[] _ = undefined
@0 IsNth-unique : {@0 xs : List e} {@0 x y : e}
→ (p : IsNth x xs n) (q : IsNth y xs n)
→ Σ (x ≡ y) λ where refl → p ≡ q
IsNth-unique (isZero refl) (isZero refl) = refl , refl
IsNth-unique (isSuc p) (isSuc q)
with refl , refl ← IsNth-unique p q
= refl , refl
@0 In≡ : {@0 xs : List e} {@0 x y : e}
→ (p : In x xs) (q : In y xs)
→ p .value ≡ q .value
→ Σ (x ≡ y) λ where refl → p ≡ q
In≡ p q refl
with refl , refl ← IsNth-unique (p .proof) (q .proof)
= refl , refl
data All (a : @0 e → Type) : (@0 xs : List e) → Type where
[] : All a []
_∷_ : a x → All a xs → All a (x ∷ xs)
{-# COMPILE AGDA2HS All to List #-}
headAll : All a (x ∷ xs) → a x
headAll (x ∷ _) = x
{-# COMPILE AGDA2HS headAll to head #-}
tailAll : All a (x ∷ xs) → All a xs
tailAll (_ ∷ xs) = xs
{-# COMPILE AGDA2HS tailAll to tail #-}
mapAll : (∀ {@0 x} → a x → b x) → (∀ {@0 xs} → All a xs → All b xs)
mapAll f [] = []
mapAll f (x ∷ xs) = f x ∷ mapAll f xs
data Any (a : @0 e → Type) : (@0 xs : List e) → Type where
Here : a x → Any a (x ∷ xs)
There : Any a xs → Any a (y ∷ xs)
{-# COMPILE AGDA2HS Any deriving (Show, Eq, Ord) #-}
¬Any[] : ¬ Any a []
¬Any[] ()
anyToEither : Any a (x ∷ xs) → Either (a x) (Any a xs)
anyToEither (Here p) = Left p
anyToEither (There p) = Right p
data First (a : @0 e → Type) : (@0 xs : List e) → Type where
FHere : a x → First a (x ∷ xs)
FThere : @0 ¬ a y → First a xs → First a (y ∷ xs)
{-# COMPILE AGDA2HS First deriving (Show, Eq, Ord) #-}
tailFirst : ¬ a x → First a (x ∷ xs) → First a xs
tailFirst ¬p (FHere p) = contradiction p ¬p
tailFirst ¬p (FThere _ p) = p
¬First[] : ¬ First a []
¬First[] ()
firstDecP : ∀ {e} {a : @0 e → Type}
→ (∀ x → DecP (a x))
→ ∀ xs → DecP (First a xs)
firstDecP f [] = No ¬First[]
firstDecP f (x ∷ xs) = ifDecP (f x)
(λ ⦃ p ⦄ → Yes (FHere p))
(λ ⦃ ¬p ⦄ → mapDecP (FThere ¬p) (tailFirst ¬p) (firstDecP f xs))
{-# COMPILE AGDA2HS firstDecP #-}
data Many (a : @0 e → Type) : (@0 xs : List e) → Type where
MNil : Many a []
MHere : a x → Many a xs → Many a (x ∷ xs)
MThere : Many a xs → Many a (x ∷ xs)
{-# COMPILE AGDA2HS Many deriving (Eq, Show) #-}
tailMany : ∀ {@0 x xs} → Many a (x ∷ xs) → Many a xs
tailMany (MHere _ xs) = xs
tailMany (MThere xs) = xs
{-# COMPILE AGDA2HS tailMany #-}
trivialMany : ∀ xs → Many a xs
trivialMany [] = MNil
trivialMany (_ ∷ xs) = MThere (trivialMany xs)
manyDecP : {e : Type} {a : @0 e → Type}
→ (∀ x → DecP (a x))
→ ∀ xs → DecP (Many a xs)
manyDecP f [] = Yes MNil
manyDecP f (x ∷ xs) =
ifDecP (f x)
(λ ⦃ px ⦄ → mapDecP (MHere px) tailMany (manyDecP f xs))
(mapDecP MThere tailMany (manyDecP f xs))
{-# COMPILE AGDA2HS manyDecP #-}
data Some (a : @0 e → Type) : (@0 xs : List e) → Type where
SHere : a x → Many a xs → Some a (x ∷ xs)
SThere : Some a xs → Some a (x ∷ xs)
{-# COMPILE AGDA2HS Some deriving (Eq, Show) #-}
someToMany : ∀ {@0 xs} → Some a xs → Many a xs
someToMany (SHere x xs) = MHere x xs
someToMany (SThere xs) = MThere (someToMany xs)
{-# COMPILE AGDA2HS someToMany #-}
tailSome : ∀ {@0 x xs} → Some a (x ∷ xs) → Many a xs
tailSome (SHere x xs) = xs
tailSome (SThere xs) = someToMany xs
{-# COMPILE AGDA2HS tailSome #-}
unthereSome : @0 ¬ a x → Some a (x ∷ xs) → Some a xs
unthereSome ¬px (SHere x xs) = contradiction x ¬px
unthereSome ¬px (SThere xs) = xs
{-# COMPILE AGDA2HS unthereSome #-}
someDecP : {e : Type} {a : @0 e → Type}
→ (∀ x → DecP (a x))
→ ∀ xs → DecP (Some a xs)
someDecP f [] = No λ _ → undefined
someDecP f (x ∷ xs) =
ifDecP (f x)
(λ ⦃ px ⦄ → mapDecP (SHere px) tailSome (manyDecP f xs))
(λ ⦃ ¬px ⦄ → mapDecP SThere (unthereSome ¬px) (someDecP f xs))
{-# COMPILE AGDA2HS someDecP #-}
data HPointwise
{@0 e : Type} {@0 p q : @0 e → Type}
(a : ∀ {@0 x} → @0 p x → @0 q x → Type)
: ∀ {@0 xs} → @0 All p xs → @0 All q xs → Type
where
[] : HPointwise a [] []
_∷_ : ∀ {@0 x xs}
→ {@0 px : p x} {@0 pxs : All p xs}
→ {@0 qx : q x} {@0 qxs : All q xs}
→ a px qx
→ HPointwise a pxs qxs
→ HPointwise a (px ∷ pxs) (qx ∷ qxs)
{-# COMPILE AGDA2HS HPointwise to List #-}
All¬⇒¬Any : All (λ x → ¬ a x) xs → ¬ Any a xs
All¬⇒¬Any [] _ = undefined
All¬⇒¬Any (x ∷ xs) (Here p) = x p
All¬⇒¬Any (x ∷ xs) (There p) = All¬⇒¬Any xs p
¬Any⇒All¬ : ∀ xs → ¬ Any a xs → All (λ x → ¬ a x) xs
¬Any⇒All¬ [] ¬p = []
¬Any⇒All¬ (x ∷ xs) ¬p = ¬p ∘ Here ∷ ¬Any⇒All¬ xs (¬p ∘ There)
First⇒Any : First a xs → Any a xs
First⇒Any (FHere p) = Here p
First⇒Any (FThere _ p) = There (First⇒Any p)
¬First⇒¬Any : ¬ First a xs → ¬ Any a xs
¬First⇒¬Any ¬p (Here p) = ¬p (FHere p)
¬First⇒¬Any ¬p (There p) = ¬First⇒¬Any (¬p ∘ FThere (¬p ∘ FHere)) p
gmapAny⁺ : {@0 f : e → e'}
→ (∀ {@0 x} → a x → b (f x))
→ Any a xs → Any b (map f xs)
gmapAny⁺ g (Here p) = Here (g p)
gmapAny⁺ g (There p) = There (gmapAny⁺ g p)
++Any⁺ˡ : Any a xs → Any a (xs ++ ys)
++Any⁺ˡ (Here p) = Here p
++Any⁺ˡ (There p) = There (++Any⁺ˡ p)
++Any⁺ʳ : ∀ {xs} {@0 ys} → Any a ys → Any a (xs ++ ys)
++Any⁺ʳ {xs = []} p = p
++Any⁺ʳ {xs = x ∷ xs} p = There (++Any⁺ʳ p)
@0 gconcatMapAny⁺ : {@0 f : e → List e'}
→ (∀ {@0 x} → a x → Any b (f x))
→ Any a xs → Any b (concatMap f xs)
gconcatMapAny⁺ g (Here p) = ++Any⁺ˡ (g p)
gconcatMapAny⁺ g (There p) = ++Any⁺ʳ (gconcatMapAny⁺ g p)
++Any⁻ : ∀ xs {@0 ys} → Any a (xs ++ ys) → Either (Any a xs) (Any a ys)
++Any⁻ [] p = Right p
++Any⁻ (x ∷ xs) (Here p) = Left (Here p)
++Any⁻ (x ∷ xs) (There p) = bimap There id (++Any⁻ xs p)
gmapAny⁻ : {@0 f : e → e'}
→ (∀ {x} → b (f x) → a x)
→ ∀ {xs} → Any b (map f xs) → Any a xs
gmapAny⁻ g {x ∷ xs} (Here p) = Here (g p)
gmapAny⁻ g {x ∷ xs} (There p) = There (gmapAny⁻ g p)
gconcatMapAny⁻ : {f : e → List e'}
→ (∀ {x} → Any b (f x) → a x)
→ ∀ {xs} → Any b (concatMap f xs) → Any a xs
gconcatMapAny⁻ {f = f} g {x ∷ xs} p with ++Any⁻ (f x) p
... | Left q = Here (g q)
... | Right q = There (gconcatMapAny⁻ g q)
¬Some⇒All¬ : ∀ xs → ¬ Some a xs → All (λ x → ¬ a x) xs
¬Some⇒All¬ [] _ = []
¬Some⇒All¬ (x ∷ xs) ¬pxxs =
(λ px → ¬pxxs (SHere px (trivialMany xs))) ∷ ¬Some⇒All¬ xs (¬pxxs ∘ SThere)