import PrologLike import Language.Lojban.Parser hiding (LA, Brivla, KOhA, GOhA, NA, LerfuString) import qualified Language.Lojban.Parser as P import System.Environment import Data.Maybe import Data.Either import Data.List main :: IO () main = do [fn] <- getArgs src <- readFile fn let Right p = parse src let facts = map readSentence $ getSentences p -- print facts q <- (readSentence . either (error "bad") id . parse) `fmap` getLine putStrLn $ case ask q facts of Just r -> case answerMa r of Just ma -> ma Nothing -> case answerRelfuString r of Just rs -> rs Nothing -> "go'i" Nothing -> "nago'i" -- maybe (return ()) putStrLn $ answerRelfuString $ ask q facts -- putStrLn $ if ask q facts then "go'i" else "nago'i" -- putStrLn $ show $ ask q facts -- print q answerRelfuString :: [[(Term, Term)]] -> Maybe String answerRelfuString ps | null answers = Nothing | otherwise = Just $ intercalate " .ija " answers where answers = map answerRelfuString1 ps answerRelfuString1 :: [(Term, Term)] -> String answerRelfuString1 ps = "tu'e " ++ intercalate " .ije " (map showDU rsps) ++ " tu'u" where rsps = filter isRSPair ps showDU :: (Term, Term) -> String showDU (LerfuString ls, LA n) = ls ++ " du la " ++ n showDU (LerfuString ls, LO n) = ls ++ " du lo " ++ n isRSPair :: (Term, Term) -> Bool isRSPair (LerfuString _, _) = True isRSPair _ = False answerMa :: [[(Term, Term)]] -> Maybe String answerMa ps | null answers = Nothing | otherwise = Just $ intercalate " .a " answers where answers = catMaybes $ map answerMa1 ps answerMa1 :: [(Term, Term)] -> Maybe String answerMa1 ps = case lookup (VKOhA "ma") ps of Nothing -> Nothing Just (LA n) -> Just $ "la " ++ n Just (LO n) -> Just $ "lo " ++ n getSentences :: Sentence -> [Sentence] getSentences (IText_1 _ _ _ _ (Just t)) = getSentences t getSentences (StatementI s1 ss) = s1 : catMaybes (map (\(_, _, s) -> s) ss) getSentences o = error $ show o headTerms :: Sentence -> [Sumti] headTerms (TermsBridiTail ts _ _ _) = ts headTerms _ = [] bridiTail :: Sentence -> Sentence bridiTail (TermsBridiTail _ _ _ bt) = bt bridiTail o = o selbri :: Sentence -> Selbri selbri (SelbriTailTerms s _ _ _) = s selbri _ = P.Brivla ([], "", []) [] tailTerms :: Sentence -> [Sumti] tailTerms (SelbriTailTerms _ ts _ _) = ts tailTerms _ = [] function :: Selbri -> Function function (P.Brivla (_, n, _) _) = Brivla n function (P.GOhA (_, n, _) _ _) = GOhA n function (P.NA (_, "na", _) _ s) = NA $ function s readLALO :: Sumti -> Term readLALO (P.LA (_, "la", _) _ _ ns _) = LA $ concat $ map ((++ ".") . snd3) ns readLALO (P.LALE (_, "lo", _) _ st _ _) = LO $ readSumtiTail st readLALO (P.KOhA (_, k@"ma", _) _) = VKOhA k readLALO (P.KOhA (_, k@"da", _) _) = VKOhA k readLALO (P.KOhA (_, k@"de", _) _) = VKOhA k readLALO (P.KOhA (_, k@"di", _) _) = VKOhA k readLALO (P.KOhA (_, k@"do", _) _) = VKOhA k readLALO (P.KOhA (_, k, _) _) = KOhA k readLALO (P.LerfuString s _ _) = LerfuString $ concatMap snd3 s readSumtiTail :: SumtiTail -> String readSumtiTail (SelbriRelativeClauses (P.Brivla (_, n, _) _) _) = n readSumtiTail st = show st readSentence :: Sentence -> FactRule readSentence s@(TermsBridiTail _ _ _ _) = Fact f $ h ++ t where h = map readLALO $ headTerms s f = function $ selbri $ bridiTail s t = map readLALO $ tailTerms $ bridiTail s readSentence (IJoikJek s [r]) = Rule (readSentence s) (getRule r) getRule (_, Jek _ _ (_, "ja", _) (Just (_, "nai", _)), _, Just t) = readTUhE t readTUhE (TUhE _ _ _ t _ _) = map readSentence $ getSentences t checkKOhA :: FactRule -> FactRule -> [(Term, Term)] checkKOhA (Fact _ ts1) (Fact _ ts2) = zip ts1 ts2 {- findFacts :: FactRule -> [FactRule] -> [FactRule] findFacts (Fact f0 _) fs = filter (isFactFor f0) fs isFactFor :: Function -> FactRule -> Bool isFactFor f0 (Fact f1 _) = f0 == f1 isFactFor _ _ = False ask :: FactRule -> [FactRule] -> Bool ask (Fact (NA f) ts) facts = not $ ask (Fact f ts) facts ask (Fact (GOhA "du") ts) _ = ts !! 0 == ts !! 1 ask q@(Fact f ts) facts | q `elem` facts = True | otherwise = case findRule q facts of Nothing -> False Just r -> and $ map (flip ask facts) $ apply ts r findRule :: FactRule -> [FactRule] -> Maybe FactRule findRule (Fact f _) rs = let ret = filter (isRuleFor f) rs in if null ret then Nothing else Just $ head ret isRuleFor :: Function -> FactRule -> Bool isRuleFor f0 (Rule (Fact f1 _) _) = f0 == f1 isRuleFor _ _ = False apply :: [Term] -> FactRule -> [FactRule] apply ts2 (Rule (Fact _ ts1) fs) = map (changeFactTerms ts1 ts2) fs changeFactTerms :: [Term] -> [Term] -> FactRule -> FactRule changeFactTerms ts1 ts2 (Fact f ts) = Fact f $ changeTerms ts1 ts2 ts changeTerms :: [Term] -> [Term] -> [Term] -> [Term] changeTerms [] _ ts = ts changeTerms _ [] ts = ts changeTerms (t1 : ts1) (t2 : ts2) ts = changeTerms ts1 ts2 $ changeTerm t1 t2 ts changeTerm :: Term -> Term -> [Term] -> [Term] changeTerm _ _ [] = [] changeTerm t1 t2 (t : ts) | t == t1 = t2 : changeTerm t1 t2 ts | otherwise = t : changeTerm t1 t2 ts sampleRule = Rule (Fact (Brivla "pendo") [KOhA "da", KOhA "de"]) [Fact (Brivla "nelci") [KOhA "da", KOhA "de"]] -} snd3 :: (a, b, c) -> b snd3 (_, y, _) = y