diff options
| author | aarne <aarne@cs.chalmers.se> | 2008-05-21 09:26:44 +0000 |
|---|---|---|
| committer | aarne <aarne@cs.chalmers.se> | 2008-05-21 09:26:44 +0000 |
| commit | 055c0d0d5a5bb0dc75904fe53df7f2e4f5732a8f (patch) | |
| tree | 0e63fb68c69c8f6ad0f78893c63420f0a3600e1c /src-3.0/GF/CF/Profile.hs | |
| parent | 915a1de71783ab8446b1af9e72c7ba7dfbc12d3f (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/CF/Profile.hs')
| -rw-r--r-- | src-3.0/GF/CF/Profile.hs | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/src-3.0/GF/CF/Profile.hs b/src-3.0/GF/CF/Profile.hs new file mode 100644 index 000000000..e573bec78 --- /dev/null +++ b/src-3.0/GF/CF/Profile.hs @@ -0,0 +1,106 @@ +---------------------------------------------------------------------- +-- | +-- Module : Profile +-- Maintainer : AR +-- Stability : (stable) +-- Portability : (portable) +-- +-- > CVS $Date: 2005/04/21 16:21:14 $ +-- > CVS $Author: bringert $ +-- > CVS $Revision: 1.8 $ +-- +-- restoring parse trees for discontinuous constituents, bindings, etc. AR 25/1/2001 +-- revised 8/4/2002 for the new profile structure +----------------------------------------------------------------------------- + +module GF.CF.Profile (postParse) where + +import GF.Canon.AbsGFC +import GF.Canon.GFC +import qualified GF.Infra.Ident as I +import GF.Canon.CMacros +---import MMacros +import GF.CF.CF +import GF.CF.CFIdent +import GF.CF.PPrCF -- for error msg +import GF.Grammar.PrGrammar + +import GF.Data.Operations + +import Control.Monad +import Data.List (nub) + +-- | the job is done in two passes: +-- +-- 1. tree2term: restore constituent order from Profile +-- +-- 2. term2trm: restore Bindings from Binds +postParse :: CFTree -> Err Exp +postParse tree = do + iterm <- errIn ("postprocessing parse tree" +++ prCFTree tree) $ tree2term tree + return $ term2trm iterm + +-- | an intermediate data structure +data ITerm = ITerm (Atom, BindVs) [ITerm] | IMeta deriving (Eq,Show) +type BindVs = [[I.Ident]] + +-- | (1) restore constituent order from Profile +tree2term :: CFTree -> Err ITerm +-- tree2term (CFTree (f,(_,[t]))) | f == dummyCFFun = tree2term t -- not used +tree2term (CFTree (cff@(CFFun (fun,pro)), (_,trees))) = case fun of + AM _ -> return IMeta + _ -> do + args <- mapM mkArg pro + binds <- mapM mkBinds pro + return $ ITerm (fun, binds) args + where + mkArg (_,arg) = case arg of + [x] -> do -- one occurrence + trx <- trees !? x + tree2term trx + [] -> return IMeta -- suppression + _ -> do -- reduplication + trees' <- mapM (trees !?) arg + xs1 <- mapM tree2term trees' + xs2 <- checkArity xs1 + unif xs2 + + checkArity xs = if length (nub [length xx | ITerm _ xx <- xs']) > 1 + then Bad "arity error" + else return xs' + where xs' = [t | t@(ITerm _ _) <- xs] + unif xs = case [t | t@(ITerm _ _) <- xs] of + [] -> return $ IMeta + (ITerm fp@(f,_) xx : ts) -> do + let hs = [h | ITerm (h,_) _ <- ts, h /= f] + testErr (null hs) -- if fails, hs must be nonempty + ("unification expects" +++ prt f +++ "but found" +++ prt (head hs)) + xx' <- mapM unifArg [0 .. length xx - 1] + return $ ITerm fp xx' + where + unifArg i = unif [zz !! i | ITerm _ zz <- xs] + + mkBinds (xss,_) = mapM mkBind xss + mkBind xs = do + ts <- mapM (trees !?) xs + let vs = [x | CFTree (CFFun (AV x,_),(_,[])) <- ts] + testErr (length ts == length vs) "non-variable in bound position" + case vs of + [x] -> return x + [] -> return $ I.identC "h_" ---- uBoundVar + y:ys -> do + testErr (all (==y) ys) ("fail to unify bindings of" +++ prt y) + return y + +-- | (2) restore Bindings from Binds +term2trm :: ITerm -> Exp +term2trm IMeta = EAtom (AM 0) ---- mExp0 +term2trm (ITerm (fun, binds) terms) = + let bterms = zip binds terms + in mkAppAtom fun [mkAbsR xs (term2trm t) | (xs,t) <- bterms] + + --- these are deprecated + where + mkAbsR c e = foldr EAbs e c + mkAppAtom a = mkApp (EAtom a) + mkApp = foldl EApp |
