open import Data.Bool
module StateSizedIO.LIB.DB.Dictionary {Key : Set}(_==_ : Key -> Key -> Bool) where
open import Data.Product
open import Data.Bool
open import Data.List using (List; _∷_; _++_; [])
Dict : Set -> Set
Dict A = List (Key × A)
hasKey : {A : Set} -> Key -> Dict A -> Bool
hasKey _ [] = false
hasKey y ((x , _) ∷ xs) = x == y ∨ hasKey y xs
HasKey : {A : Set} -> Key -> Dict A -> Set
HasKey x xs = T (hasKey x xs)
lookup : {A : Set}(x : Key)(xs : Dict A){p : HasKey x xs} -> A
lookup _ [] {}
lookup y ((x , v) ∷ xs) {p} with x == y
... | true = v
... | false = lookup y xs {p}
hasKeys : {A : Set} -> List Key -> Dict A -> Bool
hasKeys [] _ = true
hasKeys (x ∷ xs) t = hasKey x t ∧ hasKeys xs t
HasKeys : {A : Set} -> List Key -> Dict A -> Set
HasKeys xs t = T (hasKeys xs t)
andElimL : forall {a b} -> T (a ∧ b) -> T a
andElimL {true} _ = _
andElimL {false} ()
andElimR : forall a {b} -> T (a ∧ b) -> T b
andElimR true p = p
andElimR false ()
project : {A : Set}(xs : List Key)(tbl : Dict A){p : HasKeys xs tbl} ->
Dict A
project [] tbl = []
project (x ∷ xs) tbl {p} = (x , lookup x tbl {andElimL p}) ∷
project xs tbl {andElimR (hasKey x tbl) p}
distinctKeys : {A : Set} -> Dict A -> Bool
distinctKeys [] = true
distinctKeys ((x , _) ∷ xs) = not (hasKey x xs) ∧ distinctKeys xs
disjoint : {A : Set} -> Dict A -> Dict A -> Bool
disjoint xs ys = distinctKeys (xs ++ ys)
Disjoint : {A : Set} -> Dict A -> Dict A -> Set
Disjoint xs ys = T (disjoint xs ys)