summaryrefslogtreecommitdiff
path: root/src-3.0/GF/Conversion/RemoveErasing.hs
diff options
context:
space:
mode:
authoraarne <aarne@cs.chalmers.se>2008-05-21 09:26:44 +0000
committeraarne <aarne@cs.chalmers.se>2008-05-21 09:26:44 +0000
commit055c0d0d5a5bb0dc75904fe53df7f2e4f5732a8f (patch)
tree0e63fb68c69c8f6ad0f78893c63420f0a3600e1c /src-3.0/GF/Conversion/RemoveErasing.hs
parent915a1de71783ab8446b1af9e72c7ba7dfbc12d3f (diff)
GF/src is now for 2.9, and the new sources are in src-3.0 - keep it this way until the release of GF 3
Diffstat (limited to 'src-3.0/GF/Conversion/RemoveErasing.hs')
-rw-r--r--src-3.0/GF/Conversion/RemoveErasing.hs113
1 files changed, 113 insertions, 0 deletions
diff --git a/src-3.0/GF/Conversion/RemoveErasing.hs b/src-3.0/GF/Conversion/RemoveErasing.hs
new file mode 100644
index 000000000..1dc2560fc
--- /dev/null
+++ b/src-3.0/GF/Conversion/RemoveErasing.hs
@@ -0,0 +1,113 @@
+----------------------------------------------------------------------
+-- |
+-- Maintainer : PL
+-- Stability : (stable)
+-- Portability : (portable)
+--
+-- > CVS $Date: 2005/05/09 09:28:44 $
+-- > CVS $Author: peb $
+-- > CVS $Revision: 1.3 $
+--
+-- Removing erasingness from MCFG grammars (as in Ljunglöf 2004, sec 4.5.1)
+-----------------------------------------------------------------------------
+
+
+module GF.Conversion.RemoveErasing
+ (convertGrammar) where
+
+import GF.System.Tracing
+import GF.Infra.Print
+
+import Control.Monad
+import Data.List (mapAccumL)
+import Data.Maybe (mapMaybe)
+import GF.Formalism.Utilities
+import GF.Formalism.GCFG
+import GF.Formalism.MCFG
+import GF.Conversion.Types
+import GF.Data.Assoc
+import GF.Data.SortedList
+import GF.Data.GeneralDeduction
+
+convertGrammar :: EGrammar -> [SCat] -> MGrammar
+convertGrammar grammar starts = newGrammar
+ where newGrammar = tracePrt "RemoveErasing - nonerasing rules" (prt . length) $
+ [ rule | NR rule <- chartLookup finalChart True ]
+ finalChart = tracePrt "RemoveErasing - nonerasing cats"
+ (prt . length . flip chartLookup False) $
+ buildChart keyof [newRules rulesByCat] $
+ tracePrt "RemoveErasing - initial ne-cats" (prt . length) $
+ initialCats
+ initialCats = trace2 "RemoveErasing - starting categories" (prt starts) $
+ if null starts
+ then trace2 "RemoveErasing" "initialCatsBU" $
+ initialCatsBU rulesByCat
+ else trace2 "RemoveErasing" ("initialCatsTD: " ++ prt starts) $
+ initialCatsTD rulesByCat starts
+ rulesByCat = trace2 "RemoveErasing - erasing rules" (prt $ length grammar) $
+ accumAssoc id [ (cat, rule) | rule@(Rule (Abs cat _ _) _) <- grammar ]
+
+data Item r c = NR r | NC c deriving (Eq, Ord, Show)
+
+keyof (NR _) = True
+keyof (NC _) = False
+
+newRules grammar chart (NR (Rule (Abs _ cats _) _))
+ = [ NC cat | cat@(MCat _ lbls) <- cats, not (null lbls) ]
+newRules grammar chart (NC newCat@(MCat cat lbls))
+ = do Rule (Abs _ args (Name fun profile)) (Cnc _ _ lins0) <- grammar ? cat
+
+ lins <- selectLins lins0 lbls
+ -- let lins = [ lin | lin@(Lin lbl _) <- lins0,
+ -- lbl `elem` lbls ]
+
+ let argsInLin = listAssoc $
+ map (\((n,c),l) -> (n, MCat c l)) $
+ groupPairs $ nubsort $
+ [ ((nr, cat), lbl) |
+ Lin _ lin <- lins,
+ Cat (cat, lbl, nr) <- lin ]
+
+ newArgs = mapMaybe (lookupAssoc argsInLin) [0 .. length args-1]
+ argLbls = [ lbls | MCat _ lbls <- newArgs ]
+
+ newLins = [ Lin lbl newLin | Lin lbl lin <- lins,
+ let newLin = map (mapSymbol cnvCat id) lin ]
+ cnvCat (cat, lbl, nr) = (mcat, lbl, nr')
+ where Just mcat = lookupAssoc argsInLin nr
+ Unify [nr'] = newProfile !! nr
+ nonEmptyCat (Cat (MCat _ [], _, _)) = False
+ nonEmptyCat _ = True
+
+ newProfile = snd $ mapAccumL accumProf 0 $
+ map (lookupAssoc argsInLin) [0 .. length args-1]
+ accumProf nr = maybe (nr, Unify []) $ const (nr+1, Unify [nr])
+ newName = -- tracePrt "newName" (prtNewName profile newProfile) $
+ Name fun (profile `composeProfiles` newProfile)
+
+ guard $ all (not . null) argLbls
+ return $ NR (Rule (Abs newCat newArgs newName) (Cnc lbls argLbls newLins))
+
+selectLins lins0 = mapM selectLbl
+ where selectLbl lbl = [ lin | lin@(Lin lbl' _) <- lins0, lbl == lbl' ]
+
+
+prtNewName :: [Profile (SyntaxForest Fun)] -> [Profile (SyntaxForest Fun)] -> Name -> String
+prtNewName p p' n = prt p ++ " .o. " ++ prt p' ++ " : " ++ prt n
+
+
+initialCatsTD grammar starts =
+ [ cat | cat@(NC (MCat (ECat start _) _)) <- initialCatsBU grammar,
+ start `elem` starts ]
+
+initialCatsBU grammar
+ = [ NC (MCat cat [lbl]) | (cat, rules) <- aAssocs grammar,
+ let Rule _ (Cnc lbls _ _) = head rules,
+ lbl <- lbls ]
+
+
+
+
+
+
+