2009-06-27 7 views
-1

Ich beginne gerade mit Prolog, und ich kann nicht herausfinden, warum das folgende nicht funktioniert, wie ich es erwarte. Ich versuche, ein Prädikat zu erstellen, das wahr zurückgibt, wenn Liste L2 in L1 enthalten ist. Diese ist, was ich schrieb:Prolog Prädikat Probleme

assert(contains (L1, L1)). 
assert(contains(L1, [X|L2]):-member(X, L1), contains(L1, L2)). 
assert(contains(L1, [])). 

Ich dachte, dies entspricht „wenn X von‚L3 = X | L2‘ist in L1, und auch L2 ist in L1 dann wahr“ sein, mit enthält (L1, L2) werden rekursiv übersetzt, bis entweder alle Mitglieder durchlaufen wurden und wir die letzte Option übrig haben, oder wir finden ein Mitglied, das nicht in L1 ist, und es wird das Prädikat nicht bestehen.

Leider scheint es so nicht zu funktionieren. Es scheint nur den Wert von member (X, L1) zurückzugeben, also enthält ([1,2,3], [1,4,5])), enthält aber ([1,2,3], [4, 1,5]) nicht.

Was mache ich falsch?

+0

Welche Prolog-Implementierung verwenden Sie? Ich kann Ihr Problem nicht in SWI-Prolog reproduzieren (obwohl es auch nicht richtig funktioniert). – mercator

+0

SWI-Prolog Version 2.7.12 –

+3

2.7.12? Ja wirklich?! Versuchen Sie etwas neueres wie 5.6.x oder 5.7.x. – Kaarel

Antwort

5

ich nicht ganz verstehe Ihre Frage, aber ich würde das contains/2 Prädikat wie folgt schreiben:

% An empty list is contained by any list 
contains(_, []). 

% If a list is not empty, then its 
% first element must be an element of L1, 
% and its tail must be contained by L1. 
contains(L1, [X | L2]) :- 
    member(X, L1), 
    contains(L1, L2). 

Btw, beachten Sie, dass Ihre erste Regel (Tatsache)

contains (L1, L1). 

ist ein Syntaxfehler (Nach dem Prädikatnamen sollte kein Leerzeichen stehen). Auch wenn es korrigiert wird, würde es einen unerwünschten auserlesenen Punkt verursachen. Also, lösche es lieber.

Falls Sie assert/1 auf der Prolog-Eingabeaufforderung verwenden, dann

?- assert(contains(_, [])). 

Yes 
?- assert(contains(L1, [X | L2]) :- (member(X, L1), contains(L1, L2))). 

Yes 

Um zu sehen, was in der Wissensbasis, listing/0 verwenden endete auszuführen.

Ich glaube nicht, das Problem ist mit "freie Variablen behaupten", wie Sie in Ihrer eigenen Antwort angeben. Überprüfen Sie stattdessen Ihre Belichtungsreihen.

+0

Ich habe versucht, was Sie gefragt, und es hat das gleiche Problem: wenn ich behebe enthält ([1,2,3], [1,2,4]), antwortet es mit "Ja" –

+0

Seltsam, in meinem Fall antwortet es "falsch." – Kaarel

-2

Scheinbar die Verwendung von Behauptungen auf freie Variablen kann Probleme verursachen (zumindest in dieser Version), deshalb hat es sich schlecht benommen. Das Löschen der Geltendmachung und das Verwenden eines Befehls consult (file) löste dies.

+0

Ihre ursprüngliche Frage sagt nichts über behaupten. Was genau hast du behauptet? – Kaarel

+0

Ich schrieb es im Grunde in der Aufforderung, so behauptete ich alles. Die Bestätigungen zum gebuchten Code hinzugefügt. –