|
1 |
| -{-# LANGUAGE DeriveFunctor, DeriveFoldable, DeriveTraversable, TypeSynonymInstances #-} |
| 1 | +{-# LANGUAGE DeriveFunctor, DeriveFoldable, DeriveTraversable, TypeSynonymInstances, FlexibleInstances, FlexibleContexts, UndecidableInstances #-} |
2 | 2 |
|
3 | 3 | module Abstract where
|
4 | 4 |
|
5 | 5 | import Prelude hiding (foldr)
|
6 | 6 |
|
| 7 | +import Control.Monad.Reader |
| 8 | + |
7 | 9 | import Data.Set (Set)
|
8 | 10 | import qualified Data.Set as Set
|
9 | 11 |
|
| 12 | +-- import Data.Map (Map) |
| 13 | +-- import qualified Data.Map as Map |
| 14 | +import qualified Data.IntMap as M |
| 15 | + |
10 | 16 | import Data.Foldable
|
11 | 17 | import Data.Traversable
|
12 | 18 |
|
@@ -104,6 +110,102 @@ appView = loop [] where
|
104 | 110 | loop acc f = (f, acc)
|
105 | 111 | -}
|
106 | 112 |
|
| 113 | +-- * alpha equality |
| 114 | + |
| 115 | +newtype Alpha a = Alpha a |
| 116 | + deriving (Functor) |
| 117 | + |
| 118 | +instance Show a => Show (Alpha a) where |
| 119 | + show (Alpha a) = show a |
| 120 | + |
| 121 | +instance Ord (Alpha Expr) where |
| 122 | + compare (Alpha e) (Alpha e') = aCompare e e' |
| 123 | + |
| 124 | +instance Ord (Alpha a) => Eq (Alpha a) where |
| 125 | + a == a' = compare a a' == EQ |
| 126 | + -- (Alpha e) == (Alpha e') = aeq e e' Map.empty |
| 127 | + |
| 128 | +type IMap = M.IntMap UID -- map directed from left to right |
| 129 | +type Cmp = Reader IMap |
| 130 | + |
| 131 | +class OrdAlpha a where |
| 132 | + aCompare :: a -> a -> Ordering |
| 133 | + aCompare e1 e2 = runReader (acmp e1 e2) M.empty |
| 134 | + |
| 135 | +-- acmp :: MonadReader IMap m => a -> a -> m Ordering |
| 136 | + acmp :: a -> a -> Cmp Ordering |
| 137 | + acmp e1 e2 = return $ aCompare e1 e2 |
| 138 | + |
| 139 | +instance OrdAlpha Name where |
| 140 | + acmp (Name x _) (Name y _) |
| 141 | + | x == y = return EQ |
| 142 | + | otherwise = do |
| 143 | + m <- ask |
| 144 | + case M.lookup x m of |
| 145 | + Nothing -> return $ compare x y |
| 146 | + Just y' -> return $ compare y' y |
| 147 | + |
| 148 | +-- | Just look at UID |
| 149 | +instance OrdAlpha Ident where |
| 150 | + acmp x y = acmp (name x) (name y) |
| 151 | + |
| 152 | +instance OrdAlpha Expr where |
| 153 | + acmp e e' = case (e, e') of |
| 154 | + |
| 155 | + (Ident x, Ident x') -> acmp x x' |
| 156 | + (Ident _, _) -> return LT |
| 157 | + (_, Ident _) -> return GT |
| 158 | + |
| 159 | + (App f e, App f' e') -> lexM [ acmp f f', acmp e e' ] |
| 160 | + (App _ _, _) -> return LT |
| 161 | + (_, App _ _) -> return GT |
| 162 | + |
| 163 | + (Pi Nothing a b, Pi Nothing a' b') -> acmp (a,b) (a',b') |
| 164 | + (Pi Nothing _ _, _) -> return LT |
| 165 | + (_, Pi Nothing _ _) -> return GT |
| 166 | + |
| 167 | + (Pi (Just x) a b, Pi (Just x') a' b') -> lexM |
| 168 | + [ acmp a a' |
| 169 | + , local (M.insert (uid x) (uid x')) $ acmp b b' ] |
| 170 | + (Pi (Just _) _ _, _) -> return LT |
| 171 | + (_, Pi (Just _) _ _) -> return GT |
| 172 | + |
| 173 | + (Lam x a e, Lam x' a' e') -> lexM |
| 174 | + [ acmp a a' |
| 175 | + , local (M.insert (uid x) (uid x')) $ acmp e e' ] |
| 176 | + (Lam _ _ _, _) -> return LT |
| 177 | + (_, Lam _ _ _) -> return GT |
| 178 | + |
| 179 | + (Typ, Typ) -> return EQ |
| 180 | +{- |
| 181 | + (Typ, _) -> return LT |
| 182 | + (_, Typ) -> return GT |
| 183 | +-} |
| 184 | + |
| 185 | +-- | Lexicographic comparison |
| 186 | +instance (OrdAlpha a, OrdAlpha b) => OrdAlpha (a,b) where |
| 187 | + acmp (a1,b1) (a2,b2) = lexM [acmp a1 a2, acmp b1 b2] |
| 188 | + |
| 189 | +-- | Use only for lists of equal length! |
| 190 | +instance (OrdAlpha a) => OrdAlpha [a] where |
| 191 | + acmp as bs = lexM $ zipWith acmp as bs |
| 192 | + |
| 193 | +instance (OrdAlpha a) => OrdAlpha (Maybe a) where |
| 194 | + acmp Nothing Nothing = return EQ |
| 195 | + acmp Nothing (Just _) = return LT |
| 196 | + acmp (Just _) Nothing = return GT |
| 197 | + acmp (Just a) (Just b) = acmp a b |
| 198 | + |
| 199 | +-- | Lazy lexicographic combination.. |
| 200 | +lexM :: Monad m => [m Ordering] -> m Ordering |
| 201 | +lexM [] = return EQ |
| 202 | +lexM (m:ms) = do |
| 203 | + o <- m |
| 204 | + case o of |
| 205 | + LT -> return LT |
| 206 | + GT -> return GT |
| 207 | + EQ -> lexM ms |
| 208 | + |
107 | 209 | -- * Queries
|
108 | 210 |
|
109 | 211 | globalIds :: Expr -> Set Ident
|
|
0 commit comments