summaryrefslogtreecommitdiff
path: root/src/GF/Parsing/MCFG/Range.hs
diff options
context:
space:
mode:
authorpeb <unknown>2005-04-19 09:46:07 +0000
committerpeb <unknown>2005-04-19 09:46:07 +0000
commit6e93b2c4c60d5817d5695edf61fe658317192780 (patch)
treea149fdc56f601db02bd9cd90ff662b383426298c /src/GF/Parsing/MCFG/Range.hs
parentc1592825c71867711a63293b588fcbc97e52bfc4 (diff)
"Committed_by_peb"
Diffstat (limited to 'src/GF/Parsing/MCFG/Range.hs')
-rw-r--r--src/GF/Parsing/MCFG/Range.hs175
1 files changed, 175 insertions, 0 deletions
diff --git a/src/GF/Parsing/MCFG/Range.hs b/src/GF/Parsing/MCFG/Range.hs
new file mode 100644
index 000000000..6e849b46c
--- /dev/null
+++ b/src/GF/Parsing/MCFG/Range.hs
@@ -0,0 +1,175 @@
+
+module GF.NewParsing.MCFG.Range where
+
+
+-- Haskell
+import List
+import Monad
+
+-- GF modules
+import GF.Formalism.GCFG
+import GF.Formalism.MCFG
+import GF.Formalism.Utilities
+import GF.Infra.Print
+
+
+------------------------------------------------------------
+-- ranges as single pairs
+
+data Range = Range (Int, Int)
+ | EmptyRange
+ deriving (Eq, Ord, Show)
+
+makeRange :: (Int, Int) -> Range
+concatRange :: Range -> Range -> [Range]
+rangeEdge :: a -> Range -> Edge a
+minRange :: Range -> Int
+maxRange :: Range -> Int
+
+makeRange = Range
+concatRange EmptyRange rng = return rng
+concatRange rng EmptyRange = return rng
+concatRange (Range(i,j)) (Range(j',k)) = [ Range(i,k) | j==j']
+rangeEdge a (Range(i,j)) = Edge i j a
+minRange (Range rho) = fst rho
+maxRange (Range rho) = snd rho
+
+instance Print Range where
+ prt (Range (i,j)) = "(" ++ show i ++ "-" ++ show j ++ ")"
+ prt (EmptyRange) = "(?)"
+
+{-- Types --------------------------------------------------------------------
+ Linearization- and Range records implemented as lists
+-----------------------------------------------------------------------------}
+
+type LinRec c l t = [Lin c l t]
+
+type RangeRec l = [(l, Range)]
+
+
+{-- Functions ----------------------------------------------------------------
+ Concatenation : Concatenation of Ranges, Symbols and Linearizations
+ and records of Linearizations
+ Record transformation : Makes a Range record from a fully instantiated
+ Linearization record
+ Record projection : Given a label, returns the corresponding Range
+ Range restriction : Range restriction of Tokens, Symbols,
+ Linearizations and Records given a list of Tokens
+ Record replacment : Substitute a record for another in a list of Range
+ records
+ Argument substitution : Substitution of a Cat c to a Tok Range, where
+ Range is the cover of c
+ Note: The argument is still a Symbol c Range
+ Subsumation : Checks if a Range record subsumes another Range
+ record
+ Record unification : Unification of two Range records
+-----------------------------------------------------------------------------}
+
+
+--- Concatenation ------------------------------------------------------------
+
+
+concSymbols :: [Symbol c Range] -> [[Symbol c Range]]
+concSymbols (Tok rng:Tok rng':toks) = do rng'' <- concatRange rng rng'
+ concSymbols (Tok rng'':toks)
+concSymbols (sym:syms) = do syms' <- concSymbols syms
+ return (sym:syms')
+concSymbols [] = return []
+
+
+concLin :: Lin c l Range -> [Lin c l Range]
+concLin (Lin lbl syms) = do syms' <- concSymbols syms
+ return (Lin lbl syms')
+
+
+concLinRec :: LinRec c l Range -> [LinRec c l Range]
+concLinRec = mapM concLin
+
+
+--- Record transformation ----------------------------------------------------
+
+makeRangeRec :: LinRec c l Range -> RangeRec l
+makeRangeRec lins = map convLin lins
+ where convLin (Lin lbl [Tok rng]) = (lbl, rng)
+
+
+--- Record projection --------------------------------------------------------
+
+projection :: Eq l => l -> RangeRec l -> [Range]
+projection l rec = maybe (fail "projection") return $ lookup l rec
+
+
+--- Range restriction --------------------------------------------------------
+
+rangeRestTok :: Eq t => [t] -> t -> [Range]
+rangeRestTok toks tok = do i <- elemIndices tok toks
+ return (makeRange (i, i+1))
+
+
+rangeRestSym :: Eq t => [t] -> Symbol a t -> [Symbol a Range]
+rangeRestSym toks (Tok tok) = do rng <- rangeRestTok toks tok
+ return (Tok rng)
+rangeRestSym _ (Cat c) = return (Cat c)
+
+
+rangeRestLin :: Eq t => [t] -> Lin c l t -> [Lin c l Range]
+rangeRestLin toks (Lin lbl syms) = do syms' <- mapM (rangeRestSym toks) syms
+ return (Lin lbl syms')
+
+
+rangeRestRec :: Eq t => [t] -> LinRec c l t -> [LinRec c l Range]
+rangeRestRec toks = mapM (rangeRestLin toks)
+
+
+-- Record replacment ---------------------------------------------------------
+-- ineffektiv!!
+
+replaceRec :: [RangeRec l] -> Int -> RangeRec l -> [RangeRec l]
+replaceRec recs i rec = (fst tup) ++ [rec] ++ (tail $ snd tup)
+ where tup = splitAt i recs
+
+
+--- Argument substitution ----------------------------------------------------
+
+substArgSymbol :: Eq l => Int -> RangeRec l -> Symbol (c, l, Int) Range
+ -> Symbol (c, l, Int) Range
+substArgSymbol i rec (Tok rng) = (Tok rng)
+substArgSymbol i rec (Cat (c, l, j))
+ | i==j = maybe (Cat (c, l, j)) Tok $ lookup l rec
+ | otherwise = (Cat (c, l, j))
+
+
+substArgLin :: Eq l => Int -> RangeRec l -> Lin c l Range
+ -> Lin c l Range
+substArgLin i rec (Lin lbl syms) =
+ (Lin lbl (map (substArgSymbol i rec) syms))
+
+
+substArgRec :: Eq l => Int -> RangeRec l -> LinRec c l Range
+ -> LinRec c l Range
+substArgRec i rec lins = map (substArgLin i rec) lins
+
+
+--- Subsumation -------------------------------------------------------------
+
+-- "rec' subsumes rec?"
+subsumes :: Eq l => RangeRec l -> RangeRec l -> Bool
+subsumes rec rec' = and [elem r rec' | r <- rec]
+
+
+--- Record unification -------------------------------------------------------
+
+unifyRangeRecs :: Ord l => [RangeRec l] -> [RangeRec l] -> [[RangeRec l]]
+unifyRangeRecs recs recs' = zipWithM unify recs recs'
+ where unify :: Ord l => RangeRec l -> RangeRec l -> [RangeRec l]
+ unify rec [] = return rec
+ unify [] rec = return rec
+ unify rec1'@(p1@(l1, r1):rec1) rec2'@(p2@(l2, r2):rec2)
+ = case compare l1 l2 of
+ LT -> do rec3 <- unify rec1 rec2'
+ return (p1:rec3)
+ GT -> do rec3 <- unify rec1' rec2
+ return (p2:rec3)
+ EQ -> do guard (r1 == r2)
+ rec3 <- unify rec1 rec2
+ return (p1:rec3)