{-# OPTIONS --cubical-compatible --safe #-}
module Data.List.Relation.Unary.All.Properties where
open import Axiom.Extensionality.Propositional using (Extensionality)
open import Data.Bool.Base using (Bool; T; true; false)
open import Data.Bool.Properties using (T-∧)
open import Data.Fin.Base using (Fin; zero; suc)
open import Data.List.Base as List hiding (lookup; updateAt)
open import Data.List.Membership.Propositional using (_∈_; _≢∈_)
open import Data.List.Membership.Propositional.Properties
using (there-injective-≢∈; ∈-filter⁻)
import Data.List.Membership.Setoid as SetoidMembership
import Data.List.Properties as List
import Data.List.Relation.Binary.Equality.Setoid as ≋
open import Data.List.Relation.Binary.Pointwise.Base using (Pointwise; []; _∷_)
open import Data.List.Relation.Binary.Subset.Propositional using (_⊆_)
open import Data.List.Relation.Unary.All as All using
( All; []; _∷_; lookup; updateAt
; _[_]=_; here; there
; Null
)
open import Data.List.Relation.Unary.Any as Any using (Any; here; there)
open import Data.Maybe.Base as Maybe using (Maybe; just; nothing)
open import Data.Maybe.Relation.Unary.All as Maybe using (just; nothing; fromAny)
open import Data.Maybe.Relation.Unary.Any as Maybe using (just)
open import Data.Nat.Base using (zero; suc; s≤s; _<_; z<s; s<s)
open import Data.Nat.Properties using (≤-refl; m≤n⇒m≤1+n)
open import Data.Product.Base as Product using (_×_; _,_; uncurry; uncurry′)
open import Function.Base using (_∘_; _$_; id; case_of_; flip)
open import Function.Bundles using (_↠_; mk↠ₛ; _⇔_; mk⇔; _↔_; mk↔ₛ′; Equivalence)
open import Level using (Level)
open import Relation.Binary.Core using (REL)
open import Relation.Binary.Bundles using (Setoid)
import Relation.Binary.Definitions as B
open import Relation.Binary.PropositionalEquality.Core
using (_≡_; refl; cong; cong₂; _≗_)
open import Relation.Nullary.Reflects using (invert)
open import Relation.Nullary.Negation.Core using (¬_; contradiction)
open import Relation.Nullary.Decidable
using (Dec; does; yes; no; _because_; ¬?; decidable-stable)
open import Relation.Unary
using (Decidable; Pred; Universal; ∁; _∩_; _⟨×⟩_) renaming (_⊆_ to _⋐_)
open import Relation.Unary.Properties using (∁?)
private
variable
a b c p q r ℓ ℓ₁ ℓ₂ : Level
A : Set a
B : Set b
C : Set c
P : Pred A p
Q : Pred B q
R : Pred C r
x y : A
xs ys : List A
Null⇒null : Null xs → T (null xs)
Null⇒null [] = _
null⇒Null : T (null xs) → Null xs
null⇒Null {xs = [] } _ = []
null⇒Null {xs = _ ∷ _} ()
[]=-injective : ∀ {px qx : P x} {pxs : All P xs} {i : x ∈ xs} →
pxs [ i ]= px →
pxs [ i ]= qx →
px ≡ qx
[]=-injective here here = refl
[]=-injective (there x↦px) (there x↦qx) = []=-injective x↦px x↦qx
¬Any⇒All¬ : ∀ xs → ¬ Any P xs → All (¬_ ∘ P) xs
¬Any⇒All¬ [] ¬p = []
¬Any⇒All¬ (x ∷ xs) ¬p = ¬p ∘ here ∷ ¬Any⇒All¬ xs (¬p ∘ there)
All¬⇒¬Any : ∀ {xs} → All (¬_ ∘ P) xs → ¬ Any P xs
All¬⇒¬Any (¬p ∷ _) (here p) = ¬p p
All¬⇒¬Any (_ ∷ ¬p) (there p) = All¬⇒¬Any ¬p p
¬All⇒Any¬ : Decidable P → ∀ xs → ¬ All P xs → Any (¬_ ∘ P) xs
¬All⇒Any¬ dec [] ¬∀ = contradiction [] ¬∀
¬All⇒Any¬ dec (x ∷ xs) ¬∀ with dec x
... | true because [p] = there (¬All⇒Any¬ dec xs (¬∀ ∘ _∷_ (invert [p])))
... | false because [¬p] = here (invert [¬p])
Any¬⇒¬All : ∀ {xs} → Any (¬_ ∘ P) xs → ¬ All P xs
Any¬⇒¬All (here ¬p) = ¬p ∘ All.head
Any¬⇒¬All (there ¬p) = Any¬⇒¬All ¬p ∘ All.tail
¬Any↠All¬ : ∀ {xs} → (¬ Any P xs) ↠ All (¬_ ∘ P) xs
¬Any↠All¬ = mk↠ₛ {to = ¬Any⇒All¬ _} (λ y → All¬⇒¬Any y , to∘from y)
where
to∘from : ∀ {xs} (¬p : All (¬_ ∘ P) xs) → ¬Any⇒All¬ xs (All¬⇒¬Any ¬p) ≡ ¬p
to∘from [] = refl
to∘from (¬p ∷ ¬ps) = cong₂ _∷_ refl (to∘from ¬ps)
from∘to : Extensionality _ _ →
∀ xs → (¬p : ¬ Any P xs) → All¬⇒¬Any (¬Any⇒All¬ xs ¬p) ≡ ¬p
from∘to ext [] ¬p = ext λ ()
from∘to ext (x ∷ xs) ¬p = ext λ
{ (here p) → refl
; (there p) → cong (λ f → f p) $ from∘to ext xs (¬p ∘ there)
}
Any¬⇔¬All : ∀ {xs} → Decidable P → Any (¬_ ∘ P) xs ⇔ (¬ All P xs)
Any¬⇔¬All dec = mk⇔ Any¬⇒¬All (¬All⇒Any¬ dec _)
private
to∘from : Extensionality _ _ → (dec : Decidable P) →
(¬∀ : ¬ All P xs) → Any¬⇒¬All (¬All⇒Any¬ dec xs ¬∀) ≡ ¬∀
to∘from ext P ¬∀ = ext λ ∀P → contradiction ∀P ¬∀
module _ {_~_ : REL A B ℓ} where
All-swap : ∀ {xs ys} →
All (λ x → All (x ~_) ys) xs →
All (λ y → All (_~ y) xs) ys
All-swap {ys = []} _ = []
All-swap {ys = y ∷ ys} [] = All.universal (λ _ → []) (y ∷ ys)
All-swap {ys = y ∷ ys} ((x~y ∷ x~ys) ∷ pxs) =
(x~y ∷ (All.map All.head pxs)) ∷
All-swap (x~ys ∷ (All.map All.tail pxs))
[]=lookup : (pxs : All P xs) (i : x ∈ xs) →
pxs [ i ]= lookup pxs i
[]=lookup (px ∷ pxs) (here refl) = here
[]=lookup (px ∷ pxs) (there i) = there ([]=lookup pxs i)
[]=⇒lookup : ∀ {px : P x} {pxs : All P xs} {i : x ∈ xs} →
pxs [ i ]= px →
lookup pxs i ≡ px
[]=⇒lookup x↦px = []=-injective ([]=lookup _ _) x↦px
lookup⇒[]= : ∀ {px : P x} (pxs : All P xs) (i : x ∈ xs) →
lookup pxs i ≡ px →
pxs [ i ]= px
lookup⇒[]= pxs i refl = []=lookup pxs i
map-cong : ∀ {f : P ⋐ Q} {g : P ⋐ Q} (pxs : All P xs) →
(∀ {x} → f {x} ≗ g) → All.map f pxs ≡ All.map g pxs
map-cong [] _ = refl
map-cong (px ∷ pxs) feq = cong₂ _∷_ (feq px) (map-cong pxs feq)
map-id : ∀ (pxs : All P xs) → All.map id pxs ≡ pxs
map-id [] = refl
map-id (px ∷ pxs) = cong (px ∷_) (map-id pxs)
map-∘ : ∀ {f : P ⋐ Q} {g : Q ⋐ R} (pxs : All P xs) →
All.map g (All.map f pxs) ≡ All.map (g ∘ f) pxs
map-∘ [] = refl
map-∘ (px ∷ pxs) = cong (_ ∷_) (map-∘ pxs)
lookup-map : ∀ {f : P ⋐ Q} (pxs : All P xs) (i : x ∈ xs) →
lookup (All.map f pxs) i ≡ f (lookup pxs i)
lookup-map (px ∷ pxs) (here refl) = refl
lookup-map (px ∷ pxs) (there i) = lookup-map pxs i
updateAt-updates : ∀ (i : x ∈ xs) {f : P x → P x} {px : P x} (pxs : All P xs) →
pxs [ i ]= px →
updateAt i f pxs [ i ]= f px
updateAt-updates (here refl) (px ∷ pxs) here = here
updateAt-updates (there i) (px ∷ pxs) (there x↦px) =
there (updateAt-updates i pxs x↦px)
updateAt-minimal : ∀ (i : x ∈ xs) (j : y ∈ xs) →
∀ {f : P y → P y} {px : P x} (pxs : All P xs) →
i ≢∈ j →
pxs [ i ]= px →
updateAt j f pxs [ i ]= px
updateAt-minimal (here .refl) (here refl) (px ∷ pxs) i≢j here =
contradiction refl (i≢j refl)
updateAt-minimal (here .refl) (there j) (px ∷ pxs) i≢j here = here
updateAt-minimal (there i) (here refl) (px ∷ pxs) i≢j (there val) = there val
updateAt-minimal (there i) (there j) (px ∷ pxs) i≢j (there val) =
there (updateAt-minimal i j pxs (there-injective-≢∈ i≢j) val)
lookup∘updateAt : ∀ (pxs : All P xs) (i : x ∈ xs) {f : P x → P x} →
lookup (updateAt i f pxs) i ≡ f (lookup pxs i)
lookup∘updateAt pxs i =
[]=⇒lookup (updateAt-updates i pxs (lookup⇒[]= pxs i refl))
lookup∘updateAt′ : ∀ (i : x ∈ xs) (j : y ∈ xs) →
∀ {f : P y → P y} {px : P x} (pxs : All P xs) →
i ≢∈ j →
lookup (updateAt j f pxs) i ≡ lookup pxs i
lookup∘updateAt′ i j pxs i≢j =
[]=⇒lookup (updateAt-minimal i j pxs i≢j (lookup⇒[]= pxs i refl))
updateAt-id-local : ∀ (i : x ∈ xs) {f : P x → P x} (pxs : All P xs) →
f (lookup pxs i) ≡ lookup pxs i →
updateAt i f pxs ≡ pxs
updateAt-id-local (here refl)(px ∷ pxs) eq = cong (_∷ pxs) eq
updateAt-id-local (there i) (px ∷ pxs) eq = cong (px ∷_) (updateAt-id-local i pxs eq)
updateAt-id : ∀ (i : x ∈ xs) (pxs : All P xs) → updateAt i id pxs ≡ pxs
updateAt-id i pxs = updateAt-id-local i pxs refl
updateAt-∘-local : ∀ (i : x ∈ xs) {f g h : P x → P x} (pxs : All P xs) →
f (g (lookup pxs i)) ≡ h (lookup pxs i) →
updateAt i f (updateAt i g pxs) ≡ updateAt i h pxs
updateAt-∘-local (here refl) (px ∷ pxs) fg=h = cong (_∷ pxs) fg=h
updateAt-∘-local (there i) (px ∷ pxs) fg=h = cong (px ∷_) (updateAt-∘-local i pxs fg=h)
updateAt-∘ : ∀ (i : x ∈ xs) {f g : P x → P x} →
updateAt {P = P} i f ∘ updateAt i g ≗ updateAt i (f ∘ g)
updateAt-∘ i pxs = updateAt-∘-local i pxs refl
updateAt-cong-local : ∀ (i : x ∈ xs) {f g : P x → P x} (pxs : All P xs) →
f (lookup pxs i) ≡ g (lookup pxs i) →
updateAt i f pxs ≡ updateAt i g pxs
updateAt-cong-local (here refl) (px ∷ pxs) f=g = cong (_∷ pxs) f=g
updateAt-cong-local (there i) (px ∷ pxs) f=g = cong (px ∷_) (updateAt-cong-local i pxs f=g)
updateAt-cong : ∀ (i : x ∈ xs) {f g : P x → P x} →
f ≗ g → updateAt {P = P} i f ≗ updateAt i g
updateAt-cong i f≗g pxs = updateAt-cong-local i pxs (f≗g (lookup pxs i))
updateAt-commutes : ∀ (i : x ∈ xs) (j : y ∈ xs) →
∀ {f : P x → P x} {g : P y → P y} →
i ≢∈ j →
updateAt {P = P} i f ∘ updateAt j g ≗ updateAt j g ∘ updateAt i f
updateAt-commutes (here refl) (here refl) i≢j (px ∷ pxs) =
contradiction refl (i≢j refl)
updateAt-commutes (here refl) (there j) i≢j (px ∷ pxs) = refl
updateAt-commutes (there i) (here refl) i≢j (px ∷ pxs) = refl
updateAt-commutes (there i) (there j) i≢j (px ∷ pxs) =
cong (px ∷_) (updateAt-commutes i j (there-injective-≢∈ i≢j) pxs)
map-updateAt : ∀ {f : P ⋐ Q} {g : P x → P x} {h : Q x → Q x}
(pxs : All P xs) (i : x ∈ xs) →
f (g (lookup pxs i)) ≡ h (f (lookup pxs i)) →
All.map f (pxs All.[ i ]%= g) ≡ (All.map f pxs) All.[ i ]%= h
map-updateAt (px ∷ pxs) (here refl) = cong (_∷ _)
map-updateAt (px ∷ pxs) (there i) feq = cong (_ ∷_) (map-updateAt pxs i feq)
singleton⁻ : All P [ x ] → P x
singleton⁻ (px ∷ []) = px
head⁺ : All P xs → Maybe.All P (head xs)
head⁺ [] = nothing
head⁺ (px ∷ _) = just px
tail⁺ : All P xs → Maybe.All (All P) (tail xs)
tail⁺ [] = nothing
tail⁺ (_ ∷ pxs) = just pxs
last⁺ : All P xs → Maybe.All P (last xs)
last⁺ [] = nothing
last⁺ (px ∷ []) = just px
last⁺ (px ∷ pxs@(_ ∷ _)) = last⁺ pxs
uncons⁺ : All P xs → Maybe.All (P ⟨×⟩ All P) (uncons xs)
uncons⁺ [] = nothing
uncons⁺ (px ∷ pxs) = just (px , pxs)
uncons⁻ : Maybe.All (P ⟨×⟩ All P) (uncons xs) → All P xs
uncons⁻ {xs = []} nothing = []
uncons⁻ {xs = x ∷ xs} (just (px , pxs)) = px ∷ pxs
map⁺ : ∀ {f : A → B} → All (P ∘ f) xs → All P (map f xs)
map⁺ [] = []
map⁺ (p ∷ ps) = p ∷ map⁺ ps
map⁻ : ∀ {f : A → B} → All P (map f xs) → All (P ∘ f) xs
map⁻ {xs = []} [] = []
map⁻ {xs = _ ∷ _} (p ∷ ps) = p ∷ map⁻ ps
gmap⁺ : ∀ {f : A → B} → P ⋐ Q ∘ f → All P ⋐ All Q ∘ map f
gmap⁺ g = map⁺ ∘ All.map g
gmap⁻ : ∀ {f : A → B} → Q ∘ f ⋐ P → All Q ∘ map f ⋐ All P
gmap⁻ g = All.map g ∘ map⁻
mapMaybe⁺ : ∀ {f : A → Maybe B} →
All (Maybe.All P) (map f xs) → All P (mapMaybe f xs)
mapMaybe⁺ {xs = []} {f = f} [] = []
mapMaybe⁺ {xs = x ∷ xs} {f = f} (px ∷ pxs) with f x
... | nothing = mapMaybe⁺ pxs
... | just v with just pv ← px = pv ∷ mapMaybe⁺ pxs
All-catMaybes⁺ : All (Maybe.All P) xs → All P (catMaybes xs)
All-catMaybes⁺ [] = []
All-catMaybes⁺ (just px ∷ pxs) = px ∷ All-catMaybes⁺ pxs
All-catMaybes⁺ (nothing ∷ pxs) = All-catMaybes⁺ pxs
Any-catMaybes⁺ : All (Maybe.Any P) xs → All P (catMaybes xs)
Any-catMaybes⁺ = All-catMaybes⁺ ∘ All.map fromAny
++⁺ : All P xs → All P ys → All P (xs ++ ys)
++⁺ [] pys = pys
++⁺ (px ∷ pxs) pys = px ∷ ++⁺ pxs pys
++⁻ˡ : ∀ xs {ys} → All P (xs ++ ys) → All P xs
++⁻ˡ [] p = []
++⁻ˡ (x ∷ xs) (px ∷ pxs) = px ∷ (++⁻ˡ _ pxs)
++⁻ʳ : ∀ xs {ys} → All P (xs ++ ys) → All P ys
++⁻ʳ [] p = p
++⁻ʳ (x ∷ xs) (px ∷ pxs) = ++⁻ʳ xs pxs
++⁻ : ∀ xs {ys} → All P (xs ++ ys) → All P xs × All P ys
++⁻ [] p = [] , p
++⁻ (x ∷ xs) (px ∷ pxs) = Product.map (px ∷_) id (++⁻ _ pxs)
++↔ : (All P xs × All P ys) ↔ All P (xs ++ ys)
++↔ {xs = zs} = mk↔ₛ′ (uncurry ++⁺) (++⁻ zs) (++⁺∘++⁻ zs) ++⁻∘++⁺
where
++⁺∘++⁻ : ∀ xs (p : All P (xs ++ ys)) → uncurry′ ++⁺ (++⁻ xs p) ≡ p
++⁺∘++⁻ [] p = refl
++⁺∘++⁻ (x ∷ xs) (px ∷ pxs) = cong (_∷_ px) $ ++⁺∘++⁻ xs pxs
++⁻∘++⁺ : ∀ (p : All P xs × All P ys) → ++⁻ xs (uncurry ++⁺ p) ≡ p
++⁻∘++⁺ ([] , pys) = refl
++⁻∘++⁺ (px ∷ pxs , pys) rewrite ++⁻∘++⁺ (pxs , pys) = refl
concat⁺ : ∀ {xss} → All (All P) xss → All P (concat xss)
concat⁺ [] = []
concat⁺ (pxs ∷ pxss) = ++⁺ pxs (concat⁺ pxss)
concat⁻ : ∀ {xss} → All P (concat xss) → All (All P) xss
concat⁻ {xss = []} [] = []
concat⁻ {xss = xs ∷ xss} pxs = ++⁻ˡ xs pxs ∷ concat⁻ (++⁻ʳ xs pxs)
∷ʳ⁺ : All P xs → P x → All P (xs ∷ʳ x)
∷ʳ⁺ pxs px = ++⁺ pxs (px ∷ [])
∷ʳ⁻ : All P (xs ∷ʳ x) → All P xs × P x
∷ʳ⁻ pxs = Product.map₂ singleton⁻ $ ++⁻ _ pxs
unsnoc⁺ : All P xs → Maybe.All (All P ⟨×⟩ P) (unsnoc xs)
unsnoc⁺ {xs = xs} pxs with initLast xs
unsnoc⁺ {xs = .[]} pxs | [] = nothing
unsnoc⁺ {xs = .(xs ∷ʳ x)} pxs | xs ∷ʳ′ x = just (∷ʳ⁻ pxs)
unsnoc⁻ : Maybe.All (All P ⟨×⟩ P) (unsnoc xs) → All P xs
unsnoc⁻ {xs = xs} pxs with initLast xs
unsnoc⁻ {xs = .[]} nothing | [] = []
unsnoc⁻ {xs = .(xs ∷ʳ x)} (just (pxs , px)) | xs ∷ʳ′ x = ∷ʳ⁺ pxs px
module _ (S₁ : Setoid a ℓ₁) (S₂ : Setoid b ℓ₂) where
open SetoidMembership S₁ using () renaming (_∈_ to _∈₁_)
open SetoidMembership S₂ using () renaming (_∈_ to _∈₂_)
cartesianProductWith⁺ : ∀ f xs ys →
(∀ {x y} → x ∈₁ xs → y ∈₂ ys → P (f x y)) →
All P (cartesianProductWith f xs ys)
cartesianProductWith⁺ f [] ys pres = []
cartesianProductWith⁺ f (x ∷ xs) ys pres = ++⁺
(map⁺ (All.tabulateₛ S₂ (pres (here (Setoid.refl S₁)))))
(cartesianProductWith⁺ f xs ys (pres ∘ there))
cartesianProduct⁺ : ∀ xs ys →
(∀ {x y} → x ∈₁ xs → y ∈₂ ys → P (x , y)) →
All P (cartesianProduct xs ys)
cartesianProduct⁺ = cartesianProductWith⁺ _,_
drop⁺ : ∀ n → All P xs → All P (drop n xs)
drop⁺ zero pxs = pxs
drop⁺ (suc n) [] = []
drop⁺ (suc n) (px ∷ pxs) = drop⁺ n pxs
dropWhile⁺ : (Q? : Decidable Q) → All P xs → All P (dropWhile Q? xs)
dropWhile⁺ Q? [] = []
dropWhile⁺ {xs = x ∷ xs} Q? (px ∷ pxs) with does (Q? x)
... | true = dropWhile⁺ Q? pxs
... | false = px ∷ pxs
dropWhile⁻ : (P? : Decidable P) → dropWhile P? xs ≡ [] → All P xs
dropWhile⁻ {xs = []} P? eq = []
dropWhile⁻ {xs = x ∷ xs} P? eq with P? x
... | yes px = px ∷ (dropWhile⁻ P? eq)
... | no ¬px = case eq of λ ()
all-head-dropWhile : (P? : Decidable P) →
∀ xs → Maybe.All (∁ P) (head (dropWhile P? xs))
all-head-dropWhile P? [] = nothing
all-head-dropWhile P? (x ∷ xs) with P? x
... | yes px = all-head-dropWhile P? xs
... | no ¬px = just ¬px
take⁺ : ∀ n → All P xs → All P (take n xs)
take⁺ zero pxs = []
take⁺ (suc n) [] = []
take⁺ (suc n) (px ∷ pxs) = px ∷ take⁺ n pxs
takeWhile⁺ : (Q? : Decidable Q) → All P xs → All P (takeWhile Q? xs)
takeWhile⁺ Q? [] = []
takeWhile⁺ {xs = x ∷ xs} Q? (px ∷ pxs) with does (Q? x)
... | true = px ∷ takeWhile⁺ Q? pxs
... | false = []
takeWhile⁻ : (P? : Decidable P) → takeWhile P? xs ≡ xs → All P xs
takeWhile⁻ {xs = []} P? eq = []
takeWhile⁻ {xs = x ∷ xs} P? eq with P? x
... | yes px = px ∷ takeWhile⁻ P? (List.∷-injectiveʳ eq)
... | no ¬px = case eq of λ ()
all-takeWhile : (P? : Decidable P) → ∀ xs → All P (takeWhile P? xs)
all-takeWhile P? [] = []
all-takeWhile P? (x ∷ xs) with P? x
... | yes px = px ∷ all-takeWhile P? xs
... | no ¬px = []
applyUpTo⁺₁ : ∀ f n → (∀ {i} → i < n → P (f i)) → All P (applyUpTo f n)
applyUpTo⁺₁ f zero Pf = []
applyUpTo⁺₁ f (suc n) Pf = Pf z<s ∷ applyUpTo⁺₁ (f ∘ suc) n (Pf ∘ s<s)
applyUpTo⁺₂ : ∀ f n → (∀ i → P (f i)) → All P (applyUpTo f n)
applyUpTo⁺₂ f n Pf = applyUpTo⁺₁ f n (λ _ → Pf _)
applyUpTo⁻ : ∀ f n → All P (applyUpTo f n) → ∀ {i} → i < n → P (f i)
applyUpTo⁻ f (suc n) (px ∷ _) z<s = px
applyUpTo⁻ f (suc n) (_ ∷ pxs) (s<s i<n@(s≤s _)) =
applyUpTo⁻ (f ∘ suc) n pxs i<n
all-upTo : ∀ n → All (_< n) (upTo n)
all-upTo n = applyUpTo⁺₁ id n id
applyDownFrom⁺₁ : ∀ f n → (∀ {i} → i < n → P (f i)) → All P (applyDownFrom f n)
applyDownFrom⁺₁ f zero Pf = []
applyDownFrom⁺₁ f (suc n) Pf = Pf ≤-refl ∷ applyDownFrom⁺₁ f n (Pf ∘ m≤n⇒m≤1+n)
applyDownFrom⁺₂ : ∀ f n → (∀ i → P (f i)) → All P (applyDownFrom f n)
applyDownFrom⁺₂ f n Pf = applyDownFrom⁺₁ f n (λ _ → Pf _)
tabulate⁺ : ∀ {n} {f : Fin n → A} →
(∀ i → P (f i)) → All P (tabulate f)
tabulate⁺ {n = zero} Pf = []
tabulate⁺ {n = suc _} Pf = Pf zero ∷ tabulate⁺ (Pf ∘ suc)
tabulate⁻ : ∀ {n} {f : Fin n → A} →
All P (tabulate f) → (∀ i → P (f i))
tabulate⁻ (px ∷ _) zero = px
tabulate⁻ (_ ∷ pf) (suc i) = tabulate⁻ pf i
─⁺ : ∀ (p : Any P xs) → All Q xs → All Q (xs Any.─ p)
─⁺ (here px) (_ ∷ qs) = qs
─⁺ (there p) (q ∷ qs) = q ∷ ─⁺ p qs
─⁻ : ∀ (p : Any P xs) → Q (Any.lookup p) → All Q (xs Any.─ p) → All Q xs
─⁻ (here px) q qs = q ∷ qs
─⁻ (there p) q (q′ ∷ qs) = q′ ∷ ─⁻ p q qs
module _ (P? : Decidable P) where
all-filter : ∀ xs → All P (filter P? xs)
all-filter [] = []
all-filter (x ∷ xs) with P? x
... | true because [Px] = invert [Px] ∷ all-filter xs
... | false because _ = all-filter xs
filter⁺ : All Q xs → All Q (filter P? xs)
filter⁺ {xs = _} [] = []
filter⁺ {xs = x ∷ _} (Qx ∷ Qxs) with does (P? x)
... | false = filter⁺ Qxs
... | true = Qx ∷ filter⁺ Qxs
filter⁻ : All Q (filter P? xs) → All Q (filter (¬? ∘ P?) xs) → All Q xs
filter⁻ {xs = []} [] [] = []
filter⁻ {xs = x ∷ _} all⁺ all⁻ with P? x | ¬? (P? x)
filter⁻ {xs = x ∷ _} all⁺ all⁻ | yes Px | yes ¬Px = contradiction Px ¬Px
filter⁻ {xs = x ∷ _} (qx ∷ all⁺) all⁻ | yes Px | no ¬¬Px = qx ∷ filter⁻ all⁺ all⁻
filter⁻ {xs = x ∷ _} all⁺ (qx ∷ all⁻) | no _ | yes ¬Px = qx ∷ filter⁻ all⁺ all⁻
filter⁻ {xs = x ∷ _} all⁺ all⁻ | no ¬Px | no ¬¬Px = contradiction ¬Px ¬¬Px
module _ {P : A → Set p} (P? : Decidable P) where
partition-All : ∀ xs → (let ys , zs = partition P? xs) →
All P ys × All (∁ P) zs
partition-All xs rewrite List.partition-defn P? xs =
all-filter P? xs , all-filter (∁? P?) xs
module _ {R : A → A → Set q} (R? : B.Decidable R) where
derun⁺ : All P xs → All P (derun R? xs)
derun⁺ {xs = []} [] = []
derun⁺ {xs = x ∷ []} (px ∷ []) = px ∷ []
derun⁺ {xs = x ∷ y ∷ xs} (px ∷ all[P,y∷xs]) with does (R? x y)
... | false = px ∷ derun⁺ all[P,y∷xs]
... | true = derun⁺ all[P,y∷xs]
deduplicate⁺ : All P xs → All P (deduplicate R? xs)
deduplicate⁺ [] = []
deduplicate⁺ (px ∷ pxs) = px ∷ filter⁺ (¬? ∘ R? _) (deduplicate⁺ pxs)
derun⁻ : P B.Respects (flip R) → ∀ xs → All P (derun R? xs) → All P xs
derun⁻ {P = P} P-resp-R [] [] = []
derun⁻ {P = P} P-resp-R (x ∷ xs) all[P,x∷xs] = aux x xs all[P,x∷xs]
where
aux : ∀ x xs → All P (derun R? (x ∷ xs)) → All P (x ∷ xs)
aux x [] (px ∷ []) = px ∷ []
aux x (y ∷ xs) all[P,x∷y∷xs] with R? x y
aux x (y ∷ xs) all[P,y∷xs] | yes Rxy
with r@(py ∷ _) ← aux y xs all[P,y∷xs] = P-resp-R Rxy py ∷ r
aux x (y ∷ xs) (px ∷ all[P,y∷xs]) | no _ = px ∷ aux y xs all[P,y∷xs]
deduplicate⁻ : P B.Respects R → ∀ xs → All P (deduplicate R? xs) → All P xs
deduplicate⁻ {P = P} resp [] [] = []
deduplicate⁻ {P = P} resp (x ∷ xs) (px ∷ pxs!) =
px ∷ deduplicate⁻ resp xs (filter⁻ (¬? ∘ R? x) pxs! (All.tabulate aux))
where
aux : ∀ {z} → z ∈ filter (¬? ∘ ¬? ∘ R? x) (deduplicate R? xs) → P z
aux {z = z} z∈filter = resp (decidable-stable (R? x z)
(Product.proj₂ (∈-filter⁻ (¬? ∘ ¬? ∘ R? x) {z} {deduplicate R? xs} z∈filter))) px
zipWith⁺ : ∀ (f : A → B → C) → Pointwise (λ x y → P (f x y)) xs ys →
All P (zipWith f xs ys)
zipWith⁺ f [] = []
zipWith⁺ f (Pfxy ∷ Pfxsys) = Pfxy ∷ zipWith⁺ f Pfxsys
fromMaybe⁺ : ∀ {mx} → Maybe.All P mx → All P (fromMaybe mx)
fromMaybe⁺ (just px) = px ∷ []
fromMaybe⁺ nothing = []
fromMaybe⁻ : ∀ mx → All P (fromMaybe mx) → Maybe.All P mx
fromMaybe⁻ (just x) (px ∷ []) = just px
fromMaybe⁻ nothing p = nothing
replicate⁺ : ∀ n → P x → All P (replicate n x)
replicate⁺ zero px = []
replicate⁺ (suc n) px = px ∷ replicate⁺ n px
replicate⁻ : ∀ {n} → All P (replicate (suc n) x) → P x
replicate⁻ (px ∷ _) = px
inits⁺ : All P xs → All (All P) (inits xs)
inits⁺ [] = [] ∷ []
inits⁺ (px ∷ pxs) = [] ∷ gmap⁺ (px ∷_) (inits⁺ pxs)
inits⁻ : ∀ xs → All (All P) (inits xs) → All P xs
inits⁻ [] pxs = []
inits⁻ (x ∷ []) ([] ∷ p[x] ∷ []) = p[x]
inits⁻ (x ∷ xs@(_ ∷ _)) ([] ∷ pxs@(p[x] ∷ _)) =
singleton⁻ p[x] ∷ inits⁻ xs (All.map (drop⁺ 1) (map⁻ pxs))
tails⁺ : All P xs → All (All P) (tails xs)
tails⁺ [] = [] ∷ []
tails⁺ pxxs@(_ ∷ pxs) = pxxs ∷ tails⁺ pxs
tails⁻ : ∀ xs → All (All P) (tails xs) → All P xs
tails⁻ [] pxs = []
tails⁻ (x ∷ xs) (pxxs ∷ _) = pxxs
module _ (p : A → Bool) where
all⁺ : ∀ xs → T (all p xs) → All (T ∘ p) xs
all⁺ [] _ = []
all⁺ (x ∷ xs) px∷pxs =
let px , pxs = Equivalence.to (T-∧ {p x}) px∷pxs
in px ∷ all⁺ xs pxs
all⁻ : All (T ∘ p) xs → T (all p xs)
all⁻ [] = _
all⁻ (px ∷ pxs) = Equivalence.from T-∧ (px , all⁻ pxs)
anti-mono : xs ⊆ ys → All P ys → All P xs
anti-mono xs⊆ys pys = All.tabulate (lookup pys ∘ xs⊆ys)
all-anti-mono : ∀ (p : A → Bool) → xs ⊆ ys → T (all p ys) → T (all p xs)
all-anti-mono p xs⊆ys = all⁻ p ∘ anti-mono xs⊆ys ∘ all⁺ p _
module _ (S : Setoid c ℓ) where
open Setoid S
open ≋ S
respects : P B.Respects _≈_ → (All P) B.Respects _≋_
respects p≈ [] [] = []
respects p≈ (x≈y ∷ xs≈ys) (px ∷ pxs) = p≈ x≈y px ∷ respects p≈ xs≈ys pxs
Any¬→¬All = Any¬⇒¬All
{-# WARNING_ON_USAGE Any¬→¬All
"Warning: Any¬→¬All was deprecated in v1.3.
Please use Any¬⇒¬All instead."
#-}
updateAt-id-relative = updateAt-id-local
{-# WARNING_ON_USAGE updateAt-id-relative
"Warning: updateAt-id-relative was deprecated in v2.0.
Please use updateAt-id-local instead."
#-}
updateAt-compose-relative = updateAt-∘-local
{-# WARNING_ON_USAGE updateAt-compose-relative
"Warning: updateAt-compose-relative was deprecated in v2.0.
Please use updateAt-∘-local instead."
#-}
updateAt-compose = updateAt-∘
{-# WARNING_ON_USAGE updateAt-compose
"Warning: updateAt-compose was deprecated in v2.0.
Please use updateAt-∘ instead."
#-}
updateAt-cong-relative = updateAt-cong-local
{-# WARNING_ON_USAGE updateAt-cong-relative
"Warning: updateAt-cong-relative was deprecated in v2.0.
Please use updateAt-cong-local instead."
#-}
gmap = gmap⁺
{-# WARNING_ON_USAGE gmap
"Warning: gmap was deprecated in v2.0.
Please use gmap⁺ instead."
#-}
map-compose = map-∘
{-# WARNING_ON_USAGE map-compose
"Warning: map-compose was deprecated in v2.1.
Please use map-∘ instead."
#-}