diff options
| author | kr.angelov <kr.angelov@chalmers.se> | 2008-05-22 11:59:31 +0000 |
|---|---|---|
| committer | kr.angelov <kr.angelov@chalmers.se> | 2008-05-22 11:59:31 +0000 |
| commit | df0c4f81fa9c620d7c63af79c0b183a6beccf0bd (patch) | |
| tree | 0cdc80b29f8f5df0ad280f17be0ba9d46fbd948c /src-3.0/GF/Grammar | |
| parent | 6394f3ccfbb9d14017393b433a38a3921f1083e5 (diff) | |
remove all files that aren't used in GF-3.0
Diffstat (limited to 'src-3.0/GF/Grammar')
| -rw-r--r-- | src-3.0/GF/Grammar/AbsCompute.hs | 145 | ||||
| -rw-r--r-- | src-3.0/GF/Grammar/Compute.hs | 426 | ||||
| -rw-r--r-- | src-3.0/GF/Grammar/LookAbs.hs | 159 | ||||
| -rw-r--r-- | src-3.0/GF/Grammar/PrGrammar.hs | 39 | ||||
| -rw-r--r-- | src-3.0/GF/Grammar/SGrammar.hs | 169 | ||||
| -rw-r--r-- | src-3.0/GF/Grammar/TC.hs | 299 | ||||
| -rw-r--r-- | src-3.0/GF/Grammar/TypeCheck.hs | 311 |
7 files changed, 9 insertions, 1539 deletions
diff --git a/src-3.0/GF/Grammar/AbsCompute.hs b/src-3.0/GF/Grammar/AbsCompute.hs deleted file mode 100644 index 57e21f1dd..000000000 --- a/src-3.0/GF/Grammar/AbsCompute.hs +++ /dev/null @@ -1,145 +0,0 @@ ----------------------------------------------------------------------- --- | --- Module : AbsCompute --- Maintainer : AR --- Stability : (stable) --- Portability : (portable) --- --- > CVS $Date: 2005/10/02 20:50:19 $ --- > CVS $Author: aarne $ --- > CVS $Revision: 1.8 $ --- --- computation in abstract syntax w.r.t. explicit definitions. --- --- old GF computation; to be updated ------------------------------------------------------------------------------ - -module GF.Grammar.AbsCompute (LookDef, - compute, - computeAbsTerm, - computeAbsTermIn, - beta - ) where - -import GF.Data.Operations - -import GF.Grammar.Abstract -import GF.Grammar.PrGrammar -import GF.Grammar.LookAbs -import GF.Grammar.Compute - -import Debug.Trace -import Data.List(intersperse) -import Control.Monad (liftM, liftM2) - --- for debugging -tracd m t = t --- tracd = trace - -compute :: GFCGrammar -> Exp -> Err Exp -compute = computeAbsTerm - -computeAbsTerm :: GFCGrammar -> Exp -> Err Exp -computeAbsTerm gr = computeAbsTermIn (lookupAbsDef gr) [] - --- | a hack to make compute work on source grammar as well -type LookDef = Ident -> Ident -> Err (Maybe Term) - -computeAbsTermIn :: LookDef -> [Ident] -> Exp -> Err Exp -computeAbsTermIn lookd xs e = errIn ("computing" +++ prt e) $ compt xs e where - compt vv t = case t of --- Prod x a b -> liftM2 (Prod x) (compt vv a) (compt (x:vv) b) --- Abs x b -> liftM (Abs x) (compt (x:vv) b) - _ -> do - let t' = beta vv t - (yy,f,aa) <- termForm t' - let vv' = yy ++ vv - aa' <- mapM (compt vv') aa - case look f of - Just (Eqs eqs) -> tracd ("\nmatching" +++ prt f) $ - case findMatch eqs aa' of - Ok (d,g) -> do - --- let (xs,ts) = unzip g - --- ts' <- alphaFreshAll vv' ts - let g' = g --- zip xs ts' - d' <- compt vv' $ substTerm vv' g' d - tracd ("by Egs:" +++ prt d') $ return $ mkAbs yy $ d' - _ -> tracd ("no match" +++ prt t') $ - do - let v = mkApp f aa' - return $ mkAbs yy $ v - Just d -> tracd ("define" +++ prt t') $ do - da <- compt vv' $ mkApp d aa' - return $ mkAbs yy $ da - _ -> do - let t2 = mkAbs yy $ mkApp f aa' - tracd ("not defined" +++ prt_ t2) $ return t2 - - look t = case t of - (Q m f) -> case lookd m f of - Ok (Just EData) -> Nothing -- canonical --- should always be QC - Ok md -> md - _ -> Nothing - Eqs _ -> return t ---- for nested fn - _ -> Nothing - -beta :: [Ident] -> Exp -> Exp -beta vv c = case c of - Let (x,(_,a)) b -> beta vv $ substTerm vv [(x,beta vv a)] (beta (x:vv) b) - App f a -> - let (a',f') = (beta vv a, beta vv f) in - case f' of - Abs x b -> beta vv $ substTerm vv [(x,a')] (beta (x:vv) b) - _ -> (if a'==a && f'==f then id else beta vv) $ App f' a' - Prod x a b -> Prod x (beta vv a) (beta (x:vv) b) - Abs x b -> Abs x (beta (x:vv) b) - _ -> c - --- special version of pattern matching, to deal with comp under lambda - -findMatch :: [([Patt],Term)] -> [Term] -> Err (Term, Substitution) -findMatch cases terms = case cases of - [] -> Bad $"no applicable case for" +++ unwords (intersperse "," (map prt terms)) - (patts,_):_ | length patts /= length terms -> - Bad ("wrong number of args for patterns :" +++ - unwords (map prt patts) +++ "cannot take" +++ unwords (map prt terms)) - (patts,val):cc -> case mapM tryMatch (zip patts terms) of - Ok substs -> return (tracd ("value" +++ prt_ val) val, concat substs) - _ -> findMatch cc terms - -tryMatch :: (Patt, Term) -> Err [(Ident, Term)] -tryMatch (p,t) = do - t' <- termForm t - trym p t' - where - - trym p t' = err (\s -> tracd s (Bad s)) (\t -> tracd (prtm p t) (return t)) $ ---- - case (p,t') of - (PV IW, _) | notMeta t -> return [] -- optimization with wildcard - (PV x, _) | notMeta t -> return [(x,t)] - (PString s, ([],K i,[])) | s==i -> return [] - (PInt s, ([],EInt i,[])) | s==i -> return [] - (PFloat s,([],EFloat i,[])) | s==i -> return [] --- rounding? - (PP q p pp, ([], QC r f, tt)) | - p `eqStrIdent` f && length pp == length tt -> do - matches <- mapM tryMatch (zip pp tt) - return (concat matches) - (PP q p pp, ([], Q r f, tt)) | - p `eqStrIdent` f && length pp == length tt -> do - matches <- mapM tryMatch (zip pp tt) - return (concat matches) - (PT _ p',_) -> trym p' t' - (_, ([],Alias _ _ d,[])) -> tryMatch (p,d) - (PAs x p',_) -> do - subst <- trym p' t' - return $ (x,t) : subst - _ -> Bad ("no match in pattern" +++ prt p +++ "for" +++ prt t) - - notMeta e = case e of - Meta _ -> False - App f a -> notMeta f && notMeta a - Abs _ b -> notMeta b - _ -> True - - prtm p g = - prt p +++ ":" ++++ unwords [" " ++ prt_ x +++ "=" +++ prt_ y +++ ";" | (x,y) <- g] diff --git a/src-3.0/GF/Grammar/Compute.hs b/src-3.0/GF/Grammar/Compute.hs deleted file mode 100644 index c76058cc2..000000000 --- a/src-3.0/GF/Grammar/Compute.hs +++ /dev/null @@ -1,426 +0,0 @@ ----------------------------------------------------------------------- --- | --- Module : Compute --- Maintainer : AR --- Stability : (stable) --- Portability : (portable) --- --- > CVS $Date: 2005/11/01 15:39:12 $ --- > CVS $Author: aarne $ --- > CVS $Revision: 1.19 $ --- --- Computation of source terms. Used in compilation and in @cc@ command. ------------------------------------------------------------------------------ - -module GF.Grammar.Compute (computeConcrete, computeTerm,computeConcreteRec) where - -import GF.Data.Operations -import GF.Grammar.Grammar -import GF.Infra.Ident -import GF.Infra.Option -import GF.Data.Str -import GF.Grammar.PrGrammar -import GF.Infra.Modules -import GF.Grammar.Macros -import GF.Grammar.Lookup -import GF.Grammar.Refresh -import GF.Grammar.PatternMatch -import GF.Grammar.Lockfield (isLockLabel) ---- - -import GF.Grammar.AppPredefined - -import Data.List (nub,intersperse) -import Control.Monad (liftM2, liftM) - --- | computation of concrete syntax terms into normal form --- used mainly for partial evaluation -computeConcrete :: SourceGrammar -> Term -> Err Term -computeConcrete g t = {- refreshTerm t >>= -} computeTerm g [] t -computeConcreteRec g t = {- refreshTerm t >>= -} computeTermOpt True g [] t - -computeTerm :: SourceGrammar -> Substitution -> Term -> Err Term -computeTerm = computeTermOpt False - --- rec=True is used if it cannot be assumed that looked-up constants --- have already been computed (mainly with -optimize=noexpand in .gfr) - -computeTermOpt :: Bool -> SourceGrammar -> Substitution -> Term -> Err Term -computeTermOpt rec gr = comput True where - - comput full g t = ---- errIn ("subterm" +++ prt t) $ --- for debugging - case t of - - Q (IC "Predef") _ -> return t - Q p c -> look p c - - -- if computed do nothing - Computed t' -> return $ unComputed t' - - Vr x -> do - t' <- maybe (prtBad ("no value given to variable") x) return $ lookup x g - case t' of - _ | t == t' -> return t - _ -> comp g t' - - -- Abs x@(IA _) b -> do - Abs x b | full -> do - let (xs,b1) = termFormCnc t - b' <- comp ([(x,Vr x) | x <- xs] ++ g) b1 - return $ mkAbs xs b' - -- b' <- comp (ext x (Vr x) g) b - -- return $ Abs x b' - Abs _ _ -> return t -- hnf - - Let (x,(_,a)) b -> do - a' <- comp g a - comp (ext x a' g) b - - Prod x a b -> do - a' <- comp g a - b' <- comp (ext x (Vr x) g) b - return $ Prod x a' b' - - -- beta-convert - App f a -> case appForm t of - (h,as) | length as > 1 -> do - h' <- hnf g h - as' <- mapM (comp g) as - case h' of - _ | not (null [() | FV _ <- as']) -> compApp g (mkApp h' as') - c@(QC _ _) -> do - return $ mkApp c as' - Q (IC "Predef") f -> do - (t',b) <- appPredefined (mkApp h' as') - if b then return t' else comp g t' - - Abs _ _ -> do - let (xs,b) = termFormCnc h' - let g' = (zip xs as') ++ g - let as2 = drop (length xs) as' - let xs2 = drop (length as') xs - b' <- comp g' (mkAbs xs2 b) - if null as2 then return b' else comp g (mkApp b' as2) - - _ -> compApp g (mkApp h' as') - _ -> compApp g t - - P t l | isLockLabel l -> return $ R [] - ---- a workaround 18/2/2005: take this away and find the reason - ---- why earlier compilation destroys the lock field - - - P t l -> do - t' <- comp g t - case t' of - FV rs -> mapM (\c -> comp g (P c l)) rs >>= returnC . variants - R r -> maybe (prtBad "no value for label" l) (comp g . snd) $ - lookup l $ reverse r - - ExtR a (R b) -> - case comp g (P (R b) l) of - Ok v -> return v - _ -> comp g (P a l) - ---- { - --- this is incorrect, since b can contain the proper value - ExtR (R a) b -> -- NOT POSSIBLE both a and b records! - case comp g (P (R a) l) of - Ok v -> return v - _ -> comp g (P b l) ---- - } --- - - Alias _ _ r -> comp g (P r l) - - S (T i cs) e -> prawitz g i (flip P l) cs e - S (V i cs) e -> prawitzV g i (flip P l) cs e - - _ -> returnC $ P t' l - - PI t l i -> comp g $ P t l ----- - - S t@(T ti cc) v -> do - v' <- comp g v - case v' of - FV vs -> do - ts' <- mapM (comp g . S t) vs - return $ variants ts' - _ -> case ti of -{- - TComp _ -> do - case term2patt v' of - Ok p' -> case lookup p' cc of - Just u -> comp g u - _ -> do - t' <- comp g t - return $ S t' v' -- if v' is not canonical - _ -> do - t' <- comp g t - return $ S t' v' --} - _ -> case matchPattern cc v' of - Ok (c,g') -> comp (g' ++ g) c - _ | isCan v' -> prtBad ("missing case" +++ prt v' +++ "in") t - _ -> do - t' <- comp g t - return $ S t' v' -- if v' is not canonical - - - S t v -> do - - t' <- case t of --- T _ _ -> return t --- V _ _ -> return t - _ -> comp g t - - v' <- comp g v - - case v' of - FV vs -> mapM (\c -> comp g (S t' c)) vs >>= returnC . variants - _ -> case t' of - FV ccs -> mapM (\c -> comp g (S c v')) ccs >>= returnC . variants - - T _ [(PV IW,c)] -> comp g c --- an optimization - T _ [(PT _ (PV IW),c)] -> comp g c - - T _ [(PV z,c)] -> comp (ext z v' g) c --- another optimization - T _ [(PT _ (PV z),c)] -> comp (ext z v' g) c - - -- course-of-values table: look up by index, no pattern matching needed - V ptyp ts -> do - vs <- allParamValues gr ptyp - case lookup v' (zip vs [0 .. length vs - 1]) of - Just i -> comp g $ ts !! i ------ _ -> prtBad "selection" $ S t' v' -- debug - _ -> return $ S t' v' -- if v' is not canonical - - T (TComp _) cs -> do - case term2patt v' of - Ok p' -> case lookup p' cs of - Just u -> comp g u - _ -> return $ S t' v' -- if v' is not canonical - _ -> return $ S t' v' - - T _ cc -> case matchPattern cc v' of - Ok (c,g') -> comp (g' ++ g) c - _ | isCan v' -> prtBad ("missing case" +++ prt v' +++ "in") t - _ -> return $ S t' v' -- if v' is not canonical - - Alias _ _ d -> comp g (S d v') - - S (T i cs) e -> prawitz g i (flip S v') cs e - S (V i cs) e -> prawitzV g i (flip S v') cs e - _ -> returnC $ S t' v' - - -- normalize away empty tokens - K "" -> return Empty - - -- glue if you can - Glue x0 y0 -> do - x <- comp g x0 - y <- comp g y0 - case (x,y) of - (FV ks,_) -> do - kys <- mapM (comp g . flip Glue y) ks - return $ variants kys - (_,FV ks) -> do - xks <- mapM (comp g . Glue x) ks - return $ variants xks - - (Alias _ _ d, y) -> comp g $ Glue d y - (x, Alias _ _ d) -> comp g $ Glue x d - - (S (T i cs) e, s) -> prawitz g i (flip Glue s) cs e - (s, S (T i cs) e) -> prawitz g i (Glue s) cs e - (S (V i cs) e, s) -> prawitzV g i (flip Glue s) cs e - (s, S (V i cs) e) -> prawitzV g i (Glue s) cs e - (_,Empty) -> return x - (Empty,_) -> return y - (K a, K b) -> return $ K (a ++ b) - (_, Alts (d,vs)) -> do ----- (K a, Alts (d,vs)) -> do - let glx = Glue x - comp g $ Alts (glx d, [(glx v,c) | (v,c) <- vs]) - (Alts _, ka) -> checks [do - y' <- strsFromTerm ka ----- (Alts _, K a) -> checks [do - x' <- strsFromTerm x -- this may fail when compiling opers - return $ variants [ - foldr1 C (map K (str2strings (glueStr v u))) | v <- x', u <- y'] ----- foldr1 C (map K (str2strings (glueStr v (str a)))) | v <- x'] - ,return $ Glue x y - ] - (C u v,_) -> comp g $ C u (Glue v y) - - _ -> do - mapM_ checkNoArgVars [x,y] - r <- composOp (comp g) t - returnC r - - Alts _ -> do - r <- composOp (comp g) t - returnC r - - -- remove empty - C a b -> do - a' <- comp g a - b' <- comp g b - case (a',b') of - (Alts _, K a) -> checks [do - as <- strsFromTerm a' -- this may fail when compiling opers - return $ variants [ - foldr1 C (map K (str2strings (plusStr v (str a)))) | v <- as] - , - return $ C a' b' - ] - (Empty,_) -> returnC b' - (_,Empty) -> returnC a' - _ -> returnC $ C a' b' - - -- reduce free variation as much as you can - FV ts -> mapM (comp g) ts >>= returnC . variants - - -- merge record extensions if you can - ExtR r s -> do - r' <- comp g r - s' <- comp g s - case (r',s') of - (Alias _ _ d, _) -> comp g $ ExtR d s' - (_, Alias _ _ d) -> comp g $ Glue r' d - - (R rs, R ss) -> plusRecord r' s' - (RecType rs, RecType ss) -> plusRecType r' s' - _ -> return $ ExtR r' s' - - -- case-expand tables - -- if already expanded, don't expand again - T i@(TComp ty) cs -> do - -- if there are no variables, don't even go inside - cs' <- if (null g) then return cs else mapPairsM (comp g) cs ----- return $ V ty (map snd cs') - return $ T i cs' - --- this means some extra work; should implement TSh directly - TSh i cs -> comp g $ T i [(p,v) | (ps,v) <- cs, p <- ps] - - T i cs -> do - pty0 <- getTableType i - ptyp <- comp g pty0 - case allParamValues gr ptyp of - Ok vs -> do - - cs' <- mapM (compBranchOpt g) cs - sts <- mapM (matchPattern cs') vs - ts <- mapM (\ (c,g') -> comp (g' ++ g) c) sts - ps <- mapM term2patt vs - let ps' = ps --- PT ptyp (head ps) : tail ps ----- return $ V ptyp ts -- to save space, just course of values - return $ T (TComp ptyp) (zip ps' ts) - _ -> do - cs' <- mapM (compBranch g) cs - return $ T i cs' -- happens with variable types - - Alias c a d -> do - d' <- comp g d - return $ Alias c a d' -- alias only disappears in certain redexes - - -- otherwise go ahead - _ -> composOp (comp g) t >>= returnC - - where - - compApp g (App f a) = do - f' <- hnf g f - a' <- comp g a - case (f',a') of - (Abs x b, FV as) -> - mapM (\c -> comp (ext x c g) b) as >>= return . variants - (_, FV as) -> mapM (\c -> comp g (App f' c)) as >>= return . variants - (FV fs, _) -> mapM (\c -> comp g (App c a')) fs >>= return . variants - (Abs x b,_) -> comp (ext x a' g) b - - (QC _ _,_) -> returnC $ App f' a' - - (Alias _ _ d, _) -> comp g (App d a') - - (S (T i cs) e,_) -> prawitz g i (flip App a') cs e - (S (V i cs) e,_) -> prawitzV g i (flip App a') cs e - - _ -> do - (t',b) <- appPredefined (App f' a') - if b then return t' else comp g t' - - hnf = comput False - comp = comput True - - look p c - | rec = lookupResDef gr p c >>= comp [] - | otherwise = lookupResDef gr p c - -{- - look p c = case lookupResDefKind gr p c of - Ok (t,_) | noExpand p || rec -> comp [] t - Ok (t,_) -> return t - Bad s -> raise s - - noExpand p = errVal False $ do - mo <- lookupModMod gr p - return $ case getOptVal (iOpts (flags mo)) useOptimizer of - Just "noexpand" -> True - _ -> False --} - - ext x a g = (x,a):g - - returnC = return --- . computed - - variants ts = case nub ts of - [t] -> t - ts -> FV ts - - isCan v = case v of - Con _ -> True - QC _ _ -> True - App f a -> isCan f && isCan a - R rs -> all (isCan . snd . snd) rs - _ -> False - - compBranch g (p,v) = do - let g' = contP p ++ g - v' <- comp g' v - return (p,v') - - compBranchOpt g c@(p,v) = case contP p of - [] -> return c - _ -> err (const (return c)) return $ compBranch g c - - contP p = case p of - PV x -> [(x,Vr x)] - PC _ ps -> concatMap contP ps - PP _ _ ps -> concatMap contP ps - PT _ p -> contP p - PR rs -> concatMap (contP . snd) rs - - PAs x p -> (x,Vr x) : contP p - - PSeq p q -> concatMap contP [p,q] - PAlt p q -> concatMap contP [p,q] - PRep p -> contP p - PNeg p -> contP p - - _ -> [] - - prawitz g i f cs e = do - cs' <- mapM (compBranch g) [(p, f v) | (p,v) <- cs] - return $ S (T i cs') e - prawitzV g i f cs e = do - cs' <- mapM (comp g) [(f v) | v <- cs] - return $ S (V i cs') e - --- | argument variables cannot be glued -checkNoArgVars :: Term -> Err Term -checkNoArgVars t = case t of - Vr (IA _) -> Bad $ glueErrorMsg $ prt t - Vr (IAV _) -> Bad $ glueErrorMsg $ prt t - _ -> composOp checkNoArgVars t - -glueErrorMsg s = - "Cannot glue (+) term with run-time variable" +++ s ++ "." ++++ - "Use Prelude.bind instead." diff --git a/src-3.0/GF/Grammar/LookAbs.hs b/src-3.0/GF/Grammar/LookAbs.hs index 665c6b0b7..f9a251eb1 100644 --- a/src-3.0/GF/Grammar/LookAbs.hs +++ b/src-3.0/GF/Grammar/LookAbs.hs @@ -12,28 +12,12 @@ -- (Description of the module) ----------------------------------------------------------------------------- -module GF.Grammar.LookAbs (GFCGrammar, - lookupAbsDef, +module GF.Grammar.LookAbs ( lookupFunType, - lookupCatContext, - lookupTransfer, - isPrimitiveFun, - lookupRef, - refsForType, - funRulesOf, - hasHOAS, - allCatsOf, - allBindCatsOf, - funsForType, - funsOnType, - funsOnTypeFs, - allDefs, - lookupFunTypeSrc, - lookupCatContextSrc + lookupCatContext ) where import GF.Data.Operations -import qualified GF.Canon.GFC as C import GF.Grammar.Abstract import GF.Infra.Ident @@ -42,155 +26,28 @@ import GF.Infra.Modules import Data.List (nub) import Control.Monad -type GFCGrammar = C.CanonGrammar - -lookupAbsDef :: GFCGrammar -> Ident -> Ident -> Err (Maybe Term) -lookupAbsDef gr m c = errIn ("looking up absdef of" +++ prt c) $ do - mi <- lookupModule gr m - case mi of - ModMod mo -> do - info <- lookupIdentInfo mo c - case info of - C.AbsFun _ t -> return $ return t - C.AnyInd _ n -> lookupAbsDef gr n c - _ -> return Nothing - _ -> Bad $ prt m +++ "is not an abstract module" - -lookupFunType :: GFCGrammar -> Ident -> Ident -> Err Type -lookupFunType gr m c = errIn ("looking up funtype of" +++ prt c +++ "in module" +++ prt m) $ do - mi <- lookupModule gr m - case mi of - ModMod mo -> do - info <- lookupIdentInfo mo c - case info of - C.AbsFun t _ -> return t - C.AnyInd _ n -> lookupFunType gr n c - _ -> prtBad "cannot find type of" c - _ -> Bad $ prt m +++ "is not an abstract module" - -lookupCatContext :: GFCGrammar -> Ident -> Ident -> Err Context -lookupCatContext gr m c = errIn ("looking up context of cat" +++ prt c) $ do - mi <- lookupModule gr m - case mi of - ModMod mo -> do - info <- lookupIdentInfo mo c - case info of - C.AbsCat co _ -> return co - C.AnyInd _ n -> lookupCatContext gr n c - _ -> prtBad "unknown category" c - _ -> Bad $ prt m +++ "is not an abstract module" - --- | lookup for transfer function: transfer-module-name, category name -lookupTransfer :: GFCGrammar -> Ident -> Ident -> Err Term -lookupTransfer gr m c = errIn ("looking up transfer of cat" +++ prt c) $ do - mi <- lookupModule gr m - case mi of - ModMod mo -> do - info <- lookupIdentInfo mo c - case info of - C.AbsTrans t -> return t - C.AnyInd _ n -> lookupTransfer gr n c - _ -> prtBad "cannot transfer function for" c - _ -> Bad $ prt m +++ "is not a transfer module" - - --- | should be revised (20\/9\/2003) -isPrimitiveFun :: GFCGrammar -> Fun -> Bool -isPrimitiveFun gr (m,c) = case lookupAbsDef gr m c of - Ok (Just (Eqs [])) -> True -- is canonical - Ok (Just _) -> False -- has defining clauses - _ -> True -- has no definition - - --- | looking up refinement terms -lookupRef :: GFCGrammar -> Binds -> Term -> Err Val -lookupRef gr binds at = case at of - Q m f -> lookupFunType gr m f >>= return . vClos - Vr i -> maybeErr ("unknown variable" +++ prt at) $ lookup i binds - EInt _ -> return valAbsInt - EFloat _ -> return valAbsFloat - K _ -> return valAbsString - _ -> prtBad "cannot refine with complex term" at --- - -refsForType :: (Val -> Type -> Bool) -> GFCGrammar -> Binds -> Val -> [(Term,(Val,Bool))] -refsForType compat gr binds val = - -- bound variables --- never recursive? - [(Vr i, (t,False)) | (i,t) <- binds, Ok ty <- [val2exp t], compat val ty] ++ - -- integer and string literals - [(EInt i, (val,False)) | val == valAbsInt, i <- [0,1,2,5,11,1978]] ++ - [(EFloat i, (val,False)) | val == valAbsFloat, i <- [3.1415926]] ++ - [(K s, (val,False)) | val == valAbsString, s <- ["foo", "NN", "x"]] ++ - -- functions defined in the current abstract syntax - [(qq f, (vClos t,isRecursiveType t)) | (f,t) <- funsForType compat gr val] - - -funRulesOf :: GFCGrammar -> [(Fun,Type)] -funRulesOf gr = ----- funRulesForLiterals ++ - [((i,f),typ) | (i, ModMod m) <- modules gr, - mtype m == MTAbstract, - (f, C.AbsFun typ _) <- tree2list (jments m)] - --- testing for higher-order abstract syntax -hasHOAS :: GFCGrammar -> Bool -hasHOAS gr = any isHigherOrderType [t | (_,t) <- funRulesOf gr] where - -allCatsOf :: GFCGrammar -> [(Cat,Context)] -allCatsOf gr = - [((i,c),cont) | (i, ModMod m) <- modules gr, - isModAbs m, - (c, C.AbsCat cont _) <- tree2list (jments m)] - -allBindCatsOf :: GFCGrammar -> [Cat] -allBindCatsOf gr = - nub [c | (i, ModMod m) <- modules gr, - isModAbs m, - (c, C.AbsFun typ _) <- tree2list (jments m), - Ok (cont,_) <- [firstTypeForm typ], - c <- concatMap fst $ errVal [] $ mapM (catSkeleton . snd) cont - ] - -funsForType :: (Val -> Type -> Bool) -> GFCGrammar -> Val -> [(Fun,Type)] -funsForType compat gr val = [(fun,typ) | (fun,typ) <- funRulesOf gr, - compat val typ] - -funsOnType :: (Val -> Type -> Bool) -> GFCGrammar -> Val -> [((Fun,Int),Type)] -funsOnType compat gr = funsOnTypeFs compat (funRulesOf gr) - -funsOnTypeFs :: (Val -> Type -> Bool) -> [(Fun,Type)] -> Val -> [((Fun,Int),Type)] -funsOnTypeFs compat fs val = [((fun,i),typ) | - (fun,typ) <- fs, - Ok (args,_,_) <- [typeForm typ], - (i,arg) <- zip [0..] (map snd args), - compat val arg] - -allDefs :: GFCGrammar -> [(Fun,Term)] -allDefs gr = [((i,c),d) | (i, ModMod m) <- modules gr, - isModAbs m, - (c, C.AbsFun _ d) <- tree2list (jments m)] - -- | this is needed at compile time -lookupFunTypeSrc :: Grammar -> Ident -> Ident -> Err Type -lookupFunTypeSrc gr m c = do +lookupFunType :: Grammar -> Ident -> Ident -> Err Type +lookupFunType gr m c = do mi <- lookupModule gr m case mi of ModMod mo -> do info <- lookupIdentInfo mo c case info of AbsFun (Yes t) _ -> return t - AnyInd _ n -> lookupFunTypeSrc gr n c + AnyInd _ n -> lookupFunType gr n c _ -> prtBad "cannot find type of" c _ -> Bad $ prt m +++ "is not an abstract module" -- | this is needed at compile time -lookupCatContextSrc :: Grammar -> Ident -> Ident -> Err Context -lookupCatContextSrc gr m c = do +lookupCatContext :: Grammar -> Ident -> Ident -> Err Context +lookupCatContext gr m c = do mi <- lookupModule gr m case mi of ModMod mo -> do info <- lookupIdentInfo mo c case info of AbsCat (Yes co) _ -> return co - AnyInd _ n -> lookupCatContextSrc gr n c + AnyInd _ n -> lookupCatContext gr n c _ -> prtBad "unknown category" c _ -> Bad $ prt m +++ "is not an abstract module" diff --git a/src-3.0/GF/Grammar/PrGrammar.hs b/src-3.0/GF/Grammar/PrGrammar.hs index c3a21d1d6..186792eda 100644 --- a/src-3.0/GF/Grammar/PrGrammar.hs +++ b/src-3.0/GF/Grammar/PrGrammar.hs @@ -29,7 +29,7 @@ module GF.Grammar.PrGrammar (Print(..), tree2string, prprTree, prConstrs, prConstraints, prMetaSubst, prEnv, prMSubst, - prExp, prPatt, prOperSignature, + prExp, prOperSignature, lookupIdent, lookupIdentInfo ) where @@ -38,8 +38,6 @@ import GF.Data.Zipper import GF.Grammar.Grammar import GF.Infra.Modules import qualified GF.Source.PrintGF as P -import qualified GF.Canon.PrintGFC as C -import qualified GF.Canon.AbsGFC as A import GF.Grammar.Values import GF.Source.GrammarToSource --- import GFC (CanonGrammar) --- cycle of modules @@ -106,32 +104,6 @@ prContext co = unwords $ map prParenth [prt x +++ ":" +++ prt t | (x,t) <- co] -- some GFC notions -instance Print A.Exp where prt = C.printTree -instance Print A.Term where prt = C.printTree -instance Print A.Case where prt = C.printTree -instance Print A.CType where prt = C.printTree -instance Print A.Label where prt = C.printTree -instance Print A.Module where prt = C.printTree -instance Print A.Def where prt = C.printTree -instance Print A.Canon where prt = C.printTree -instance Print A.Sort where prt = C.printTree - -instance Print A.Atom where - prt = C.printTree - prt_ (A.AC c) = prt_ c - prt_ (A.AD c) = prt_ c - prt_ a = prt a - -instance Print A.Patt where - prt = C.printTree - prt_ = prPatt - -instance Print A.CIdent where - prt = C.printTree - prt_ (A.CIQ _ c) = prt c - --- printing values and trees in editing - instance Print a => Print (Tr a) where prt (Tr (n, trees)) = prt n +++ unwords (map prt2 trees) prt2 t@(Tr (_,args)) = if null args then prt t else prParenth (prt t) @@ -252,15 +224,6 @@ prExp e = case e of App _ _ -> prParenth $ prExp e _ -> pr1 e -prPatt :: A.Patt -> String -prPatt p = case p of - A.PC c ps -> prt_ c +++ unwords (map pr1 ps) - _ -> prt p --- PR - where - pr1 p = case p of - A.PC _ (_:_) -> prParenth $ prPatt p - _ -> prPatt p - -- | option @-strip@ strips qualifications prTermOpt :: Options -> Term -> String prTermOpt opts = if oElem nostripQualif opts then prt else prExp diff --git a/src-3.0/GF/Grammar/SGrammar.hs b/src-3.0/GF/Grammar/SGrammar.hs deleted file mode 100644 index e0c001b6b..000000000 --- a/src-3.0/GF/Grammar/SGrammar.hs +++ /dev/null @@ -1,169 +0,0 @@ ----------------------------------------------------------------------- --- | --- Module : SGrammar --- Maintainer : AR --- Stability : (stable) --- Portability : (portable) --- --- --- A simple format for context-free abstract syntax used e.g. in --- generation. AR 31\/3\/2006 --- --- (c) Aarne Ranta 2004 under GNU GPL --- --- Purpose: to generate corpora. We use simple types and don't --- guarantee the correctness of bindings\/dependences. ------------------------------------------------------------------------------ - -module GF.Grammar.SGrammar where - -import GF.Canon.GFC -import GF.Grammar.LookAbs -import GF.Grammar.PrGrammar -import GF.Grammar.Macros -import GF.Grammar.Values -import GF.Grammar.Grammar -import GF.Infra.Ident (Ident) - -import GF.Data.Operations -import GF.Data.Zipper -import GF.Infra.Option - -import Data.List - --- (c) Aarne Ranta 2006 under GNU GPL - - -type SGrammar = BinTree SCat [SRule] -type SIdent = String -type SRule = (SFun,SType) -type SType = ([SCat],SCat) -type SCat = SIdent -type SFun = (Double,SIdent) - -allRules gr = concat [rs | (c,rs) <- tree2list gr] - -data STree = - SApp (SFun,[STree]) - | SMeta SCat - | SString String - | SInt Integer - | SFloat Double - deriving (Show,Eq) - -depth :: STree -> Int -depth t = case t of - SApp (_,ts@(_:_)) -> maximum (map depth ts) + 1 - _ -> 1 - -type Probs = BinTree Ident Double - -emptyProbs :: Probs -emptyProbs = emptyBinTree - -prProbs :: Probs -> String -prProbs = unlines . map pr . tree2list where - pr (f,p) = prt f ++ "\t" ++ show p - ------------------------------------------- --- translate grammar to simpler form and generated trees back - -gr2sgr :: Options -> Probs -> GFCGrammar -> SGrammar -gr2sgr opts probs gr = buildTree [(c,norm (noexp c rs)) | rs@((_,(_,c)):_) <- rules] where - noe = maybe [] (chunks ',') $ getOptVal opts (aOpt "noexpand") - only = maybe [] (chunks ',') $ getOptVal opts (aOpt "doexpand") - un = getOptInt opts (aOpt "atoms") - rules = - prune $ - groupBy (\x y -> scat x == scat y) $ - sortBy (\x y -> compare (scat x) (scat y)) $ - [(trId f, ty') | (f,ty) <- funRulesOf gr, ty' <- trTy ty] - trId (_,f) = let f' = prt f in case lookupTree prt f probs of - Ok p -> (p,f') - _ -> (2.0, f') - trTy ty = case catSkeleton ty of - Ok (mcs,mc) -> [(map trCat mcs, trCat mc)] - _ -> [] - trCat (m,c) = prt c --- - scat (_,(_,c)) = c - - prune rs = maybe rs (\n -> map (onlyAtoms n) rs) $ un - - norm = fillProb - - onlyAtoms n rs = - let (rs1,rs2) = partition atom rs - in take n rs1 ++ rs2 - atom = null . fst . snd - - noexp c rs - | null only = if elem c noe then [((2.0,'?':c),([],c))] else rs - | otherwise = if elem c only then rs else [((2.0,'?':c),([],c))] - --- for cases where explicit probability is not given (encoded as --- p > 1) divide the remaining mass by the number of such cases - -fillProb :: [SRule] -> [SRule] -fillProb rs = [((defa p,f),ty) | ((p,f),ty) <- rs] where - defa p = if p > 1.0 then def else p - def = (1 - sum given) / genericLength nope - (nope,given) = partition (> 1.0) [p | ((p,_),_) <- rs] - --- str2tr :: STree -> Exp -str2tr t = case t of - SApp ((_,'?':c),[]) -> mkMeta 0 -- from noexpand=c - SApp ((_,f),ts) -> mkApp (trId f) (map str2tr ts) - SMeta _ -> mkMeta 0 - SString s -> K s - SInt i -> EInt i - SFloat i -> EFloat i - where - trId = cn . zIdent - --- tr2str :: Tree -> STree -tr2str (Tr (N (_,at,val,_,_),ts)) = case (at,val) of - (AtC (_,f), _) -> SApp ((2.0,prt_ f),map tr2str ts) - (AtM _, v) -> SMeta (catOf v) - (AtL s, _) -> SString s - (AtI i, _) -> SInt i - (AtF i, _) -> SFloat i - _ -> SMeta "FAILED_TO_GENERATE" ---- err monad! - where - catOf v = case v of - VApp w _ -> catOf w - VCn (_,c) -> prt_ c - _ -> "FAILED_TO_GENERATE_FROM_META" - - ------------------------------------------- --- to test - -prSTree t = case t of - SApp ((_,f),ts) -> f ++ concat (map pr1 ts) - SMeta c -> '?':c - SString s -> prQuotedString s - SInt i -> show i - SFloat i -> show i - where - pr1 t@(SApp (_,ts)) = ' ' : (if null ts then id else prParenth) (prSTree t) - pr1 t = prSTree t - -pSRule :: String -> SRule -pSRule s = case words s of - f : _ : cs -> ((2.0,f),(init cs', last cs')) - where cs' = [cs !! i | i <- [0,2..length cs - 1]] - _ -> error $ "not a rule" +++ s - -exSgr = map pSRule [ - "Pred : NP -> VP -> S" - ,"Compl : TV -> NP -> VP" - ,"PredVV : VV -> VP -> VP" - ,"DefCN : CN -> NP" - ,"ModCN : AP -> CN -> CN" - ,"john : NP" - ,"walk : VP" - ,"love : TV" - ,"try : VV" - ,"girl : CN" - ,"big : AP" - ] diff --git a/src-3.0/GF/Grammar/TC.hs b/src-3.0/GF/Grammar/TC.hs deleted file mode 100644 index be52d1889..000000000 --- a/src-3.0/GF/Grammar/TC.hs +++ /dev/null @@ -1,299 +0,0 @@ ----------------------------------------------------------------------- --- | --- Module : TC --- Maintainer : AR --- Stability : (stable) --- Portability : (portable) --- --- > CVS $Date: 2005/10/02 20:50:19 $ --- > CVS $Author: aarne $ --- > CVS $Revision: 1.11 $ --- --- Thierry Coquand's type checking algorithm that creates a trace ------------------------------------------------------------------------------ - -module GF.Grammar.TC (AExp(..), - Theory, - checkExp, - inferExp, - checkEqs, - eqVal, - whnf - ) where - -import GF.Data.Operations -import GF.Grammar.Abstract -import GF.Grammar.AbsCompute - -import Control.Monad -import Data.List (sortBy) - -data AExp = - AVr Ident Val - | ACn QIdent Val - | AType - | AInt Integer - | AFloat Double - | AStr String - | AMeta MetaSymb Val - | AApp AExp AExp Val - | AAbs Ident Val AExp - | AProd Ident AExp AExp - | AEqs [([Exp],AExp)] --- not used - | AData Val - deriving (Eq,Show) - -type Theory = QIdent -> Err Val - -lookupConst :: Theory -> QIdent -> Err Val -lookupConst th f = th f - -lookupVar :: Env -> Ident -> Err Val -lookupVar g x = maybe (prtBad "unknown variable" x) return $ lookup x ((IW,uVal):g) --- wild card IW: no error produced, ?0 instead. - -type TCEnv = (Int,Env,Env) - -emptyTCEnv :: TCEnv -emptyTCEnv = (0,[],[]) - -whnf :: Val -> Err Val -whnf v = ---- errIn ("whnf" +++ prt v) $ ---- debug - case v of - VApp u w -> do - u' <- whnf u - w' <- whnf w - app u' w' - VClos env e -> eval env e - _ -> return v - -app :: Val -> Val -> Err Val -app u v = case u of - VClos env (Abs x e) -> eval ((x,v):env) e - _ -> return $ VApp u v - -eval :: Env -> Exp -> Err Val -eval env e = ---- errIn ("eval" +++ prt e +++ "in" +++ prEnv env) $ - case e of - Vr x -> lookupVar env x - Q m c -> return $ VCn (m,c) - QC m c -> return $ VCn (m,c) ---- == Q ? - Sort c -> return $ VType --- the only sort is Type - App f a -> join $ liftM2 app (eval env f) (eval env a) - _ -> return $ VClos env e - -eqVal :: Int -> Val -> Val -> Err [(Val,Val)] -eqVal k u1 u2 = ---- errIn (prt u1 +++ "<>" +++ prBracket (show k) +++ prt u2) $ - do - w1 <- whnf u1 - w2 <- whnf u2 - let v = VGen k - case (w1,w2) of - (VApp f1 a1, VApp f2 a2) -> liftM2 (++) (eqVal k f1 f2) (eqVal k a1 a2) - (VClos env1 (Abs x1 e1), VClos env2 (Abs x2 e2)) -> - eqVal (k+1) (VClos ((x1,v x1):env1) e1) (VClos ((x2,v x1):env2) e2) - (VClos env1 (Prod x1 a1 e1), VClos env2 (Prod x2 a2 e2)) -> - liftM2 (++) - (eqVal k (VClos env1 a1) (VClos env2 a2)) - (eqVal (k+1) (VClos ((x1,v x1):env1) e1) (VClos ((x2,v x1):env2) e2)) - (VGen i _, VGen j _) -> return [(w1,w2) | i /= j] - (VCn (_, i), VCn (_,j)) -> return [(w1,w2) | i /= j] - --- thus ignore qualifications; valid because inheritance cannot - --- be qualified. Simplifies annotation. AR 17/3/2005 - _ -> return [(w1,w2) | w1 /= w2] --- invariant: constraints are in whnf - -checkType :: Theory -> TCEnv -> Exp -> Err (AExp,[(Val,Val)]) -checkType th tenv e = checkExp th tenv e vType - -checkExp :: Theory -> TCEnv -> Exp -> Val -> Err (AExp, [(Val,Val)]) -checkExp th tenv@(k,rho,gamma) e ty = do - typ <- whnf ty - let v = VGen k - case e of - Meta m -> return $ (AMeta m typ,[]) - EData -> return $ (AData typ,[]) - - Abs x t -> case typ of - VClos env (Prod y a b) -> do - a' <- whnf $ VClos env a --- - (t',cs) <- checkExp th - (k+1,(x,v x):rho, (x,a'):gamma) t (VClos ((y,v x):env) b) - return (AAbs x a' t', cs) - _ -> prtBad ("function type expected for" +++ prt e +++ "instead of") typ - --- {- --- to get deprec when checkEqs works (15/9/2005) - Eqs es -> do - bcs <- mapM (\b -> checkBranch th tenv b typ) es - let (bs,css) = unzip bcs - return (AEqs bs, concat css) --- - } - Prod x a b -> do - testErr (typ == vType) "expected Type" - (a',csa) <- checkType th tenv a - (b',csb) <- checkType th (k+1, (x,v x):rho, (x,VClos rho a):gamma) b - return (AProd x a' b', csa ++ csb) - - _ -> checkInferExp th tenv e typ - -checkInferExp :: Theory -> TCEnv -> Exp -> Val -> Err (AExp, [(Val,Val)]) -checkInferExp th tenv@(k,_,_) e typ = do - (e',w,cs1) <- inferExp th tenv e - cs2 <- eqVal k w typ - return (e',cs1 ++ cs2) - -inferExp :: Theory -> TCEnv -> Exp -> Err (AExp, Val, [(Val,Val)]) -inferExp th tenv@(k,rho,gamma) e = case e of - Vr x -> mkAnnot (AVr x) $ noConstr $ lookupVar gamma x - Q m c - | m == cPredefAbs && (elem c (map identC ["Int","String","Float"])) -> - return (ACn (m,c) vType, vType, []) - | otherwise -> mkAnnot (ACn (m,c)) $ noConstr $ lookupConst th (m,c) - QC m c -> mkAnnot (ACn (m,c)) $ noConstr $ lookupConst th (m,c) ---- - EInt i -> return (AInt i, valAbsInt, []) - EFloat i -> return (AFloat i, valAbsFloat, []) - K i -> return (AStr i, valAbsString, []) - Sort _ -> return (AType, vType, []) - App f t -> do - (f',w,csf) <- inferExp th tenv f - typ <- whnf w - case typ of - VClos env (Prod x a b) -> do - (a',csa) <- checkExp th tenv t (VClos env a) - b' <- whnf $ VClos ((x,VClos rho t):env) b - return $ (AApp f' a' b', b', csf ++ csa) - _ -> prtBad ("Prod expected for function" +++ prt f +++ "instead of") typ - _ -> prtBad "cannot infer type of expression" e - where - predefAbs c s = case c of - IC "Int" -> return $ const $ Q cPredefAbs cInt - IC "Float" -> return $ const $ Q cPredefAbs cFloat - IC "String" -> return $ const $ Q cPredefAbs cString - _ -> Bad s - -checkEqs :: Theory -> TCEnv -> (Fun,Trm) -> Val -> Err [(Val,Val)] -checkEqs th tenv@(k,rho,gamma) (fun@(m,f),def) val = case def of - Eqs es -> liftM concat $ mapM checkBranch es - _ -> liftM snd $ checkExp th tenv def val - where - checkBranch (ps,df) = - let - (ps',_,vars) = foldr p2t ([],0,[]) ps - fps = mkApp (Q m f) ps' - in errIn ("branch" +++ prt fps) $ do - (aexp, typ, cs1) <- inferExp th tenv fps - let - bds = binds vars aexp - tenv' = (k, rho, bds ++ gamma) - (_,cs2) <- errIn (show bds) $ checkExp th tenv' df typ - return $ (cs1 ++ cs2) - p2t p (ps,i,g) = case p of - PW -> (meta (MetaSymb i) : ps, i+1, g) - PV IW -> (meta (MetaSymb i) : ps, i+1, g) - PV x -> (meta (MetaSymb i) : ps, i+1,upd x i g) - PString s -> ( K s : ps, i, g) - PInt n -> (EInt n : ps, i, g) - PFloat n -> (EFloat n : ps, i, g) - PP m c xs -> (mkApp (qq (m,c)) xss : ps, i', g') - where (xss,i',g') = foldr p2t ([],i,g) xs - _ -> error $ "undefined p2t case" +++ prt p +++ "in checkBranch" - upd x i g = (x,i) : g --- to annotate pattern variables: treat as metas - - -- notice: in vars, the sequence 0.. is sorted. In subst aexp, all - -- this occurs and nothing else. - binds vars aexp = [(x,v) | ((x,_),v) <- zip vars metas] where - metas = map snd $ sortBy (\ (x,_) (y,_) -> compare x y) $ subst aexp - subst aexp = case aexp of - AMeta (MetaSymb i) v -> [(i,v)] - AApp c a _ -> subst c ++ subst a - _ -> [] -- never matter in patterns - -checkBranch :: Theory -> TCEnv -> Equation -> Val -> Err (([Exp],AExp),[(Val,Val)]) -checkBranch th tenv b@(ps,t) ty = errIn ("branch" +++ show b) $ - chB tenv' ps' ty - where - - (ps',_,rho2,k') = ps2ts k ps - tenv' = (k, rho2++rho, gamma) ---- k' ? - (k,rho,gamma) = tenv - - chB tenv@(k,rho,gamma) ps ty = case ps of - p:ps2 -> do - typ <- whnf ty - case typ of - VClos env (Prod y a b) -> do - a' <- whnf $ VClos env a - (p', sigma, binds, cs1) <- checkP tenv p y a' - let tenv' = (length binds, sigma ++ rho, binds ++ gamma) - ((ps',exp),cs2) <- chB tenv' ps2 (VClos ((y,p'):env) b) - return ((p:ps',exp), cs1 ++ cs2) -- don't change the patt - _ -> prtBad ("Product expected for definiens" +++prt t +++ "instead of") typ - [] -> do - (e,cs) <- checkExp th tenv t ty - return (([],e),cs) - checkP env@(k,rho,gamma) t x a = do - (delta,cs) <- checkPatt th env t a - let sigma = [(x, VGen i x) | ((x,_),i) <- zip delta [k..]] - return (VClos sigma t, sigma, delta, cs) - - ps2ts k = foldr p2t ([],0,[],k) - p2t p (ps,i,g,k) = case p of - PW -> (meta (MetaSymb i) : ps, i+1,g,k) - PV IW -> (meta (MetaSymb i) : ps, i+1,g,k) - PV x -> (vr x : ps, i, upd x k g,k+1) - PString s -> (K s : ps, i, g, k) - PInt n -> (EInt n : ps, i, g, k) - PFloat n -> (EFloat n : ps, i, g, k) - PP m c xs -> (mkApp (qq (m,c)) xss : ps, j, g',k') - where (xss,j,g',k') = foldr p2t ([],i,g,k) xs - _ -> error $ "undefined p2t case" +++ prt p +++ "in checkBranch" - - upd x k g = (x, VGen k x) : g --- hack to recognize pattern variables - - -checkPatt :: Theory -> TCEnv -> Exp -> Val -> Err (Binds,[(Val,Val)]) -checkPatt th tenv exp val = do - (aexp,_,cs) <- checkExpP tenv exp val - let binds = extrBinds aexp - return (binds,cs) - where - extrBinds aexp = case aexp of - AVr i v -> [(i,v)] - AApp f a _ -> extrBinds f ++ extrBinds a - _ -> [] -- no other cases are possible - ---- ad hoc, to find types of variables - checkExpP tenv@(k,rho,gamma) exp val = case exp of - Meta m -> return $ (AMeta m val, val, []) - Vr x -> return $ (AVr x val, val, []) - EInt i -> return (AInt i, valAbsInt, []) - EFloat i -> return (AFloat i, valAbsFloat, []) - K s -> return (AStr s, valAbsString, []) - - Q m c -> do - typ <- lookupConst th (m,c) - return $ (ACn (m,c) typ, typ, []) - QC m c -> do - typ <- lookupConst th (m,c) - return $ (ACn (m,c) typ, typ, []) ---- - App f t -> do - (f',w,csf) <- checkExpP tenv f val - typ <- whnf w - case typ of - VClos env (Prod x a b) -> do - (a',_,csa) <- checkExpP tenv t (VClos env a) - b' <- whnf $ VClos ((x,VClos rho t):env) b - return $ (AApp f' a' b', b', csf ++ csa) - _ -> prtBad ("Prod expected for function" +++ prt f +++ "instead of") typ - _ -> prtBad "cannot typecheck pattern" exp - --- auxiliaries - -noConstr :: Err Val -> Err (Val,[(Val,Val)]) -noConstr er = er >>= (\v -> return (v,[])) - -mkAnnot :: (Val -> AExp) -> Err (Val,[(Val,Val)]) -> Err (AExp,Val,[(Val,Val)]) -mkAnnot a ti = do - (v,cs) <- ti - return (a v, v, cs) - diff --git a/src-3.0/GF/Grammar/TypeCheck.hs b/src-3.0/GF/Grammar/TypeCheck.hs deleted file mode 100644 index 97b7ff243..000000000 --- a/src-3.0/GF/Grammar/TypeCheck.hs +++ /dev/null @@ -1,311 +0,0 @@ ----------------------------------------------------------------------- --- | --- Module : TypeCheck --- Maintainer : AR --- Stability : (stable) --- Portability : (portable) --- --- > CVS $Date: 2005/09/15 16:22:02 $ --- > CVS $Author: aarne $ --- > CVS $Revision: 1.16 $ --- --- (Description of the module) ------------------------------------------------------------------------------ - -module GF.Grammar.TypeCheck (-- * top-level type checking functions; TC should not be called directly. - annotate, annotateIn, - justTypeCheck, checkIfValidExp, - reduceConstraints, - splitConstraints, - possibleConstraints, - reduceConstraintsNode, - performMetaSubstNode, - -- * some top-level batch-mode checkers for the compiler - justTypeCheckSrc, - grammar2theorySrc, - checkContext, - checkTyp, - checkEquation, - checkConstrs, - editAsTermCommand, - exp2termCommand, - exp2termlistCommand, - tree2termlistCommand - ) where - -import GF.Data.Operations -import GF.Data.Zipper - -import GF.Grammar.Abstract -import GF.Grammar.AbsCompute -import GF.Grammar.Refresh -import GF.Grammar.LookAbs -import qualified GF.Grammar.Lookup as Lookup --- - -import GF.Grammar.TC - -import GF.Grammar.Unify --- - -import Control.Monad (foldM, liftM, liftM2) -import Data.List (nub) --- - --- top-level type checking functions; TC should not be called directly. - -annotate :: GFCGrammar -> Exp -> Err Tree -annotate gr exp = annotateIn gr [] exp Nothing - --- | type check in empty context, return a list of constraints -justTypeCheck :: GFCGrammar -> Exp -> Val -> Err Constraints -justTypeCheck gr e v = do - (_,constrs0) <- checkExp (grammar2theory gr) (initTCEnv []) e v - constrs1 <- reduceConstraints (lookupAbsDef gr) 0 constrs0 - return $ fst $ splitConstraints gr constrs1 - --- | type check in empty context, return the expression itself if valid -checkIfValidExp :: GFCGrammar -> Exp -> Err Exp -checkIfValidExp gr e = do - (_,_,constrs0) <- inferExp (grammar2theory gr) (initTCEnv []) e - constrs1 <- reduceConstraints (lookupAbsDef gr) 0 constrs0 - ifNull (return e) (Bad . unwords . prConstrs) constrs1 - -annotateIn :: GFCGrammar -> Binds -> Exp -> Maybe Val -> Err Tree -annotateIn gr gamma exp = maybe (infer exp) (check exp) where - infer e = do - (a,_,cs) <- inferExp theory env e - aexp2treeC (a,cs) - check e v = do - (a,cs) <- checkExp theory env e v - aexp2treeC (a,cs) - env = initTCEnv gamma - theory = grammar2theory gr - aexp2treeC (a,c) = do - c' <- reduceConstraints (lookupAbsDef gr) (length gamma) c - aexp2tree (a,c') - --- | invariant way of creating TCEnv from context -initTCEnv gamma = - (length gamma,[(x,VGen i x) | ((x,_),i) <- zip gamma [0..]], gamma) - --- | process constraints after eqVal by computing by defs -reduceConstraints :: LookDef -> Int -> Constraints -> Err Constraints -reduceConstraints look i = liftM concat . mapM redOne where - redOne (u,v) = do - u' <- computeVal look u - v' <- computeVal look v - eqVal i u' v' - -computeVal :: LookDef -> Val -> Err Val -computeVal look v = case v of - VClos g@(_:_) e -> do - e' <- compt (map fst g) e --- bindings of g in e? - whnf $ VClos g e' -{- ---- - _ -> do ---- how to compute a Val, really?? - e <- val2exp v - e' <- compt [] e - whnf $ vClos e' --} - VApp f c -> liftM2 VApp (compv f) (compv c) >>= whnf - _ -> whnf v - where - compt = computeAbsTermIn look - compv = computeVal look - --- | take apart constraints that have the form (? <> t), usable as solutions -splitConstraints :: GFCGrammar -> Constraints -> (Constraints,MetaSubst) -splitConstraints gr = splitConstraintsGen (lookupAbsDef gr) - -splitConstraintsSrc :: Grammar -> Constraints -> (Constraints,MetaSubst) -splitConstraintsSrc gr = splitConstraintsGen (Lookup.lookupAbsDef gr) - -splitConstraintsGen :: LookDef -> Constraints -> (Constraints,MetaSubst) -splitConstraintsGen look cs = csmsu where - - csmsu = (nub [(a,b) | (a,b) <- csf1,a /= b],msf1) - (csf1,msf1) = unif (csf,msf) -- alternative: filter first - (csf,msf) = foldr mkOne ([],[]) cs - - csmsf = foldr mkOne ([],msu) csu - (csu,msu) = unif (cs1,[]) -- alternative: unify first - - cs1 = errVal cs $ reduceConstraints look 0 cs - - mkOne (u,v) = case (u,v) of - (VClos g (Meta m), v) | null g -> sub m v - (v, VClos g (Meta m)) | null g -> sub m v - -- do nothing if meta has nonempty closure; null g || isConstVal v WAS WRONG - c -> con c - con c (cs,ms) = (c:cs,ms) - sub m v (cs,ms) = (cs,(m,v):ms) - - unifo = id -- alternative: don't use unification - - unif cm@(cs,ms) = errVal cm $ do --- alternative: use unification - (cs',ms') <- unifyVal cs - return (cs', ms' ++ ms) - -performMetaSubstNode :: MetaSubst -> TrNode -> TrNode -performMetaSubstNode subst n@(N (b,a,v,(c,m),s)) = let - v' = metaSubstVal v - b' = [(x,metaSubstVal v) | (x,v) <- b] - c' = [(u',v') | (u,v) <- c, - let (u',v') = (metaSubstVal u, metaSubstVal v), u' /= v'] - in N (b',a,v',(c',m),s) - where - metaSubstVal u = errVal u $ whnf $ case u of - VApp f a -> VApp (metaSubstVal f) (metaSubstVal a) - VClos g e -> VClos [(x,metaSubstVal v) | (x,v) <- g] (metaSubstExp e) - _ -> u - metaSubstExp e = case e of - Meta m -> errVal e $ maybe (return e) val2expSafe $ lookup m subst - _ -> composSafeOp metaSubstExp e - -reduceConstraintsNode :: GFCGrammar -> TrNode -> TrNode -reduceConstraintsNode gr = changeConstrs red where - red cs = errVal cs $ reduceConstraints (lookupAbsDef gr) 0 cs - --- | weak heuristic to narrow down menus; not used for TC. 15\/11\/2001. --- the age-old method from GF 0.9 -possibleConstraints :: GFCGrammar -> Constraints -> Bool -possibleConstraints gr = and . map (possibleConstraint gr) - -possibleConstraint :: GFCGrammar -> (Val,Val) -> Bool -possibleConstraint gr (u,v) = errVal True $ do - u' <- val2exp u >>= compute gr - v' <- val2exp v >>= compute gr - return $ cts u' v' - where - cts t u = isUnknown t || isUnknown u || case (t,u) of - (Q m c, Q n d) -> c == d || notCan (m,c) || notCan (n,d) - (QC m c, QC n d) -> c == d - (App f a, App g b) -> cts f g && cts a b - (Abs x b, Abs y c) -> cts b c - (Prod x a f, Prod y b g) -> cts a b && cts f g - (_ , _) -> False - - isUnknown t = case t of - Vr _ -> True - Meta _ -> True - _ -> False - - notCan = not . isPrimitiveFun gr - --- interface to TC type checker - -type2val :: Type -> Val -type2val = VClos [] - -aexp2tree :: (AExp,[(Val,Val)]) -> Err Tree -aexp2tree (aexp,cs) = do - (bi,at,vt,ts) <- treeForm aexp - ts' <- mapM aexp2tree [(t,[]) | t <- ts] - return $ Tr (N (bi,at,vt,(cs,[]),False),ts') - where - treeForm a = case a of - AAbs x v b -> do - (bi, at, vt, args) <- treeForm b - v' <- whnf v ---- should not be needed... - return ((x,v') : bi, at, vt, args) - AApp c a v -> do - (_,at,_,args) <- treeForm c - v' <- whnf v ---- - return ([],at,v',args ++ [a]) - AVr x v -> do - v' <- whnf v ---- - return ([],AtV x,v',[]) - ACn c v -> do - v' <- whnf v ---- - return ([],AtC c,v',[]) - AInt i -> do - return ([],AtI i,valAbsInt,[]) - AFloat i -> do - return ([],AtF i,valAbsFloat,[]) - AStr s -> do - return ([],AtL s,valAbsString,[]) - AMeta m v -> do - v' <- whnf v ---- - return ([],AtM m,v',[]) - _ -> Bad "illegal tree" -- AProd - -grammar2theory :: GFCGrammar -> Theory -grammar2theory gr (m,f) = case lookupFunType gr m f of - Ok t -> return $ type2val t - Bad s -> case lookupCatContext gr m f of - Ok cont -> return $ cont2val cont - _ -> Bad s - -cont2exp :: Context -> Exp -cont2exp c = mkProd (c, eType, []) -- to check a context - -cont2val :: Context -> Val -cont2val = type2val . cont2exp - --- some top-level batch-mode checkers for the compiler - -justTypeCheckSrc :: Grammar -> Exp -> Val -> Err Constraints -justTypeCheckSrc gr e v = do - (_,constrs0) <- checkExp (grammar2theorySrc gr) (initTCEnv []) e v - return $ filter notJustMeta constrs0 ----- return $ fst $ splitConstraintsSrc gr constrs0 ----- this change was to force proper tc of abstract modules. ----- May not be quite right. AR 13/9/2005 - -notJustMeta (c,k) = case (c,k) of - (VClos g1 (Meta m1), VClos g2 (Meta m2)) -> False - _ -> True - -grammar2theorySrc :: Grammar -> Theory -grammar2theorySrc gr (m,f) = case lookupFunTypeSrc gr m f of - Ok t -> return $ type2val t - Bad s -> case lookupCatContextSrc gr m f of - Ok cont -> return $ cont2val cont - _ -> Bad s - -checkContext :: Grammar -> Context -> [String] -checkContext st = checkTyp st . cont2exp - -checkTyp :: Grammar -> Type -> [String] -checkTyp gr typ = err singleton prConstrs $ justTypeCheckSrc gr typ vType - -checkEquation :: Grammar -> Fun -> Trm -> [String] -checkEquation gr (m,fun) def = err singleton id $ do - typ <- lookupFunTypeSrc gr m fun ----- cs <- checkEqs (grammar2theorySrc gr) (initTCEnv []) ((m,fun),def) (vClos typ) - cs <- justTypeCheckSrc gr def (vClos typ) - let cs1 = filter notJustMeta cs ----- filter (not . possibleConstraint gr) cs ---- - return $ ifNull [] (singleton . prConstraints) cs1 - -checkConstrs :: Grammar -> Cat -> [Ident] -> [String] -checkConstrs gr cat _ = [] ---- check constructors! - - - - - - -{- ---- -err singleton concat . mapM checkOne where - checkOne con = do - typ <- lookupFunType gr con - typ' <- computeAbsTerm gr typ - vcat <- valCat typ' - return $ if (cat == vcat) then [] else ["wrong type in constructor" +++ prt con] --} - -editAsTermCommand :: GFCGrammar -> (Loc TrNode -> Err (Loc TrNode)) -> Exp -> [Exp] -editAsTermCommand gr c e = err (const []) singleton $ do - t <- annotate gr $ refreshMetas [] e - t' <- c $ tree2loc t - return $ tree2exp $ loc2tree t' - -exp2termCommand :: GFCGrammar -> (Exp -> Err Exp) -> Tree -> Err Tree -exp2termCommand gr f t = errIn ("modifying term" +++ prt t) $ do - let exp = tree2exp t - exp2 <- f exp - annotate gr exp2 - -exp2termlistCommand :: GFCGrammar -> (Exp -> [Exp]) -> Tree -> [Tree] -exp2termlistCommand gr f = err (const []) fst . mapErr (annotate gr) . f . tree2exp - -tree2termlistCommand :: GFCGrammar -> (Tree -> [Exp]) -> Tree -> [Tree] -tree2termlistCommand gr f = err (const []) fst . mapErr (annotate gr) . f |
