Programmierung
Sommer 2022
Meine Übungen am
  • Montag von 1300 bis 1430 Uhr (4. DS) im Raum APB/E006
  • Mittwoch von 1110 bis 1240 Uhr (3. DS) im Raum HSZ/0108
starten ab 11. April 2022. Die Einschreibung findet via OPAL statt.

Inhalte der Übungen

Im Rahmen der zur Lehrveranstaltung gehörenden Übungen wenden wir das in der Vorlesung erlernte Wissen an und versuchen die Theorie an Beispielen zu illustrieren:

  • Grundlagen der funktionalen Programmierung in Haskell
  • Unifikationsalgorithmus
  • Beweis von Programmeigenschaften mit struktureller Induktion
  • Lambda-Kalkül
  • Logikprogrammierung in Prolog
  • Abstrakte Maschinen AM0 und AM1 sowie deren Übersetzung von/nach C
  • Beweis von Programmeigenschaften mit dem Hoare-Kalkül
  • Abstrakte Maschinen mit Haskell

News

  • 19.04.2022: Die am Ostermontag ausgefallene Übung 2 wird am Mittwoch, dem 20.04.2022 von 13 Uhr bis 14.30 Uhr (4. Doppelstunde) im Georg-Schumann-Bau Raum SCH/A419 nachgeholt. Informiert euch bitte im Campus-Navigator, wie ihr zu diesem Raum findet - der Schumann-Bau ist da manchmal etwas tückisch.
  • 30.03.2022: Herzlich Willkommen im Kurs "Programmierung" im Sommersemester 2022. Die Übungen starten ab dem 11.04.2022 in Präsenz.
    • Montag von 1300 bis 1430 Uhr (4. DS) im APB/E006
    • Mittwoch von 1110 bis 1240 Uhr (3. DS) im HSZ/0108
    Die Einschreibung findet via OPAL statt.

Ich bemühe mich stets euch das Lernen so angenehm, unterhaltsam und einfach wie möglich zu machen. Das ist mein eigener Anspruch und dafür opfere ich auch gern mal meine Freizeit. Ein Beispiel, wofür relativ viel Zeit drauf gegangen ist, seht ihr gerade vor euren Augen: diese Website. Sie ist sicher nicht perfekt und sicher auch nicht notwendig, um euch eine Übung zu bieten. Ebenso ensteht mein ganzes Material wie Slides und Mitschriften nicht mal eben so. Vielleicht hat der ein oder andere schon erkannt, worauf es hinaus laufen soll: wenn du Lust und das nötige Kleingeld dafür hast, würde ich mich sehr freuen, wenn du meine Arbeit unterstützt und mir vielleicht einen Kaffee oder ein Mensaessen spendierst. Aber versteht mich bitte nicht falsch: ich mache das alles wirklich super gerne und habe auch meinen Spaß daran - und Geld wird auf meine Arbeit nie einen Einfluss haben. Und ja, für meine Tutorentätigkeit werde ich auch als studentische Hilfskraft bezahlt - mit vier bzw. fünf Stunden für zwei Übungen deckt das aber gerade einmal die Übungszeit und ein wenig Vorbereitung ab.

Informationen

Alle für die Lehrveranstaltungen relevanten Informationen findet ihr im OPAL-Kurs. Die Vorlesung wird in diesem Semester nicht mehr als Video bereitgestellt, sondern findet jeden Freitag (ab 8. April 2022) von 920 Uhr bis 1050 online via Zoom statt. Es wird keine Aufzeichnungen geben. Den Zugangslink findet ihr im OPAL-Kurs im Baustein "Vorlesungen". Bei Fragen oder Problemen könnt ihr euch an mich oder an Thomas Ruprecht wenden. Mich erreicht ihr auch schnell und problemlos via Telegram @oakoneric.

Übungsmaterial

Vom Lehrstuhl werden die in der Vorlesung verwendeten Slides sowie eine Aufgabensammlung zur Verfügung gestellt. Diese Materialien sind nur aus dem TU-Netz erreichbar, d.h. ihr müsst dafür ggf. eine VPN-Verbindung verwenden. Für die verlinkten Materialien vom Lehrstuhl gelten die entsprechenden Hinweise im OPAL-Kurs.

Slides    Aufgabensammlung

