All pastes #341494 Raw Edit

Anonymous

public text v1 · immutable
·published 2007-02-05 18:02 UTC
rendered paste body
Alp Vorl 5.2.07
Verzögerte Auswertung (Lazy Evaluation)
---------------------------------------

square x = x * x
> square (3+4) = (3+4) * (3+4) = 7 * (3+4) = 7*7 = 49 -- leftmost-outermost
> square (3+4) = square 7 = 7 * 7 = 49                -- leftmost-innermost
Church Rosser Theorem: Die Reihenfolge der Auswertung hat keine Auswirkung auf
das Ergebnis, ausser das gegebenfalls eine Auswertung nicht zum Ergebnis führt

Wenn leftmostinnermost zum Ergebnis führt, ist dies i.a. schneller
Normalisierungsrek. Wenn ein Ausdruck A ein Ergebnis hat, dann lässt sich dies durch
leftmostoutermost - Strategie gewinnen

Bsp:  one x = 1
          y = y             -- wenn man reduziert leftmostoutermost, one y und nehmen definition von one
l.o.: one y = 1             -- wird y nicht ausgerechnet, und ergebnis ist 1
l.i.: one y = one y = ...   -- leftmostinnermost zwingt das system erst das argument auszurechnen,
                            -- wird durch rechte seite errechnet, so eine endlose berechnung,
                            -- zwischenergebnisse sind nicht falsch
Gesucht: Sichere Strategie, die keine unnötigen Reduktionen macht!
Idee: Stelle Ausdrücke nicht durch Bäume sondern Graphen dar
-- (3+4) * (3+4) =
         *               @         @
        / \             / \   =>  / \
        \ /        square  x     @  |
         +                      / \ /
        / \                    *   x
       3  4

Definierende Gleichungen werden durch Graphtransformationen ersetzt.
Lazy Evaluation verwendet die lo-Strategie über Graphen, dadurch ist sie sicher.
Wenn ein Argument ausgewertet werden muss, dann ein für alle mal
Bsp: f :: [Int] -> Int
     f [] = 0
     f (x:xs) = 1
   nats = [1..]   -- natürliche zahlen, > take n nats
   ones = 1:ones
l.i. > f nats
l.i. > f ones = f (1:ones) = f (1:(1:ones)) = ..
lazy > f ones = 1
-- dadurch unendliche listen sinnvoll verwendbar
-- mit l.i. niemals unendliche dynamische datenstrukturen verwenden, terminiert nicht
-- mit l.o., lazyevaluation macht es mehr sinn

Erzeuge Primzahlen:
Eine Zahl p ist primzahl, g.d.w p nur durch 1 + sich selbst teilbar ist

teilbar :: Int -> Int -> Bool
p `teilbar` z = p `mod` z => 0

prim :: Int -> Bool
prim p = not ( or [p `teilbar` z | z <- [2..p-1]])

primes :: [Int]
primes = [p | p <- [2..], prim p]

Sieb des Erastothemes:

2,3,4,5,6,7,8,9,10,11,12,13,...
-- alle vielfachen der ersten gefunden wegwerfen
-- von nächster zahl alle vielfachen weg usw

primes :: [Int]
primes = sieve [2..]
sieve (p:xs) = p:sieve [x|x<-xs, x `mod` p /= 0 ]
> primes = sieve [2..] = 2:sieve [x|x<-[3..], x `mod` 2 /=0 ]
-- lazy evaulation führt dazu das sieve wieder reduziert wird
         = 2:sieve (3: [x|x<-[4..], x `mod` 2 /= 0])= 2:3:sieve([y|y<-xs, y `mod` 3 /= 0])