-- 'nShallow', rather than expanding the named inst with 'nExpose'. Since
-- the right hand side is not getting smaller in such a case, the latter
-- strategy would lead divergence.
-leqNY :: (LeqC m f n k) => n -> InstF f (VR f n k) -> m Bool
+leqNY :: forall m f n k . (LeqC m f n k) => n -> InstF f (VR f n k) -> m Bool
leqNY nl (nShallow -> Just nr) = leqNN nl nr
-leqNY nl yr = iLeq_ leqNY leqNX (nExpose nl) yr
+leqNY nl yr = iLeq_ leqNL leqNX (nExpose nl) yr
+ where
+ leqNL :: NIX f -> (forall i_ . InstF f i_) -> m Bool
+ leqNL nl' yr' = leqNY nl' (ly yr')
+
+ -- What a mess. Necessary that it is written and scoped under here to
+ -- avoid ambiguous tyvars.
+ ly :: (forall i_ . InstF f i_) -> InstF f (VR f n k)
+ ly x = x
-- | Induction hypothesis YN
--
-- Induction is similarly funny as in 'leqNY'
leqYN :: (LeqC m f n k) => InstF f (VR f n k) -> n -> m Bool
leqYN (nShallow -> Just nl) nr = leqNN nl nr
-leqYN yl nr = iLeq_ leqXI leqXN yl (nExpose nr)
+leqYN yl nr = iLeq_ leqXL leqXN yl (nExpose nr)
-- | Induction hypothesis YY
leqYY :: (LeqC m f n k) => InstF f (VR f n k) -> InstF f (VR f n k) -> m Bool
-leqYY = iLeq_ leqXY leqXX
+leqYY = iLeq_ leqXL leqXX
+leqXL :: (LeqC m f n k) => VR f n k -> (forall i_ . InstF f i_) -> m Bool
+leqXL xl yr = leqXX xl (VRStruct yr)
+
+{-
-- | Repackage Y as X and invoke generic dispatch. Despite the growth of
-- the RHS, this is guaranteed to then step to one of the induction
-- hypotheses, which will reduce both sides.
leqXY :: (LeqC m f n k) => VR f n k -> InstF f (VR f n k) -> m Bool
leqXY xl yr = leqXX xl (VRStruct yr)
+-}
+{-
leqXI :: (LeqC m f n k) => VR f n k -> InstF f n -> m Bool
leqXI xl ir = leqXX xl (VRName $ nHide ir)
+-}
leqXN :: (LeqC m f n k) => VR f n k -> n -> m Bool
leqXN xl nr = leqXX xl (VRName nr)
(liftM Right . cnew . const . return . Right)
-- | Induction hypothesis QQ
-unifyQQ :: (UnifC m f n, UnifKC m f n k)
+unifyQQ :: forall m f n k .
+ (UnifC m f n, UnifKC m f n k)
=> Uniq
-> KRI f n k
-> KRI f n k
f jUpUniq jUpUniq fJQ fJQ unifyJJ u ya yb
>>= either throwError return
where
+ fJQ :: Uniq -> (forall i_. InstF f i_) -> Either n k -> m (Either n k)
fJQ u' q' j' = unifyJQ u' j' q'
-- | Name-on-Name unification, which computes a new name for the result.
leqXX :: (LeqC m f n)
=> VR f n -> VR f n -> m Bool
-leqXX (VRStruct yl) (VRStruct yr) = iLeq_ leqXY leqXX yl yr
+leqXX (VRStruct yl) (VRStruct yr) = iLeq_ leqXL leqXX yl yr
leqXX (VRName nl) (VRStruct yr) = leqNY nl yr
leqXX (VRStruct yl) (VRName nr) = leqYN yl nr
leqXX (VRName nl) (VRName nr) = return $ nLeq nl nr
+leqXL :: (LeqC m f n)
+ => VR f n -> (forall i_ . InstF f i_) -> m Bool
+leqXL (VRName nl) yr = iLeq_ leqNL leqNX (nExpose nl) yr
+leqXL (VRStruct yl) yr = iLeq_ leqXL leqXX yl yr
+
+{-
leqXY :: (LeqC m f n)
=> VR f n -> InstF f (VR f n) -> m Bool
leqXY (VRName nl) yr = iLeq_ leqNY leqNX (nExpose nl) yr
leqXY (VRStruct yl) yr = iLeq_ leqXY leqXX yl yr
+-}
leqNX :: (LeqC m f n)
=> NIX f -> VR f n -> m Bool
leqNX nl (VRName nr) = return $ nLeq nl nr
-leqNX nl (VRStruct yr) = iLeq_ leqNY leqNX (nExpose nl) yr
+leqNX nl (VRStruct yr) = iLeq_ leqNL leqNX (nExpose nl) yr
leqNY :: (LeqC m f n)
=> NIX f -> InstF f (VR f n) -> m Bool
leqNY nl (nShallow -> Just nr) = {- XT.trace "LNYS" $-} return $ nLeq nl nr
-leqNY nl ir = {-XT.traceShow ("LNY",nl,ir) $-} iLeq_ leqNY leqNX (nExpose nl) ir
+leqNY nl ir = {-XT.traceShow ("LNY",nl,ir) $-} iLeq_ leqNL leqNX (nExpose nl) ir
+
+-- XXX I am uncertain why this is necessary.
+leqNL :: (LeqC m f n)
+ => NIX f -> (forall i_ . InstF f i_) -> m Bool
+leqNL n l = leqNY n l
leqYN :: (LeqC m f n)
=> InstF f (VR f n) -> NIX f -> m Bool
-leqYN il nr = iLeq_ leqXI leqXN il (nExpose nr)
+leqYN il nr = iLeq_ leqXL leqXN il (nExpose nr)
+{-
leqXI :: (LeqC m f n)
=> VR f n -> InstF f (NIX f) -> m Bool
leqXI (VRStruct yl) ir = leqYN yl (nHide ir)
leqXI (VRName nl) ir = return $ nLeq nl (nHide ir)
+-}
leqXN :: (LeqC m f n)
=> VR f n -> NIX f -> m Bool
subNN a b = {- XT.traceShow ("SNN",a,b) $-} return $ nSub a b
subXI :: (SubC m f n)
- => VR f n -> InstF f (NIX f) -> m Bool
+ => VR f n -> (forall i_ . InstF f i_) -> m Bool
subXI (VRName ln) ri = subNN ln (nHide ri)
subXI (VRStruct ly) ri = subYI ly ri
(Ord f)
=> (forall a b m .
(Monad m)
- => (a -> InstF f b -> m Bool)
+ => (a -> (forall i_ . InstF f i_) -> m Bool)
-> (a -> b -> m Bool)
-> InstF f a -> InstF f b -> m Bool)
-> NIX f -> NIX f -> Bool
-- Q Out of Phase
qop l ri = -- XT.traceShow ("NCMP QOP",l,ri) $
- tsc _2 (l,ri) $ eml l0 (return . flip (nCmp q) (NIX ri rm))
- (flip (q qop qip) ri)
- lm l
+ tsc _2 (l,downcast ri)
+ $ eml l0 (return . flip (nCmp q) (NIX ri rm))
+ (flip (q qop qip) ri)
+ lm l
+
+ downcast :: (forall i_ . InstF f i_) -> InstF f ()
+ downcast i = i
nEq, nLeq, nSub :: (Ord f) => NIX f -> NIX f -> Bool
nEq = nCmp (\_ -> iEq_)
(Monad m)
=> (Uniq -> a -> m c)
-> (Uniq -> b -> m c)
- -> (Uniq -> InstF f b -> a -> m c)
- -> (Uniq -> InstF f a -> b -> m c)
+ -> (Uniq -> (forall i_ . InstF f i_) -> a -> m c)
+ -> (Uniq -> (forall i_ . InstF f i_) -> b -> m c)
-> (Uniq -> a -> b -> m c)
-> Uniq
-> InstF f a -> InstF f b -> m (InstF f c))
(Monad m, Show a, Show b, Show c)
=> (Uniq -> a -> m c)
-> (Uniq -> b -> m c)
- -> (Uniq -> InstF f b -> a -> m c)
- -> (Uniq -> InstF f a -> b -> m c)
+ -> (Uniq -> (forall i_ . InstF f i_) -> a -> m c)
+ -> (Uniq -> (forall i_ . InstF f i_) -> b -> m c)
-> (Uniq -> a -> b -> m c)
-> Uniq
-> InstF f a -> InstF f b -> m (Either e (InstF f c)))
{-# LANGUAGE TemplateHaskell #-}
{-# OPTIONS_GHC -Wall #-}
module Dyna.Analysis.Mode.Inst(
- InstF(..), inst_uniq, inst_rec, inst_recps,
+ InstF(..), inst_uniq, inst_rec, inst_recps, inst_irecps,
iNotReached, iIsNotReached,
iUniq, iIsFree, iWellFormed_, iEq_, iGround_,
iLeq_, iLeqGLB_, TyILeqGLB_,
,("_inst_rec","inst_rec")
]
''InstF)
+-- Note that makeLensesFor creates INLINE pragmas for its lenses, too. :)
-- | Traverse all of the recursion points @a@, rather than the @M.Map f [a]@
-- structure itself. This provides a more robust interface to term
-- recursion, but of course loses information about disjunctions.
inst_recps :: (Applicative a) => (i -> a i') -> InstF f i -> a (InstF f i')
inst_recps = inst_rec . each . each
+{-# INLINABLE inst_recps #-}
+
+-- | An indexed variant of 'inst_recps' which reveals the functor of the
+-- disjunct and the argument position being traversed right now.
+inst_irecps :: (Applicative a) => ((f, Int) -> i -> a i')
+ -> InstF f i -> a (InstF f i')
+inst_irecps = itraverseOf (inst_rec .> each <.> each)
+{-# INLINABLE inst_irecps #-}
------------------------------------------------------------------------}}}
-- Instantiation States: Unary predicates {{{
--
-- Definition 3.2.14, p51 (see also definitions 3.1.4 (p32) and 3.2.5 (p46))
iLeq_ :: (Ord f, Monad m)
- => (i -> InstF f i' -> m Bool)
+ => (i -> (forall i_ . InstF f i_) -> m Bool)
-> (i -> i' -> m Bool)
-> InstF f i -> InstF f i' -> m Bool
iLeq_ _ _ _ IFree = return $ True
type TyILeqGLB_ f m i i' i'' r =
(Uniq -> i -> m i'') -- ^ Import left
-> (Uniq -> i' -> m i'') -- ^ Import right
- -> (Uniq -> InstF f i' -> i -> m i'') -- ^ Lopsided merge left
- -> (Uniq -> InstF f i -> i' -> m i'') -- ^ Lopsided merge right
+ -> (Uniq -> (forall i_ . InstF f i_) -> i -> m i'') -- ^ Lopsided merge left
+ -> (Uniq -> (forall i_ . InstF f i_) -> i' -> m i'') -- ^ Lopsided merge right
-> (Uniq -> i -> i' -> m i'') -- ^ Simultaneous Merge
-> Uniq -- ^ Uniq of outer context
-> InstF f i -- ^ Left
-- Definition 3.2.15, p51 (see also definitions 3.1.11 (p35) and 3.2.7
-- (p46))
iSub_ :: (Ord f, Monad m)
- => (i -> InstF f i' -> m Bool)
+ => (i -> (forall i_ . InstF f i_) -> m Bool)
-> (i -> i' -> m Bool)
-> InstF f i
-> InstF f i'
-- on 'IFree' are with 'IFree' or 'iNotReached', there is no recursion to be
-- done.
iSubGLB_ :: (Ord f, Monad m)
- => (InstF f i' -> i -> m i'')
- -> (InstF f i -> i' -> m i'')
+ => ((forall i_ . InstF f i_) -> i -> m i'')
+ -> ((forall i_ . InstF f i_) -> i' -> m i'')
-> (i -> i' -> m i'')
-> InstF f i -> InstF f i' -> m (InstF f i'')
iSubGLB_ _ _ _ IFree IFree = return $ IFree
iSubGLB_ _ _ _ (IUniv u) (IAny u') = return $ IUniv (min u u')
iSubGLB_ _ _ _ (IUniv u) (IUniv u') = return $ IUniv (min u u')
-iSubGLB_ l _ _ (IBound u m b) r@(IAny u') = (return . flip (IBound (min u u')) b)
- =<< T.mapM (T.mapM (l r)) m
-iSubGLB_ _ r _ l@(IAny u') (IBound u m b) = (return . flip (IBound (min u u')) b)
- =<< T.mapM (T.mapM (r l)) m
+iSubGLB_ l _ _ (IBound u m b) (IAny u') = (return . flip (IBound (min u u')) b)
+ =<< T.mapM (T.mapM (l (IAny u'))) m
+iSubGLB_ _ r _ (IAny u') (IBound u m b) = (return . flip (IBound (min u u')) b)
+ =<< T.mapM (T.mapM (r (IAny u'))) m
-iSubGLB_ l _ _ (IBound u m b) r@(IUniv u') = (return . flip (IBound (min u u')) b)
- =<< T.mapM (T.mapM (l r)) m
-iSubGLB_ _ r _ l@(IUniv u') (IBound u m b) = (return . flip (IBound (min u u')) b)
- =<< T.mapM (T.mapM (r l)) m
+iSubGLB_ l _ _ (IBound u m b) (IUniv u') = (return . flip (IBound (min u u')) b)
+ =<< T.mapM (T.mapM (l (IUniv u'))) m
+iSubGLB_ _ r _ (IUniv u') (IBound u m b) = (return . flip (IBound (min u u')) b)
+ =<< T.mapM (T.mapM (r (IUniv u'))) m
iSubGLB_ _ _ q (IBound u m b) (IBound u' m' b') = do
let u'' = min u u'