diff options
| author | Gregor Kleen <gkleen@yggdrasil.li> | 2015-11-13 23:38:35 +0000 |
|---|---|---|
| committer | Gregor Kleen <gkleen@yggdrasil.li> | 2015-11-13 23:38:35 +0000 |
| commit | 14dc76bda755c850f859a4b974c793e694f2b0b4 (patch) | |
| tree | 0af6195ea01f412a3c3d0df6265acc9d91d71689 | |
| parent | d1297aee25605ebc35124023c2523ce90abbc787 (diff) | |
| download | uni-14dc76bda755c850f859a4b974c793e694f2b0b4.tar uni-14dc76bda755c850f859a4b974c793e694f2b0b4.tar.gz uni-14dc76bda755c850f859a4b974c793e694f2b0b4.tar.bz2 uni-14dc76bda755c850f859a4b974c793e694f2b0b4.tar.xz uni-14dc76bda755c850f859a4b974c793e694f2b0b4.zip | |
Finished Work on A4-3
| -rw-r--r-- | ws2015/FFP/blaetter/04/FFP_U04_Lazy.hs | 116 |
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) | |||
| 20 | import qualified Data.List as List ((\\)) | 20 | import qualified Data.List as List ((\\)) |
| 21 | 21 | ||
| 22 | import Data.Maybe (fromMaybe) | 22 | import Data.Maybe (fromMaybe) |
| 23 | import Data.Tuple (swap) | ||
| 24 | |||
| 25 | import 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 | ||
| 160 | transClS :: (Ord a) => (a -> Set a) -> Set a -> Set a | 165 | transClS :: (Ord a) => (a -> Set a) -> Set a -> Set a |
| 161 | transClS rel xs = build xs Set.empty | 166 | transClS rel xs = build xs Set.empty |
| @@ -283,18 +288,23 @@ evalStrict :: Term -> Term | |||
| 283 | evalStrict t = showMem $ evalS0 t | 288 | evalStrict 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: |
| 286 | evalS0 ::Term -> (Memory, Term) | 291 | evalS0 :: Term -> (Memory, Term) |
| 287 | evalS0 = evalS Map.empty | 292 | evalS0 = 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 | ||
| 291 | evalS :: Memory -> Term -> (Memory, Term) | 296 | evalS :: Memory -> Term -> (Memory, Term) |
| 292 | evalS m x@(Var v) = (,) m $ fromMaybe x $ Map.lookup v m | 297 | evalS m x@(Var v) = (,) m $ fromMaybe x $ Map.lookup v m |
| 293 | evalS m (App f x) = case f' of | 298 | evalS 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 |
| 298 | evalS m x = (m, x) | 308 | evalS 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) | |||
| 339 | evalL0 = evalL Map.empty | 349 | evalL0 = evalL Map.empty |
| 340 | 350 | ||
| 341 | evalL :: Memory -> Term -> (Memory, Term) | 351 | evalL :: Memory -> Term -> (Memory, Term) |
| 342 | evalL = undefined -- !!! TODO !!! | 352 | evalL 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') | ||
| 357 | evalL 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 | ||
| 366 | evalL m x = (m, x) | ||
| 367 | |||
| 368 | |||
| 369 | |||
| 370 | -- I am of the considered opinion that the above exercises call for State. Therefore: | ||
| 371 | |||
| 372 | data State s a = State { unState :: s -> (a, s) } | ||
| 373 | |||
| 374 | instance Functor (State s) where | ||
| 375 | fmap f (State g) = State ((\(a, s) -> (f a, s)) . g) | ||
| 376 | |||
| 377 | instance 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 | |||
| 381 | instance Monad (State s) where | ||
| 382 | return = pure | ||
| 383 | (State f) >>= g = State ((\(a, s) -> (unState $ g a) s) . f) | ||
| 343 | 384 | ||
| 385 | get :: State s s | ||
| 386 | get = State (\s -> (s, s)) | ||
| 344 | 387 | ||
| 388 | put :: s -> State s () | ||
| 389 | put s = State (\_ -> ((), s)) | ||
| 390 | |||
| 391 | modify :: (s -> s) -> State s () | ||
| 392 | modify f = (f <$> get) >>= put | ||
| 393 | |||
| 394 | evalStrict' :: Term -> Term | ||
| 395 | evalStrict' t = showMem $ evalS0' t | ||
| 396 | where | ||
| 397 | evalS0' = evalS' Map.empty | ||
| 398 | |||
| 399 | evalLazy' :: Term -> Term | ||
| 400 | evalLazy' t = showMem $ evalL0' t | ||
| 401 | where | ||
| 402 | evalL0' = evalL' Map.empty | ||
| 403 | |||
| 404 | evalS' :: Memory -> Term -> (Memory, Term) | ||
| 405 | evalS' 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 | |||
| 424 | evalL' :: Memory -> Term -> (Memory, Term) | ||
| 425 | evalL' 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 |
