P1-WS04-MusterLoesung06.txt: Unterschied zwischen den Versionen
Zur Navigation springen
Zur Suche springen
Muelli (Diskussion | Beiträge) Keine Bearbeitungszusammenfassung |
K 2 Versionen |
||
| (Eine dazwischenliegende Version von einem anderen Benutzer wird nicht angezeigt) | |||
| 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> | ||
Aktuelle Version vom 5. November 2007, 05:50 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]]).