{-# LANGUAGE TypeFamilies #-} {-# LANGUAGE Rank2Types, GeneralizedNewtypeDeriving #-} {-# LANGUAGE NoMonomorphismRestriction, EmptyDataDecls #-} -- | This is the Haskell version of symantics1.ml, for comparison -- ACG with a more expressive semantic lexicon that includes -- multi-prompt delimited continuations and the notion of evaluation. -- Types are considered as a mere approximation rather than -- the complete specification of grammatical composition. -- -- * -- module Language.Symantics1 where -- Part of the Dybvig, Sabry, Peyton-Jones' library -- for multi-prompt delimited control -- import CC_Frame -- ed. Oleg uses CC_Frame, available in the CC-delcont package now -- import Control.Monad.CC import Control.Monad.Reader -- The abstract form, to be interpreted in several ways. -- | Abstract signature, which defines base types, constants and their types -- data N -- Base types data NP data S data SM -- | An interpretation of the base type btyp in the signature -- labeled by lab type family I lab btyp class Abstract c where john :: c (I c NP) -- constants bill :: c (I c NP) man :: c (I c N) woman :: c (I c N) see :: c (I c NP) -> c (I c NP) -> c (I c S) love :: c (I c NP) -> c (I c NP) -> c (I c S) every :: c (I c N) -> c (I c NP) some :: c (I c N) -> c (I c NP) dot :: c (I c S) -> c (I c SM) -- Terminating dot {- everyone :: c (I c NP) someone :: c (I c NP) -} -- Sample phrases in the abstract language -- term1 = see someone everyone -- | Example from Sec 4.3 of the ESSLLI Advanced ACG course. term43 = dot (love (some woman) (every man)) -- | An interpretation of the abstract signature as the surface form: strings -- newtype LString a = LString a deriving Show -- All base type are interpreted as strings type instance I LString N = String type instance I LString NP = String type instance I LString S = String type instance I LString SM = String ccat :: LString String -> LString String -> LString String ccat (LString a) (LString b) = LString (a ++ b) instance Abstract LString where john = LString "John" bill = LString "Bill" man = LString "man" woman = LString "woman" every = \x -> LString "every " `ccat` x some = \x -> LString "some " `ccat` x see = \o s -> s `ccat` LString " saw " `ccat` o love = \o s -> s `ccat` LString " loves " `ccat` o dot = \s -> s `ccat` LString "." -- Surface forms of sample terms term43S = case term43 of LString x -> x -- ------------------------------------------------------------------------ -- | Semantic forms -- data E = Ind String deriving Show data T = Man E | Woman E | See E E | Love E E | And T T | Imply T T | Exists Varname T | Forall Varname T deriving Show type Varname = String -- We now build the semantic signature and the lexicon -- stepwise -- | The order of quantification data QuantOrder = Uni_over_Exi | Exi_over_Uni data SemEnv r = SemEnv{puni :: Prompt r T, pexi :: Prompt r T, quant_order :: QuantOrder, pcnt :: Prompt r (Int -> CC r T) -- to generate variable names } -- | The Semantic monad newtype SemM r a = SemM (ReaderT (SemEnv r) (CC r) a) deriving Monad unSem :: SemM r a -> SemEnv r -> CC r a unSem (SemM m) env = runReaderT m env -- | Interpretation of Basic types type instance I (SemM r) NP = E type instance I (SemM r) N = E -> T type instance I (SemM r) S = T type instance I (SemM r) SM = T instance Abstract (SemM r) where john = return $ Ind "John'" bill = return $ Ind "Bill'" man = return Man woman= return Woman love = \o s -> (return Love) `ap` o `ap` s see = \o s -> (return See) `ap` o `ap` s every pred = pred >>= \pr -> make_ind_quant puni (\vn x -> return $ Forall vn $ Imply (pr (Ind vn)) x) some pred = pred >>= \pr -> make_ind_quant pexi (\vn x -> return $ Exists vn $ And (pr (Ind vn)) x) dot m = SemM $ do env <- ask lift $ do case quant_order env of Uni_over_Exi -> pushPrompt (puni env) $ pushPrompt (pexi env) (unSem m env) Exi_over_Uni -> pushPrompt (pexi env) $ pushPrompt (puni env) (unSem m env) runSem :: QuantOrder -> (forall r. SemM r T) -> T runSem qorder m = runCC init where init = do uni <- newPrompt exi <- newPrompt cnt <- newPrompt -- initialize to 0 the counter to create variable names pushPrompt cnt (do v <- unSem m (SemEnv{puni=uni, pexi=exi, quant_order=qorder, pcnt=cnt}) return $ const (return v)) `app` (return 0) -- | /Movement/ into the position of the prompt selected by psel make_ind_quant psel body = do vn <- genvar let v = Ind vn SemM $ do env <- ask lift $ shiftP (psel env) $ \sk -> body vn =<< sk (Ind vn) -- | Logical forms of sample terms in different semantic environment term43L1 = runSem Uni_over_Exi term43 {- Forall "v1" (Imply (Man (Ind "v1")) (Exists "v0" (And (Woman (Ind "v0")) (Love (Ind "v0") (Ind "v1"))))) -} term43L2 = runSem Exi_over_Uni term43 {- Exists "v0" (And (Woman (Ind "v0")) (Forall "v1" (Imply (Man (Ind "v1")) (Love (Ind "v0") (Ind "v1"))))) -} -- | Auxiliary functions -- app :: Monad m => m (a -> m b) -> m a -> m b app m1 m2 = (m1 `ap` m2) >>= id -- | Generate a new variable name genvar :: SemM r Varname genvar = SemM $ do env <- ask cnt <- lift $ shiftP (pcnt env) $ \sk -> return $ \cnt -> sk cnt `app` (return (succ cnt)) return $ "v" ++ show cnt shiftP :: Prompt r b -> ((a -> CC r b) -> CC r b) -> CC r a shiftP p f = withSubCont p $ \sk -> pushPrompt p (f (\v -> pushPrompt p (pushSubCont sk (return v))))