packages feed

huff-0.1.0.0: src/Huff/Compile/AST.hs

{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DeriveFoldable #-}
{-# LANGUAGE DeriveTraversable #-}

module Huff.Compile.AST where

import           Data.Foldable (foldMap)
import qualified Data.Map.Strict as Map
import           Data.Monoid (Monoid(..))
import qualified Data.Text as T


data Domain a = Domain { domName      :: T.Text
                       , domObjects   :: [Object]
                       , domPreds     :: [Pred]
                       , domOperators :: [Operator a]
                       } deriving (Show)

data Problem = Problem { probInit :: [Literal]
                       , probGoal :: Term
                       } deriving (Show)

data Operator a = Operator { opName    :: !T.Text
                           , opDerived :: !Bool
                           , opParams  :: [Param]
                           , opVal     :: Maybe a
                           , opPrecond :: Term
                           , opEffects :: Effect
                           } deriving (Show,Functor,Foldable,Traversable)

type Name = T.Text

type Type = T.Text

data Typed a = Typed { tValue :: a
                     , tType  :: !Type
                     } deriving (Show,Eq,Ord)

-- | Types and all their inhabitants.
newtype TypeMap a = TypeMap { getTypeMap :: Map.Map Type [a]
                            } deriving (Show)

instance Monoid (TypeMap a) where
  mempty =
    TypeMap mempty

  mappend (TypeMap a) (TypeMap b) =
    TypeMap (Map.unionWith (++) a b)

typeMap :: [Typed a] -> TypeMap a
typeMap  = foldMap (\ Typed { .. } -> TypeMap (Map.singleton tType [tValue]) )

lookupType :: Type -> TypeMap a -> [a]
lookupType k (TypeMap m) = Map.findWithDefault [] k m


type Param  = Typed Name
type Object = Typed Name

data Term = TAnd    [Term]
          | TOr     [Term]
          | TNot    !Term
          | TImply  !Term   !Term
          | TExists [Param] !Term
          | TForall [Param] !Term
          | TLit    !Literal
            deriving (Show)

mkTAnd :: [Term] -> Term
mkTAnd [t] = t
mkTAnd ts  = TAnd ts

mkTOr :: [Term] -> Term
mkTOr [t] = t
mkTOr ts  = TOr ts

data Effect = EForall [Param] Effect
            | EWhen Term [Literal]
            | EAnd [Effect]
            | ELit Literal
              deriving (Show)

mkEWhen :: [Term] -> [Literal] -> Effect
mkEWhen [] = mkELitConj
mkEWhen ps = EWhen (mkTAnd ps)

mkELitConj :: [Literal] -> Effect
mkELitConj xs = EAnd (map ELit xs)

mkEAnd :: [Effect] -> Effect
mkEAnd [e] = e
mkEAnd es  = EAnd es

elimEAnd :: Effect -> [Effect]
elimEAnd (EAnd es) = concatMap elimEAnd es
elimEAnd e         = [e]

isELit :: Effect -> Bool
isELit ELit{} = True
isELit _      = False

data Literal = LAtom Atom
             | LNot  Atom
               deriving (Show)

data App a = App !Name [a]
            deriving (Show,Eq,Ord)

type Atom = App Arg

pattern Atom n as = App n as

negAtom :: Atom -> Atom
negAtom (Atom a as) = Atom (T.append "$not-" a) as

type Pred = App Type

pattern Pred n ts = App n ts

data Arg = AName !Name
         | AVar  !Name
           deriving (Show,Eq,Ord)