Die in meinen Übungen verwendeten Materialien habe ich größtenteils in meiner Freizeit erstellt. Sie stammen insbesondere nicht vom Lehrstuhl und können damit trotz gründlicher Arbeit noch Fehler enthalten. Die Folien sollen keineswegs den aktiven Besuch der Übungen ersetzen, sondern vielmehr eine Hilfestellung sein um sich während der Übung auf das Verständnis konzentrieren zu können und das Nacharbeiten zu erleichtern. Die Slides und den zugehörigen Latex-Code dazu findet ihr in meinem entsprechenden Github-Repository. Findet ihr einen Fehler in meinen Lösungen, dann fühlt euch eingeladen mir dies mitzuteilen oder direkt selbst mit einem Request zu beheben.

Einen Eindruck der Übungen könnt ihr euch anhand des letzten Durchlaufes im Sommersemester 2021 machen. Damals musste ein großer Teil der Übungen online stattfinden - diese Übungen existieren auch als Video. Kontaktiert mich, wenn ihr die Zugangsdaten dafür benötigt.

Klausurvorbereitung

Zur Klausurvorbereitung findet ihr auf dem FTP-Server vom iFSR einige Altklausuren. Ihr benötigt dafür eine VPN-Verbindung ins Uni-Netz.

Übungsübersicht

Im Folgenden findet ihr das gesamte Material meiner Übungen und den Vorlesungsinhalten. Vorlesungsmaterialien sind urheberrechtlich seitens der Professur geschützt und keinsweg mein Eigentum. Es sind die Hinweise im OPAL-Kurs einzuhalten.

Teil 1: Funktionale Programmierung

Leider haben wir in den Übungen nicht die Zeit um allen einen funktionsfähigen Compiler und ein optimales Setup zu garantieren. Wie immer sind natürliche Google und YouTube sehr gute Quellen für Hilfe. Im Zweifelsfall hilft euch sicher auch der iFSR. Außerdem habe ich euch einige Hinweise zusammengetragen:

Für das Selbststudium gibt es zwei sehr gute Bücher, die ich euch empfehlen möchte. Beide Bücher sind frei online verfügbar, sogar ohne VPN und ohne SLUB-Zugang.

  • Learn You a Haskell For Great Good! Ein sehr gut geschriebenes Buch, kann ich nur empfehlen einmal reinzusehen. Erklärt sehr ausführlich und kurzweilig. Damit sollte jeder Haskell verstehen können. Eine Online-Version des Buches findet ihr hier.
  • Real World Haskell Ebenso ein sehr gutes Buch, deckt aber wesentlich mehr Inhalte ab, als wir brauchen werden. Die Online-Version gibt's hier.
Woche 1: Einführung in Haskell
11.04. bis 15.04.2022
  • Übungsblatt 1
  • Lösungen
    • Aufgabe 1: siehe Slides
    • Aufgabe 2

      Wir berechnen die Fakultät \(n! = \prod_{i=1}^n i\).

      -- Aufgabe 2(a)
      fac :: Int -> Int
      fac 0 = 1
      fac n = n * fac (n-1)

      Wir summieren Fakultäten auf, d.h. berechnen \(\operatorname{sumFacs}(n,m) = \sum_{i=n}^m i!\). Dabei können wir wahlweise die obere Grenze oder die untere Grenze "rausziehen".

      -- Aufgabe 2(b)
      sumFacs :: Int -> Int -> Int
      sumFacs n m
        | n > m = 0
        | otherwise = fac n + sumFacs (n+1) m
      
      sumFacs' :: Int -> Int -> Int
      sumFacs' n m
        | n > m = 0
        | otherwise = fac m + sumFacs' n (m-1)
    • Aufgabe 3

      Wir berechnen die Fibonacci-Zahlen und nutzen dafür die bereits gegebene Rekursionsvorschrift \(f_n = f_{n-1} + f_{n-2}\) mit den Startwerten \(f_0 = 1\) und \(f_1 = 1\).

      fib :: Int -> Int
      fib 0 = 1
      fib 1 = 1
      fib n = fib (n-1) + fib (n-2)

      Wenn man mittels :set +s die Laufzeitmessung in GHCi aktiviert und fib n für große n versucht zu berechnen, wird man feststellen, dass das sehr lange dauert. Daher kann man eine alternative Variante implementieren, die drei "Speicherplätze" nutzt und somit ein iteratives Verfahren nachahmt (vgl. Slides).

      fib' :: Int -> Int
      fib' n = fib_help 1 1 n
      
      fib_help :: Int -> Int -> Int -> Int
      fib_help x _ 0 = x
      fib_help x y n = fib_help y (x+y) (n-1)
