2016-06-04 4 views
2

Я хочу удалить все элементы элемента из списка, похожие на this, но в моем случае список может иметь неконкретизированные переменные. Например:Prolog: удалить член списка с неконкретизируемыми значениями

delMember(z, [A,B,A,z], L). 
L = [A, B, A]; 
false. 

и

delMember(A, [A, B, A, z], L). 
L = [B,z]; 
false. 

Я попытался определения delMember как:

delMember(_, [], []). 
delMember(X, [X|Xs], Y) :- delMember(X, Xs, Y). 
delMember(X, [T|Xs], [T|Y]) :- X \== T, delMember(X, Xs, Y). 

С этим определением, последний результат я получаю правильно, но он все еще пытается для экземпляра переменных до этого.

?- delMember(A, [A,B,A,z], R). 
A = B, B = z, 
R = [] ; 
A = B, 
R = [z] ; 
A = z, 
R = [B] ; 
R = [B, z] ; 

любые идеи ???

+2

Объединение происходит в вашем втором предложении: 'delMember (X, [X | Xs], Y): - delMember (X, Xs, Y) .', который объединит первый аргумент с заголовком списка во втором аргументе, если они будут унифицированы. Поскольку вы пытаетесь избежать этого, вам нужно также использовать '==': 'delMember (X, [Y | Xs], R): - X == Y, delMember (X, Xs, R) .' – lurker

+0

Спасибо @lurker! Это было именно то, что мне нужно. Если вы хотите ответить на этот вопрос, я буду рад принять его. – lithiium

ответ

1

Если вы посмотрите на втором пункте предиката:

delMember(X, [X|Xs], Y) :- delMember(X, Xs, Y). 

Унификация происходит с X в первой и второй аргументы. Это приводит к результатам, которые вы наблюдаете, когда делаете запрос. Вам необходимо применить тот же оператор, что и в третьем разделе. Таким образом, ваш полный предикат (с некоторыми слегка измененными именами переменными, чтобы быть более обычным) будет выглядеть следующим образом:

delMember(_, [], []). 
delMember(X, [X1|Xs], Ys) :- X == X1, delMember(X, Xs, Ys). 
delMember(X, [X1|Xs], [X1|Ys]) :- X \== X1, delMember(X, Xs, Ys). 
Смежные вопросы