summaryrefslogtreecommitdiff
path: root/ws2015
diff options
context:
space:
mode:
authorGregor Kleen <gkleen@yggdrasil.li>2015-11-13 23:38:35 +0000
committerGregor Kleen <gkleen@yggdrasil.li>2015-11-13 23:38:35 +0000
commit14dc76bda755c850f859a4b974c793e694f2b0b4 (patch)
tree0af6195ea01f412a3c3d0df6265acc9d91d71689 /ws2015
parentd1297aee25605ebc35124023c2523ce90abbc787 (diff)
downloaduni-14dc76bda755c850f859a4b974c793e694f2b0b4.tar
uni-14dc76bda755c850f859a4b974c793e694f2b0b4.tar.gz
uni-14dc76bda755c850f859a4b974c793e694f2b0b4.tar.bz2
uni-14dc76bda755c850f859a4b974c793e694f2b0b4.tar.xz
uni-14dc76bda755c850f859a4b974c793e694f2b0b4.zip
Finished Work on A4-3
Diffstat (limited to 'ws2015')
-rw-r--r--ws2015/FFP/blaetter/04/FFP_U04_Lazy.hs116
1 files changed, 110 insertions, 6 deletions
diff --git a/ws2015/FFP/blaetter/04/FFP_U04_Lazy.hs b/ws2015/FFP/blaetter/04/FFP_U04_Lazy.hs
index b84ad0b..36c0578 100644
--- a/ws2015/FFP/blaetter/04/FFP_U04_Lazy.hs
+++ b/ws2015/FFP/blaetter/04/FFP_U04_Lazy.hs
@@ -20,6 +20,9 @@ import Data.Set (Set)
20import qualified Data.List as List ((\\)) 20import qualified Data.List as List ((\\))
21 21
22import Data.Maybe (fromMaybe) 22import Data.Maybe (fromMaybe)
23import Data.Tuple (swap)
24
25import Control.Applicative (Applicative(..), (<$>))
23 26
24---- A4-1 Verzögerte Auswertung 27---- A4-1 Verzögerte Auswertung
25-- Gegeben ist folgendes Programm: 28-- Gegeben ist folgendes Programm:
@@ -156,6 +159,8 @@ rel2S = Set.fromList . rel2
156-- Implementieren Sie die Aufgabe noch mal ganz schnell 159-- Implementieren Sie die Aufgabe noch mal ganz schnell
157-- ohne Rücksicht auf Zirkularität oder Effizienz, 160-- ohne Rücksicht auf Zirkularität oder Effizienz,
158-- sondern ganz bequem mit der Standardbibliothek für Data.Set 161-- sondern ganz bequem mit der Standardbibliothek für Data.Set
162
163-- The implementation below seems to me no nicer than a :(
159 164
160transClS :: (Ord a) => (a -> Set a) -> Set a -> Set a 165transClS :: (Ord a) => (a -> Set a) -> Set a -> Set a
161transClS rel xs = build xs Set.empty 166transClS rel xs = build xs Set.empty
@@ -283,18 +288,23 @@ evalStrict :: Term -> Term
283evalStrict t = showMem $ evalS0 t 288evalStrict t = showMem $ evalS0 t
284 289
285-- Die Funktion evalS0 ist nur eine Kurzform, um die Auswertung mit leerem Speicher zu starten: 290-- Die Funktion evalS0 ist nur eine Kurzform, um die Auswertung mit leerem Speicher zu starten:
286evalS0 ::Term -> (Memory, Term) 291evalS0 :: Term -> (Memory, Term)
287evalS0 = evalS Map.empty 292evalS0 = evalS Map.empty
288 293
289-- Ihre Aufgabe ist es also, evalS zu implementieren: 294-- Ihre Aufgabe ist es also, evalS zu implementieren:
290 295
291evalS :: Memory -> Term -> (Memory, Term) 296evalS :: Memory -> Term -> (Memory, Term)
292evalS m x@(Var v) = (,) m $ fromMaybe x $ Map.lookup v m 297evalS m x@(Var v) = (,) m $ fromMaybe x $ Map.lookup v m
293evalS m (App f x) = case f' of 298evalS m t@(App f x) = case f' of
294 (Abs v t) -> undefined 299 (Abs v t) -> let
295 t -> evalS m' t 300 usedVars = Set.unions $ (Map.keysSet m'' :) $ map freeVars $ Map.elems m''
301 v' = generateFreshVar usedVars
302 (m'', x') = evalS m' x
303 m''' = Map.insert v' x' m''
304 in evalS m''' $ subst (v,Var v') t
305 _ -> (m, t)
296 where 306 where
297 (m', f') <- evalS m f 307 (m', f') = evalS m f
298evalS m x = (m, x) 308evalS m x = (m, x)
299 309
300-- Dabei verfolgen wir folgende Auswertestrategie: 310-- Dabei verfolgen wir folgende Auswertestrategie:
@@ -339,9 +349,103 @@ evalL0 ::Term -> (Memory, Term)
339evalL0 = evalL Map.empty 349evalL0 = evalL Map.empty
340 350
341evalL :: Memory -> Term -> (Memory, Term) 351evalL :: Memory -> Term -> (Memory, Term)
342evalL = undefined -- !!! TODO !!! 352evalL m x@(Var v) = case Map.lookup v m of
353 Nothing -> (m, x)
354 Just t -> let
355 (m', t') = evalL m t
356 in (Map.insert v t' m', t')
357evalL m t@(App f x) = case f' of
358 (Abs v t) -> let
359 usedVars = Set.unions $ (Map.keysSet m' :) $ map freeVars $ Map.elems m'
360 v' = generateFreshVar usedVars
361 m'' = Map.insert v' x m'
362 in evalL m'' $ subst (v,Var v') t
363 _ -> (m, t)
364 where
365 (m', f') = evalL m f
366evalL m x = (m, x)
367
368
369
370 -- I am of the considered opinion that the above exercises call for State. Therefore:
371
372data State s a = State { unState :: s -> (a, s) }
373
374instance Functor (State s) where
375 fmap f (State g) = State ((\(a, s) -> (f a, s)) . g)
376
377instance Applicative (State s) where
378 pure a = State (\s -> (a, s))
379 (State f) <*> (State g) = State (\s -> (\(g', s) -> (\(f', s') -> (f' g', s')) $ f s) $ g s)
380
381instance Monad (State s) where
382 return = pure
383 (State f) >>= g = State ((\(a, s) -> (unState $ g a) s) . f)
343 384
385get :: State s s
386get = State (\s -> (s, s))
344 387
388put :: s -> State s ()
389put s = State (\_ -> ((), s))
390
391modify :: (s -> s) -> State s ()
392modify f = (f <$> get) >>= put
393
394evalStrict' :: Term -> Term
395evalStrict' t = showMem $ evalS0' t
396 where
397 evalS0' = evalS' Map.empty
398
399evalLazy' :: Term -> Term
400evalLazy' t = showMem $ evalL0' t
401 where
402 evalL0' = evalL' Map.empty
403
404evalS' :: Memory -> Term -> (Memory, Term)
405evalS' m t = swap $ (unState $ eval t) m
406 where
407 eval :: Term -> State Memory Term
408 eval t@(Var v) = (fromMaybe t . Map.lookup v) <$> get
409 eval t@(App f x) = do
410 f' <- eval f
411 case f' of
412 (Abs v t) -> do
413 x' <- eval x
414 mem <- get
415 let
416 boundInTerms = Set.unions . map freeVars $ Map.elems mem
417 usedVars = boundInTerms `Set.union` Map.keysSet mem
418 v' = generateFreshVar usedVars
419 modify $ Map.insert v' x'
420 eval $ subst (v, Var v') t
421 _ -> pure t
422 eval t = pure t
423
424evalL' :: Memory -> Term -> (Memory, Term)
425evalL' m t = swap $ (unState $ eval t) m
426 where
427 eval :: Term -> State Memory Term
428 eval t@(Var v) = do
429 t' <- Map.lookup v <$> get
430 case t' of
431 Nothing -> return t
432 Just t -> do
433 t' <- eval t
434 modify $ Map.insert v t'
435 return t'
436 eval t@(App f x) = do
437 f' <- eval f
438 case f' of
439 (Abs v t) -> do
440 mem <- get
441 let
442 boundInTerms = Set.unions . map freeVars $ Map.elems mem
443 usedVars = boundInTerms `Set.union` Map.keysSet mem
444 v' = generateFreshVar usedVars
445 modify $ Map.insert v' x
446 eval $ subst (v, Var v') t
447 _ -> pure t
448 eval t = pure t
345 449
346----------------------------------------------------------------------- 450-----------------------------------------------------------------------
347-- ANHANG 451-- ANHANG