3

I have an assignment for school, that I need help on. So far I've created two types, Argument and Predicate, per the assignment instructions.

In this project, I have to create a list, titled 'context', of arguments (or, objects) in the world AND a list of facts about these objects, in a list titled 'facts'.

So, for instance, the context list has arguments "john" and "boston" and then in our fact list we can create a predicate with the function fly to have a fact "fly john to_boston" where to denotes that John flies to Boston.

For the final step of the project, we have to be able to ask Haskell: "qWhere fly john" and have Haskell search the context list for "john" and use that to search the list of facts for "fly" and "john" in order to eventually return "to_boston" or "boston."

I understand that this is nested list comprehension, but I don't understand how to get Haskell to return "to_boston" once it has "fly john". I'll include bits of the code below (scroll to the bottom for what I've been working on):

{-# LANGUAGE MultiParamTypeClasses #-}

-- GL TYPES
data Type = HUMN |         -- human
            ANIM |         -- animate
            ORGN |         -- organic
            ORGZ |         -- organization
            PHYS |         -- physical object
            ARTF |         -- artifact
            EVNT |         -- event
            PROP |         -- proposition
            INFO |         -- information
            SENS |         -- sensation
            LOCA |         -- location
            TIME |         -- time period
            ATTD |         -- attitude
            EMOT |         -- emotion
            PPTY |         -- property
            OBLG |         -- obligation
            RULE           -- rule
                 deriving (Show, Eq, Enum)

-- CUSTOM DATA TYPES
data Argument = Argument { ttype :: Type, value :: String } 
                  deriving (Show, Eq)

data Predicate = Predicate { lemma :: String
                           , arguments :: [Argument] } 
                  deriving (Show, Eq)

type Context = [Argument]

-- CREATE SEMANTICALLY TYPED ARGUMENTS AS FOLLOWS
date :: String -> Argument
date s = Argument { ttype = TIME, value = s }

time :: String -> Argument
time s = Argument { ttype = TIME, value = s }

location :: String -> Argument
location s = Argument { ttype = LOCA, value = s }

human :: String -> Argument
human s = Argument { ttype = HUMN, value = s }

phys :: String -> Argument
phys s = Argument { ttype = PHYS, value = s }

artifact :: String -> Argument
artifact s = Argument { ttype = ARTF, value = s }

animate :: String -> Argument
animate s = Argument { ttype = ANIM, value = s }

-- CREATE ENTITIES/PPs AS FOLLOWS
may15 = date "May 15, 2014"
sevenAM = time "7:00"
sandiego = location "San Diego"
john = human "John"
mary = human "Mary"
boston = location "Boston"
ball = phys "ball"
car = artifact "car"
cat = animate "cat"
mouse = animate "mouse"
to_boston = to boston

context = [
        may15,
        sevenAM,
        sandiego,
        john,
        mary,
        boston,
        ball,
        cat,
        mouse
      ]

-- HELPER FUNCTIONS
getValue :: Argument -> String
getValue c = value c

getType :: Argument -> Type
getType c = ttype c

isType :: Argument -> Type -> Bool
isType c t = (ttype c == t)

-- CREATE PREPOSITIONS AS FOLLOWS
to :: Argument -> Predicate
to x = Predicate { lemma = "to", arguments = [x] }

-- CREATE VERBS AS FOLLOWS
class Fly a b where
      fly :: a -> b -> Predicate

instance Fly Argument Argument where
      fly x y = Predicate { lemma = "fly", arguments = [x, y] }

--overwrite lemma, 
instance Fly Argument Predicate where
      fly x y = Predicate { lemma = lemma y
                          , arguments = [x, arguments y !! 0] }

facts = [fly john to_boston, fly mary to_boston]

-- THIS IS WHERE I'M STUCK\/
qWhere :: (Argument -> Argument -> Predicate) -> Argument 
                                              -> [[Argument]]
qWhere f x = [[arguments z | ]| z <- facts, x `elem` (arguments z)] 

-- THIS RETURNS THE ENTIRE STATEMENT:
qWhere f x = [[arguments z | ]| z <- facts, x `elem` (arguments z)] 
1
  • Can you give a concrete example of what a call to qWhere should return? E.g. qWhere fly boston = ???. Commented Oct 29, 2014 at 17:11

1 Answer 1

1

I don't think you need/want nested list comprehension. First you need to understand that list comprehension is really just syntactic sugar.

But we can use let ... in syntax to make use of multiple list comprehensions. A solution could look like this:

qWhere :: (Argument -> Argument -> Predicate)
       -> Argument
       -> [[Argument]]
qWhere f x = case find (== x) context of
  Just e ->
        -- first we get all facts about e.g. john
    let personFacts = [z | z <- facts, e `elem` arguments z]
        -- then we get all facts when we apply f to john and
        -- any other arguments that exist in john
        actionFacts = fmap (f e) (concatMap arguments personFacts)
        -- and extract all arguments of those facts
        actionArgs  = concatMap arguments actionFacts
        -- and can finally build the actual list of facts,
        -- reduced by checking if the argument "john" is in one of our
        -- actionArgs where we applied f to
    in map arguments [z | z <- personFacts, e `elem` actionArgs]
  Nothing -> []

You might need to import Data.List.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.