Woche 2: Listen
19.04. bis 22.04.2022
  • Die Montag-Übung am 18.04.2022 findet wegen des Ostermontags nicht statt. Die Übung wird für diese Gruppe stattdessen am Mittwoch, dem 20.04.2022 von 13 Uhr bis 14.30 Uhr (4. Doppelstunde) im Georg-Schumann-Bau Raum SCH/A419 abgehalten.
  • Übungsblatt 2
  • Lösungen
    • Aufgabe 1

      Wir berechnen den Binomialkoeffizienten \(\binom{n}{k} = \frac{n!}{k! \ (n-k)!}\). Man beachte dabei, dass die Integer-Division in Haskell mit der Funktion div erfolgen muss. Man kann die Funktion durch `div` auch in Infixnotation zwischen die Operanten schreiben.

      bincoeff :: Int -> Int -> Int
      bincoeff n k = fac n ‘div‘ (fac (n-k) * fac k)
          where
              fac n
                  | n < 1     = 1
                  | otherwise = n * fac (n-1)
    • Aufgabe 2
      1. Produkt einer Liste
        prod :: [Int] -> Int
        prod []     = 1
        prod (x:xs) = x * prod xs
      2. eine Liste umkehren
        rev :: [Int] -> [Int]
        rev [] = []
        rev (x:xs) = rev xs ++ [x]
      3. Elemente einer Liste löschen
        excl :: Int -> [Int] -> [Int]
        excl _  []    = []
        excl y (x:xs)
            | x == y    = excl y xs
            | otherwise = x : excl y xs
      4. Sortierung einer Liste prüfen
        isOrd' :: [Int] -> Bool
        isOrd' [] = True
        isOrd' [x] = True
        isOrd' (x:y:xs) = x <= y && isOrd' (y:xs)
      5. (sortierte) Listen zusammenfügen
        merge :: [Int] -> [Int] -> [Int]
        merge [] ys = ys
        merge xs [] = xs
        merge (x:xs) (y:ys)
          | x < y = x : merge xs (y:ys)
          | otherwise = y : merge (x:xs) ys
      6. (unendliche) Liste der Fibonacci-Zahlen
        fib :: Int -> Int
        fib 0 = 1
        fib 1 = 1
        fib n = fib (n-1) + fib (n-2)
        
        fib' :: Int -> Int
        fib' i = stack 1 1 i
            where 
                stack f0 f1 0 = f0
                stack f0 f1 i = stack f1 (f0 + f1) (i-1)
        
        fibs :: [Int]
        fibs = fibAppend 0
        where fibAppend x = fib x : fibAppend (x+1)
        
        fibs' :: [Int]
        fibs' = fib_stack 1 1
            where
              fib_stack x y =  x : fib_stack y (x+y)

        Testen kann man diese Funktion beispielsweise mittels take 7 fibs, was uns die ersten sieben Fibonacci-Zahlen zurückgibt. take ist dabei eine Funktion aus der Standard-Bibliothek Prelude vom Typ take :: Int -> [Int] -> [Int], siehe auch hier. Man kann nun zwischen den beiden Varianten fibs und fibs' umschalten und die Laufzeitunterschiede vergleichen.

    • Zusatzaufgabe

      Die Collatz-Folge ist eine relativ einfach definierte Folge, deren Verhalten aber erstaunlich wenig erforscht ist. Die sogenannte Collatz-Vermutung geht davon aus, dass - egal welchen Startwert man wählt - man irgendwann stets in einen Zyklus \( 1 \to 4 \to 2 \to 1\) kommt. Dementsprechend sind wir in dieser Aufgabe auf der Suche nach dem Index, für den wir in diesen Zyklus einsteigen. Mehr Informationen erfahrt ihr in folgendem Video.

      cnext :: Int -> Int
      cnext n
          | n `mod` 2 == 0 = n `div` 2
          | otherwise      = 3 * n + 1
      
      ck :: Int -> Int
      ck 1 = 1
      ck n = 1 + ck (cnext n)
      
      cmax :: Int -> Int
      cmax 0 = 0
      cmax n = max (cmax (n-1)) (ck n) -- oder cmax (n-1) ‘max‘ ck n
          where max a b
              | a > b     = a
              | otherwise = b
      
      collatz :: Int -> [Int]
      collatz 1 = [1]
      collatz n = n : collatz (cnext n)
