ersetzen member1
mit memberchk
und Ihr Code wird viel besser funktionieren. Der Grund, warum Sie überraschen werden! Lassen Sie uns einige "Debuggen printfs" zu Ihrem member1/2
Prädikat hinzu:
member1(X,[H|_]) :- format('testing ~w == ~w?~n', [X,H]), X==H,!.
member1(X,[_|T]) :- format('looking in tail ~w for ~w~n', [T,X]), member1(X,T).
scheint OK zu arbeiten, nicht wahr?
?- member1(bar, [foo,bar,baz]).
testing bar == foo?
looking in tail [bar,baz] for bar
testing bar == bar?
true.
Übrigens tut memberchk/2
das Gleiche:
?- memberchk(bar, [foo,bar,baz]).
true.
Nun, wir bekommen "true". :) Aber was passiert, wenn ich etwas Seltsames übergebe, wie eine Variable statt einer Liste?
?- memberchk(bar, V).
V = [bar|_G483709].
Ah, na ja, memberchk/2
wird dies als eine Art Behauptung nehmen, dass es an der Spitze der Liste ist (dies ist, weil es das tut, was member/2
tut, aber mit nur einer Lösung). Was macht member1/2
?
?- member1(bar, V).
looking in tail _G478121 for bar
testing bar == _G478129?
looking in tail _G478130 for bar
testing bar == _G478138?
looking in tail _G478139 for bar
testing bar == _G478147?
looking in tail _G478148 for bar
testing bar == _G478156?
looking in tail _G478157 for bar
testing bar == _G478165?
looking in tail _G478166 for bar
testing bar == _G478174?
looking in tail _G478175 for bar
testing bar == _G478183?
...
eventually, boom, stack depth exceeded
Überraschenderweise tritt Ihr Code tatsächlich in diesen Fall ein! Beachten Sie, dass Sie Bedingungen, die Variablen auf einer Seite definieren, aber nicht die andere:
(B1==B2 -> K is J + 1; K is J + 0, LB1=[B1],LB2=[B2]),
Welche Werte LB1
und LB2
nehmen, wenn B1 zu B2 nicht gleich? Sie bleiben uninstantiiert! Dann ein paar Zeilen später Sie bedingungslos hängen Sie sie:
append(LA1,LB1,AB1),
append(LC1,LD1,CD1),
append(AB1,CD1,L1),
So von diesem Punkt L1 = LA1 + LB1 + LC1 + LD1, aber LB1 ist eine reine Variable! Dies kann passieren einer beliebigen Ihrer LX1/LX2-Variablen, und dann landen Sie member1/2
mit einer Art Loch in Ihrer Liste eingeben! Diese
ist kein Fehler in Prolog, nebenbei bemerkt. Es gibt Zeiten, in denen Sie beispielsweise das Ende einer Liste uninstantiierter Differenzlisten verlassen wollen.
Nun, ich habe Eimer andere Ratschläge für Sie, aber ich denke, die Moral der jetzt Geschichte ist, dass Sie, wann immer möglich Einbau-Prädikate verwenden sollten. :)
Es ist ein bisschen unhöflich, auf ein Repo zu zeigen; Es ist besser, ein [minimales Beispiel] (http://stackoverflow.com/help/mcve) einzuschließen.Das Vorbereiten eines minimalen Beispiels würde Ihnen wahrscheinlich helfen, das Problem zu isolieren und wahrscheinlich unser beider Leben einfacher zu machen. –
Nicht eine Antwort genau, aber einige Ihrer Prädikate haben Standardgegenstücke: 'member1/2' ist' memberchk/2', ich würde 'sort/2' anstelle von' distinct/2' verwenden, 'nonmember/2' würde ich ersetzen mit '\ + member (...)'. Du benutzt "!" Genug, um mich nervös zu machen, aber ich habe dort keine offensichtlichen Fehler gesehen. Darüber hinaus sieht es nicht schrecklich aus; Ich würde stärkere Formatierungsprädikate verwenden und die Logik von der Präsentation mehr trennen, aber für einen Anfänger sieht das sehr gut aus. –