{-# LANGUAGE TypeOperators #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE GADTs #-} module Generics.MRSOP.STDiff.Types where import Generics.MRSOP.Base -- * Functorial Changes -- -- $functorialchanges -- -- Represents changes on the /first layer/ of two values of -- mutually recursive families. For a more in-depth explanation -- of the datatypes and their meaning we refer the interested reader -- to the relevant literature: -- -- - Miraldo, Dagand and Swierstra, TyDe 2017 -- - van Putten, MSc thesis -- -- |Represents a change between two opaque values. When they -- are equal represents a copy. data TrivialK (ki :: kon -> *) :: kon -> * where Trivial :: ki kon -> ki kon -> TrivialK ki kon -- |Represents a change between two atoms, where an atom is -- either a recursive or an opaque value. data At (ki :: kon -> *) (codes :: [[[Atom kon]]]) :: Atom kon -> * where AtSet :: TrivialK ki kon -> At ki codes ('K kon) AtFix :: (IsNat ix) => Almu ki codes ix ix -> At ki codes ('I ix) -- |Represents an alignment between two product of atoms. data Al (ki :: kon -> *) (codes :: [[[Atom kon]]]) :: [Atom kon] -> [Atom kon] -> * where A0 :: Al ki codes '[] '[] AX :: At ki codes x -> Al ki codes xs ys -> Al ki codes (x ': xs) (x ': ys) ADel :: NA ki (Fix ki codes) x -> Al ki codes xs ys -> Al ki codes (x ': xs) ys AIns :: NA ki (Fix ki codes) x -> Al ki codes xs ys -> Al ki codes xs (x ': ys) -- |Represents a change at the coproduct structure. data Spine (ki :: kon -> *) (codes :: [[[Atom kon]]]) :: [[Atom kon]] -> [[Atom kon]] -> * where Scp :: Spine ki codes s1 s1 SCns :: Constr s1 c1 -> NP (At ki codes) (Lkup c1 s1) -> Spine ki codes s1 s1 SChg :: Constr s1 c1 -> Constr s2 c2 -> Al ki codes (Lkup c1 s1) (Lkup c2 s2) -> Spine ki codes s1 s2 -- * Fixpoint Changes -- -- $fixpointchanges -- -- The next datatypes represent a sequence of 'Spine', 'Al' and 'At' assembled -- coupled with operators to describe changes in the recursive structure such -- as inserting and deleting constructors. -- |Represents a /one-hole context/ over a @NP (NA ki (fix ki codes)) xs@ where -- the hole is in a distinguished element indexed by @'I ix@ and is filled -- with applying @p@ to the relevant indexes. data Ctx (ki :: kon -> *) (codes :: [[[Atom kon]]]) (p :: Nat -> Nat -> *) (ix :: Nat) :: [Atom kon] -> * where H :: IsNat iy => p ix iy -> PoA ki (Fix ki codes) xs -> Ctx ki codes p ix ('I iy ': xs) T :: NA ki (Fix ki codes) a -> Ctx ki codes p ix xs -> Ctx ki codes p ix (a ': xs) -- |Simple synonym for contexts. type InsCtx ki codes ix xs = Ctx ki codes (Almu ki codes) ix xs -- |A deletion context needs to swap the indexes in the hole, hence -- we use a newtype for that. type DelCtx ki codes ix xs = Ctx ki codes (AlmuMin ki codes) ix xs -- |The newtype used to swap the indexes to |Almu|. newtype AlmuMin ki codes ix iy = AlmuMin { unAlmuMin :: Almu ki codes iy ix } -- |Represent recursive spines. data Almu (ki :: kon -> *) (codes :: [[[Atom kon]]]) :: Nat -> Nat -> * where Spn :: Spine ki codes (Lkup ix codes) (Lkup iy codes) -> Almu ki codes ix iy Ins :: Constr (Lkup iy codes) c -> InsCtx ki codes ix (Lkup c (Lkup iy codes)) -- its an ix with an iy typed-hoed -> Almu ki codes ix iy Del :: IsNat iy => Constr (Lkup ix codes) c -> DelCtx ki codes iy (Lkup c (Lkup ix codes)) -> Almu ki codes ix iy {- {- instance (ShowHO ki) => Show (At ki codes at) where show (AtSet t) = show t show (AtFix a) = a instance ShowHO ki => Show (TrivialK ki x) where show (Trivial x y) = show x ++ "|" ++ show y -} {- instance (HasDatatypeInfo ki fam codes, Show1 ki) => Show (Al ki codes xs ys) where show A0 = "A0" show (AX x xs) = "(AX " ++ show1 x ++ " " ++ show xs ++ ")" show (ADel x xs) = "(ADel " ++ show x ++ " " ++ show xs ++ ")" show (AIns x xs) = "(AIns " ++ show x ++ " " ++ show xs ++ ")" -} {- instance (IsNat ix,IsNat iy, HasDatatypeInfo ki fam codes, Show1 ki) => Show (AlmuMin ki codes ix iy) where show (AlmuMin x) = show x -} -- | An NP p xs, but there exists an x in xs such that h x -- -- Note that: NP p xs <=> Ctx' p p xs -- -- and that the list is never empty, because it contains at -- least the pointed element -- instance (IsNat ix, HasDatatypeInfo ki fam codes, Show1 ki) => Show (InsCtx ki codes ix xs) where show (H p poa) = "(H " ++ show p ++ " " ++ show poa ++ ")" show (T n c) = "(T " ++ show n ++ " " ++ show c ++ ")" instance (IsNat ix, HasDatatypeInfo ki fam codes, Show1 ki) => Show (DelCtx ki codes ix xs) where show (H p poa) = "(H " ++ show p ++ " " ++ show poa ++ ")" show (T n c) = "(T " ++ show n ++ " " ++ show c ++ ")" -- TODO ins del instance forall ki fam codes ix iy. (IsNat ix, IsNat iy, Show1 ki, HasDatatypeInfo ki fam codes) => Show (Almu ki codes ix iy) where show (Spn s) = "(Spn " ++ showSpine (getSNat @ix Proxy) (getSNat @iy Proxy) s ++ ")" show (Ins c ic) = "(Ins " ++ showC c ++ " " ++ show ic ++ ")" where showC c = constructorName . constrInfoLkup c $ (datatypeInfo (Proxy @fam) (getSNat @iy Proxy)) show (Del c ic) = "(Del " ++ showC c ++ " " ++ show ic ++ ")" where showC c = constructorName . constrInfoLkup c $ (datatypeInfo (Proxy @fam) (getSNat @ix Proxy)) instance (Show1 p) => Show1 (NP p) where show1 np = parens . concat . intersperse " " $ elimNP show1 np where parens x = "(" ++ x ++ ")" showSpine :: forall ki fam codes ix iy. (Show1 ki, HasDatatypeInfo ki fam codes, IsNat ix, IsNat iy) => SNat ix -> SNat iy -> Spine ki codes (Lkup ix codes) (Lkup iy codes) -> String showSpine six siy Scp = "Scp" showSpine six siy (SCns c x) = "(Scns " ++ showC c six ++ " " ++ show1 x ++ ")" where showC c six = constructorName . constrInfoLkup c $ (datatypeInfo (Proxy @fam) six) showSpine six siy (SChg c1 c2 a) = "(SChg " ++ showCX ++ " " ++ showCY ++ " " ++ show a ++ ")" where showCX = constructorName . constrInfoLkup c1 $ (datatypeInfo (Proxy @fam) six) showCY = constructorName . constrInfoLkup c2 $ (datatypeInfo (Proxy @fam) siy) {- instance (HasDatatypeInfo ki fam codes, Show1 ki) => Show (Spine ki codes x y) where show Scp = "COPY" show (SCns c x) = "(Scns " ++ showC c ++ " " ++ show1 x ++ ")" where showC showC c = constructorName . consterInfoLookup c (datatypeInfo (Proxy @fam) (getSNat @ix Proxy)) show (SChg c1 c2 a) = "(SChg " ++ showC c1 ++ " " ++ showC c2 ++ " " ++ show a ++ ")" where showC c = constructorName . consterInfoLookup c (datatypeInfo (Proxy @fam) (getSNat @ix Proxy)) -} -- OR what about: ix iy guard' :: String -> Bool -> Either String () guard' s False = Left s guard' _ True = Right () instance Show1 SNat where show1 = show . go where go :: SNat n -> Int go SZ = 0 go (SS s) = 1 + go s -}