Ich versuche, etwas sehr einfaches in Prolog zu tun, aber aus irgendeinem Grund funktioniert es nicht und ich kann nicht herausfinden, warum. Ich benutze SWI.Stapel von Blöcken in Prolog
Ich habe eine Reihe von Blöcken, a bis f, und sie sind alle übereinander gestapelt, ein Wesen auf der Unterseite und f ganz oben. So ist das:
on(b, a).
on(c, b).
on(d, c).
on(e, d).
on(f, e).
above(X, Y) :- on(X, Y).
above(X, Y) :- on(X, Z), above(Z, Y).
So ein Block ist über einem anderen Block, wenn es einen Block darunter gibt, der auf diesem Block ist. Für mich ergibt das Sinn.
Also jetzt möchte ich ein Prädikat definieren, das mir sagt, ob ein bestimmter Block genau 3 Blöcke darunter hat. In meinem Beispiel wäre das Block d. Also begann ich mit:
exactlyThree(X) :- above(X, Y), above(Y, Z), above (Z, W), \+ above(W, _).
So X hat exaclty drei Blöcke darunter, wenn X über einem Block Y, wenn Y über einem Block Z, wenn Z über einen Block W und Block W ist nicht über jedem Block. Aber das funktioniert nicht.
Also habe ich versucht diese, die praktisch die gleiche Sache ist:
bottomBlock(X) :- \+ above(X, _).
exactlyThree(X) :- above(X, Y), above(Y, Z), above (Z, W), bottomBlock(W).
Das hat nicht funktioniert entweder. Als Test versucht:
?-bottomBlock(a).
true.
Sinn macht, aber dann habe ich versucht:
?-bottomBlock(X).
false.
Was ist hier los? Warum sagt Prolog nicht X = a? Und warum tun meine Prädikate nicht, was sie tun sollen?
Ein Problem ist, dass Ihre Definition von 'exactlyThree'' '' 'verwendet, was eine beliebige Anzahl von Blöcken zwischen seinen Argumenten erlaubt, nicht genau eins. Wenn Sie * genau * drei wollen, müssen Sie 'on' von' exactThree' aufrufen, nicht 'oben'. Wenn Sie also 'genau drei (X): - an (X, Y), an (Y, Z), an (Z, W), \ + an (W, _) geschrieben haben, würden Sie' X = erhalten d'. – lurker
Der Grund, dass der 'bottomBlock (X)' -Aufruf 'X = a' nicht generiert, ist, weil der Ausdruck' \ + über (X, _). 'Kein' X' erzeugen kann, das 'über (X, _) 'falsch. Um dies zu erreichen, definieren Sie Ihr Prädikat wie folgt: 'bottomBlock (X): - is_block (X), \ + über (X, _).' Und definieren 'is_block (X)' als wahr, wenn 'X' ein a ist gültiger Block Dann wird das Prädikat wissen, worüber das "Universum des gültigen Blocks" entscheiden soll. – lurker