@@ -87,7 +87,9 @@ normaliseTrace tr ctxt env t
88specialise :: Context -> Env -> [(Name, Int)] -> TT Name -> TT Name
88specialise :: Context -> Env -> [(Name, Int)] -> TT Name -> TT Name
89specialise ctxt env limits t
89specialise ctxt env limits t
90− = evalState (do val <- eval False ctxt limits (map finalEntry env) (finalise t) []
90+ = evalState (do val <- eval False ctxt []
91+ (map finalEntry env) (finalise t)
91 quote 0 val) (initEval { limited = limits })
93 quote 0 val) (initEval { limited = limits })
93-- | Like normalise, but we only reduce functions that are marked as okay to
95-- | Like normalise, but we only reduce functions that are marked as okay to
@@ -125,18 +127,38 @@ unbindEnv :: EnvTT n -> TT n -> TT n
125unbindEnv [] tm = tm
127unbindEnv [] tm = tm
126unbindEnv (_:bs) (Bind n b sc) = unbindEnv bs sc
128unbindEnv (_:bs) (Bind n b sc) = unbindEnv bs sc
128−usable :: Bool -> Name -> [(Name, Int)] -> (Bool, [(Name, Int)])
130+usable :: Bool -> Bool -> Name -> [(Name, Int)] -> Eval (Bool, [(Name, Int)])
129−usable _ _ ns@((MN 0 "STOP", _) : _) = (False, ns)
131+usable _ _ _ ns@((MN 0 "STOP", _) : _) = return (False, ns)
130−usable True (UN "io_bind") ns = (False, ns)
132+usable True _ (UN "io_bind") ns = return (False, ns)
131−usable s n [] = (True, [])
133+usable simpl False n [] = return (True, [])
134+usable simpl True n ns
135+ = do ES ls num <- get
137+ Just 0 -> return (False, ns)
138+ Just i -> return (True, ns)
139+ _ -> return (True, ns)
140+usable simpl False n ns
132−usable s n ns = case lookup n ns of
141+ = case lookup n ns of
133− Just 0 -> (False, ns)
142+ Just 0 -> return (False, ns)
134− Just i -> (True, (n, abs (i-1)) : filter (\ (n', _) -> n/=n') ns)
143+ Just i -> return $ (True, (n, abs (i-1)) : filter (\ (n', _) -> n/=n') ns)
135− _ -> if s then (True, (n, 0) : filter (\ (n', _) -> n/=n') ns)
144+ _ -> if simpl then return $ (True, (n, 0) : filter (\ (n', _) -> n/=n') ns)
136− else (True, (n, 100) : filter (\ (n', _) -> n/=n') ns)
145+ else return $ (True, (n, 100) : filter (\ (n', _) -> n/=n') ns)
148+deduct :: Name -> Eval ()
149+deduct n = do ES ls num <- get
151+ Just i -> do put $ ES ((n, (i-1)) :
152+ filter (\ (n', _) -> n/=n') ls) num
138-- | Evaluate in a context of locally named things (i.e. not de Bruijn indexed,
155-- | Evaluate in a context of locally named things (i.e. not de Bruijn indexed,
139-- such as we might have during construction of a proof)
156-- such as we might have during construction of a proof)
158+-- The (Name, Int) pair in the arguments is the maximum depth of unfolding of
159+-- a name. The corresponding pair in the state is the maximum number of
160+-- unfoldings overall.
140eval :: Bool -> Context -> [(Name, Int)] -> Env -> TT Name ->
162eval :: Bool -> Context -> [(Name, Int)] -> Env -> TT Name ->
141 [EvalOpt] -> Eval Value
163 [EvalOpt] -> Eval Value
142eval traceon ctxt ntimes genv tm opts = ev ntimes [] True [] tm where
164eval traceon ctxt ntimes genv tm opts = ev ntimes [] True [] tm where
@@ -153,23 +175,27 @@ eval traceon ctxt ntimes genv tm opts = ev ntimes [] True [] tm where
153 | Just (Let t v) <- lookup n genv = ev ntimes stk top env v
175 | Just (Let t v) <- lookup n genv = ev ntimes stk top env v
154 ev ntimes_in stk top env (P Ref n ty)
176 ev ntimes_in stk top env (P Ref n ty)
155 | not top && hnf = liftM (VP Ref n) (ev ntimes stk top env ty)
177 | not top && hnf = liftM (VP Ref n) (ev ntimes stk top env ty)
156− | (True, ntimes) <- usable simpl n ntimes_in
179+ = do (u, ntimes) <- usable simpl spec n ntimes_in
157− = do let val = lookupDefAcc n atRepl ctxt
181+ do let val = lookupDefAcc n atRepl ctxt
158− case val of
182+ case val of
159− [(Function _ tm, Public)] ->
183+ [(Function _ tm, Public)] ->
160− ev ntimes (n:stk) True env tm
184+ ev ntimes (n:stk) True env tm
161− [(TyDecl nt ty, _)] -> do vty <- ev ntimes stk True env ty
185+ [(TyDecl nt ty, _)] -> do vty <- ev ntimes stk True env ty
162− return $ VP nt n vty
186+ return $ VP nt n vty
163− [(CaseOp inl inr _ _ _ [] tree _ _, acc)]
187+ [(CaseOp inl inr _ _ _ [] tree _ _, acc)]
164− | acc == Public || simpl -> -- unoptimised version
188+ | acc == Public || simpl -> -- unoptimised version
165− if canSimplify inl inr n stk
189+ if canSimplify inl inr n stk
166− then liftM (VP Ref n) (ev ntimes stk top env ty)
190+ then liftM (VP Ref n) (ev ntimes stk top env ty)
167− else do c <- evCase ntimes (n:stk) top env [] [] tree
191+ else do c <- evCase ntimes n (n:stk) top env [] [] tree
168− case c of
192+ case c of
169− (Nothing, _) -> liftM (VP Ref n) (ev ntimes stk top env ty)
193+ (Nothing, _) -> liftM (VP Ref n) (ev ntimes stk top env ty)
170− (Just v, _) -> return v
194+ (Just v, _) -> return v
171− _ -> liftM (VP Ref n) (ev ntimes stk top env ty)
195+ _ -> liftM (VP Ref n) (ev ntimes stk top env ty)
196+ else liftM (VP Ref n) (ev ntimes stk top env ty)
197+ ev ntimes stk top env (P nt n ty)
172− ev ntimes stk top env (P nt n ty) = liftM (VP nt n) (ev ntimes stk top env ty)
198+ = liftM (VP nt n) (ev ntimes stk top env ty)
173 ev ntimes stk top env (V i)
199 ev ntimes stk top env (V i)
174 | i < length env && i >= 0 = return $ env !! i
200 | i < length env && i >= 0 = return $ env !! i
175 | otherwise = return $ VV i
201 | otherwise = return $ VV i
@@ -228,27 +254,31 @@ eval traceon ctxt ntimes genv tm opts = ev ntimes [] True [] tm where
228 | not top && hnf = case args of
254 | not top && hnf = case args of
229 [] -> return f
255 [] -> return f
230 _ -> return $ unload env f args
256 _ -> return $ unload env f args
231− | (True, ntimes) <- usable simpl n ntimes_in
258+ = do (u, ntimes) <- usable simpl spec n ntimes_in
232− = traceWhen traceon (show stk) $
259+ if u then
233− do let val = lookupDefAcc n atRepl ctxt
260+ do let val = lookupDefAcc n atRepl ctxt
234− case val of
261+ case val of
235− [(CaseOp inl inr _ _ _ ns tree _ _, acc)]
262+ [(CaseOp inl inr _ _ _ ns tree _ _, acc)]
236− | acc == Public -> -- unoptimised version
263+ | acc == Public -> -- unoptimised version
237− if canSimplify inl inr n stk
264+ if canSimplify inl inr n stk
238− then return $ unload env (VP Ref n ty) args
265+ then return $ unload env (VP Ref n ty) args
239− else do c <- evCase ntimes (n:stk) top env ns args tree
266+ else do c <- evCase ntimes n (n:stk) top env ns args tree
240− case c of
267+ case c of
241− (Nothing, _) -> return $ unload env (VP Ref n ty) args
268+ (Nothing, _) -> return $ unload env (VP Ref n ty) args
242− (Just v, rest) -> evApply ntimes stk top env rest v
269+ (Just v, rest) -> evApply ntimes stk top env rest v
243− [(Operator _ i op, _)] ->
270+ [(Operator _ i op, _)] ->
244− if (i <= length args)
271+ if (i <= length args)
245− then case op (take i args) of
272+ then case op (take i args) of
246− Nothing -> return $ unload env (VP Ref n ty) args
273+ Nothing -> return $ unload env (VP Ref n ty) args
247− Just v -> evApply ntimes stk top env (drop i args) v
274+ Just v -> evApply ntimes stk top env (drop i args) v
248− else return $ unload env (VP Ref n ty) args
275+ else return $ unload env (VP Ref n ty) args
249− _ -> case args of
276+ _ -> case args of
250− [] -> return f
277+ [] -> return f
251− _ -> return $ unload env f args
278+ _ -> return $ unload env f args
280+ (a : as) -> return $ unload env f (a:as)
252 apply ntimes stk top env f (a:as) = return $ unload env f (a:as)
282 apply ntimes stk top env f (a:as) = return $ unload env f (a:as)
253 apply ntimes stk top env f [] = return f
283 apply ntimes stk top env f [] = return f
@@ -264,10 +294,11 @@ eval traceon ctxt ntimes genv tm opts = ev ntimes [] True [] tm where
264 unload env f [] = f
294 unload env f [] = f
265 unload env f (a:as) = unload env (VApp f a) as
295 unload env f (a:as) = unload env (VApp f a) as
267− evCase ntimes stk top env ns args tree
297+ evCase ntimes n stk top env ns args tree
268 | length ns <= length args
298 | length ns <= length args
269 = do let args' = take (length ns) args
299 = do let args' = take (length ns) args
270 let rest = drop (length ns) args
300 let rest = drop (length ns) args
301+ when spec $ deduct n -- successful, so deduct usages
271 t <- evTree ntimes stk top env
302 t <- evTree ntimes stk top env
272 (zipWith (\n t -> (n, t)) ns args') tree
303 (zipWith (\n t -> (n, t)) ns args') tree
273 return (t, rest)
304 return (t, rest)