Woche 3: Zeichenketten & Bäume
25.04. bis 29.04.2022
  • Übungsblatt 3
  • Lösungen
    • Aufgabe 1
      1. Präfix-Test
        isPrefix :: String -> String -> Bool
        isPrefix [] _ = True
        isPrefix _ [] = False
        isPrefix (p:ps) (c:cs) = p == c && isPrefix ps cs
      2. Vorkommen eines Patterns zählen
        countPattern :: String -> String -> Int
        countPattern "" "" = 1
        countPattern _  "" = 0
        countPattern ps ccs@(c:cs)
            | isPrefix ps ccs = 1 + countPattern ps cs
            | otherwise       = countPattern ps cs
    • Aufgabe 2
      1. Beispielbaum
        mytree :: BinTree
        mytree = Branch 0 
                  ( Nil )
                  ( Branch 3 
                    ( Branch 1 Nil Nil )
                    ( Branch 5 Nil Nil )
                  )
      2. Test auf Baumgleichheit
        equal :: BinTree -> BinTree -> Bool
        equal Nil              Nil              = True
        equal Nil              (Branch y l2 r2) = False
        equal (Branch x l1 r1) Nil              = False
        equal (Branch x l1 r1) (Branch y l2 r2) = (x == y) && (equal l1 l2) && (equal r1 r2)
      3. Schlüssel in einen (Such-)Baum einfügen
        insert :: BinTree -> [Int] -> BinTree
        insert t     [] = t
        insert t (n:ns) = insert t' ns
          where
            t' = insertSingle t n
            insertSingle Nil            n = Branch n Nil Nil
            insertSingle (Branch x l r) n
              | n < x     = Branch x (insertSingle l n) r
              | otherwise = Branch x l                  (insertSingle r n)
      4. Levelorder-Traversierung
        unwind :: BinTree -> [Int]
        unwind t = go [t]
          where
              go []                  = []
              go ( Nil           : ts) = go ts
              go ((Branch x l r) : ts) = x : go (ts ++ [l,r])
