Skip to content

Commit a5d52db

Browse files
committed
de Bruijn memoizing translation unsound
1 parent 6455473 commit a5d52db

7 files changed

+63
-28
lines changed

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ bench : helf
1313
$(time) $(helf) examples/ltal/w32_sig_semant.elf
1414

1515
current : helf
16-
$(helf) test/succeed/word32_ltal_sig.elf
16+
$(helf) test/succeed/z.elf
1717

1818
helf :
1919
make -C src helf

src/HerBruijnVal.hs

+1-1
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ evaluate2 expr env =
269269
SigDef t v <- sigLookup' (uid x) <$> ask
270270
return $ def x v t
271271
BApp t1 t2 -> Util.appM2 apply (evaluate' t1 env) (evaluate' t2 env)
272-
BLam x t -> (\z -> return $ HLam x z) =<< (evaluate' t env)
272+
BLam (Annotation x) t -> (\z -> return $ HLam x z) =<< (evaluate' t env)
273273
-- HLam x <$> evaluate' t env
274274
BConstLam t -> (\z -> return $ HK z) =<< (evaluate' t env)
275275
BSort sort -> return $ HSort sort

src/LocallyNamelessSyntax.hs

+20-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
{-# LANGUAGE DeriveFunctor #-}
12
-- stuff taken from HerBruijnVal
23

3-
module LocallyNamelessSyntax (BTm(..), DBIndex(..), toLocallyNameless, fromLocallyNameless) where
4+
module LocallyNamelessSyntax (BTm(..), DBIndex(..), Annotation(..), toLocallyNameless, fromLocallyNameless) where
45

56
import Data.Map (Map)
67
import qualified Data.Map as Map
@@ -11,22 +12,33 @@ import Value
1112

1213
-- * de Bruijn Terms
1314

15+
newtype Annotation a = Annotation { annotation :: a }
16+
deriving (Show, Functor)
17+
18+
instance Eq (Annotation a) where
19+
a == b = True
20+
21+
instance Ord (Annotation a) where
22+
a <= b = True
23+
1424
data DBIndex = DBIndex { index :: Int, identifier :: A.Name }
15-
deriving (Ord)
1625

1726
instance Eq DBIndex where
1827
i == j = index i == index j
1928

2029
instance Show DBIndex where
2130
show (DBIndex i x) = show x ++ "@" ++ show i
2231

32+
instance Ord DBIndex where
33+
compare i j = compare (index i) (index j)
34+
2335
data BTm -- names are only used for quoting
2436
= B DBIndex -- bound variable: de Bruijn index
2537
| BVar A.Name -- free variable: name
2638
| BCon A.Name
2739
| BDef A.Name
2840
| BApp BTm BTm
29-
| BLam A.Name BTm -- name irrelevant for execution
41+
| BLam (Annotation A.Name) BTm -- name irrelevant for execution
3042
| BConstLam BTm -- these are lambdas, but not counted
3143
| BSort Value.Sort
3244
| BPi BTm BTm
@@ -49,11 +61,12 @@ fromLocallyNameless t =
4961
BDef x -> Ident $ Def x
5062
BApp t u -> App (fromLocallyNameless t) (fromLocallyNameless u)
5163
BPi u (BConstLam t) -> Pi Nothing (fromLocallyNameless u) (fromLocallyNameless t)
52-
BPi u (BLam x t) -> Pi (Just x) (fromLocallyNameless u) (fromLocallyNameless t)
64+
BPi u (BLam (Annotation x) t) -> Pi (Just x) (fromLocallyNameless u) (fromLocallyNameless t)
5365

54-
BLam x t -> Lam x Nothing $ fromLocallyNameless t
66+
BLam (Annotation x) t -> Lam x Nothing $ fromLocallyNameless t
67+
BConstLam t -> Lam A.noName Nothing $ fromLocallyNameless t
5568
BSort Type -> Typ
56-
-- impossible: BConstLam t, BSort Kind
69+
-- impossible: BSort Kind
5770

5871
-- * transformation, only used for evaluate2
5972

@@ -81,7 +94,7 @@ toLocallyNameless = trans lbl_empty where
8194
Con x -> BCon x
8295
Def x -> BDef x
8396
trans lbl (App e1 e2) = BApp (trans lbl e1) (trans lbl e2)
84-
trans lbl (Lam name _ e) = BLam name $ trans (insert_lbl name lbl) e
97+
trans lbl (Lam name _ e) = BLam (Annotation name) $ trans (insert_lbl name lbl) e
8598
trans _ Typ = BSort Type
8699
trans lbl (Pi mname a b) = case mname of
87100
Just n ->

src/Makefile

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ profflags=-prof -auto-all
1010

1111
default : helf test
1212

13-
current : helf
14-
helf test/succeed/comments.elf
13+
current :
14+
helf test/succeed/z.elf
1515

1616
helf : ../bin/helf
1717

src/TGChecker.hs

+8-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
-- * environments as finite maps
44

55
{-# LANGUAGE OverlappingInstances, IncoherentInstances, UndecidableInstances,
6-
PatternGuards, TupleSections #-}
6+
PatternGuards, TupleSections, TypeSynonymInstances, MultiParamTypeClasses #-}
77

88
module TGChecker where
99

@@ -103,6 +103,13 @@ instance MonadCheckExpr Head Val Env EvalM CheckExprM where
103103
typeTrace tr cont = -- traceM (showM tr) >>
104104
enterDoc (prettyM tr) cont
105105

106+
{-
107+
traceEval m = do
108+
v <- m
109+
traceM (showTG v)
110+
return v
111+
-}
112+
106113
lookupGlobal x = symbType . sigLookup' (A.uid x) <$> asks globals
107114

108115
-- lookupGlobal x = ReaderT $ \ sig -> return $ lookupSafe x sig

src/TermGraph.hs

+25-15
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,8 @@ type TDict a = Map a Term
179179
type TransM a = StateT (TDict a) ORefM
180180
type TransT a = StateT (TDict a)
181181

182-
{-
182+
-- Direct translation from A.Expr
183+
183184
addPredefs :: MonadTG m => TDict A.Expr -> m (TDict A.Expr)
184185
addPredefs dict = do
185186
ty <- predefType
@@ -191,19 +192,21 @@ trans :: (Signature Term sig, MonadReader sig m, MonadTG m) =>
191192
trans rho e = -- trace ("translating " ++ show e) $ do
192193
evalStateT (transT e) =<< addPredefs
193194
(Map.mapKeysMonotonic (A.Ident . A.Var) rho)
194-
-}
195195

196-
addPredefs :: MonadTG m => TDict BTm -> m (TDict BTm)
197-
addPredefs dict = do
198-
ty <- predefType
199-
return $ Map.insert (BSort Type) ty dict
196+
{-
197+
-- Translation via BTm
200198
201199
trans :: (Signature Term sig, MonadReader sig m, MonadTG m) =>
202200
Env -> A.Expr -> m Term
203201
trans rho e = -- trace ("translating " ++ show e) $ do
204202
evalStateT (transB (toLocallyNameless e)) =<< addPredefs
205203
(Map.mapKeysMonotonic BVar rho)
206204
205+
addPredefs :: MonadTG m => TDict BTm -> m (TDict BTm)
206+
addPredefs dict = do
207+
ty <- predefType
208+
return $ Map.insert (BSort Type) ty dict
209+
-}
207210

208211
-- | From locally nameless to Term.
209212
transB :: (Signature Term sig, MonadReader sig m, MonadTG m) =>
@@ -222,14 +225,18 @@ transB' e = do
222225
SigDef t v <- sigLookup' (A.uid x) <$> ask
223226
Right <$> (return $ def x t v)
224227
BVar n -> -- free variable
225-
-- fail ("transB': unbound variable " ++ A.suggestion n)
228+
fail ("transB': unbound variable " ++ A.suggestion n)
226229
-- trace ("transB': unbound variable " ++ A.suggestion n)
227-
Right <$> (return $ Var n) -- only for binding in Lam and Pi
228-
BLam n e -> do
230+
-- Right <$> (return $ Var n) -- only for binding in Lam and Pi
231+
BLam (Annotation n) e -> do
229232
x <- transAddBind BVar n
230233
Right . Abs x <$> transB e
231234
BConstLam e -> Right . K <$> transB e
232-
BPi a b -> Right <$> (Fun <$> transB a <*> transB b)
235+
BPi a b -> do
236+
a <- transB a
237+
b <- transB b
238+
return $ Right $ Fun a b
239+
-- BPi a b -> Right <$> (Fun <$> transB a <*> transB b)
233240
else do
234241
r <- transB f
235242
Right . App r <$> (mapM transB sp)
@@ -240,19 +247,20 @@ transG :: (Signature Term sig, MonadReader sig m, MonadTG m, Ord a, Show a) =>
240247
(a -> TransT a m (Either Term Term')) -> a -> TransT a m Term
241248
transG transT' e = do
242249
dict <- get
250+
-- traceM $ return ("? searching translation for " ++ show e ++ " in dict " ++ show dict)
243251
case Map.lookup e dict of -- TODO compare upto alpha!
244252
Just r -> do
245253
unlessM (atomic r) $ do
246-
traceM $ return ("==> found translation for " ++ show e)
254+
traceM $ return ("==> found translation " ++ show r ++ " for " ++ show e) -- ++ " in dict " ++ show (Map.keys dict))
247255
return r
248256
Nothing -> do
249257
rt <- transT' e
250258
case rt of
251259
Left r -> return r
252260
Right t -> do
253261
r <- newORef t
254-
-- traceM $ return ("adding translation for " ++ show e)
255-
put $ Map.insert e r dict
262+
-- traceM $ return ("==> adding translation " ++ show r ++ " for " ++ show e)
263+
modify $ Map.insert e r
256264
return r
257265

258266
transAddBind :: (Signature Term sig, MonadReader sig m, MonadTG m, Ord a) =>
@@ -389,7 +397,7 @@ prettyT r = do
389397
Nothing -> do
390398
d <- prettyT' =<< readORef r
391399
put $ Map.insert r d dict
392-
return $ d -- text (show r ++ "@") <> d
400+
return $ text (show r ++ "@") <> d
393401

394402
prettyT' :: MonadORef m => Term' -> PrettyT m Doc
395403
prettyT' t = do
@@ -461,8 +469,10 @@ substT r = do
461469
traceM $ return ("==> fire subst of " ++ s' ++ " for " ++ s)
462470
return $ Just r'
463471
Just (Nothing) -> do
472+
{-
464473
x <- showTG r
465-
-- traceM $ return ("skipping bound variable " ++ x ++ " with ref " ++ show r)
474+
traceM $ return ("skipping bound variable " ++ x ++ " with ref " ++ show r)
475+
-}
466476
return Nothing
467477
Nothing -> do
468478
mt <- substT' =<< readORef r

src/TypeCheck.hs

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
{-# LANGUAGE TupleSections, UndecidableInstances, TypeSynonymInstances, FlexibleInstances, MultiParamTypeClasses, GeneralizedNewtypeDeriving, FlexibleContexts, FunctionalDependencies #-}
2+
13
-- A generic bidirectional type-checker for LF
24

35
module TypeCheck where
@@ -100,6 +102,9 @@ class (Monad m, -- Scoping.Scope m,
100102
newError :: TypeError val -> m a -> m a
101103
-- handleError :: m a -> (TypeError val -> m a) -> m a
102104
typeTrace :: TypeTrace val -> m a -> m a
105+
typeTrace tr cont = cont -- default: do not trace type checker
106+
traceEval :: m val -> m val
107+
traceEval cont = cont -- default: do not print evaluated term
103108

104109
{- Type checking Gamma |- e <=: t
105110
@@ -263,7 +268,7 @@ class (Monad m, -- Scoping.Scope m,
263268
{-# INLINE doCheckExpr #-}
264269

265270
evalExpr :: Expr -> m val
266-
evalExpr = doCheckExpr . doEval . evaluate'
271+
evalExpr = doCheckExpr . traceEval . doEval . evaluate'
267272

268273
{- Rules for checking declarations
269274

0 commit comments

Comments
 (0)