Vain schrieb:
Was ist der Unterschied zwischen beispielsweise „5, 10, 5“ und „5, 5, 10“? Die eine Liste ist aufsteigend sortiert, die andere nicht.
Ich habe nur diese beiden Sätze gelesen und mich dann an die Arbeit gemacht! ☺ Ich bin auf ein ähnlichen Quelltext gekommen. Lediglich ein paar syntaktische Unterschiede, semantisch jedoch - abgesehen vom Cut - ziemlich äquivalent.
sortiert([_]).
sortiert([ K | R]) :- R = [K2 | _], K =< K2, sortiert(R), !.
(Beim nochmaligen Lesen bin ich mir nicht mehr sicher, ob die Lösung wirklich so „ganz simpel“ ist. Irgendwie muss man schon drauf kommen. Am Donnerstag fand ich das total naheliegend…)
Das war das Verwirrende. Da Du sagtest, es sei ganz simpel, bin ich von einer geringen Codeänderung ausgegangen.
Ich zog es deshalb nicht in Betracht, eine weitere Regel zu definieren.
Du hast mir sehr geholfen, auch dahingehend, mein Verständnis für Prolog zu erweitern. Danke dafür!
Beste Grüße!
Zusatz:
Ich habe hier gleich noch den vollständigen Quelltext, mit dem ich meinem Ursprungsprogramm, wie ich es im ersten Beitrag gewünscht hatte, näher komme.
Mit der Regel gib_Bezeichner/2
gebe ich entsprechend die Bezeichner, sprich das erste Atom im Faktum basis/2
aus.
basis(a, 5).
basis(b, 10).
basis(c, 20).
sortiert([_]).
sortiert([K | R]) :- R = [K2 | _],
K =< K2,
sortiert(R), !.
gib_Bezeichner(ListeB, ListeZ) :- ListeB = [KB],
ListeZ = [KZ],
basis(KB, KZ).
gib_Bezeichner(ListeB, ListeZ) :- ListeB = [KB | RB],
ListeZ = [KZ | RZ],
basis(KB, KZ),
gib_Bezeichner(RB, RZ).
berechne(E, [E]) :- basis(_, E).
berechne(W, [K | R]) :- basis(_, K),
N is W - K,
N > 0,
berechne(N, R),
sortiert([K | R]).
Nun gibt z.B. die Anfrage ?- berechne(15, X), gib_Bezeichner(Y, X)
auch die entsprechenden Permutationen mit den "Bezeichnern".
Zusatz2:
Man benötigt die Regel gib_Bezeichner/2
eigentlich gar nicht. Ich habe berechne/2
entsprechend umgeschrieben und berechne2/2
genannt. Nun werden nur die Bezeichner ausgegeben.
berechne2(KZ, ListeB) :- ListeB = [KB], basis(KB, KZ), _ = [KZ].
berechne2(W, ListeB) :- ListeB = [KB | RB], basis(KB, KZ), _ = [KZ | _],
N is W - KZ,
N > 0,
berechne(N, RB),
sortiertB(ListeB).
Problem hierbei ist, dass auch die Regel sortiert/1
so umgeschrieben werden muss, dass sie die Bezeichner in der korrekten Folge erkennt. Dies schaffen wir durch die Bindung der Bezeichner an ihre Zahlen.
sortiertB([KB]) :- basis(KB, KZ), _ = [KZ].
sortiertB([KB | RB]) :- RB = [KB2 | _], basis(KB, KZ), basis(KB2, KZ2),
KZ =< KZ2,
sortiertB(RB), !.