P1-WS04-MusterLoesung06.txt: Unterschied zwischen den Versionen
Zur Navigation springen
Zur Suche springen
Muelli (Diskussion | Beiträge) Keine Bearbeitungszusammenfassung |
fsrwiki_>Oddmuse Import K (link fix) |
||
Zeile 1: | Zeile 1: | ||
<pre> | <pre> | ||
% Musterloesung Aufgabenblatt 6 | % Musterloesung Aufgabenblatt 6 | ||
% P1 WiSe 04/05 | % P1 [[WiSe]] 04/05 | ||
% Daniel Schreckling | % Daniel Schreckling | ||
Zeile 57: | Zeile 57: | ||
% ---------- | % ---------- | ||
% hoehenunterschied_ww_verbr(+Wasserwerk, +VerbrRegion, ?Unterschied) | % hoehenunterschied_ww_verbr(+Wasserwerk, +[[VerbrRegion]], ?Unterschied) | ||
% | % | ||
% Gelingt, wenn die Verbraucherregion +VerbrRegion letztlich von | % Gelingt, wenn die Verbraucherregion +[[VerbrRegion]] letztlich von | ||
% +Wasserwerk mit Wasser versorgt wird. ?Unterschied enthaelt bei Erfolg | % +Wasserwerk mit Wasser versorgt wird. ?Unterschied enthaelt bei Erfolg | ||
% den Hoehenunterschied zwischen Wasserwerk und Verbraucherregion. | % den Hoehenunterschied zwischen Wasserwerk und Verbraucherregion. | ||
Zeile 65: | Zeile 65: | ||
% gegebenenfalls auch mehrer Hoehenunterschiede. | % gegebenenfalls auch mehrer Hoehenunterschiede. | ||
hoehenunterschied_ww_verbr(Wasserwerk, VerbrRegion, Unterschied) :- | hoehenunterschied_ww_verbr(Wasserwerk, [[VerbrRegion]], Unterschied) :- | ||
wasserwerk(Wasserwerk, HoeheWW), | wasserwerk(Wasserwerk, [[HoeheWW]]), | ||
region(VerbrRegion, HoeheVR), | region([[VerbrRegion]], [[HoeheVR]]), | ||
wird_versorgt_von(VerbrRegion, Wasserwerk, _), | wird_versorgt_von([[VerbrRegion]], Wasserwerk, _), | ||
hoehen_unterschied(VerbrRegion, Wasserwerk, Unterschied). | hoehen_unterschied([[VerbrRegion]], Wasserwerk, Unterschied). | ||
% Aufgabe 1c | % Aufgabe 1c | ||
% ---------- | % ---------- | ||
% wird_versorgt_von(?Senke, ?Quelle, ?MaxDiff) | % wird_versorgt_von(?Senke, ?Quelle, ?[[MaxDiff]]) | ||
% | % | ||
% Gelingt, wenn ?Senke von ?Quelle mit Trinkwasser versorgt wird. | % Gelingt, wenn ?Senke von ?Quelle mit Trinkwasser versorgt wird. | ||
% In ?MaxDiff wird die größte Höhendifferenz gespeichert, | % In ?[[MaxDiff]] wird die größte Höhendifferenz gespeichert, | ||
% die auf irgendeinem Weg von der Senke zur Quelle überwunden wird. | % die auf irgendeinem Weg von der Senke zur Quelle überwunden wird. | ||
% Da es mehrere Wege geben kann, liefert wird_versorgt_von\2 | % Da es mehrere Wege geben kann, liefert wird_versorgt_von\2 | ||
% gegebenenfalls auch mehrer Hoehenunterschiede. | % gegebenenfalls auch mehrer Hoehenunterschiede. | ||
wird_versorgt_von(Senke,Quelle, MaxDiff) :- | wird_versorgt_von(Senke,Quelle, [[MaxDiff]]) :- | ||
wasserwerk(Quelle, _), | wasserwerk(Quelle, _), | ||
ist_angeschlossen_an(Senke,Quelle), | ist_angeschlossen_an(Senke,Quelle), | ||
hoehen_unterschied(Senke, Quelle, MaxDiff). | hoehen_unterschied(Senke, Quelle, [[MaxDiff]]). | ||
wird_versorgt_von(Senke,Quelle, MaxDiff) :- | wird_versorgt_von(Senke,Quelle, [[MaxDiff]]) :- | ||
ist_angeschlossen_an(Senke,Ort), | ist_angeschlossen_an(Senke,Ort), | ||
wird_versorgt_von(Ort,Quelle, ThisDiff), | wird_versorgt_von(Ort,Quelle, [[ThisDiff]]), | ||
hoehen_unterschied(Senke, Ort, Diff), | hoehen_unterschied(Senke, Ort, Diff), | ||
max(Diff, ThisDiff, MaxDiff). | max(Diff, [[ThisDiff]], [[MaxDiff]]). | ||
% max_hoehenunterschied_ww_verbr(+Wasserwerk, +VerbrRegion, ?MaxDiff) | % max_hoehenunterschied_ww_verbr(+Wasserwerk, +[[VerbrRegion]], ?[[MaxDiff]]) | ||
% | % | ||
% Gelingt, wenn die Verbraucherregion +VerbrRegion letztlich von | % Gelingt, wenn die Verbraucherregion +[[VerbrRegion]] letztlich von | ||
% +Wasserwerk mit Wasser versorgt wird. ?MaxDiff liefert bei Erfolg | % +Wasserwerk mit Wasser versorgt wird. ?[[MaxDiff]] liefert bei Erfolg | ||
% den maximalen Hoehenunterschied zwischen zwei Netzknoten auf dem Weg | % den maximalen Hoehenunterschied zwischen zwei Netzknoten auf dem Weg | ||
% zwischen Wasserwerk und Verbraucherregion. | % zwischen Wasserwerk und Verbraucherregion. | ||
Zeile 102: | Zeile 102: | ||
% gegebenenfalls auch mehrer Hoehenunterschiede. | % gegebenenfalls auch mehrer Hoehenunterschiede. | ||
max_hoehenunterschied_ww_verbr(Wasserwerk, VerbrRegion, MaxDiff) :- | max_hoehenunterschied_ww_verbr(Wasserwerk, [[VerbrRegion]], [[MaxDiff]]) :- | ||
region(VerbrRegion, _), | region([[VerbrRegion]], _), | ||
wasserwerk(Wasserwerk, _), | wasserwerk(Wasserwerk, _), | ||
wird_versorgt_von(VerbrRegion, Wasserwerk, MaxDiff). | wird_versorgt_von([[VerbrRegion]], Wasserwerk, [[MaxDiff]]). | ||
Zeile 121: | Zeile 121: | ||
zzins(Anlage, Zinssatz, Laufzeit, Ausschuettung) :- | zzins(Anlage, Zinssatz, Laufzeit, Ausschuettung) :- | ||
Laufzeit > 0, | Laufzeit > 0, | ||
Years2Go is Laufzeit - 1, | [[Years2Go]] is Laufzeit - 1, | ||
zzins(Anlage, Zinssatz, Years2Go, ZwischenBetrag), | zzins(Anlage, Zinssatz, [[Years2Go]], [[ZwischenBetrag]]), | ||
Ausschuettung is (ZwischenBetrag * (1 + Zinssatz/100)). | Ausschuettung is ([[ZwischenBetrag]] * (1 + Zinssatz/100)). | ||
% Aufgabe 2b | % Aufgabe 2b | ||
Zeile 183: | Zeile 183: | ||
% veranschaulicht wird. Es wird eine normale Parabel gezeichnet, deren | % veranschaulicht wird. Es wird eine normale Parabel gezeichnet, deren | ||
% Punkte aber proportional zum Funktionswert größer werden. Das | % Punkte aber proportional zum Funktionswert größer werden. Das | ||
% Ergebnis könnte jedem Monster/Alien/Katastrophenfilm entnommen sein; | % Ergebnis könnte jedem Monster[[/Alien/Katastrophenfilm]] entnommen sein; | ||
% schon kubisches Wachstum wäre nicht mehr richtig zu erkennen, | % schon kubisches Wachstum wäre nicht mehr richtig zu erkennen, | ||
% geschweige denn exponentielles. | % geschweige denn exponentielles. | ||
Zeile 198: | Zeile 198: | ||
% draw_parabola(+Bildobjekt, +X, +MaxX) erzeugt eine normale Parabel, | % draw_parabola(+Bildobjekt, +X, +[[MaxX]]) erzeugt eine normale Parabel, | ||
% d.h. die Kurve y = x^2, wobei die Punkte proportional zum Wert y | % d.h. die Kurve y = x^2, wobei die Punkte proportional zum Wert y | ||
% größer werden. | % größer werden. | ||
draw_parabola(_,X,MaxX):- X >= MaxX. | draw_parabola(_,X,[[MaxX]]):- X >= [[MaxX]]. | ||
draw_parabola(Bild,X,MaxX) :- | draw_parabola(Bild,X,[[MaxX]]) :- | ||
Y is X*X / 100, | Y is X*X / 100, | ||
new(O, circle(Y)), | new(O, circle(Y)), | ||
Zeile 210: | Zeile 210: | ||
send(Bild, display(O, point(X,Y2))), | send(Bild, display(O, point(X,Y2))), | ||
X2 is X + 1, | X2 is X + 1, | ||
draw_parabola(Bild,X2,MaxX). | draw_parabola(Bild,X2,[[MaxX]]). | ||
% :-draw(300). | % :-draw(300). | ||
Zeile 257: | Zeile 257: | ||
% -------- | % -------- | ||
% Prädikat slice_i(+Liste, ?NewList) | % Prädikat slice_i(+Liste, ?[[NewList]]) | ||
% | % | ||
% Extrahiert aus der Liste +Liste jedes zweite Element und | % Extrahiert aus der Liste +Liste jedes zweite Element und | ||
% speichert diese mit Hilfe gerade_Pos/2 und findall/3 in | % speichert diese mit Hilfe gerade_Pos/2 und findall/3 in | ||
% ?NewList | % ?[[NewList]] | ||
% | % | ||
% Da gerade_Pos/2 für eine leere Liste nicht erfolgreich, | % Da gerade_Pos/2 für eine leere Liste nicht erfolgreich, | ||
% liefert slice_i([], NewList) in NewList auch eine leere | % liefert slice_i([], [[NewList]]) in [[NewList]] auch eine leere | ||
% Liste. | % Liste. | ||
slice_i(List, NewList) :- | slice_i(List, [[NewList]]) :- | ||
findall(Element, gerade_Pos(List, Element), NewList). | findall(Element, gerade_Pos(List, Element), [[NewList]]). | ||
% Teil (ii) | % Teil (ii) | ||
% --------- | % --------- | ||
% Prädikat slice_ii(+Liste, ?NewList) | % Prädikat slice_ii(+Liste, ?[[NewList]]) | ||
% | % | ||
% Extrahiert aus der Liste +Liste jedes zweite Element und | % Extrahiert aus der Liste +Liste jedes zweite Element und | ||
Zeile 281: | Zeile 281: | ||
slice_ii([], []). | slice_ii([], []). | ||
slice_ii([_], []). | slice_ii([_], []). | ||
slice_ii([_,Element2|Tail], [Element2|NewList]) :- slice_ii(Tail, NewList). | slice_ii([_,Element2|Tail], [Element2|[[NewList]]]) :- slice_ii(Tail, [[NewList]]). | ||
</pre> | </pre> |
Version vom 5. November 2007, 06:49 Uhr
% Musterloesung Aufgabenblatt 6 % P1 [[WiSe]] 04/05 % Daniel Schreckling % Aufgabe 1 % --------- % Hilfsprädikat max(+Zahl1, +Zahl2, ?Max) % % Liefert in ?Max das Maximum der Zahlen +Zahl1 % und +Zahl2 max(Zahl1, Zahl2, Zahl2) :- Zahl1 < Zahl2. max(Zahl1, Zahl2, Zahl1) :- Zahl1 >= Zahl2. % Hilfsprädikat Ort(?Ort, ?Hoehe) % % Liefert die ?Hoehe zu einem Ort ?Ort ort(Ort, Hoehe) :- region(Ort,Hoehe). ort(Ort, Hoehe) :- wasserwerk(Ort, Hoehe). ort(Ort, Hoehe) :- pumpstation(Ort, Hoehe). % es werden Prädikate aus früheren Übungsaufgaben verwendet % und modifiziert % Aufgabe 1a % ---------- % Hilfsprädikat hoehen_unterschied(+Ort1, +Ort2, ?Unterschied) % % berechnet die Hoehendifferenz nach der Vorschrift: % Hoehe von Ort1 minus Hoehe von Ort2 hoehen_unterschied(Ort1, Ort2, Unterschied) :- ort(Ort1, Hoehe1), ort(Ort2, Hoehe2), Unterschied is (Hoehe1 - Hoehe2). % hoehen_unterschied_verb(+Senke, +Quelle, ?Unterschied) % % Gelingt, wenn +Senke und +Quelle in Fließrichtung direkt % miteinander verbunden sind. ?Unterschied enthält bei % Erfolg den Hoehenunterschieds ziwschen Senke und Quelle hoehen_unterschied_verb(Senke, Quelle, Unterschied) :- ist_angeschlossen_an(Senke, Quelle), hoehen_unterschied(Senke, Quelle, Unterschied). % Aufgabe 1b % ---------- % hoehenunterschied_ww_verbr(+Wasserwerk, +[[VerbrRegion]], ?Unterschied) % % Gelingt, wenn die Verbraucherregion +[[VerbrRegion]] letztlich von % +Wasserwerk mit Wasser versorgt wird. ?Unterschied enthaelt bei Erfolg % den Hoehenunterschied zwischen Wasserwerk und Verbraucherregion. % Da es mehrere Wege geben kann, liefert hoehen_unterschied_ww_verbr\3 % gegebenenfalls auch mehrer Hoehenunterschiede. hoehenunterschied_ww_verbr(Wasserwerk, [[VerbrRegion]], Unterschied) :- wasserwerk(Wasserwerk, [[HoeheWW]]), region([[VerbrRegion]], [[HoeheVR]]), wird_versorgt_von([[VerbrRegion]], Wasserwerk, _), hoehen_unterschied([[VerbrRegion]], Wasserwerk, Unterschied). % Aufgabe 1c % ---------- % wird_versorgt_von(?Senke, ?Quelle, ?[[MaxDiff]]) % % Gelingt, wenn ?Senke von ?Quelle mit Trinkwasser versorgt wird. % In ?[[MaxDiff]] wird die größte Höhendifferenz gespeichert, % die auf irgendeinem Weg von der Senke zur Quelle überwunden wird. % Da es mehrere Wege geben kann, liefert wird_versorgt_von\2 % gegebenenfalls auch mehrer Hoehenunterschiede. wird_versorgt_von(Senke,Quelle, [[MaxDiff]]) :- wasserwerk(Quelle, _), ist_angeschlossen_an(Senke,Quelle), hoehen_unterschied(Senke, Quelle, [[MaxDiff]]). wird_versorgt_von(Senke,Quelle, [[MaxDiff]]) :- ist_angeschlossen_an(Senke,Ort), wird_versorgt_von(Ort,Quelle, [[ThisDiff]]), hoehen_unterschied(Senke, Ort, Diff), max(Diff, [[ThisDiff]], [[MaxDiff]]). % max_hoehenunterschied_ww_verbr(+Wasserwerk, +[[VerbrRegion]], ?[[MaxDiff]]) % % Gelingt, wenn die Verbraucherregion +[[VerbrRegion]] letztlich von % +Wasserwerk mit Wasser versorgt wird. ?[[MaxDiff]] liefert bei Erfolg % den maximalen Hoehenunterschied zwischen zwei Netzknoten auf dem Weg % zwischen Wasserwerk und Verbraucherregion. % Da es mehrere Wege geben kann, liefert hoehen_unterschied_ww_verbr\3 % gegebenenfalls auch mehrer Hoehenunterschiede. max_hoehenunterschied_ww_verbr(Wasserwerk, [[VerbrRegion]], [[MaxDiff]]) :- region([[VerbrRegion]], _), wasserwerk(Wasserwerk, _), wird_versorgt_von([[VerbrRegion]], Wasserwerk, [[MaxDiff]]). % Aufgabe 2a % ---------- % zinseszins(+Anlage,+Zinssatz,+Laufzeit,?Ausschuettung) % % Das Kapital +Anlage ist in Währungseinheiten anzugeben, % der +Zinssatz in Prozent, z.b. `5' entspricht 5%, % die +Laufzeit in Jahren. % Die +Ausschuettung wird ebenfalls in Währungseinheiten ausgegeben zzins(Anlage, _, 0, Anlage). zzins(Anlage, Zinssatz, Laufzeit, Ausschuettung) :- Laufzeit > 0, [[Years2Go]] is Laufzeit - 1, zzins(Anlage, Zinssatz, [[Years2Go]], [[ZwischenBetrag]]), Ausschuettung is ([[ZwischenBetrag]] * (1 + Zinssatz/100)). % Aufgabe 2b % ---------- % Im Prolog-System genügen fünf Nachkommastellen, um genaue % Verdopplung zu erreichen: % % ?- zzins(1000,7.17735,10,X). % % X = 2000.0 % Es gibt eine analytische Loesung, denn für das Kapital % K_n nach n Jahren gilt bei einem Zinssatz p und einem % Startkapital K: % % K_n = K * (1 + p/100)^n % % Damit ergibt sich für eine Verdopplung von K nach 10 Jahren % (also K_10 = 2 * K) für den Zinssatz p folgende Gleichheit: % % p = (sqrt(10, 2) - 1) * 100 = 7.1773463 % % wobei sqrt(10, 2) die 10te Wurzel aus 2 berechnet. % Aufgabe 2c % ---------- % Prädikat zzinslist(+Anlage, +Zinssatz, +Laufzeit, ?Liste) % % Liefert zu einem Startkapital +Anlage und einem Zinssatz +Zinssatz % eine Liste ?Liste der Kapitalbeträge in den Jahren +Laufzeit, in % denen das Anlagekapital verzinst wird zzinslist(Anlage, Zinssatz, Laufzeit, Liste) :- findall( kapital(Jahr, Kapital), (between(0, Laufzeit, Jahr), zzins(Anlage, Zinssatz, Jahr, Kapital)), Liste). % ?-zzinslist(10000, 7.17735, 10, List). % List = [kapital(0, 10000), % kapital(1, 10717.7), % kapital(2, 11487.0), % kapital(3, 12311.4), % kapital(4, 13195.1), % kapital(5, 14142.1), % kapital(6, 15157.2), % kapital(7, 16245.1), % kapital(8, 17411.0), % kapital(9, 18660.7), % kapital(10, 20000.0)] % Aufgabe 3 % --------- % Hier ein Beispiel, in dem das Ausmaß des quadratischen Wachstums % veranschaulicht wird. Es wird eine normale Parabel gezeichnet, deren % Punkte aber proportional zum Funktionswert größer werden. Das % Ergebnis könnte jedem Monster[[/Alien/Katastrophenfilm]] entnommen sein; % schon kubisches Wachstum wäre nicht mehr richtig zu erkennen, % geschweige denn exponentielles. % % Man beachte die symmetrischen Moirémuster unterhalb des letzten % Funktionswertes. draw(Max) :- free(@bild), new(@bild,picture('Beispiel',size(900,900))), send(@bild,background,colour(black)), send(@bild,open), draw_parabola(@bild,0,Max). % draw_parabola(+Bildobjekt, +X, +[[MaxX]]) erzeugt eine normale Parabel, % d.h. die Kurve y = x^2, wobei die Punkte proportional zum Wert y % größer werden. draw_parabola(_,X,[[MaxX]]):- X >= [[MaxX]]. draw_parabola(Bild,X,[[MaxX]]) :- Y is X*X / 100, new(O, circle(Y)), send(O,fill_pattern(colour(yellow))), % XPCE zählt Y von links oben, aber wir wollen von links unten zählen Y2 is 300 - Y, send(Bild, display(O, point(X,Y2))), X2 is X + 1, draw_parabola(Bild,X2,[[MaxX]]). % :-draw(300). % Aufgabe 4a % ---------- % (i) Bindungen sind X=y und Y=x % (ii) Bindungen sind L=a und X=[a,a] % (iii) Bindungen sind F=[a,b], G=[[a,[b]], [[b]|a]], A=a und B=[b] % Aufgabe 4b % ---------- %% Prädikat last\2 %% mylast(+List, +Element) %% Ausgabe: yes, wenn letztes Element der Liste +List %% mit dem Element +Element identisch ist. mylast([Last], Last). mylast([_|Tail], Element) :- mylast(Tail, Element). % Das Prädikat läßt sich sowohl zum Testen als auch zum Extrahieren % oder Generieren einsetzten. Wenn nur Variable angegeben werden, % werden nacheinander abstrakte Listen aller möglichen Längen % angegeben. Bei leeren Listen mißlingt der Aufruf sofort. % Aufgabe 4c % ---------- % Hilfsprädikat gerade_Pos(+Liste, ?Element) % ist erfolgreich, falls ?Element an einer Position % in +Liste mit geradem Index steht (der Index ist % nullbasiert, d.h. das erste Element in der Liste hat % Index 0, das zweite Element den Index 1, ...) % % Die Anwendung dieses Prädikates auf eine leere Liste % ist nicht erfolgreich. gerade_Pos([_,E|_], E). gerade_Pos([_,_|R], E) :- gerade_Pos(R,E). % Teil (i) % -------- % Prädikat slice_i(+Liste, ?[[NewList]]) % % Extrahiert aus der Liste +Liste jedes zweite Element und % speichert diese mit Hilfe gerade_Pos/2 und findall/3 in % ?[[NewList]] % % Da gerade_Pos/2 für eine leere Liste nicht erfolgreich, % liefert slice_i([], [[NewList]]) in [[NewList]] auch eine leere % Liste. slice_i(List, [[NewList]]) :- findall(Element, gerade_Pos(List, Element), [[NewList]]). % Teil (ii) % --------- % Prädikat slice_ii(+Liste, ?[[NewList]]) % % Extrahiert aus der Liste +Liste jedes zweite Element und % konstruiert mit Hilfe von von Rekursion eine Ergebnisliste, % die genau diese Elemente enthält slice_ii([], []). slice_ii([_], []). slice_ii([_,Element2|Tail], [Element2|[[NewList]]]) :- slice_ii(Tail, [[NewList]]).