summaryrefslogtreecommitdiff
path: root/src-2.9/GF/Parsing/MCFG/Naive.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src-2.9/GF/Parsing/MCFG/Naive.hs')
-rw-r--r--src-2.9/GF/Parsing/MCFG/Naive.hs142
1 files changed, 142 insertions, 0 deletions
diff --git a/src-2.9/GF/Parsing/MCFG/Naive.hs b/src-2.9/GF/Parsing/MCFG/Naive.hs
new file mode 100644
index 000000000..7d1fa0a8a
--- /dev/null
+++ b/src-2.9/GF/Parsing/MCFG/Naive.hs
@@ -0,0 +1,142 @@
+----------------------------------------------------------------------
+-- |
+-- Maintainer : PL
+-- Stability : (stable)
+-- Portability : (portable)
+--
+-- > CVS $Date: 2005/08/08 09:01:25 $
+-- > CVS $Author: peb $
+-- > CVS $Revision: 1.5 $
+--
+-- MCFG parsing, the naive algorithm
+-----------------------------------------------------------------------------
+
+module GF.Parsing.MCFG.Naive (parse, parseR) where
+
+import Control.Monad (guard)
+
+-- GF modules
+import GF.Data.GeneralDeduction
+import GF.Formalism.GCFG
+import GF.Formalism.MCFG
+import GF.Formalism.Utilities
+import GF.Parsing.MCFG.Range
+import GF.Parsing.MCFG.PInfo
+import GF.Data.SortedList
+import GF.Data.Assoc
+import GF.System.Tracing
+
+import GF.Infra.Print
+
+----------------------------------------------------------------------
+-- * parsing
+
+-- | Builds a chart from the initial agenda, given by prediction, and the inference rules
+parse :: (Ord t, Ord n, Ord c, Ord l) => MCFParser c n l t
+parse pinfo starts toks
+ = accumAssoc groupSyntaxNodes $
+ [ ((cat, makeRangeRec lins), SNode fun (zip rhs rrecs)) |
+ Active (Abs cat _Nil fun, rhs) lins rrecs <- chartLookup chart Final ]
+ where chart = process pinfo toks
+
+-- | Builds a chart from the initial agenda, given by prediction, and the inference rules
+-- parseR :: (Ord t, Ord n, Ord c, Ord l) => MCFParser c n l t
+parseR pinfo starts
+ = accumAssoc groupSyntaxNodes $
+ [ ((cat, makeRangeRec lins), SNode fun (zip rhs rrecs)) |
+ Active (Abs cat _Nil fun, rhs) lins rrecs <- chartLookup chart Final ]
+ where chart = processR pinfo
+
+process :: (Ord t, Ord n, Ord c, Ord l) => MCFPInfo c n l t -> Input t -> NChart c n l
+process pinfo toks
+ = tracePrt "MCFG.Naive - chart size" prtSizes $
+ buildChart keyof [convert, combine] (predict pinfo toks)
+
+processR :: (Ord n, Ord c, Ord l) => MCFPInfo c n l Range -> NChart c n l
+processR pinfo
+ = tracePrt "MCFG.Naive Range - chart size" prtSizes $
+ buildChart keyof [convert, combine] (predictR pinfo)
+
+
+----------------------------------------------------------------------
+-- * inference rules
+
+-- Creates an Active Item of every Rule in the Grammar to give the initial Agenda
+predict :: (Ord l, Ord t) => MCFPInfo c n l t -> Input t -> [Item c n l]
+predict pinfo toks = tracePrt "MCFG.Naive - predicted rules" (prt . length) $
+ do Rule abs (Cnc _ _ lins) <- rulesMatchingInput pinfo toks
+ lins' <- rangeRestRec toks lins
+ return $ Active (abs, []) lins' []
+
+-- Creates an Active Item of every Rule in the Grammar to give the initial Agenda
+predictR :: (Ord l) => MCFPInfo c n l Range -> [Item c n l]
+predictR pinfo = tracePrt "MCFG.Naive Range - predicted rules" (prt . length) $
+ do Rule abs (Cnc _ _ lins) <- allRules pinfo
+ return $ Active (abs, []) lins []
+
+-- | Creates an Active Item every time it is possible to combine
+-- an Active Item from the agenda with a Passive Item from the Chart
+combine :: (Ord n, Ord c, Ord l) => NChart c n l -> Item c n l -> [Item c n l]
+combine chart item@(Active (Abs _ (c:_) _, _) _ _) =
+ do Passive _c rrec <- chartLookup chart (Pass c)
+ combine2 chart rrec item
+combine chart (Passive c rrec) =
+ do item <- chartLookup chart (Act c)
+ combine2 chart rrec item
+combine _ _ = []
+
+combine2 chart rrec (Active (Abs nt (c:find) f, found) lins rrecs) =
+ do lins' <- substArgRec (length found) rrec lins
+ return $ Active (Abs nt find f, found ++ [c]) lins' (rrecs ++ [rrec])
+
+-- | Active Items with nothing to find are converted to Passive Items
+convert :: (Ord n, Ord c, Ord l) => NChart c n l -> Item c n l -> [Item c n l]
+convert _ (Active (Abs cat [] fun, _) lins _) = [Passive cat (makeRangeRec lins)]
+convert _ _ = []
+
+
+----------------------------------------------------------------------
+-- * type definitions
+
+type NChart c n l = ParseChart (Item c n l) (NKey c)
+
+data Item c n l = Active (DottedRule c n) (LinRec c l Range) [RangeRec l]
+ | Passive c (RangeRec l)
+ deriving (Eq, Ord, Show)
+
+type DottedRule c n = (Abstract c n, [c])
+
+data NKey c = Act c
+ | Pass c
+ | Final
+ deriving (Eq, Ord, Show)
+
+keyof :: Item c n l -> NKey c
+keyof (Active (Abs _ (next:_) _, _) _ _) = Act next
+keyof (Passive cat _) = Pass cat
+keyof _ = Final
+
+-- for tracing purposes
+prtSizes chart = "final=" ++ show (length (chartLookup chart Final)) ++
+ ", passive=" ++ show (sum [length (chartLookup chart k) |
+ k@(Pass _) <- chartKeys chart ]) ++
+ ", active=" ++ show (sum [length (chartLookup chart k) |
+ k@(Act _) <- chartKeys chart ])
+
+prtChart chart = concat [ "\n*** KEY: " ++ prt k ++
+ prtBefore "\n " (chartLookup chart k) |
+ k <- chartKeys chart ]
+
+instance (Print c, Print n, Print l) => Print (Item c n l) where
+ prt (Active (abs, cs) lrec rrecs) = "? " ++ prt abs ++ " . " ++ prtSep " " cs ++ ";\n\t" ++
+ "{" ++ prtSep " " lrec ++ "}" ++
+ ( if null rrecs then ";" else ";\n\t" ++
+ "{" ++ prtSep "} {" (map (prtSep " ") rrecs) ++ "}" )
+ prt (Passive c rrec) = "- " ++ prt c ++ "; {" ++ prtSep " " rrec ++ "}"
+
+instance Print c => Print (NKey c) where
+ prt (Act c) = "Active " ++ prt c
+ prt (Pass c) = "Passive " ++ prt c
+ prt (Final) = "Final"
+
+