module AnswerBase where import GSyntax -- interpretation of Base type Prop = Bool type Ent = Int domain = [0 .. 100] iS :: GS -> Prop iS s = case s of GPredAP np ap -> iNP np (iAP ap) iNP :: GNP -> (Ent -> Prop) -> Prop iNP np p = case np of GEvery cn -> all (\x -> not (iCN cn x) || p x) domain GSome cn -> any (\x -> iCN cn x && p x) domain GNone -> not (any (\x -> p x) domain) GMany pns -> and (map p (iListPN pns)) GConjNP c np1 np2 -> iConj c (iNP np1 p) (iNP np2 p) GUsePN a -> p (iPN a) iPN :: GPN -> Ent iPN pn = case pn of GUseInt i -> iInt i GSum pns -> sum (iListPN pns) GProduct pns -> product (iListPN pns) GGCD pns -> foldl1 gcd (iListPN pns) iAP :: GAP -> Ent -> Prop iAP ap e = case ap of GComplA2 a2 np -> iNP np (iA2 a2 e) GConjAP c ap1 ap2 -> iConj c (iAP ap1 e) (iAP ap2 e) GEven -> even e GOdd -> odd e GPrime -> prime e iCN :: GCN -> Ent -> Prop iCN cn e = case cn of GModCN ap cn0 -> (iCN cn0 e) && (iAP ap e) GNumber -> True iConj :: GConj -> Prop -> Prop -> Prop iConj c = case c of GAnd -> (&&) GOr -> (||) iA2 :: GA2 -> Ent -> Ent -> Prop iA2 a2 e1 e2 = case a2 of GGreater -> e1 > e2 GSmaller -> e1 < e2 GEqual -> e1 == e2 GDivisible -> e2 /= 0 && mod e1 e2 == 0 iListPN :: GListPN -> [Ent] iListPN gls = case gls of GListPN pns -> map iPN pns iInt :: GInt -> Ent iInt gi = case gi of GInt i -> fromInteger i -- questions and answers iQuestion :: GQuestion -> Either Bool [Ent] iQuestion q = case q of GWhatIs pn -> Right [iPN pn] -- computes the value GWhichAre cn ap -> Right [e | e <- domain, iCN cn e, iAP ap e] GQuestS s -> Left (iS s) question2answer :: GQuestion -> GAnswer question2answer q = case iQuestion q of Left True -> GYes Left False -> GNo Right [] -> GValue GNone Right [v] -> GValue (GUsePN (ent2pn v)) Right vs -> GValue (GMany (GListPN (map ent2pn vs))) ent2pn :: Ent -> GPN ent2pn e = GUseInt (GInt (toInteger e)) -- auxiliary prime :: Int -> Bool prime x = elem x primes where primes = sieve [2 .. x] sieve (p:xs) = p : sieve [ n | n <- xs, n `mod` p > 0 ] sieve [] = []