@@ -19,12 +19,15 @@ import Data.Binary hiding (get, put)
19import Core.TT
19import Core.TT
20import Core.CaseTree
20import Core.CaseTree
22−type EvalState = ()
22+data EvalState = ES { limited :: [(Name, Int)],
23type Eval a = State EvalState a
24type Eval a = State EvalState a
25data EvalOpt = Spec | HNF | Simplify | AtREPL
26data EvalOpt = Spec | HNF | Simplify | AtREPL
26 deriving (Show, Eq)
27 deriving (Show, Eq)
28-- VALUES (as HOAS) ---------------------------------------------------------
31-- VALUES (as HOAS) ---------------------------------------------------------
30data Value = VP NameType Name Value
33data Value = VP NameType Name Value
@@ -46,7 +49,7 @@ data HNF = HP NameType Name (TT Name)
46 deriving Show
49 deriving Show
48instance Show Value where
51instance Show Value where
49− show x = show $ evalState (quote 100 x) ()
52+ show x = show $ evalState (quote 100 x) initEval
51instance Show (a -> b) where
54instance Show (a -> b) where
52 show x = "<<fn>>"
55 show x = "<<fn>>"
@@ -60,36 +63,36 @@ instance Show (a -> b) where
61normaliseC :: Context -> Env -> TT Name -> TT Name
64normaliseC :: Context -> Env -> TT Name -> TT Name
62normaliseC ctxt env t
65normaliseC ctxt env t
63− = evalState (do val <- eval ctxt emptyContext env t []
66+ = evalState (do val <- eval ctxt [] env t []
64− quote 0 val) ()
67+ quote 0 val) initEval
66normaliseAll :: Context -> Env -> TT Name -> TT Name
69normaliseAll :: Context -> Env -> TT Name -> TT Name
67normaliseAll ctxt env t
70normaliseAll ctxt env t
68− = evalState (do val <- eval ctxt emptyContext env t [AtREPL]
71+ = evalState (do val <- eval ctxt [] env t [AtREPL]
69− quote 0 val) ()
72+ quote 0 val) initEval
71normalise :: Context -> Env -> TT Name -> TT Name
74normalise :: Context -> Env -> TT Name -> TT Name
72normalise ctxt env t
75normalise ctxt env t
73− = evalState (do val <- eval ctxt emptyContext (map finalEntry env) (finalise t) []
76+ = evalState (do val <- eval ctxt [] (map finalEntry env) (finalise t) []
74− quote 0 val) ()
77+ quote 0 val) initEval
76−specialise :: Context -> Ctxt [Bool] -> TT Name -> TT Name
79+specialise :: Context -> Env -> [(Name, Int)] -> TT Name -> TT Name
77−specialise ctxt statics t
80+specialise ctxt env limits t
78− = evalState (do val <- eval ctxt statics [] (finalise t) [Spec]
81+ = evalState (do val <- eval ctxt limits (map finalEntry env) (finalise t) []
79− quote 0 val) ()
82+ quote 0 val) (initEval { limited = limits })
81-- Like normalise, but we only reduce functions that are marked as okay to
84-- Like normalise, but we only reduce functions that are marked as okay to
82-- inline (and probably shouldn't reduce lets?)
85-- inline (and probably shouldn't reduce lets?)
84simplify :: Context -> Env -> TT Name -> TT Name
87simplify :: Context -> Env -> TT Name -> TT Name
85simplify ctxt env t
88simplify ctxt env t
86− = evalState (do val <- eval ctxt emptyContext (map finalEntry env) (finalise t) [Simplify]
89+ = evalState (do val <- eval ctxt [] (map finalEntry env) (finalise t) [Simplify]
87− quote 0 val) ()
90+ quote 0 val) initEval
89hnf :: Context -> Env -> TT Name -> TT Name
92hnf :: Context -> Env -> TT Name -> TT Name
90hnf ctxt env t
93hnf ctxt env t
91− = evalState (do val <- eval ctxt emptyContext (map finalEntry env) (finalise t) [HNF]
94+ = evalState (do val <- eval ctxt [] (map finalEntry env) (finalise t) [HNF]
92− quote 0 val) ()
95+ quote 0 val) initEval
95-- unbindEnv env (quote 0 (eval ctxt (bindEnv env t)))
98-- unbindEnv env (quote 0 (eval ctxt (bindEnv env t)))
@@ -106,120 +109,141 @@ unbindEnv :: EnvTT n -> TT n -> TT n
106unbindEnv [] tm = tm
109unbindEnv [] tm = tm
107unbindEnv (_:bs) (Bind n b sc) = unbindEnv bs sc
110unbindEnv (_:bs) (Bind n b sc) = unbindEnv bs sc
112+usable :: Name -> [(Name, Int)] -> (Bool, [(Name, Int)])
113+usable n [] = (True, [])
114+usable n ns = case lookup n ns of
115+ Just 0 -> (False, ns)
116+ Just i -> (True, (n, abs (i-1)) : filter (\ (n', _) -> n/=n') ns)
117+ _ -> (True, (n, 100) : filter (\ (n', _) -> n/=n') ns)
120+reduction = do ES ns s <- get
109-- Evaluate in a context of locally named things (i.e. not de Bruijn indexed,
123-- Evaluate in a context of locally named things (i.e. not de Bruijn indexed,
110-- such as we might have during construction of a proof)
124-- such as we might have during construction of a proof)
112−eval :: Context -> Ctxt [Bool] -> Env -> TT Name -> [EvalOpt] -> Eval Value
126+eval :: Context -> [(Name, Int)] -> Env -> TT Name -> [EvalOpt] -> Eval Value
113−eval ctxt statics genv tm opts = ev [] True [] tm where
127+eval ctxt ntimes genv tm opts = ev ntimes [] True [] tm where
114 spec = Spec `elem` opts
128 spec = Spec `elem` opts
115 simpl = Simplify `elem` opts
129 simpl = Simplify `elem` opts
116 atRepl = AtREPL `elem` opts
130 atRepl = AtREPL `elem` opts
118− ev stk top env (P _ n ty)
132+ ev ntimes stk top env (P _ n ty)
119− | Just (Let t v) <- lookup n genv = ev stk top env v
133+ | Just (Let t v) <- lookup n genv = ev ntimes stk top env v
134+ ev ntimes_in stk top env (P Ref n ty)
135+ | (True, ntimes) <- usable n ntimes_in
120− ev stk top env (P Ref n ty) = case lookupDefAcc Nothing n atRepl ctxt of
136+ = do let val = lookupDefAcc Nothing n atRepl ctxt
121− [(Function _ tm, Public)] ->
138+ [(Function _ tm, Public)] ->
122− ev (n:stk) True env tm
139+ ev ntimes (n:stk) True env tm
123− [(TyDecl nt ty, _)] -> do vty <- ev stk True env ty
140+ [(TyDecl nt ty, _)] -> do vty <- ev ntimes stk True env ty
124− return $ VP nt n vty
141+ return $ VP nt n vty
125− [(CaseOp inl _ _ [] tree _ _, Public)] -> -- unoptimised version
142+ [(CaseOp inl _ _ [] tree _ _, Public)] -> -- unoptimised version
126− if simpl && (not inl || elem n stk)
143+ if simpl && (not inl || elem n stk)
127− then liftM (VP Ref n) (ev stk top env ty)
144+ then liftM (VP Ref n) (ev ntimes stk top env ty)
128− else do c <- evCase (n:stk) top env [] [] tree
145+ else do c <- evCase ntimes (n:stk) top env [] [] tree
129− case c of
146+ case c of
130− (Nothing, _) -> liftM (VP Ref n) (ev stk top env ty)
147+ (Nothing, _) -> liftM (VP Ref n) (ev ntimes stk top env ty)
131− (Just v, _) -> return v
148+ (Just v, _) -> return v
132− _ -> liftM (VP Ref n) (ev stk top env ty)
149+ _ -> liftM (VP Ref n) (ev ntimes stk top env ty)
133− ev stk top env (P nt n ty) = liftM (VP nt n) (ev stk top env ty)
150+ ev ntimes stk top env (P nt n ty) = liftM (VP nt n) (ev ntimes stk top env ty)
134− ev stk top env (V i) | i < length env = return $ env !! i
151+ ev ntimes stk top env (V i) | i < length env = return $ env !! i
135 | otherwise = return $ VV i
152 | otherwise = return $ VV i
136− ev stk top env (Bind n (Let t v) sc)
153+ ev ntimes stk top env (Bind n (Let t v) sc)
137− = do v' <- ev stk top env v --(finalise v)
154+ = do v' <- ev ntimes stk top env v --(finalise v)
138− sc' <- ev stk top (v' : env) sc
155+ sc' <- ev ntimes stk top (v' : env) sc
139 wknV (-1) sc'
156 wknV (-1) sc'
140− ev stk top env (Bind n (NLet t v) sc)
157+ ev ntimes stk top env (Bind n (NLet t v) sc)
141− = do t' <- ev stk top env (finalise t)
158+ = do t' <- ev ntimes stk top env (finalise t)
142− v' <- ev stk top env (finalise v)
159+ v' <- ev ntimes stk top env (finalise v)
143− sc' <- ev stk top (v' : env) sc
160+ sc' <- ev ntimes stk top (v' : env) sc
144 return $ VBind n (Let t' v') (\x -> return sc')
161 return $ VBind n (Let t' v') (\x -> return sc')
145− ev stk top env (Bind n b sc)
162+ ev ntimes stk top env (Bind n b sc)
146 = do b' <- vbind env b
163 = do b' <- vbind env b
147− return $ VBind n b' (\x -> ev stk top (x:env) sc)
164+ return $ VBind n b' (\x -> ev ntimes stk top (x:env) sc)
148− where vbind env t = fmapMB (\tm -> ev stk top env (finalise tm)) t
165+ where vbind env t = fmapMB (\tm -> ev ntimes stk top env (finalise tm)) t
149− ev stk top env (App f a) = do f' <- ev stk top env f
166+ ev ntimes stk top env (App f a)
167+ = do f' <- ev ntimes stk top env f
150− a' <- ev stk False env a
168+ a' <- ev ntimes stk False env a
151− evApply stk top env [a'] f'
169+ evApply ntimes stk top env [a'] f'
152− ev stk top env (Constant c) = return $ VConstant c
170+ ev ntimes stk top env (Constant c) = return $ VConstant c
153− ev stk top env Erased = return VErased
171+ ev ntimes stk top env Erased = return VErased
154− ev stk top env (Set i) = return $ VSet i
172+ ev ntimes stk top env (Set i) = return $ VSet i
156− evApply stk top env args (VApp f a) =
174+ evApply ntimes stk top env args (VApp f a) =
157− evApply stk top env (a:args) f
175+ evApply ntimes stk top env (a:args) f
158− evApply stk top env args f = apply stk top env f args
176+ evApply ntimes stk top env args f = apply ntimes stk top env f args
160− apply stk top env (VBind n (Lam t) sc) (a:as)
178+ apply ntimes stk top env (VBind n (Lam t) sc) (a:as)
161 = do a' <- sc a
179 = do a' <- sc a
162− app <- apply stk top env a' as
180+ app <- apply ntimes stk top env a' as
163 wknV (-1) app
181 wknV (-1) app
164− apply stk False env f args
182+-- apply ntimes stk False env f args
165− | spec = specApply stk env f args
183+-- | spec = specApply ntimes stk env f args
166− apply stk top env (VP Ref n ty) args
184+ apply ntimes_in stk top env f@(VP Ref n ty) args
185+ | (True, ntimes) <- usable n ntimes_in
167− | [(CaseOp inl _ _ ns tree _ _, Public)] <- lookupDefAcc Nothing n atRepl ctxt
186+ = do let val = lookupDefAcc Nothing n atRepl ctxt
168− = -- traceWhen (n == UN ["interp"]) (show (n, args)) $
187+ case val of
188+ [(CaseOp inl _ _ ns tree _ _, Public)] ->
169− if simpl && (not inl || elem n stk)
189+ if simpl && (not inl || elem n stk)
170− then return $ unload env (VP Ref n ty) args
190+ then return $ unload env (VP Ref n ty) args
171− else do c <- evCase (n:stk) top env ns args tree
191+ else do c <- evCase ntimes (n:stk) top env ns args tree
172− case c of
192+ case c of
173− (Nothing, _) -> return $ unload env (VP Ref n ty) args
193+ (Nothing, _) -> return $ unload env (VP Ref n ty) args
174− (Just v, rest) -> evApply stk top env rest v
194+ (Just v, rest) -> evApply ntimes stk top env rest v
175− | [Operator _ i op] <- lookupDef Nothing n ctxt
195+ [(Operator _ i op, _)] ->
176− = if (i <= length args)
196+ if (i <= length args)
177− then case op (take i args) of
197+ then case op (take i args) of
178− Nothing -> return $ unload env (VP Ref n ty) args
198+ Nothing -> return $ unload env (VP Ref n ty) args
179− Just v -> evApply stk top env (drop i args) v
199+ Just v -> evApply ntimes stk top env (drop i args) v
180− else return $ unload env (VP Ref n ty) args
200+ else return $ unload env (VP Ref n ty) args
203+ _ -> return $ unload env f args
181− apply stk top env f (a:as) = return $ unload env f (a:as)
204+ apply ntimes stk top env f (a:as) = return $ unload env f (a:as)
182− apply stk top env f [] = return f
205+ apply ntimes stk top env f [] = return f
184− specApply stk env f@(VP Ref n ty) args
207+-- specApply stk env f@(VP Ref n ty) args
185− = case lookupCtxt Nothing n statics of
208+-- = case lookupCtxt Nothing n statics of
186− [as] -> if or as
209+-- [as] -> if or as
187− then trace (show (n, map fst (filter (\ (_, s) -> s) (zip args as)))) $
210+-- then trace (show (n, map fst (filter (\ (_, s) -> s) (zip args as)))) $
188− return $ unload env f args
211+-- return $ unload env f args
189− else return $ unload env f args
212+-- else return $ unload env f args
190− _ -> return $ unload env f args
213+-- _ -> return $ unload env f args
191− specApply stk env f args = return $ unload env f args
214+-- specApply stk env f args = return $ unload env f args
193 unload env f [] = f
216 unload env f [] = f
194 unload env f (a:as) = unload env (VApp f a) as
217 unload env f (a:as) = unload env (VApp f a) as
196− evCase stk top env ns args tree
219+ evCase ntimes stk top env ns args tree
197 | length ns <= length args
220 | length ns <= length args
198 = do let args' = take (length ns) args
221 = do let args' = take (length ns) args
199 let rest = drop (length ns) args
222 let rest = drop (length ns) args
200− t <- evTree stk top env (zipWith (\n t -> (n, t)) ns args') tree
223+ t <- evTree ntimes stk top env (zipWith (\n t -> (n, t)) ns args') tree
201 return (t, rest)
224 return (t, rest)
202 | otherwise = return (Nothing, args)
225 | otherwise = return (Nothing, args)
227+ evTree :: [(Name, Int)] -> [Name] -> Bool ->
204− evTree :: [Name] -> Bool -> [Value] -> [(Name, Value)] -> SC -> Eval (Maybe Value)
228+ [Value] -> [(Name, Value)] -> SC -> Eval (Maybe Value)
205− evTree stk top env amap (UnmatchedCase str) = return Nothing
229+ evTree ntimes stk top env amap (UnmatchedCase str) = return Nothing
206− evTree stk top env amap (STerm tm)
230+ evTree ntimes stk top env amap (STerm tm)
207 = do let etm = pToVs (map fst amap) tm
231 = do let etm = pToVs (map fst amap) tm
208− etm' <- ev stk top (map snd amap ++ env) etm
232+ etm' <- ev ntimes stk top (map snd amap ++ env) etm
209 return $ Just etm'
233 return $ Just etm'
210− evTree stk top env amap (Case n alts)
234+ evTree ntimes stk top env amap (Case n alts)
211 = case lookup n amap of
235 = case lookup n amap of
212 Just v -> do c <- chooseAlt env v (getValArgs v) alts amap
236 Just v -> do c <- chooseAlt env v (getValArgs v) alts amap
213 case c of
237 case c of
214− Just (altmap, sc) -> evTree stk top env altmap sc
238+ Just (altmap, sc) -> evTree ntimes stk top env altmap sc
215− _ -> do c' <- chooseAlt' stk env v (getValArgs v) alts amap
239+ _ -> do c' <- chooseAlt' ntimes stk env v (getValArgs v) alts amap
216 case c' of
240 case c' of
217− Just (altmap, sc) -> evTree stk top env altmap sc
241+ Just (altmap, sc) -> evTree ntimes stk top env altmap sc
218 _ -> return Nothing
242 _ -> return Nothing
219 _ -> return Nothing
243 _ -> return Nothing
221− chooseAlt' stk env _ (f, args) alts amap
245+ chooseAlt' ntimes stk env _ (f, args) alts amap
222− = do f' <- apply stk True env f args
246+ = do f' <- apply ntimes stk True env f args
223 chooseAlt env f' (getValArgs f') alts amap
247 chooseAlt env f' (getValArgs f') alts amap
225 chooseAlt :: [Value] -> Value -> (Value, [Value]) -> [CaseAlt] -> [(Name, Value)] ->
249 chooseAlt :: [Value] -> Value -> (Value, [Value]) -> [CaseAlt] -> [(Name, Value)] ->
@@ -571,7 +595,7 @@ initContext = MkContext [] 0 emptyContext
571ctxtAlist :: Context -> [(Name, Def)]
595ctxtAlist :: Context -> [(Name, Def)]
572ctxtAlist ctxt = map (\(n, (d, a, t)) -> (n, d)) $ toAlist (definitions ctxt)
596ctxtAlist ctxt = map (\(n, (d, a, t)) -> (n, d)) $ toAlist (definitions ctxt)
574−veval ctxt env t = evalState (eval ctxt emptyContext env t []) ()
598+veval ctxt env t = evalState (eval ctxt [] env t []) initEval
576addToCtxt :: Name -> Term -> Type -> Context -> Context
600addToCtxt :: Name -> Term -> Type -> Context -> Context
577addToCtxt n tm ty uctxt
601addToCtxt n tm ty uctxt