mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-05-23 01:52:50 -06:00
now we use the GF reasoner to fillin meta variables in the abstract trees generated from the parser
This commit is contained in:
@@ -24,6 +24,7 @@ import PGF.CId
|
|||||||
import PGF.Data
|
import PGF.Data
|
||||||
import PGF.Macros
|
import PGF.Macros
|
||||||
import PGF.TypeCheck
|
import PGF.TypeCheck
|
||||||
|
import PGF.Generate
|
||||||
import Data.List
|
import Data.List
|
||||||
import Data.Array.IArray
|
import Data.Array.IArray
|
||||||
import qualified Data.Set as Set
|
import qualified Data.Set as Set
|
||||||
@@ -118,9 +119,7 @@ isLindefCId id
|
|||||||
getAbsTrees :: Forest -> PArg -> Maybe Type -> Either [(FId,TcError)] [Expr]
|
getAbsTrees :: Forest -> PArg -> Maybe Type -> Either [(FId,TcError)] [Expr]
|
||||||
getAbsTrees (Forest abs cnc forest root) arg@(PArg _ fid) ty =
|
getAbsTrees (Forest abs cnc forest root) arg@(PArg _ fid) ty =
|
||||||
let (err,res) = runTcM abs (do e <- go Set.empty emptyScope (fmap (TTyp []) ty) arg
|
let (err,res) = runTcM abs (do e <- go Set.empty emptyScope (fmap (TTyp []) ty) arg
|
||||||
e <- refineExpr e
|
generateForForest (prove (Just 20)) e) fid IntMap.empty
|
||||||
checkResolvedMetaStore emptyScope e
|
|
||||||
return e) fid IntMap.empty
|
|
||||||
in if null res
|
in if null res
|
||||||
then Left (nub err)
|
then Left (nub err)
|
||||||
else Right (nubsort [e | (_,_,e) <- res])
|
else Right (nubsort [e | (_,_,e) <- res])
|
||||||
@@ -131,10 +130,12 @@ getAbsTrees (Forest abs cnc forest root) arg@(PArg _ fid) ty =
|
|||||||
return (mkAbs (EMeta i))
|
return (mkAbs (EMeta i))
|
||||||
Nothing -> mzero
|
Nothing -> mzero
|
||||||
| Set.member fid rec_ = mzero
|
| Set.member fid rec_ = mzero
|
||||||
| otherwise = foldForest (\funid args trees ->
|
| otherwise = do fid0 <- get
|
||||||
|
put fid
|
||||||
|
x <- foldForest (\funid args trees ->
|
||||||
do let CncFun fn lins = cncfuns cnc ! funid
|
do let CncFun fn lins = cncfuns cnc ! funid
|
||||||
case isLindefCId fn of
|
case isLindefCId fn of
|
||||||
Just _ -> do arg <- bracket (go (Set.insert fid rec_) scope mb_tty) arg
|
Just _ -> do arg <- go (Set.insert fid rec_) scope mb_tty arg
|
||||||
return (mkAbs arg)
|
return (mkAbs arg)
|
||||||
Nothing -> do ty_fn <- lookupFunType fn
|
Nothing -> do ty_fn <- lookupFunType fn
|
||||||
(e,tty0) <- foldM (\(e1,tty) arg -> goArg (Set.insert fid rec_) scope fid e1 arg tty)
|
(e,tty0) <- foldM (\(e1,tty) arg -> goArg (Set.insert fid rec_) scope fid e1 arg tty)
|
||||||
@@ -154,11 +155,14 @@ getAbsTrees (Forest abs cnc forest root) arg@(PArg _ fid) ty =
|
|||||||
`mplus`
|
`mplus`
|
||||||
trees)
|
trees)
|
||||||
mzero fid forest
|
mzero fid forest
|
||||||
|
put fid0
|
||||||
|
return x
|
||||||
|
|
||||||
where
|
where
|
||||||
(scope,mkAbs,mb_tty) = updateScope hypos scope_ id mb_tty_
|
(scope,mkAbs,mb_tty) = updateScope hypos scope_ id mb_tty_
|
||||||
|
|
||||||
goArg rec_ scope fid e1 arg (TTyp delta (DTyp ((bt,x,ty):hs) c es)) = do
|
goArg rec_ scope fid e1 arg (TTyp delta (DTyp ((bt,x,ty):hs) c es)) = do
|
||||||
e2' <- bracket (go rec_ scope (Just (TTyp delta ty))) arg
|
e2' <- go rec_ scope (Just (TTyp delta ty)) arg
|
||||||
let e2 = case bt of
|
let e2 = case bt of
|
||||||
Explicit -> e2'
|
Explicit -> e2'
|
||||||
Implicit -> EImplArg e2'
|
Implicit -> EImplArg e2'
|
||||||
@@ -183,14 +187,6 @@ getAbsTrees (Forest abs cnc forest root) arg@(PArg _ fid) ty =
|
|||||||
(x:_) | fid == fidVar = [wildCId]
|
(x:_) | fid == fidVar = [wildCId]
|
||||||
| otherwise = [x | PConst _ (EFun x) _ <- maybe [] Set.toList (IntMap.lookup fid forest)]
|
| otherwise = [x | PConst _ (EFun x) _ <- maybe [] Set.toList (IntMap.lookup fid forest)]
|
||||||
|
|
||||||
bracket f arg@(PArg _ fid) = do
|
|
||||||
fid0 <- get
|
|
||||||
put fid
|
|
||||||
x <- f arg
|
|
||||||
put fid0
|
|
||||||
return x
|
|
||||||
|
|
||||||
|
|
||||||
foldForest :: (FunId -> [PArg] -> b -> b) -> (Expr -> [String] -> b -> b) -> b -> FId -> IntMap.IntMap (Set.Set Production) -> b
|
foldForest :: (FunId -> [PArg] -> b -> b) -> (Expr -> [String] -> b -> b) -> b -> FId -> IntMap.IntMap (Set.Set Production) -> b
|
||||||
foldForest f g b fcat forest =
|
foldForest f g b fcat forest =
|
||||||
case IntMap.lookup fcat forest of
|
case IntMap.lookup fcat forest of
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ module PGF.Generate
|
|||||||
, generateFrom, generateFromDepth
|
, generateFrom, generateFromDepth
|
||||||
, generateRandom, generateRandomDepth
|
, generateRandom, generateRandomDepth
|
||||||
, generateRandomFrom, generateRandomFromDepth
|
, generateRandomFrom, generateRandomFromDepth
|
||||||
|
, prove
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import PGF.CId
|
import PGF.CId
|
||||||
@@ -43,7 +44,10 @@ generateFrom pgf ex = generateFromDepth pgf ex Nothing
|
|||||||
-- | A variant of 'generateFrom' which also takes as argument
|
-- | A variant of 'generateFrom' which also takes as argument
|
||||||
-- the upper limit of the depth of the generated subexpressions.
|
-- the upper limit of the depth of the generated subexpressions.
|
||||||
generateFromDepth :: PGF -> Expr -> Maybe Int -> [Expr]
|
generateFromDepth :: PGF -> Expr -> Maybe Int -> [Expr]
|
||||||
generateFromDepth pgf e dp = generateForMetas () pgf e dp
|
generateFromDepth pgf e dp =
|
||||||
|
[e | (_,_,e) <- snd $ runTcM (abstract pgf)
|
||||||
|
(generateForMetas (prove dp) e)
|
||||||
|
() emptyMetaStore]
|
||||||
|
|
||||||
-- | Generates an infinite list of random abstract syntax expressions.
|
-- | Generates an infinite list of random abstract syntax expressions.
|
||||||
-- This is usefull for tree bank generation which after that can be used
|
-- This is usefull for tree bank generation which after that can be used
|
||||||
@@ -63,7 +67,9 @@ generateRandomFrom g pgf e = generateRandomFromDepth g pgf e Nothing
|
|||||||
-- | Random generation based on template with a limitation in the depth.
|
-- | Random generation based on template with a limitation in the depth.
|
||||||
generateRandomFromDepth :: RandomGen g => g -> PGF -> Expr -> Maybe Int -> [Expr]
|
generateRandomFromDepth :: RandomGen g => g -> PGF -> Expr -> Maybe Int -> [Expr]
|
||||||
generateRandomFromDepth g pgf e dp =
|
generateRandomFromDepth g pgf e dp =
|
||||||
restart g (\g -> generateForMetas (Identity g) pgf e dp)
|
restart g (\g -> [e | (_,ms,e) <- snd $ runTcM (abstract pgf)
|
||||||
|
(generateForMetas (prove dp) e)
|
||||||
|
(Identity g) emptyMetaStore])
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
@@ -71,21 +77,12 @@ generateRandomFromDepth g pgf e dp =
|
|||||||
|
|
||||||
generate :: Selector sel => sel -> PGF -> Type -> Maybe Int -> [Expr]
|
generate :: Selector sel => sel -> PGF -> Type -> Maybe Int -> [Expr]
|
||||||
generate sel pgf ty dp =
|
generate sel pgf ty dp =
|
||||||
[e | (_,ms,e) <- snd $ runTcM (abstract pgf) (prove emptyScope (TTyp [] ty) dp >>= refineExpr) sel emptyMetaStore]
|
[e | (_,ms,e) <- snd $ runTcM (abstract pgf)
|
||||||
|
(prove dp emptyScope (TTyp [] ty) >>= checkResolvedMetaStore emptyScope)
|
||||||
|
sel emptyMetaStore]
|
||||||
|
|
||||||
generateForMetas :: Selector sel => sel -> PGF -> Expr -> Maybe Int -> [Expr]
|
prove :: Selector sel => Maybe Int -> Scope -> TType -> TcM sel Expr
|
||||||
generateForMetas sel pgf e dp =
|
prove dp scope (TTyp env1 (DTyp [] cat es1)) = do
|
||||||
case unTcM (infExpr emptyScope e) abs sel emptyMetaStore of
|
|
||||||
Ok sel ms (e,_) -> let gen = do fillinVariables $ \scope tty -> do
|
|
||||||
prove scope tty dp
|
|
||||||
refineExpr e
|
|
||||||
in [e | (_,ms,e) <- snd $ runTcM abs gen sel ms]
|
|
||||||
Fail _ _ -> []
|
|
||||||
where
|
|
||||||
abs = abstract pgf
|
|
||||||
|
|
||||||
prove :: Selector sel => Scope -> TType -> Maybe Int -> TcM sel Expr
|
|
||||||
prove scope (TTyp env1 (DTyp [] cat es1)) dp = do
|
|
||||||
(fe,DTyp hypos _ es2) <- select cat dp
|
(fe,DTyp hypos _ es2) <- select cat dp
|
||||||
if fe == EFun (mkCId "plus") then mzero else return ()
|
if fe == EFun (mkCId "plus") then mzero else return ()
|
||||||
case dp of
|
case dp of
|
||||||
@@ -102,7 +99,7 @@ prove scope (TTyp env1 (DTyp [] cat es1)) dp = do
|
|||||||
mv <- getMeta i
|
mv <- getMeta i
|
||||||
case mv of
|
case mv of
|
||||||
MBound e -> c e
|
MBound e -> c e
|
||||||
MUnbound scope tty cs -> do e <- prove scope tty dp
|
MUnbound _ scope tty cs -> do e <- prove dp scope tty
|
||||||
setMeta i (MBound e)
|
setMeta i (MBound e)
|
||||||
sequence_ [c e | c <- (c:cs)]
|
sequence_ [c e | c <- (c:cs)]
|
||||||
|
|
||||||
@@ -118,7 +115,7 @@ prove scope (TTyp env1 (DTyp [] cat es1)) dp = do
|
|||||||
descend (bt,arg) = do let dp' = fmap (flip (-) 1) dp
|
descend (bt,arg) = do let dp' = fmap (flip (-) 1) dp
|
||||||
e <- case arg of
|
e <- case arg of
|
||||||
Right e -> return e
|
Right e -> return e
|
||||||
Left tty -> prove scope tty dp'
|
Left tty -> prove dp' scope tty
|
||||||
e <- case bt of
|
e <- case bt of
|
||||||
Implicit -> return (EImplArg e)
|
Implicit -> return (EImplArg e)
|
||||||
Explicit -> return e
|
Explicit -> return e
|
||||||
|
|||||||
@@ -18,12 +18,13 @@ module PGF.TypeCheck ( checkType, checkExpr, inferExpr
|
|||||||
, ppTcError, TcError(..)
|
, ppTcError, TcError(..)
|
||||||
|
|
||||||
-- internals needed for the typechecking of forests
|
-- internals needed for the typechecking of forests
|
||||||
, MetaStore, emptyMetaStore, newMeta, newGuardedMeta, fillinVariables, getMeta, setMeta, MetaValue(..)
|
, MetaStore, emptyMetaStore, newMeta, newGuardedMeta
|
||||||
|
, getMeta, setMeta, lookupMeta, MetaValue(..)
|
||||||
, Scope, emptyScope, scopeSize, scopeEnv, addScopedVar
|
, Scope, emptyScope, scopeSize, scopeEnv, addScopedVar
|
||||||
, TcM(..), TcResult(..), runTcM, TType(..), Selector(..)
|
, TcM(..), TcResult(..), runTcM, TType(..), Selector(..)
|
||||||
, tcExpr, infExpr, eqType, eqValue
|
, tcExpr, infExpr, eqType, eqValue
|
||||||
, lookupFunType, eval
|
, lookupFunType, eval
|
||||||
, refineExpr, checkResolvedMetaStore, lookupMeta
|
, generateForMetas, generateForForest, checkResolvedMetaStore
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import PGF.Data
|
import PGF.Data
|
||||||
@@ -78,7 +79,7 @@ scopeSize (Scope gamma) = length gamma
|
|||||||
|
|
||||||
type MetaStore s = IntMap (MetaValue s)
|
type MetaStore s = IntMap (MetaValue s)
|
||||||
data MetaValue s
|
data MetaValue s
|
||||||
= MUnbound Scope TType [Expr -> TcM s ()]
|
= MUnbound s Scope TType [Expr -> TcM s ()]
|
||||||
| MBound Expr
|
| MBound Expr
|
||||||
| MGuarded Expr [Expr -> TcM s ()] {-# UNPACK #-} !Int -- the Int is the number of constraints that have to be solved
|
| MGuarded Expr [Expr -> TcM s ()] {-# UNPACK #-} !Int -- the Int is the number of constraints that have to be solved
|
||||||
-- to unlock this meta variable
|
-- to unlock this meta variable
|
||||||
@@ -152,7 +153,7 @@ emptyMetaStore = IntMap.empty
|
|||||||
|
|
||||||
newMeta :: Scope -> TType -> TcM s MetaId
|
newMeta :: Scope -> TType -> TcM s MetaId
|
||||||
newMeta scope tty = TcM (\abstr s ms -> let metaid = IntMap.size ms + 1
|
newMeta scope tty = TcM (\abstr s ms -> let metaid = IntMap.size ms + 1
|
||||||
in Ok s (IntMap.insert metaid (MUnbound scope tty []) ms) metaid)
|
in Ok s (IntMap.insert metaid (MUnbound s scope tty []) ms) metaid)
|
||||||
|
|
||||||
newGuardedMeta :: Expr -> TcM s MetaId
|
newGuardedMeta :: Expr -> TcM s MetaId
|
||||||
newGuardedMeta e = TcM (\abstr s ms -> let metaid = IntMap.size ms + 1
|
newGuardedMeta e = TcM (\abstr s ms -> let metaid = IntMap.size ms + 1
|
||||||
@@ -170,24 +171,14 @@ lookupMeta ms i =
|
|||||||
Just (MBound t) -> Just t
|
Just (MBound t) -> Just t
|
||||||
Just (MGuarded t _ x) | x == 0 -> Just t
|
Just (MGuarded t _ x) | x == 0 -> Just t
|
||||||
| otherwise -> Nothing
|
| otherwise -> Nothing
|
||||||
Just (MUnbound _ _ _) -> Nothing
|
Just (MUnbound _ _ _ _) -> Nothing
|
||||||
Nothing -> Nothing
|
Nothing -> Nothing
|
||||||
|
|
||||||
fillinVariables :: (Scope -> TType -> TcM s Expr) -> TcM s ()
|
|
||||||
fillinVariables f = do
|
|
||||||
fvs <- TcM (\abstr s ms -> Ok s ms [(i,scope,tty,cs) | (i,MUnbound scope tty cs) <- IntMap.toList ms])
|
|
||||||
case fvs of
|
|
||||||
[] -> return ()
|
|
||||||
(i,scope,tty,cs):_ -> do e <- f scope tty
|
|
||||||
setMeta i (MBound e)
|
|
||||||
sequence_ [c e | c <- cs]
|
|
||||||
fillinVariables f
|
|
||||||
|
|
||||||
addConstraint :: MetaId -> MetaId -> (Expr -> TcM s ()) -> TcM s ()
|
addConstraint :: MetaId -> MetaId -> (Expr -> TcM s ()) -> TcM s ()
|
||||||
addConstraint i j c = do
|
addConstraint i j c = do
|
||||||
mv <- getMeta j
|
mv <- getMeta j
|
||||||
case mv of
|
case mv of
|
||||||
MUnbound scope tty cs -> addRef >> setMeta j (MUnbound scope tty ((\e -> release >> c e) : cs))
|
MUnbound s scope tty cs -> addRef >> setMeta j (MUnbound s scope tty ((\e -> release >> c e) : cs))
|
||||||
MBound e -> c e
|
MBound e -> c e
|
||||||
MGuarded e cs x | x == 0 -> c e
|
MGuarded e cs x | x == 0 -> c e
|
||||||
| otherwise -> addRef >> setMeta j (MGuarded e ((\e -> release >> c e) : cs) x)
|
| otherwise -> addRef >> setMeta j (MGuarded e ((\e -> release >> c e) : cs) x)
|
||||||
@@ -312,9 +303,7 @@ tcCatArgs scope _ delta _ ty0@(DTyp _ cat _) n m = do
|
|||||||
checkExpr :: PGF -> Expr -> Type -> Either TcError Expr
|
checkExpr :: PGF -> Expr -> Type -> Either TcError Expr
|
||||||
checkExpr pgf e ty =
|
checkExpr pgf e ty =
|
||||||
case unTcM (do e <- tcExpr emptyScope e (TTyp [] ty)
|
case unTcM (do e <- tcExpr emptyScope e (TTyp [] ty)
|
||||||
e <- refineExpr e
|
checkResolvedMetaStore emptyScope e) (abstract pgf) () emptyMetaStore of
|
||||||
checkResolvedMetaStore emptyScope e
|
|
||||||
return e) (abstract pgf) () emptyMetaStore of
|
|
||||||
Ok _ ms e -> Right e
|
Ok _ ms e -> Right e
|
||||||
Fail _ err -> Left err
|
Fail _ err -> Left err
|
||||||
|
|
||||||
@@ -367,8 +356,7 @@ tcExpr scope e0 tty = do
|
|||||||
inferExpr :: PGF -> Expr -> Either TcError (Expr,Type)
|
inferExpr :: PGF -> Expr -> Either TcError (Expr,Type)
|
||||||
inferExpr pgf e =
|
inferExpr pgf e =
|
||||||
case unTcM (do (e,tty) <- infExpr emptyScope e
|
case unTcM (do (e,tty) <- infExpr emptyScope e
|
||||||
e <- refineExpr e
|
e <- checkResolvedMetaStore emptyScope e
|
||||||
checkResolvedMetaStore emptyScope e
|
|
||||||
ty <- evalType 0 tty
|
ty <- evalType 0 tty
|
||||||
return (e,ty)) (abstract pgf) () emptyMetaStore of
|
return (e,ty)) (abstract pgf) () emptyMetaStore of
|
||||||
Ok _ ms (e,ty) -> Right (e,ty)
|
Ok _ ms (e,ty) -> Right (e,ty)
|
||||||
@@ -468,7 +456,7 @@ eqValue fail suspend k v1 v2 = do
|
|||||||
MBound e -> apply env e vs
|
MBound e -> apply env e vs
|
||||||
MGuarded e _ x | x == 0 -> apply env e vs
|
MGuarded e _ x | x == 0 -> apply env e vs
|
||||||
| otherwise -> return v
|
| otherwise -> return v
|
||||||
MUnbound _ _ _ -> return v
|
MUnbound _ _ _ _ -> return v
|
||||||
deRef v = return v
|
deRef v = return v
|
||||||
|
|
||||||
eqValue' k (VSusp i env vs1 c) v2 = suspend i (\e -> apply env e vs1 >>= \v1 -> eqValue fail suspend k (c v1) v2)
|
eqValue' k (VSusp i env vs1 c) v2 = suspend i (\e -> apply env e vs1 >>= \v1 -> eqValue fail suspend k (c v1) v2)
|
||||||
@@ -476,13 +464,13 @@ eqValue fail suspend k v1 v2 = do
|
|||||||
eqValue' k (VMeta i env1 vs1) (VMeta j env2 vs2) | i == j = zipWithM_ (eqValue fail suspend k) vs1 vs2
|
eqValue' k (VMeta i env1 vs1) (VMeta j env2 vs2) | i == j = zipWithM_ (eqValue fail suspend k) vs1 vs2
|
||||||
eqValue' k (VMeta i env1 vs1) v2 = do mv <- getMeta i
|
eqValue' k (VMeta i env1 vs1) v2 = do mv <- getMeta i
|
||||||
case mv of
|
case mv of
|
||||||
MUnbound scopei _ cs -> do e2 <- mkLam i scopei env1 vs1 v2
|
MUnbound _ scopei _ cs -> do e2 <- mkLam i scopei env1 vs1 v2
|
||||||
setMeta i (MBound e2)
|
setMeta i (MBound e2)
|
||||||
sequence_ [c e2 | c <- cs]
|
sequence_ [c e2 | c <- cs]
|
||||||
MGuarded e cs x -> setMeta i (MGuarded e ((\e -> apply env1 e vs1 >>= \v1 -> eqValue' k v1 v2) : cs) x)
|
MGuarded e cs x -> setMeta i (MGuarded e ((\e -> apply env1 e vs1 >>= \v1 -> eqValue' k v1 v2) : cs) x)
|
||||||
eqValue' k v1 (VMeta i env2 vs2) = do mv <- getMeta i
|
eqValue' k v1 (VMeta i env2 vs2) = do mv <- getMeta i
|
||||||
case mv of
|
case mv of
|
||||||
MUnbound scopei _ cs -> do e1 <- mkLam i scopei env2 vs2 v1
|
MUnbound _ scopei _ cs -> do e1 <- mkLam i scopei env2 vs2 v1
|
||||||
setMeta i (MBound e1)
|
setMeta i (MBound e1)
|
||||||
sequence_ [c e1 | c <- cs]
|
sequence_ [c e1 | c <- cs]
|
||||||
MGuarded e cs x -> setMeta i (MGuarded e ((\e -> apply env2 e vs2 >>= \v2 -> eqValue' k v1 v2) : cs) x)
|
MGuarded e cs x -> setMeta i (MGuarded e ((\e -> apply env2 e vs2 >>= \v2 -> eqValue' k v1 v2) : cs) x)
|
||||||
@@ -520,7 +508,7 @@ eqValue fail suspend k v1 v2 = do
|
|||||||
case mv of
|
case mv of
|
||||||
MBound e -> apply env e vs >>= occurCheck i0 k xs
|
MBound e -> apply env e vs >>= occurCheck i0 k xs
|
||||||
MGuarded e _ _ -> apply env e vs >>= occurCheck i0 k xs
|
MGuarded e _ _ -> apply env e vs >>= occurCheck i0 k xs
|
||||||
MUnbound scopei _ _ | scopeSize scopei > k -> fail
|
MUnbound _ scopei _ _ | scopeSize scopei > k -> fail
|
||||||
| otherwise -> do vs <- mapM (occurCheck i0 k xs) vs
|
| otherwise -> do vs <- mapM (occurCheck i0 k xs) vs
|
||||||
return (VMeta i env vs)
|
return (VMeta i env vs)
|
||||||
occurCheck i0 k xs (VSusp i env vs cnt) = do suspend i (\e -> apply env e vs >>= \v -> occurCheck i0 k xs (cnt v) >> return ())
|
occurCheck i0 k xs (VSusp i env vs cnt) = do suspend i (\e -> apply env e vs >>= \v -> occurCheck i0 k xs (cnt v) >> return ())
|
||||||
@@ -536,21 +524,61 @@ eqValue fail suspend k v1 v2 = do
|
|||||||
|
|
||||||
|
|
||||||
-----------------------------------------------------------
|
-----------------------------------------------------------
|
||||||
-- check for meta variables that still have to be resolved
|
-- three ways of dealing with meta variables that
|
||||||
|
-- still have to be resolved
|
||||||
-----------------------------------------------------------
|
-----------------------------------------------------------
|
||||||
|
|
||||||
checkResolvedMetaStore :: Scope -> Expr -> TcM s ()
|
checkResolvedMetaStore :: Scope -> Expr -> TcM s Expr
|
||||||
checkResolvedMetaStore scope e = TcM (\abstr s ms ->
|
checkResolvedMetaStore scope e = do
|
||||||
|
e <- refineExpr e
|
||||||
|
TcM (\abstr s ms ->
|
||||||
let xs = [i | (i,mv) <- IntMap.toList ms, not (isResolved mv)]
|
let xs = [i | (i,mv) <- IntMap.toList ms, not (isResolved mv)]
|
||||||
in if List.null xs
|
in if List.null xs
|
||||||
then Ok s ms ()
|
then Ok s ms ()
|
||||||
else Fail s (UnresolvedMetaVars (scopeVars scope) e xs))
|
else Fail s (UnresolvedMetaVars (scopeVars scope) e xs))
|
||||||
|
return e
|
||||||
where
|
where
|
||||||
isResolved (MUnbound _ _ []) = True
|
isResolved (MUnbound _ _ _ []) = True
|
||||||
isResolved (MGuarded _ _ _) = True
|
isResolved (MGuarded _ _ _) = True
|
||||||
isResolved (MBound _) = True
|
isResolved (MBound _) = True
|
||||||
isResolved _ = False
|
isResolved _ = False
|
||||||
|
|
||||||
|
generateForMetas :: Selector s => (Scope -> TType -> TcM s Expr) -> Expr -> TcM s Expr
|
||||||
|
generateForMetas prove e = do
|
||||||
|
infExpr emptyScope e
|
||||||
|
fillinVariables
|
||||||
|
refineExpr e
|
||||||
|
return e
|
||||||
|
where
|
||||||
|
fillinVariables = do
|
||||||
|
fvs <- TcM (\abstr s ms -> Ok s ms [(i,s,scope,tty,cs) | (i,MUnbound s scope tty cs) <- IntMap.toList ms])
|
||||||
|
case fvs of
|
||||||
|
[] -> return ()
|
||||||
|
(i,_,scope,tty,cs):_ -> do e <- prove scope tty
|
||||||
|
setMeta i (MBound e)
|
||||||
|
sequence_ [c e | c <- cs]
|
||||||
|
fillinVariables
|
||||||
|
|
||||||
|
generateForForest :: (Scope -> TType -> TcM FId Expr) -> Expr -> TcM FId Expr
|
||||||
|
generateForForest prove e = do
|
||||||
|
fillinVariables
|
||||||
|
refineExpr e
|
||||||
|
return e
|
||||||
|
where
|
||||||
|
fillinVariables = do
|
||||||
|
fvs <- TcM (\abstr s ms -> Ok s ms [(i,s,scope,tty,cs) | (i,MUnbound s scope tty cs) <- IntMap.toList ms])
|
||||||
|
case fvs of
|
||||||
|
[] -> return ()
|
||||||
|
(i,s,scope,tty,cs):_ -> TcM (\abstr s0 ms ->
|
||||||
|
case snd $ runTcM abstr (prove scope tty) s ms of
|
||||||
|
[] -> unTcM (do ty <- evalType (scopeSize scope) tty
|
||||||
|
throwError (UnsolvableGoal (scopeVars scope) s ty)
|
||||||
|
) abstr s ms
|
||||||
|
((_,ms,e):_) -> unTcM (do setMeta i (MBound e)
|
||||||
|
sequence_ [c e | c <- cs]
|
||||||
|
fillinVariables
|
||||||
|
) abstr s ms)
|
||||||
|
|
||||||
-----------------------------------------------------
|
-----------------------------------------------------
|
||||||
-- evalType
|
-- evalType
|
||||||
-----------------------------------------------------
|
-----------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user