Aufgaben aus learn prolog now

Hat da jemand was draus gemacht? Die sind eigentlich recht interessant…

Disclaimer: Dieser Thread wurde aus dem alten Forum importiert. Daher werden eventuell nicht alle Formatierungen richtig angezeigt. Der ursprüngliche Thread beginnt im zweiten Post dieses Threads.

Aufgaben aus learn prolog now
Hi Leute,

hat sich jemand von euch schon Übungen aus dem learn prolog now gemacht? (was ich übrigens sehr gut gemacht finde - wenn auch stellenweise etwas sehr ausführlich - und sehr empfehlen kann)

Im Allgemeinen find ich die Aufgaben relativ einfach, manche sind aber auch etwas tricky. Die reiten auch immer ziemlich auf den traces rum, was sicher sinnvoll ist, aber mit der Zeit irgendwie langweilt.

Um zum Punkt zu kommen: Die definieren prefix und suffix von Funktionen so:

prefix(P,L) :- append(P,_,L).
suffix(S,L) :- append(_,S,L).

Und dann ist die Frage: Warum findet prefix (wenn man es mit einer Variablen für P aufruft) zuerst kurze Listen und suffix zuerst lange?
Meine Vermutung ist, dass es an append liegt und append zunächst versucht kurze Listen an lange anzuhängen.

Was meint ihr?

Gruß,
kynan


Sieh dir an was append(X,Y,[a,b,c]) macht und dann siehst du dass es wohl so ist wie du sagst…
der liefert dann fuer X=[] Y=[a,b,c],X=[a],Y=[b,c] usw…


Kommt natürlich ganz auf die Def. an, hier mal 2 charakteristische (meistens wird append3 genommen, das von kleinen A, zu grossen A geht):

Bei solchen Sachen kommt es natürlich extrem auf die Klauselordnung an!
Je nachdem ob erst die Klausel kommt die A= oder erst die die B= unifiziert ist die Abfolge der Ergebnisse für A und B genau invers. Die ganzen anderen Möglichkeiten zur Klauselordnung hab ich mir auch mal angeschaut, sind aber weniger intuitiv. Einige könnte man als Reissverschluss bezeichnen. :>


Zu den cuts gibts auch noch ne Aufgabe. Da soll man eine prozedur nu/2 schreiben, die Yes zurückgibt, wenn die beiden übergebenen Ausdrücke nicht unifizierbar sind, No wenn sie unifizierbar sind. Dafür soll man weder = noch + verwenden. Jemand eine Idee?

Gar keinen Plan hab ich bei der Aufgabe drunter: unifiable(List1,Term,List2).


Also entweder = benutzen… :stuck_out_tongue_winking_eye:
Oder halt einfach:

nu(A,A) :- !, fail.
nu(A,B).

Poste mal die andere Aufgabe, habs grad nicht zur Hand. :>


Oh ja, das wär ne Idee, stimmt. Hab ich wieder nicht genug um die Ecke rum gedacht.

Die andere Aufgabe ist folgende:

Define a predicate

unifiable(List1,Term,List2)

where List2 is the list of all members of List1 that match Term , but are not instantiated by the matching.

For example,

unifiable([X,b,t(Y)],t(a),List]

should yield

List = [X,t(Y)].

Note that X and Y are still not instantiated. So the tricky part is: how do we check that they match with t(a) without instantiating them? (Hint: consider using the test \+ (term1 = term2). Why? Think about it. You might also like to think about the test \+(\+ (term1 = term2)).)

Und wo wir schon mal dabei sind:
Ich hab auch noch etwas Schwierigkeiten bei der Implementierung von zwei Funktionen aus der Pratice Session von Kapitel 6: set und flatten.

set(List1,List2)

soll eine Liste zurückgeben, in der alle doppelten Vorkommen von List1 eliminiert sind.

flatten(List,Flat)

soll eine eingeebnete Liste zurückgeben, ohne Verwendung von append.


set([],[]).
set([H|T],[H|Erg]):-not(member(H,T)),!,set(T,Erg).
set([_|T],Erg):-set(T,Erg).

wenn der Head nicht Element der Restliste ist, hänge ihn an die Ergebnisliste, ansonsten verwerfe ihn.


Na wenn sie schon solche Tipps geben…

check_unifiable(A,B) :- \+(\+ A = B). % check ohne Instanzierung (schlägt ja fehl ...)
unifiable(L,T,R) :- filter(check_unifiable(T), L, R).

Achso, filter übrigens als:

filter(P,[H|T],R) :- filter(P,T,R2), ( apply(P,[H]) -> R=[H|R2]; R=R2 ).

Und wenns nicht sowieso schon definiert ist (swi hats zB):

apply(F,Args) :- F=..FL, append(FL,Args,FL2), F2=..FL2, F2.

set (wäre aber wohl schöner mit if-then-else statt Cut) wurde schon erklärt und flatten steht doch in ner alten Klausur als unk (iirc ohne append).


hm hoffe das ist alles über klausurniveau

chars(X,X):-not(is_list(X)).
chars([H|],X):-chars(H,X).
chars([
|T],X):-chars(T,X).
flatten(X,XFlat):-findall(Y,chars(X,Y),XFlat).


ach ich denke das sogar 5 level niedriger noch zu hoch für mich sind :smiley:


filter und apply sind ziemlich sicher über Klausurniveau aber das bei nem not bzw + keine Instanzierung entsteht sollte doch schon durch SLD-Resultion klar sein… :>
Die entstehenden Substitutionen werden ja einfach weggeschmissen wenns ein “toter Ast” ist.

_thomas’ flatten ist ein bisschen zu kompliziert für den Normalgebrauch ^^
Siehe besagte Klausur (zumindest so in der Art wars):

unk([],[]).
unk([H|T],[RH|RT]) :- !, unk(H,RH), unk(T,RT).
unk(X,[X]).

müsste eigentlich auch irgendwo hier im Forum stehen. ;D


?- unk([1,2,3],X).

X = [[1], [2], [3]]

in den klausuren gabs glaub nur ein unk mit append am schluss


Ach löl dann meinte ich das. ^^
Hätte das jetzt spontan mit Differenzlisten geschrieben oder halt einfach ein eigenes append.
Wollen die etwa wirklich deine Lösung über ein Metaprädikat?