packages feed

inch-0.1.0: src/Language/Inch/Kind.lhs

> {-# LANGUAGE GADTs, TypeOperators, TypeFamilies, RankNTypes,
>              FlexibleInstances, StandaloneDeriving, MultiParamTypeClasses,
>              FlexibleContexts, EmptyDataDecls #-}

> module Language.Inch.Kind where

> import Data.Foldable
> import Data.Map (Map)
> import qualified Data.Map as Map
> import Data.Monoid
> import Prelude hiding (any, elem)

> import Language.Inch.BwdFwd
> import Language.Inch.Kit



> type TmName           = String
> type TyConName        = String
> type TmConName        = String
> type ClassName        = String


> data Binder where
>     Pi   :: Binder
>     All  :: Binder
>   deriving (Eq, Ord, Show)

> data VarState where
>     UserVar  :: Binder -> VarState
>     SysVar   :: VarState
>   deriving (Eq, Ord, Show)

> data TyName where
>     N :: String -> Int -> VarState -> TyName
>   deriving (Eq, Ord, Show)

> nameToString :: TyName -> String
> nameToString (N s _ _) = s

> nameToSysString :: TyName -> String
> nameToSysString (N s i _) = s ++ "_" ++ show i

> nameEq :: TyName -> String -> Bool
> nameEq (N x _ (UserVar _)) y  = x == y
> nameEq (N _ _ SysVar)  _  = False

> nameBinder :: TyName -> Maybe Binder
> nameBinder (N _ _ (UserVar b))  = Just b
> nameBinder _                    = Nothing

> data KSet
> data KNum
> data KConstraint
> data k :-> l

> data Kind k where
>     KSet   :: Kind KSet
>     KNum   :: Kind KNum
>     KConstraint :: Kind KConstraint
>     (:->)  :: Kind k -> Kind l -> Kind (k :-> l)
> infixr 5 :->

> deriving instance Show (Kind k)

> instance HetEq Kind where
>     hetEq KSet KSet yes _ = yes
>     hetEq KNum KNum yes _ = yes
>     hetEq KConstraint KConstraint yes _ = yes
>     hetEq (k :-> k') (l :-> l') yes no = hetEq k l (hetEq k' l' yes no) no
>     hetEq _ _ _ no = no

> instance HetOrd Kind where
>     KSet         <?=  _           = True
>     _            <?=  KSet        = False
>     KNum         <?=  _           = True
>     _            <?=  KNum        = False
>     KConstraint  <?= _            = True
>     _            <?= KConstraint  = False
>     (k :-> k')   <?= (l :-> l')   | k =?= k' =  l <?= l'
>                                   | otherwise = k <?= k'

> class KindI t where
>     kind :: Kind t

> instance KindI KSet where
>     kind = KSet

> instance KindI KNum where
>     kind = KNum

> instance (KindI k, KindI l) => KindI (k :-> l) where
>     kind = kind :-> kind

> data SKind where
>     SKSet   :: SKind
>     SKNum   :: SKind
>     SKNat   :: SKind
>     SKConstraint :: SKind
>     (:-->)  :: SKind -> SKind -> SKind
>   deriving (Eq, Show)
> infixr 5 :-->


> targetsSet :: Kind k -> Bool
> targetsSet KSet       = True
> targetsSet KNum       = False
> targetsSet KConstraint = False
> targetsSet (_ :-> k)  = targetsSet k 

> fogKind :: Kind k -> SKind
> fogKind KSet       = SKSet
> fogKind KNum       = SKNum
> fogKind KConstraint = SKConstraint
> fogKind (k :-> l)  = fogKind k :--> fogKind l

> kindKind :: SKind -> Ex Kind
> kindKind SKSet       = Ex KSet
> kindKind SKNum       = Ex KNum
> kindKind SKNat       = Ex KNum
> kindKind SKConstraint = Ex KConstraint
> kindKind (k :--> l)  = case (kindKind k, kindKind l) of
>                            (Ex k', Ex l') -> Ex (k' :-> l')

> kindCod :: Kind (k :-> l) -> Kind l
> kindCod (_ :-> l) = l







> data BVar a k where
>     Top  :: BVar (a, k) k
>     Pop  :: BVar a k -> BVar (a, l) k

> instance Show (BVar a k) where
>     show x = '!' : show (bvarToInt x)

> instance HetEq (BVar a) where
>     hetEq Top      Top      yes _  = yes
>     hetEq (Pop x)  (Pop y)  yes no = hetEq x y yes no
>     hetEq _        _        _   no = no

> instance Eq (BVar a k) where
>     (==) = (=?=)

> instance HetOrd (BVar a) where
>     Top    <?= _      = True
>     Pop x  <?= Pop y  = x <?= y
>     Pop _  <?= Top    = False

> instance Ord (BVar a k) where
>     (<=) = (<?=)



> bvarToInt :: BVar a k -> Int
> bvarToInt Top      = 0
> bvarToInt (Pop x)  = succ (bvarToInt x)



> data Var a k where
>     BVar :: BVar a k          -> Var a k
>     FVar :: TyName -> Kind k  -> Var a k
>  deriving Show

> instance HetEq (Var a) where
>     hetEq (FVar a k)  (FVar b l)  yes _ | a == b =
>         hetEq k l yes (error "eqVar: kinding error")
>     hetEq (BVar x)    (BVar y)    yes no = hetEq x y yes no
>     hetEq _           _           _   no = no

> instance Eq (Var a k) where
>     (==) = (=?=)

> instance HetOrd (Var a) where
>     BVar x    <?= BVar y    = x <?= y
>     BVar _    <?= FVar _ _  = True
>     FVar a _  <?= FVar b _  = a <= b
>     FVar _ _  <?= BVar _    = False

> instance Ord (Var a k) where
>     (<=) = (<?=)


> impossibleBVar :: BVar () k -> a
> impossibleBVar b = error $ "impossible BVar: " ++ show b

> varName :: Var () k -> TyName
> varName (FVar a _)  = a
> varName (BVar b)    = impossibleBVar b

> varKind :: Var () k -> Kind k
> varKind (FVar _ k)  = k
> varKind (BVar b)    = impossibleBVar b

> varBinder :: Var () k -> Maybe Binder
> varBinder (FVar a _)  = nameBinder a
> varBinder (BVar b)    = impossibleBVar b

> fogVar :: Var () k -> String
> fogVar = fogVar' nameToString []

> fogSysVar :: Var () k -> String
> fogSysVar = fogVar' nameToSysString []

> fogVar' :: (TyName -> String) -> [String] -> Var a k -> String
> fogVar' g _  (FVar a _)  = g a
> fogVar' _ bs (BVar x)    = bs !! bvarToInt x

> varNameEq :: Var a k -> String -> Bool
> varNameEq (FVar nom _)  y = nameEq nom y
> varNameEq (BVar _)      _ = False

> wkF :: (forall k . Var a k -> t) -> t -> Var (a, l) k' -> t
> wkF f _ (FVar a k)      = f (FVar a k)
> wkF _ t (BVar Top)      = t
> wkF f _ (BVar (Pop y))  = f (BVar y)


> withBVar :: (BVar a k -> BVar b k) -> Var a k -> Var b k
> withBVar _ (FVar a k)  = FVar a k
> withBVar f (BVar x)    = BVar (f x)

> wkVar :: Var a k -> Var (a, l) k
> wkVar = withBVar Pop

> wkRenaming :: (Var a k -> Var b k) -> Var (a, l) k -> Var (b, l) k
> wkRenaming g (FVar a k)      = wkVar . g $ FVar a k
> wkRenaming _ (BVar Top)      = BVar Top
> wkRenaming g (BVar (Pop x))  = wkVar . g $ BVar x

> bindVar :: Var a k -> Var a l -> Var (a, k) l
> bindVar v w = hetEq v w (BVar Top) (wkVar w)

> unbindVar :: Var a k -> Var (a, k) l -> Var a l 
> unbindVar v (BVar Top)      = v
> unbindVar _ (BVar (Pop x))  = BVar x
> unbindVar _ (FVar a k)      = FVar a k

> wkClosedVar :: Var () k -> Var a k
> wkClosedVar (FVar a k)  = FVar a k
> wkClosedVar (BVar b)    = impossibleBVar b

> fixKind :: Kind k -> Var () l -> Maybe (Var () k)
> fixKind k v = hetEq k (varKind v) (Just v) Nothing

> fixNum :: Var () l -> Maybe (Var () KNum)
> fixNum = fixKind KNum  


> class FV t a where
>     fvFoldMap :: Monoid m => (forall k . Var a k -> m) -> t -> m

> (<<?) :: FV t a => [Ex (Var a)] -> t -> Bool
> as <<? t = getAny $ fvFoldMap (Any . (`hetElem` as)) t

> (<?) :: FV t a => Var a k -> t -> Bool
> a <? t = [Ex a] <<? t

> vars :: FV t a => t -> [Ex (Var a)]
> vars = fvFoldMap (\ x -> [Ex x])

> numvars :: FV t () => t -> [Var () KNum]
> numvars = fvFoldMap f
>   where
>     f :: Var () k -> [Var () KNum]
>     f a@(FVar _ KNum)  = [a]
>     f _                = []


> instance FV (Var a l) a where
>     fvFoldMap f a = f a

> instance FV t a => FV [t] a where
>     fvFoldMap f = foldMap (fvFoldMap f)

> instance FV t a => FV (Fwd t) a where
>     fvFoldMap f = foldMap (fvFoldMap f)

> instance FV t a => FV (Bwd t) a where
>     fvFoldMap f = foldMap (fvFoldMap f)

> instance (FV t a, FV u a) => FV (Either t u) a where
>     fvFoldMap f (Left x)   = fvFoldMap f x
>     fvFoldMap f (Right x)  = fvFoldMap f x

> instance (FV t a, FV u a) => FV (t, u) a where
>     fvFoldMap f (x, y) = fvFoldMap f x <.> fvFoldMap f y

> instance (FV s a, FV t a, FV u a) => FV (s, t, u) a where
>     fvFoldMap f (x, y, z) = fvFoldMap f x <.> fvFoldMap f y <.> fvFoldMap f z

> instance (Ord t, FV t a) => FV (Map t x) a where
>     fvFoldMap f = Map.foldrWithKey (\ t _ m -> fvFoldMap f t <.> m) mempty

> instance FV (Ex (Var a)) a where
>     fvFoldMap f (Ex v) = f v 

> data VarSuffix a b x where
>     VS0    :: VarSuffix a a ()
>     (:<<)  :: VarSuffix a b x -> Var a k -> VarSuffix a (b, k) (x, k)

> renameBVarVS :: VarSuffix a b x -> BVar a k -> BVar b k
> renameBVarVS VS0         x = x
> renameBVarVS (vs :<< _)  x = Pop (renameBVarVS vs x)

> renameVS :: VarSuffix a b x -> Var a k -> Var b k
> renameVS _   (FVar a k)  = FVar a k
> renameVS vs  (BVar x)    = BVar (renameBVarVS vs x)

> renameVSinv :: VarSuffix a b x -> Var b k -> Var a k
> renameVSinv _          (FVar a k)      = FVar a k
> renameVSinv VS0        (BVar v)        = BVar v
> renameVSinv (_ :<< v)  (BVar Top)      = v
> renameVSinv (vs :<< _) (BVar (Pop x))  = renameVSinv vs (BVar x)

> extRenaming :: VarSuffix a b x -> VarSuffix c d x -> (Var a k -> Var c k) ->
>                    Var b k -> Var d k
> extRenaming _            ecd          g (FVar a k)      = renameVS ecd $ g (FVar a k)
> extRenaming VS0          VS0          g (BVar v)        = g (BVar v)
> extRenaming (_ :<<_)     (_ :<< _)    _ (BVar Top)      = BVar Top
> extRenaming (eab :<< _)  (ecd :<< _)  g (BVar (Pop v))  = wkVar $ extRenaming eab ecd g (BVar v)
> extRenaming _ _ _ _ = error "extRenaming: invariant violation"

< extExt :: Ext a b x -> (forall d y . Ext c d y -> p) -> p
< extExt E0       q = q E0
< extExt (EC ex)  q = extExt ex (q . EC)

> extComp :: VarSuffix a b x -> VarSuffix b c y -> (forall z . VarSuffix a c z -> p) -> p
> extComp eab VS0          q = q eab
> extComp eab (ebc :<< v)  q = extComp eab ebc (q . (:<< renameVSinv eab v))



> data VarSuffixFwd a b where
>     VF0    :: VarSuffixFwd a a
>     (:>>)  :: Var a k -> VarSuffixFwd (a, k) b -> VarSuffixFwd a b

> {-
> renameVSFinv :: VarSuffixFwd a b -> Var b k -> Var a k
> renameVSFinv _ (FVar a k) = FVar a k
> renameVSFinv VF0 (BVar v) = BVar v
> renameVSFinv (v :>> _) (BVar Top) = v
> -}