module Vec.Updates.Base where
open import Level
open import Function
open import Data.Empty
open import Data.Bool
open import Data.Maybe as Maybe
open import Data.Maybe.Properties
open import Data.Product
open import Data.Nat hiding (less-than-or-equal)
open import Data.Fin as Fin
open import Data.Vec as Vec hiding (_[_]≔_)
import Data.Vec.Properties as Vec
open import Data.Vec.Functional using (Vector; fromVec)
open import Data.Vec.Functional.Properties using (updateAt-updates; updateAt-minimal)
open import Relation.Binary.PropositionalEquality
open import Vec.Relation.FirstOrNot
open import Relation.Nullary.Decidable
open import Relation.Nullary
open import Relation.Binary
open import Vector
private variable
ℓ ℓ1 : Level
A : Set ℓ
a : A
m n p q : ℕ
b : Bool
xs : Vec A n
open ≡-Reasoning
evalFromListUpdates : (xs : Vector A n) {indices : Vec (Fin n) m} (values : Vec A m) (i : Fin n)
(firstOrNot : FirstOrNot (i ≡_) indices b) → A
evalFromListUpdates xs values i (there _ firstOrNot) =
evalFromListUpdates xs (tail values) i firstOrNot
evalFromListUpdates {b = false} xs values i firstOrNot = xs i
evalFromListUpdates {b = true} xs (x ∷ values) i (here _ _) = x
vecUpdates : (xs : Vector A n) (indices : Vec (Fin n) m) (values : Vec A m) → Vector A n
vecUpdates xs [] [] = xs
vecUpdates xs (ind ∷ indices) (val ∷ values) = vecUpdates xs indices values [ ind ]≔ val
vecUpdates≡listUpdates : ∀ (xs : Vector A n) {indices : Vec (Fin n) m} (values : Vec A m) i
(firstOrNot : FirstOrNot (i ≡_) indices b)
→ vecUpdates xs indices values i ≡ evalFromListUpdates xs values i firstOrNot
vecUpdates≡listUpdates xs [] i notHere = refl
vecUpdates≡listUpdates xs {.(i ∷ _)} (_ ∷ values) i (here refl _) = updateAt-updates i _
vecUpdates≡listUpdates xs {ind ∷ inds} (val ∷ values) i (there ¬p firstOrNot) = begin
(vecUpdates xs inds values [ ind ]≔ val) i ≡⟨ updateAt-minimal _ _ _ ¬p ⟩
vecUpdates xs inds values i ≡⟨ vecUpdates≡listUpdates xs values i firstOrNot ⟩
evalFromListUpdates xs (val ∷ values) i (there ¬p firstOrNot) ∎
evalFromPosition : (values : Vec A n) (default : A) (pos : Maybe $ Fin n) → A
evalFromPosition = maybe′ ∘ fromVec
firstOrNot→pos : (xs : Vector A n) {indices : Vec (Fin n) m} (values : Vec A m) (i : Fin n)
(firstOrNot : FirstOrNot (i ≡_) indices b) → A
firstOrNot→pos xs values i = evalFromPosition values (xs i) ∘ firstOrNotPositionMaybe
infixr 5 _∷_
data VecWithType {A : Set ℓ} (P : A → Set ℓ1) : Vec A n → Set (ℓ Level.⊔ ℓ1) where
[] : VecWithType P []
_∷_ : P a → VecWithType P xs → VecWithType P (a ∷ xs)
VecIndBool : ∀ (indices : Vec A n) vBool k → Set _
VecIndBool indices vBool k = VecWithType (λ (ind , b) → Reflects (k ≡ ind) b) $ Vec.zip indices vBool
evalFromVReflect : (xs : Vector A n) {vBool : Vec Bool m}
(values : Vec A m) (i : Fin n) (firstOrNot : FirstOrNot T vBool b) → A
evalFromVReflect xs values i firstOrNot = evalFromPosition values
(xs i) (firstOrNotPositionMaybe firstOrNot)
evalFromVReflect¬≡ : ∀ (xs : Vector A n) {vBool : Vec Bool m}
(values : Vec A m) (i : Fin n) (firstOrNot : FirstOrNot T vBool b) val →
evalFromVReflect xs (val ∷ values) i (there id firstOrNot)
≡ evalFromVReflect xs values i firstOrNot
evalFromVReflect¬≡ {b = false} xs values i firstOrNot val = refl
evalFromVReflect¬≡ {b = true} xs values i firstOrNot val = refl
vecUpdates≡reflectBool : ∀ (xs : Vector A n) {indices : Vec (Fin n) m} (values : Vec A m) i
{vBool : Vec Bool m} (vType : VecWithType (λ (ind , b) → Reflects (i ≡ ind) b) (Vec.zip indices vBool))
(firstOrNot : FirstOrNot T vBool b)
→ vecUpdates xs indices values i ≡ evalFromVReflect xs values i firstOrNot
vecUpdates≡reflectBool xs {[]} [] i vType notHere = refl
vecUpdates≡reflectBool xs {ind ∷ indices} (val ∷ values) _ (ofʸ refl ∷ vType) (here _ vBool) = updateAt-updates ind _
vecUpdates≡reflectBool xs {ind ∷ indices} (val ∷ values) _ (ofʸ refl ∷ vType) (there ¬p firstOrNot) with () ← ¬p _
vecUpdates≡reflectBool xs {ind ∷ indices} (val ∷ values) i (ofⁿ ¬i≡ind ∷ vType) (there ¬p firstOrNot) = begin
(vecUpdates xs indices values [ ind ]≔ val) i ≡⟨ updateAt-minimal i _ _ ¬i≡ind ⟩
vecUpdates xs indices values i ≡⟨ vecUpdates≡reflectBool xs values i vType firstOrNot ⟩
evalFromVReflect xs values i firstOrNot ≡˘⟨ evalFromVReflect¬≡ xs values i firstOrNot val ⟩
evalFromVReflect xs (val ∷ values) i (there ¬p firstOrNot) ∎
vecUpdates≡reflectBool-lema₂ : ∀ (xs : Vector A n) (values : Vec A m) (vBool : Vec Bool m) →
firstOrNotPositionMaybe (proj₂ (firstOrNotFromDec T? vBool)) ≡ firstTrue vBool
vecUpdates≡reflectBool-lema₂ xs [] [] = refl
vecUpdates≡reflectBool-lema₂ xs (x ∷ values) (true ∷ vBool) = refl
vecUpdates≡reflectBool-lema₂ xs (x ∷ values) (false ∷ vBool)
rewrite sym $ vecUpdates≡reflectBool-lema₂ xs values vBool
with firstOrNotFromDec T? vBool in eq
... | true , _ = refl
... | false , _ = refl
vecUpdates≡reflectBool-lemma : ∀ (xs : Vector A n) (values : Vec A m) i (vBool : Vec Bool m) →
evalFromPosition values (xs i) (firstOrNotPositionMaybe $ proj₂ (firstOrNotFromDec T? vBool)) ≡
evalFromPosition values (xs i) (firstTrue vBool)
vecUpdates≡reflectBool-lemma xs values i vBool rewrite vecUpdates≡reflectBool-lema₂ xs values vBool = refl
vecUpdates≡reflectBool-theo : ∀ (xs : Vector A n) {indices : Vec (Fin n) m} (values : Vec A m) i
{vBool : Vec Bool m} (vType : VecIndBool indices vBool i)
→ vecUpdates xs indices values i ≡ evalFromPosition values (xs i) (firstTrue vBool)
vecUpdates≡reflectBool-theo xs {indices} values i {vBool} vType = begin
vecUpdates xs indices values i ≡⟨ vecUpdates≡reflectBool xs values i vType (proj₂ (firstOrNotFromDec T? vBool)) ⟩
evalFromVReflect xs values i (proj₂ (firstOrNotFromDec T? vBool)) ≡⟨ vecUpdates≡reflectBool-lemma xs values i vBool ⟩
evalFromPosition values (xs i) (firstTrue vBool) ∎
vBoolFromIndices : ∀ (indices : Vec (Fin n) m) (i : Fin n) → Σ[ vBool ∈ Vec Bool m ]
VecWithType (λ (ind , b) → Reflects (i ≡ ind) b) (Vec.zip indices vBool)
vBoolFromIndices [] i = [] , []
vBoolFromIndices (ind ∷ indices) i = _ , proof (i Fin.≟ ind) ∷ proj₂ (vBoolFromIndices indices i)
vecUpdates≡reflectBool-theo2 : ∀ (xs : Vector A n) (indices : Vec (Fin n) m) (values : Vec A m) i
→ vecUpdates xs indices values i ≡ evalFromPosition values (xs i) (firstTrue (vBoolFromIndices indices i .proj₁))
vecUpdates≡reflectBool-theo2 xs indices values i = vecUpdates≡reflectBool-theo xs values i (proj₂ (vBoolFromIndices indices i))
vecUpdates≡reflectBool-lemma3 : ∀ (indices : Vec (Fin n) m) i
{vBool : Vec Bool m} (vType : VecIndBool indices vBool i)
→ vBoolFromIndices indices i .proj₁ ≡ vBool
vecUpdates≡reflectBool-lemma3 [] i {[]} vType = refl
vecUpdates≡reflectBool-lemma3 (ind ∷ indices) i {false ∷ vBool} (ofⁿ ¬a ∷ vType) =
cong₂ _∷_ (dec-false (_ Fin.≟ _) ¬a) (vecUpdates≡reflectBool-lemma3 indices _ vType)
vecUpdates≡reflectBool-lemma3 (ind ∷ indices) _ {true ∷ vBool} (ofʸ refl ∷ vType)
= cong₂ _∷_ (dec-true (ind Fin.≟ ind) refl) (vecUpdates≡reflectBool-lemma3 indices _ vType)
vecUpdates≡reflectBool-theo3 : ∀ (xs : Vector A n) (indices : Vec (Fin n) m) (values : Vec A m) i
{vBool : Vec Bool m} (vType : VecIndBool indices vBool i)
→ evalFromPosition values (xs i) (firstTrue (vBoolFromIndices indices i .proj₁))
≡ evalFromPosition values (xs i) (firstTrue vBool)
vecUpdates≡reflectBool-theo3 xs indices values i vType
rewrite vecUpdates≡reflectBool-lemma3 indices i vType = refl