{-# LANGUAGE DataKinds #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeOperators #-} module Data.Array.Nested.Internal.Lemmas where import Data.Proxy import Data.Type.Equality import GHC.TypeLits import Data.Array.Mixed.Lemmas import Data.Array.Mixed.Permutation import Data.Array.Mixed.Shape import Data.Array.Mixed.Types import Data.Array.Nested.Internal.Shape lemRankMapJust :: ShS sh -> Rank (MapJust sh) :~: Rank sh lemRankMapJust ZSS = Refl lemRankMapJust (_ :$$ sh') | Refl <- lemRankMapJust sh' = Refl lemMapJustApp :: ShS sh1 -> Proxy sh2 -> MapJust (sh1 ++ sh2) :~: MapJust sh1 ++ MapJust sh2 lemMapJustApp ZSS _ = Refl lemMapJustApp (_ :$$ sh) p | Refl <- lemMapJustApp sh p = Refl lemTakeLenMapJust :: Perm is -> ShS sh -> TakeLen is (MapJust sh) :~: MapJust (TakeLen is sh) lemTakeLenMapJust PNil _ = Refl lemTakeLenMapJust (_ `PCons` is) (_ :$$ sh) | Refl <- lemTakeLenMapJust is sh = Refl lemTakeLenMapJust (_ `PCons` _) ZSS = error "TakeLen of empty" lemDropLenMapJust :: Perm is -> ShS sh -> DropLen is (MapJust sh) :~: MapJust (DropLen is sh) lemDropLenMapJust PNil _ = Refl lemDropLenMapJust (_ `PCons` is) (_ :$$ sh) | Refl <- lemDropLenMapJust is sh = Refl lemDropLenMapJust (_ `PCons` _) ZSS = error "DropLen of empty" lemIndexMapJust :: SNat i -> ShS sh -> Index i (MapJust sh) :~: Just (Index i sh) lemIndexMapJust SZ (_ :$$ _) = Refl lemIndexMapJust (SS (i :: SNat i')) ((_ :: SNat n) :$$ (sh :: ShS sh')) | Refl <- lemIndexMapJust i sh , Refl <- lemIndexSucc (Proxy @i') (Proxy @(Just n)) (Proxy @(MapJust sh')) , Refl <- lemIndexSucc (Proxy @i') (Proxy @n) (Proxy @sh') = Refl lemIndexMapJust _ ZSS = error "Index of empty" lemPermuteMapJust :: Perm is -> ShS sh -> Permute is (MapJust sh) :~: MapJust (Permute is sh) lemPermuteMapJust PNil _ = Refl lemPermuteMapJust (i `PCons` is) sh | Refl <- lemPermuteMapJust is sh , Refl <- lemIndexMapJust i sh = Refl lemKnownMapJust :: forall sh. KnownShS sh => Proxy sh -> Dict KnownShX (MapJust sh) lemKnownMapJust _ = lemKnownShX (go (knownShS @sh)) where go :: ShS sh' -> StaticShX (MapJust sh') go ZSS = ZKX go (n :$$ sh) = SKnown n :!% go sh