Woche 4: Funktionen höherer Ordnung & Typpolymorphie
02.05. bis 06.05.2022
  • Übungsblatt 4
  • Lösungen
    • Aufgabe 1

      Produkt der Quadratzahlen aller geraden Elemente einer Liste

      f :: [Int] -> Int
      f xs = foldr product 1 (map square (filter even' xs))
        where
          even' x = mod x 2 == 0
          square x = x * x
          product x y = x * y
      
      f' :: [Int] -> Int
      f' xs = foldr (*) 1 (map (^2) (filter even xs))
      
      f'' :: [Int] -> Int
      f'' = foldr (*) 1 . map (^2) . filter even
      
      f''' :: [Int] -> Int
      f''' = foldr (*) 1 . map (^2) . filter ((== 0) . (`mod` 2))

      Hinweise: In Haskell werden Funktionen, die in Infix (also zwischen den Argumenten, z.B. +, -, /, ==, &&) benutzt werden, in Klammern notiert (z.B. (+) :: Int -> Int -> Int). D.h. Operatoren werden wie alle anderen Funktionen behandelt, wenn man sie klammert, z.B. in (+) 2 1 == 3. Andere Funktionen können auch Infix benutzt werden, indem sie durch Backticks `...` umgeben werden, z.B. 5 `mod` 2 == 1 statt mod 5 2 == 1. Mittels partieller Applikation kann man bei Infixfunktionen einen Wert an den zweiten (rechten) Operanden binden, so ist `mod` 2 beispielsweise eine Funktion, die für alle Eingabewerte den Restbetrag der Division durch 2 berechnet. Der Operator . ist die Funktionskomposition, also berechet (== 0) . (`mod` 2) zuerst den Restbetrag der Division durch 2 und testet diesen Wert dann der Gleichheit mit 0. Die entstehende Funktion gibt also genau für alle geraden Eingabewerte den Wert True zurück.

    • Aufgabe 2

      Liste von links falten

      foldleft :: (Int -> Int -> Int) -> Int -> [Int] -> Int
      foldleft f x []     = x
      foldleft f x (y:ys) = foldleft f (f x y) ys

      Die Funktion ist als foldl in der Standarbibliothek Prelude enthalten.

    • Aufgabe 3
      1. Beispielbaum
        mytree :: Tree Char
        mytree = Node ’a’ [ 
                    Node ’b’ [ Node ’c’ [], Node ’d’ [] ] ,
                    Node ’e’ [ Node ’f’ [] ],
                    Node ’g’ []
                  ]
      2. Baum auf ungerade Anzahl an Kindern testen
        oddTree :: Tree a -> Bool
        oddTree (Node _ []) = True
        oddTree (Node _ ts) = oddTrees ts && (length ts ‘mod‘ 2 == 1)
          where 
            oddTrees :: [Tree a] -> Bool
            oddTrees []       = True
            oddTrees (t : ts) = oddTree t && oddTrees ts
      3. Pre-Order-Traversierung
        preOrder :: Tree a -> [a]
        preOrder (Node x ts) = x : preOrderTrees ts
          where
            preOrderTrees []       = []
            preOrderTrees (t : ts) = preOrder t ++ preOrderTrees ts
          
        -- alternativ mit Prelude:
        preOrder :: Tree a -> [a]
        preOrder (Node x ts) = x : concatMap preOrder ts
Woche 5: Unifikation & Induktion auf Listen
09.05. bis 13.05.2022
Woche 6: Strukturelle Induktion & \(\lambda\)-Kalkül
16.05. bis 20.05.2022
  • Die Mittwoch-Übung am 18.05.2022 findet trotz des Dies Academicus zur gewohnten Zeit um 1110 Uhr statt. Jedoch weichen wir auf einem Seminarraum im APB aus, vorzugsweise nutzen wir die E006. Sollte diese aus unerklärlichen Gründen anderweitig belegt sein, sind wir einfach in einem anderen Raum im APB-Erdgeschoss - sucht dann einfach alle durch.
  • Übungsblatt 6
Woche 7: \(\lambda\)-Kalkül
23.05. bis 27.05.2022
  • Auch in diesem Jahr werden die Lehrveranstaltungen, insbesondere auch meine Übungen, evaluiert. Ich bitte euch dazu die folgende Umfrage auszufüllen. Nutzt gern auch die Freitextkommentare, um eure Gedanken und Verbesserungsmöglichkeiten loszuwerden.
  • Übungsblatt 7

Teil 2: Logikprogrammierung

Für Prolog können wir auch relativ gut auf einen Online-Interpreter zurückgreifen.

Hinweise zu Prolog
Woche 8: Prolog (Teil 1)
30.05. bis 03.06.2022
  • Auch in diesem Jahr werden die Lehrveranstaltungen, insbesondere auch meine Übungen, evaluiert. Ich bitte euch dazu die folgende Umfrage auszufüllen. Nutzt gern auch die Freitextkommentare, um eure Gedanken und Verbesserungsmöglichkeiten loszuwerden.
  • Übungsblatt 8
  • Lösungen
    • Aufgabe 1

      Achtung: die Zeilenangaben in den SLD-Refutationen können zwischen Übungsnotizen und Folien sowie den Lösungen hier abweichen.

      1. Abbildung der Kantenrelation des gegebenen Graphen durch ein Prädikat edge

        edge(1, 4).
        edge(1, 2).
        edge(3, 2).
        edge(4, 3).
        edge(1, 1).
      2. Pfade als zweistelliges Prädikt path

        path(U, U).
        path(U, W) :- edge(U, V), path(V, W).
      3. SLD-Refutationen für das Goal ?- path(4, X).

                   ?- path(4,X).
        { X = 4 }  ?- .                          % 7 
                   ?- path(4,X).
                   ?- edge(4,W), path(W,X).     % 8
        { W = 3 }  ?- path(3,X).                % 5
        { X = 3 }  ?- .                         % 6 
                   ?- path(4,X).
                   ?- edge(4,W), path(W,X).     % 8 
        { W = 3 }  ?- path(3,X).                % 5
                   ?- edge(3,U), path(U,X).     % 8 
        { U = 2 }  ?- path(2,X).                % 4
        { X = 2 }  ?- .                         % 7 

        Damit ist also \( X \in \{ 2,3,4 \} \).

    • Aufgabe 2
      1. Prädikat even, das alle geraden Zahlen enthält

        even(0).
        even(s(s(N))) :- even(N).
      2. Prädikt div2, dass alle Paare \( ( n, \lfloor \frac n 2 \rfloor ) \) enthält

        div2(0, 0).
        div2(s(0), 0).
        div2(s(s(N)), s(M)) :- div2(N, M).
      3. SLD-Refutation für das Goal ?- div2(<3>, <1>).

        ?- div2(<3>, <1>).
        ?- div2(<1>, 0)           % 12
        ?- .                      % 11 
Woche 9: Prolog (Teil 2)
13.06. bis 17.06.2022
  • Auch in diesem Jahr werden die Lehrveranstaltungen, insbesondere auch meine Übungen, evaluiert. Ich bitte euch dazu die folgende Umfrage auszufüllen. Nutzt gern auch die Freitextkommentare, um eure Gedanken und Verbesserungsmöglichkeiten loszuwerden.
  • Übungsblatt 9
  • Lösungen
    • Aufgabe 1

      Achtung: die Zeilenangaben in den SLD-Refutationen können zwischen Übungsnotizen und Folien sowie den Lösungen hier abweichen.

      1. Prüfen der Teillisteneigenschaft durch ein Prädikat sublist

        nat (0).
        nat(s(X)) :- nat(X).
        
        listnat ([]).
        listnat ([X|XS]) :- nat(X), listnat(XS).
        
        prefix([]    , Ys )    :- listnat(Ys).
        prefix([X|Xs], [X|Ys]) :- nat(X), prefix(Xs, Ys).
        
        sublist(Xs   , [Y|Ys]) :- nat(Y), sublist(Xs, Ys).
        sublist(Xs   , Ys )    :- prefix(Xs, Ys).
      2. SLD-Refutationen für das Goal ?- sublist([<4>|XS], [<5>, <4>, <3>]).

                        ?-  sublist ([<4>|Xs], [<5>, <4>, <3>]).
                        ?-  nat(<5>), sublist ([<4>|Xs], [<4>, <3>]). % 6
                        ?-* nat(0), sublist ([<4>|Xs], [<4>, <3>]).   % 2
                        ?-  sublist ([<4>|Xs], [<4>, <3>]).           % 1
                        ?-  prefix ([<4>|Xs], [<4>, <3>]).            % 7
                        ?-  nat(<4>), prefix(Xs , [<3>]).             % 10
                        ?-* nat(0), prefix(Xs , [<3>]).               % 2
                        ?-  prefix(Xs , [<3>]).                       % 1
        {Xs = []}       ?-  listnat ([<3>]).                          % 9
                        ?-  nat(<3>), listnat ([]).                   % 5
                        ?-* nat(0), listnat ([]).                     % 2
                        ?-  listnat ([]).                             % 1
                        ?-  .                                         % 4
                        ?-  sublist ([<4>|Xs], [<5>, <4>, <3>]).
                        ?-  nat(<5>), sublist ([<4>|Xs], [<4>, <3>]). % 6
                        ?-* nat(0), sublist ([<4>|Xs], [<4>, <3>]).   % 2
                        ?-  sublist ([<4>|Xs], [<4>, <3>]).           % 1
                        ?-  prefix ([<4>|Xs], [<4>, <3>]).            % 7
                        ?-  nat(<4>), prefix(Xs , [<3>]).             % 10
                        ?-* nat(0), prefix(Xs , [<3>]).               % 2
                        ?-  prefix(Xs , [<3>]).                       % 1
        {Xs=[<3>|Xs1]}  ?-  nat(<3>), prefix(Xs1 , []).               % 10
                        ?-* nat(0), prefix(Xs1 , []).                 % 2
                        ?-  prefix(Xs1 , []).                         % 1
        {Xs1 = []}      ?-  listnat ([]).                             % 9
                        ?-  .                                         % 4
    • Aufgabe 2
      1. Evaluierung eines binären Termbaums mit dem Prädikat eval

        sum(0, Y, Y) :- nat(Y).
        sum(s(X), Y, s(S)) :- sum(X, Y, S).
        
        eval( X         , X ) :-  nat(X).
        eval( plus (L,R), X ) :-  eval(L, LE), eval(R, RE), sum(LE, RE,  X).
        eval( minus(L,R), X ) :-  eval(L, LE), eval(R, RE), sum(RE,  X, LE).
      2. SLD-Refutation für das Goal ?- insert(<t1>, <t2>, X).

        Ausführlichere Hinweise zu Anschauung des Prädikats insert finden sich in den Slides.

        1.                            ?-  insert(<t1>, <t2>, X).
          {X = tree(a, LT1, RT1)}    ?-  insert(tree(b, nil, nil), <t2>, LT1), 
                                         insert(tree(v, nil, nil), <t2>, RT1).   % 6
          {LT1 = tree(b, LT2, RT2)}  ?-  insert(nil , <t2>, LT2), 
                                         insert(nil, <t2>, RT2), 
                                         insert(tree(v, nil, nil), <t2>, RT1).   % 6
          {LT2 = nil, RT2 = nil}     ?-* insert(tree(v, nil, nil), <t2>, RT1).   % 4
          {RT1 = <t2>}               ?-  istree(<t2>).                           % 5
                                     ?-* istree(nil), istree(nil), istree(nil).  % 2
                                     ?-* .                                       % 4
        2.                            ?-  insert(<t1>, <t2>, X).
          {X = tree(a, LT1, RT1)}    ?-  insert(tree(b, nil, nil), <t2>, LT1), 
                                         insert(tree(v, nil, nil), <t2>, RT1).   % 6
          {LT1 = tree(b, LT2, RT2)}  ?-  insert(nil , <t2>, LT2), 
                                         insert(nil, <t2>, RT2), 
                                         insert(tree(v, nil, nil), <t2>, RT1).   % 6
          {LT2 = nil, RT2 = nil}     ?-* insert(tree(v, nil, nil), <t2>, RT1).   % 4
          {RT1 = tree(v, LT3, RT3)}  ?-  insert(nil, <t2>, LT3),
                                         insert(nil, <t2>, RT3).                 % 6
          {RT3 = nil, LT3 = nil}     ?-* .                                       % 4

Teil 3: Abstrakte Maschinen

Woche 10: Abstrakte Maschine AM0
20.06. bis 25.06.2022
Woche 11: Abstrakte Maschine AM1
27.06. bis 01.07.2022
Woche 12: Hoare-Kalkül
04.07. bis 08.07.2022
  • Es gibt einen (vorläufigen) Prüfungsplan der Fakultät Informatik. Bitte beachtet die darin angebebenen Daten zur Prüfung, achtet stets auf Aktualisierungen und meldet euch rechtzeitig an.

  • Übungsblatt 12
Woche 13: H0 und Wiederholung
11.07. bis 15.07.2022
  • Bitte achtet neben den Prüfungsinformationen im Prüfungsplan der Fakultät Informatik auch auf Hinweise im OPAL-Kurs, vor allem zur Startzeit der Klausur.

  • Übungsblatt 13
    • Zu den Zusatzaufgaben wird es meinerseits keine schriftlichen Lösungsvorschläge geben. Ihr findet den Großteil der Aufgaben auch mit Lösung in der offiziellen Aufgabensammlung.
    • Möchtet ihr unbedingt eine Aufgabe der Zusatzaufgaben besprechen, dann teilt mir das gern im Vorfeld mit; ggf. kann ich dann etwas vorbereiten.

Konsultation

Zur Vorbereitung auf die Prüfung biete ich die Möglichkeit einer Konsultation an. Diese ist vor allem für eure Fragen da, sodass ich also nichts dafür vorbereiten oder an Material zur Verfügung stellen werde. Aufgrund der zeitlichen Nähe der Prüfung und gleichzeitig schwieriger Raumverfügbarkeit, kann ich nur folgendes Angebot machen:

  • Mittwoch, 13. Juli 2022 von 1800 bis 2200 Uhr
  • SLUB Zentralbibliothek, Gruppenarbeitsraum 0.43

Ich würde mich freuen, wenn ihr mir ganz unkompliziert auf irgendeinem Weg mitteilt, dass ihr vorbeischauen wollt. Ich bin für spontane Besuche definitiv in der Zeit zwischen 1800 und 2000 anwesend, anschließend nur noch nach Anmeldung.

Gern können wir auch eine Art Co-Working-Space draus machen, sodass ihr für euch selbst lernen könnt und ich einfach für Fragen zur Verfügung stehe. Ich kann schließlich auch nicht für alle gleichzeitig da sein. :)

Solltet ihr nicht zur Konsultation kommen können, stehe ich natürlich auf den bekannten Kommunikationswegen jederzeit (bis ca. 30min vor Prüfungsbeginn) zur Verfügung.