mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-04-22 19:22:50 -06:00
more tc of gfcc
This commit is contained in:
@@ -3,6 +3,7 @@ module GF.Canon.GFCC.CheckGFCC where
|
|||||||
import GF.Canon.GFCC.DataGFCC
|
import GF.Canon.GFCC.DataGFCC
|
||||||
import GF.Canon.GFCC.AbsGFCC
|
import GF.Canon.GFCC.AbsGFCC
|
||||||
import GF.Canon.GFCC.PrintGFCC
|
import GF.Canon.GFCC.PrintGFCC
|
||||||
|
import GF.Canon.GFCC.ErrM
|
||||||
|
|
||||||
import qualified Data.Map as Map
|
import qualified Data.Map as Map
|
||||||
import Control.Monad
|
import Control.Monad
|
||||||
@@ -20,31 +21,76 @@ checkGFCC gfcc = andMapM (checkConcrete gfcc) $ Map.assocs $ concretes gfcc
|
|||||||
|
|
||||||
checkConcrete :: GFCC -> (CId,Map.Map CId Term) -> IO Bool
|
checkConcrete :: GFCC -> (CId,Map.Map CId Term) -> IO Bool
|
||||||
checkConcrete gfcc (lang,cnc) =
|
checkConcrete gfcc (lang,cnc) =
|
||||||
labelBoolIO (printTree lang) $ andMapM (checkLin gfcc lang) $ linRules cnc
|
labelBoolIO ("happened in language " ++ printTree lang) $
|
||||||
|
andMapM (checkLin gfcc lang) $ linRules cnc
|
||||||
|
|
||||||
checkLin :: GFCC -> CId -> (CId,Term) -> IO Bool
|
checkLin :: GFCC -> CId -> (CId,Term) -> IO Bool
|
||||||
checkLin gfcc lang (f,t) =
|
checkLin gfcc lang (f,t) =
|
||||||
labelBoolIO (printTree f) $ checkTerm (lintype gfcc lang f) $ inline gfcc lang t
|
labelBoolIO ("happened in function " ++ printTree f) $
|
||||||
|
checkTerm (lintype gfcc lang f) $ inline gfcc lang t
|
||||||
|
|
||||||
|
inferTerm :: [Tpe] -> Term -> Maybe Tpe
|
||||||
|
inferTerm args trm = case trm of
|
||||||
|
K _ -> return str
|
||||||
|
C i -> return $ ints i
|
||||||
|
V i -> if i < length args
|
||||||
|
then (return $ args !! i)
|
||||||
|
else error ("index " ++ show i)
|
||||||
|
S ts -> do
|
||||||
|
tys <- mapM infer ts
|
||||||
|
if all (==str) tys
|
||||||
|
then return str
|
||||||
|
else error ("only strings expected in: " ++ printTree trm
|
||||||
|
++ " instead of " ++ unwords (map printTree tys)
|
||||||
|
)
|
||||||
|
R ts -> do
|
||||||
|
tys <- mapM infer ts
|
||||||
|
return $ tuple tys
|
||||||
|
P t u -> do
|
||||||
|
R tys <- infer t
|
||||||
|
case u of
|
||||||
|
C i -> if (i < length tys)
|
||||||
|
then (return $ tys !! i) -- record: index must be known
|
||||||
|
else error ("too few fields in " ++ printTree (R tys))
|
||||||
|
_ -> if all (==head tys) tys -- table: must be same
|
||||||
|
then return (head tys)
|
||||||
|
else error ("projection " ++ printTree trm)
|
||||||
|
FV ts -> return $ head ts ---- empty variants; check equality
|
||||||
|
W s r -> infer r
|
||||||
|
_ -> error ("no type inference for " ++ printTree trm)
|
||||||
|
where
|
||||||
|
infer = inferTerm args
|
||||||
|
|
||||||
checkTerm :: LinType -> Term -> IO Bool
|
checkTerm :: LinType -> Term -> IO Bool
|
||||||
checkTerm (args,val) trm = case (val,trm) of
|
checkTerm (args,val) trm = case inferTerm args trm of
|
||||||
(R tys, R trs) -> do
|
Just ty -> if eqType ty val then return True else do
|
||||||
let (ntys,ntrs) = (length tys,length trs)
|
putStrLn $ "term: " ++ printTree trm ++
|
||||||
b <- checkCond
|
"\nexpected type: " ++ printTree val ++
|
||||||
("number of fields in " ++ prtrm ++ " does not match " ++ prval) (ntys == ntrs)
|
"\ninferred type: " ++ printTree ty
|
||||||
bs <- andMapM (uncurry check) (zip tys trs)
|
return False
|
||||||
return $ b && bs
|
_ -> do
|
||||||
(R _, W _ r) -> check val r
|
putStrLn $ "cannot infer type of " ++ printTree trm
|
||||||
_ -> return True
|
return False
|
||||||
where
|
|
||||||
checkCond msg cond = if cond then return True else (putStrLn msg >> return False)
|
eqType :: Tpe -> Tpe -> Bool
|
||||||
check ty tr = checkTerm (args,ty) tr
|
eqType inf exp = case (inf,exp) of
|
||||||
prtrm = printTree trm
|
(C k, C n) -> k <= n -- only run-time corr.
|
||||||
prval = printTree val
|
(R rs,R ts) -> length rs == length ts && and [eqType r t | (r,t) <- zip rs ts]
|
||||||
|
_ -> inf == exp
|
||||||
|
|
||||||
-- should be in a generic module, but not in the run-time DataGFCC
|
-- should be in a generic module, but not in the run-time DataGFCC
|
||||||
|
|
||||||
type LinType = ([Term],Term)
|
type Tpe = Term
|
||||||
|
type LinType = ([Tpe],Tpe)
|
||||||
|
|
||||||
|
tuple :: [Tpe] -> Tpe
|
||||||
|
tuple = R
|
||||||
|
|
||||||
|
ints :: Int -> Tpe
|
||||||
|
ints = C
|
||||||
|
|
||||||
|
str :: Tpe
|
||||||
|
str = S []
|
||||||
|
|
||||||
lintype :: GFCC -> CId -> CId -> LinType
|
lintype :: GFCC -> CId -> CId -> LinType
|
||||||
lintype gfcc lang fun = case lookType gfcc fun of
|
lintype gfcc lang fun = case lookType gfcc fun of
|
||||||
|
|||||||
@@ -96,7 +96,8 @@ compute mcfg lang args = comp where
|
|||||||
|
|
||||||
proj r p = case (r,p) of
|
proj r p = case (r,p) of
|
||||||
(_, FV ts) -> FV $ Prelude.map (proj r) ts
|
(_, FV ts) -> FV $ Prelude.map (proj r) ts
|
||||||
(W s t, _) -> kks (s ++ getString (proj t p))
|
(W s t, _) -> kks (s ++ getString (proj t p))
|
||||||
|
(_,R is) -> comp $ foldl P r is
|
||||||
_ -> comp $ getField r (getIndex p)
|
_ -> comp $ getField r (getIndex p)
|
||||||
|
|
||||||
getString t = case t of
|
getString t = case t of
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ mkCType :: Type -> C.Term
|
|||||||
mkCType t = case t of
|
mkCType t = case t of
|
||||||
EInt i -> C.C $ fromInteger i
|
EInt i -> C.C $ fromInteger i
|
||||||
-- record parameter alias - created in gfc preprocessing
|
-- record parameter alias - created in gfc preprocessing
|
||||||
RecType [(LIdent "_", i)] -> mkCType i
|
----RecType [(LIdent "_", i)] -> mkCType i
|
||||||
--- RecType [(LIdent "_", i), (LIdent "__", t)] -> C.RP (mkCType i) (mkCType t)
|
--- RecType [(LIdent "_", i), (LIdent "__", t)] -> C.RP (mkCType i) (mkCType t)
|
||||||
RecType rs -> C.R [mkCType t | (_, t) <- rs]
|
RecType rs -> C.R [mkCType t | (_, t) <- rs]
|
||||||
Table pt vt -> C.R $ replicate (getI (mkCType pt)) $ mkCType vt
|
Table pt vt -> C.R $ replicate (getI (mkCType pt)) $ mkCType vt
|
||||||
@@ -83,7 +83,7 @@ mkTerm tr = case tr of
|
|||||||
C.V (read (reverse (takeWhile (/='_') (reverse s)))) ---- from gf parser of gfc
|
C.V (read (reverse (takeWhile (/='_') (reverse s)))) ---- from gf parser of gfc
|
||||||
EInt i -> C.C $ fromInteger i
|
EInt i -> C.C $ fromInteger i
|
||||||
-- record parameter alias - created in gfc preprocessing
|
-- record parameter alias - created in gfc preprocessing
|
||||||
R [(LIdent "_", (_,i))] -> mkTerm i
|
----R [(LIdent "_", (_,i))] -> mkTerm i
|
||||||
--- R [(LIdent "_", (_,i)), (LIdent "__", (_,t))] -> C.RP (mkTerm i) (mkTerm t)
|
--- R [(LIdent "_", (_,i)), (LIdent "__", (_,t))] -> C.RP (mkTerm i) (mkTerm t)
|
||||||
-- ordinary record
|
-- ordinary record
|
||||||
R rs -> C.R [mkTerm t | (_, (_,t)) <- rs]
|
R rs -> C.R [mkTerm t | (_, (_,t)) <- rs]
|
||||||
@@ -273,10 +273,12 @@ term2term cgr env@(labels,untyps,typs) tr = case tr of
|
|||||||
(l,(_,t)) <- unlock rs]
|
(l,(_,t)) <- unlock rs]
|
||||||
rs' = [(mkLab i, (Nothing, t2t t)) |
|
rs' = [(mkLab i, (Nothing, t2t t)) |
|
||||||
(i,(l,(_,t))) <- zip [0..] (unlock rs)]
|
(i,(l,(_,t))) <- zip [0..] (unlock rs)]
|
||||||
in if (any (isStr . trmAss) rs)
|
in
|
||||||
then R rs'
|
----if (any (isStr . trmAss) rs)
|
||||||
|
----then
|
||||||
|
R rs'
|
||||||
--- else mkValCase tr
|
--- else mkValCase tr
|
||||||
else R [(LIdent "_", (Nothing, mkValCase tr'))]
|
----else R [(LIdent "_", (Nothing, mkValCase tr'))]
|
||||||
--- else R [(LIdent "_", (Nothing, mkValCase tr)), (LIdent "__",(Nothing,R rs'))]
|
--- else R [(LIdent "_", (Nothing, mkValCase tr)), (LIdent "__",(Nothing,R rs'))]
|
||||||
P t l -> r2r tr
|
P t l -> r2r tr
|
||||||
PI t l i -> EInt $ toInteger i
|
PI t l i -> EInt $ toInteger i
|
||||||
|
|||||||
Reference in New Issue
Block a user