Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
| Download
Logic of "all" + verbs + relative clauses, for a class at Indiana University
Project: moss notebooks
Views: 7225{-# LANGUAGE LambdaCase #-}1module FrontEnd where23import Data.List4import ARC/Syntax25import ARC/ExampleSentences6import Control.Arrow7import Control.Monad (guard)8import Data.Maybe (listToMaybe,maybeToList)9import Data.Char (toLower)10import Data.List (transpose, intercalate)1112type Parser a b = [a] -> [(b,[a])]13type PARSER a b = Parser a (ParseTree a b)1415epsilonT :: PARSER a b16epsilonT = succeed Ep1718symbolT :: Eq a => a -> PARSER a b19symbolT s = (\ x -> Leaf x) <$$> symbol s2021symbol :: Eq a => a -> Parser a a22symbol c [] = []23symbol c (x:xs) | c == x = [(x,xs)]24| otherwise = []2526infixl 6 <:>2728(<:>) :: Parser a b -> Parser a [b] -> Parser a [b]29(p <:> q) xs = [ (r:rs,zs) | (r,ys) <- p xs,30(rs,zs) <- q ys ]3132(<|>) :: Parser a b -> Parser a b -> Parser a b33(p1 <|> p2) xs = p1 xs ++ p2 xs3435(<**>) :: Parser a [b] -> Parser a [b] -> Parser a [b]36(p <**> q) xs = [ (r1 ++ r2,zs) | (r1,ys) <- p xs,37(r2,zs) <- q ys ]38infixl 7 <$$>3940(<$$>) :: (a -> b) -> Parser s a -> Parser s b41(f <$$> p) xs = [ (f x,ys) | (x,ys) <- p xs ]4243data ParseTree a b = Ep | Leaf a | Branch b [ParseTree a b]44deriving Eq4546instance (Show a, Show b) => Show (ParseTree a b) where47show Ep = "[]"48show (Leaf t) = show t49show (Branch l ts) = "[." ++ show l ++ " "50++ show ts ++ "]"515253succeed :: b -> Parser a b54succeed r xs = [(r,xs)]5556collect :: [Parser a b] -> Parser a [b]57collect [] = succeed []58collect (p:ps) = p <:> collect ps5960parseAs :: b -> [PARSER a b] -> PARSER a b61parseAs label ps = (\ xs -> Branch label xs) <$$> collect ps6263sent, tv, cn, det, t, int, intOrT, neg, np :: PARSER String String64cn = symbolT "skunks"65<|> symbolT "mammals"66<|> symbolT "chordates"67<|> symbolT "boys" <|> symbolT "girls" <|> symbolT "animals"6869tv = symbolT "see" <|> symbolT "love" <|> symbolT "admire" <|> symbolT "hate"7071det = symbolT "every"72<|> symbolT "some"73<|> symbolT "no"74<|> symbolT "all"75<|> symbolT "most"7677t = parseAs "Term" [cn]78<|> parseAs "Term" [symbolT "non" ,cn]79<|> parseAs "Term" [tv, det, intOrT]80<|> parseAs "Term" [tv, det, symbolT "who", intOrT]8182--pcn = parseAs "PCN" [pol, cn]83neg = symbolT "non"8485np = parseAs "NP" [det,intOrT]86--pv = parseAs "PV" [pol, tv]8788sent = parseAs "S" [det,intOrT,intOrT]899091int = parseAs "Int" [cn,symbolT "who",t]9293intOrT = int <|> t9495move :: ParseTree String String -> Term96move (Branch "Term" [Leaf "skunks"]) = (CNasTerm skunks)97move (Branch "Term" [Leaf "mammals"]) = (CNasTerm mammals)98move (Branch "Term" [Leaf "animals"]) = (CNasTerm animals)99move (Branch "Term" [Leaf "chordates"]) = (CNasTerm chordates)100move (Branch "Term" [Leaf "sneetches"]) = (CNasTerm sneetches)101move (Branch "Term" [(Leaf "non"), (Leaf "skunks")]) = (CNasTerm non_skunks)102move (Branch "Term" [(Leaf "non"), Leaf "mammals"]) = (CNasTerm non_mammals)103move (Branch "Term" [(Leaf "non"), Leaf "animals"]) = (CNasTerm non_animals)104move (Branch "Term" [(Leaf "non"), Leaf "chordates"]) = (CNasTerm non_chordates)105move (Branch "Term" [(Leaf "non"), Leaf "sneetches"]) = (CNasTerm non_sneetches)106107108move (Branch "Term" [(Leaf "see"), (Leaf "all"), (Leaf "who"), subtree])109= (TermMaker sees (TermNP All (move subtree)))110move (Branch "Term" [(Leaf "see"), (Leaf "all"), subtree])111= (TermMaker sees (TermNP All (move subtree)))112move (Branch "Term" [(Leaf "love"), (Leaf "all"), (Leaf "who"), subtree])113= (TermMaker loves (TermNP All (move subtree)))114move (Branch "Term" [(Leaf "love"), (Leaf "all"), subtree])115= (TermMaker loves (TermNP All (move subtree)))116move (Branch "Term" [(Leaf "hate"), (Leaf "all"), (Leaf "who"), subtree])117= (TermMaker hates (TermNP All (move subtree)))118move (Branch "Term" [(Leaf "hate"), (Leaf "all"), subtree])119= (TermMaker hates (TermNP All (move subtree)))120move (Leaf "skunks") = (CNasTerm skunks)121--move (Leaf ["mammals"]) = (CNasTerm mammals)122--move (Leaf ["animals"]) = (CNasTerm animals)123124moveS :: ParseTree String String -> Sent125moveS (Branch "S" [(Leaf "all"), ttree, ttree2]) = (Sent All (move ttree) (move ttree2))126127readMe = moveS . fst . head . sent . words128129sentParses :: String -> [Sent]130sentParses =131map (moveS . fst)132. filter (null . snd)133. sent134. words135136-----USAGE: moveS $ (fst.head) $ sent $ words "all see all see all skunks love all mammals"137---- ALSO move $ (fst . head) $ t $ words "see all see all non skunks"138--- note how 'non' worls139140split2 :: [t] -> [[[t]]] ---- split2 takes any list $\ell$ and gives the list of all ways to split $\ell$ into two sublists141--- whose concatenation is $\ell$ again.142split2 [] = [[[],[]]]143split2 (x:xs) = [[ [], x:xs]] ++ map (\z -> [x:(z!!0),z!!1]) (split2 xs)144145split2' :: [t] -> [([t],[t])]146split2' = \case147xs@(x : xs') -> ([],xs) : map (first (x :)) (split2' xs')148149{-150[] = [([],[])]151split2' (x:xs) = [[ [], x:xs]] ++ map (\z -> [x:(z!!0),z!!1]) (split2 xs)152-}153154tF :: [String] -> [Term]155tF quoted -- this parses terms156| quoted == [] = []157| (quoted!! 0 == "who") = tF $ drop 1 quoted158| (quoted!! 0 == "are") = tF $ drop 1 quoted159| (quoted!! 0 == "also") = tF $ drop 1 quoted160| quoted == ["skunks"] = [CNasTerm skunks]161| quoted == ["mammals"] = [CNasTerm mammals]162| quoted == ["chordates"] = [CNasTerm chordates]163| quoted == ["boys"] = [CNasTerm boys]164| quoted == ["girls"] = [CNasTerm girls]165| quoted == ["dogs"] = [CNasTerm dogs]166| quoted == ["cats"] = [CNasTerm cats]167| quoted == ["birds"] = [CNasTerm birds]168| quoted == ["animals"] = [CNasTerm animals]169| quoted == ["sneetches"] = [CNasTerm sneetches]170| quoted == ["non-skunks"] = [CNasTerm non_skunks]171| quoted == ["non-mammals"] = [CNasTerm non_mammals]172| quoted == ["non-chordates"] = [CNasTerm non_chordates]173| quoted == ["non-boys"] = [CNasTerm non_boys]174| quoted == ["non-girls"] = [CNasTerm non_girls]175| quoted == ["non-dogs"] = [CNasTerm non_dogs]176| quoted == ["non-cats"] = [CNasTerm non_cats]177| quoted == ["non-birds"] = [CNasTerm non_birds]178| quoted == ["non-animals"] = [CNasTerm non_animals]179| quoted == ["non-sneetches"] = [CNasTerm non_sneetches]180| quoted == ["x"] = [CNasTerm x]181| quoted == ["y"] = [CNasTerm y]182| quoted == ["z"] = [CNasTerm z]183| quoted == ["p"] = [CNasTerm p]184| quoted == ["q"] = [CNasTerm q]185| quoted == ["non-x"] = [CNasTerm non_x]186| quoted == ["non-y"] = [CNasTerm non_y]187| quoted == ["non-z"] = [CNasTerm non_z]188| quoted == ["non-p"] = [CNasTerm non_p]189| quoted == ["non-q"] = [CNasTerm non_q]190| (quoted!! 0 == "see") = [(TermMaker sees r) | r <- (npF (drop 1 quoted))]191| (quoted!! 0 == "sees") = [(TermMaker sees r) | r <- (npF (drop 1 quoted))]192| (quoted!! 0 == "admires") = [(TermMaker admires r) | r <- (npF (drop 1 quoted))]193| (quoted!! 0 == "admire") = [(TermMaker admires r) | r <- (npF (drop 1 quoted))]194| (quoted!! 0 == "loves") = [(TermMaker loves r) | r <- (npF (drop 1 quoted))]195| (quoted!! 0 == "love") = [(TermMaker loves r) | r <- (npF (drop 1 quoted))]196| (quoted!! 0 == "helps") = [(TermMaker helps r) | r <- (npF (drop 1 quoted))]197| (quoted!! 0 == "help") = [(TermMaker helps r) | r <- (npF (drop 1 quoted))]198| (quoted!! 0 == "hates") = [(TermMaker hates r) | r <- (npF (drop 1 quoted))]199| (quoted!! 0 == "hate") = [(TermMaker hates r) | r <- (npF (drop 1 quoted))]200| (quoted!! 0 == "doesn't-see") = [(TermMaker not_sees r) | r <- (npF (drop 1 quoted))]201| (quoted!! 0 == "doesn't-admire") = [(TermMaker not_admires r) | r <- (npF (drop 1 quoted))]202| (quoted!! 0 == "doesn't-love") = [(TermMaker not_loves r) | r <- (npF (drop 1 quoted))]203| (quoted!! 0 == "doesn't-help") = [(TermMaker not_helps r) | r <- (npF (drop 1 quoted))]204| (quoted!! 0 == "doesn't-hate") = [(TermMaker not_hates r) | r <- (npF (drop 1 quoted))]205| (quoted!! 0 == "don't-see") = [(TermMaker not_sees r) | r <- (npF (drop 1 quoted))]206| (quoted!! 0 == "don't-admire") = [(TermMaker not_admires r) | r <- (npF (drop 1 quoted))]207| (quoted!! 0 == "don't-love") = [(TermMaker not_loves r) | r <- (npF (drop 1 quoted))]208| (quoted!! 0 == "don't-help") = [(TermMaker not_helps r) | r <- (npF (drop 1 quoted))]209| (quoted!! 0 == "don't-hate") = [(TermMaker not_hates r) | r <- (npF (drop 1 quoted))]210| (quoted!! 0 == "r") = [(TermMaker r blurt) | blurt <- (npF (drop 1 quoted))]211| otherwise = []212213{--214intTF quoted215| (quoted !! 0 == ["skunks"]) = [(IntersectionTerm (PCN Pos Skunks) x) | x <- (map tF (drop 1 quoted))]216| quoted !! 0 == ["mammals"] = [CNasTerm mammals]217| quoted !! 0== ["chordates"] = [CNasTerm chordates]218| quoted !! 0== ["boys"] = [CNasTerm boys]219| quoted !! 0 == ["girls"] = [CNasTerm girls]220| quoted !! 0 == ["dogs"] = [CNasTerm dogs]221| quoted !! 0 == ["cats"] = [CNasTerm cats]222| quoted !! 0 == ["birds"] = [CNasTerm birds]223| quoted !! 0 == ["animals"] = [CNasTerm animals]224| quoted !! 0 == ["sneetches"] = [CNasTerm sneetches]225| otherwise = []226--}227228npF x --- this parses noun phrases229| x == [] = []230| (x!! 0 == "all") = [(TermNP All w) | w <- tF (drop 1 x)]231| (x!! 0 == "some") = [(TermNP Some w) | w <- tF (drop 1 x)]232| (x!! 0 == "no") = [(TermNP No w) | w <- tF (drop 1 x)]233| (x!! 0 == "most") = [(TermNP Most w) | w <- tF (drop 1 x)]234| otherwise = []235236readS input = --- this parses sentences237let238w = words input239firstWord = head w240y = tail w241sp = split2 y242tr = [ x | x <- (map (map tF) sp), (x!!0) /= [], (x!!1) /= []]243a = head $ head $ head tr244b = head $ head $ tail $ head tr245output246| firstWord == "all" = Sent All a b247| firstWord == "some" = Sent Some a b248| firstWord == "most" = Sent Most a b249| firstWord == "atleast" = Sent Atleast a b250| firstWord == "more" = Sent More a b251| firstWord == "no" = Sent No a b252| firstWord == "All" = Sent All a b253| firstWord == "Some" = Sent Some a b254| firstWord == "Most" = Sent Most a b255| firstWord == "No" = Sent No a b256| otherwise = None257in output258259readSs = map readS260261toMaybe :: Foldable t => t a -> Maybe a262toMaybe = foldl (maybe Just (const . Just)) Nothing263{-# INLINE toMaybe #-}264265readS' :: String -> Maybe Sent266readS' input = case words input of267w0:ws -> do268q <- lookup (toLower <$> w0)269[ ( "all" , All )270, ( "some" , Some )271, ( "most" , Most )272, ( "atleast" , Atleast )273, ( "more" , More )274, ( "no" , No )275]276(a,b) <- listToMaybe277$ split2' ws >>= uncurry zip . (tF *** tF)278return $ Sent q a b279_ -> Nothing280281-- return either the strings which failed to be parsed,282-- or the full set of parsed sentences.283readSs' :: [String] -> Either [String] [Sent]284readSs' = foldr rS $ Right []285where286rS :: String -> Either [String] [Sent] -> Either [String] [Sent]287rS s es = case readS' s of288Just s' -> case es of289Left bad -> Left bad290Right good -> Right $ s' : good291Nothing -> case es of292Left bad -> Left $ s : bad293Right good -> Left [s]294295-- A few items used in display of models and proofs296297298-- a type for fill functions299type Filler = Int -> String -> String300301-- a type for describing table columns302data ColDesc t = ColDesc { colTitleFill :: Filler303, colTitle :: String304, colValueFill :: Filler305, colValue :: t -> String306}307308309310-- functions that fill a string (s) to a given width (n) by adding pad311-- character (c) to align left, right, or center312fillLeft c n s = s ++ replicate (n - length s) c313fillRight c n s = replicate (n - length s) c ++ s314fillCenter c n s = replicate l c ++ s ++ replicate r c315where x = n - length s316l = x `div` 2317r = x - l318319-- functions that fill with spaces320321left = fillLeft ' '322right = fillRight ' '323center = fillCenter ' '324--showTable :: [ColDesc t] -> [t] -> String325326327showTable cs ts =328let header = map colTitle cs329rows = [[colValue c t | c <- cs] | t <- ts]330widths = [maximum $ map length col | col <- transpose $ header : rows]331separator = intercalate "-+-" [replicate width '-' | width <- widths]332fillCols fill cols = intercalate " | " [fill c width col | (c, width, col) <- zip3 cs widths cols]333in334unlines $ fillCols colTitleFill header : separator : map (fillCols colValueFill) rows335336showTableForProofs cs ts =337let header = map colTitle cs338rows = [[colValue c t | c <- cs] | t <- ts]339widths = [maximum $ map length col | col <- transpose $ header : rows]340separator = intercalate " " [replicate width ' ' | width <- widths]341fillCols fill cols = intercalate " " [fill c width col | (c, width, col) <- zip3 cs widths cols]342in343-- unlines $ fillCols colTitleFill header : separator : map (fillCols colValueFill) rows344unlines $ fillCols colTitleFill header : map (fillCols colValueFill) rows345{--346showTableForProofs cs ts =347let header = map colTitle cs348-- rows = [[colValue c t | c <- cs] | t <- ts]349-- widths = [maximum $ map length col | col <- transpose $ header : rows]350-- separator = intercalate " " [replicate width ' ' | width <- widths]351-- fillCols fill cols = intercalate " " [fill c width col | (c, width, col) <- zip3 cs widths cols]352in353tableWithLegend354(("first", "second"), "third")355[((linum, prop), just)356| linum <- [1 .. (length header)]357, prop <- cs358, just <- ts] :: Table [(Int, String, String)]359--}360361362