Предупреждения об одноэлементных переменных не являются актуальной проблемой.
Одиночные переменные - это логические переменные, которые встречаются один раз в некотором предложении Prolog (факт или правило).Пролог предупреждает вас об этих переменных, если они названы как не-одиночные переменные, т. Е. Если их имя не начинается с _
.
Это соглашение помогает избежать опечаток противного типа - опечаток, которые не вызывают синтаксических ошибок, но делают меняют значение.
Давайте построимканоническое решение вашей проблемы.
Во-первых, забудьте о CamelCase
и выберите правильное имя предиката, которое отражает реляционный характер рассматриваемой проблемы: как насчет list_uniques/2
?
Затем документируйте случаи, в которых вы ожидаете, что предикат даст один ответ, несколько ответов или вообще никакого ответа.Как?Не просто текст, а запросы .
Начните с самого общего запроса:
?- list_uniques(Xs, Ys).
Добавьте несколько наземных запросов:
?- list_uniques([], []).
?- list_uniques([1,2,2,1,3,4], [3,4]).
?- list_uniques([a,b,b,a], []).
И добавьте запросы, содержащие переменные:
?- list_uniques([n,i,x,o,n], Xs).
?- list_uniques([i,s,p,y,i,s,p,y], Xs).
?- list_uniques([A,B], [X,Y]).
?- list_uniques([A,B,C], [D,E]).
?- list_uniques([A,B,C,D], [X]).
Теперь давайте напишем некоторый код!Основано на library(reif)
запись:
:- use_module(library(reif)).
list_uniques(Xs, Ys) :-
list_past_uniques(Xs, [], Ys).
list_past_uniques([], _, []). % auxiliary predicate
list_past_uniques([X|Xs], Xs0, Ys) :-
if_((memberd_t(X,Xs) ; memberd_t(X,Xs0)),
Ys = Ys0,
Ys = [X|Ys0]),
list_past_uniques(Xs, [X|Xs0], Ys0).
Что происходит?
list_uniques/2
построено на предикате помощника list_past_uniques/3
В любой момент list_past_uniques/3
отслеживает:
- все элементы впереди (
Xs
) и - все элементы "позади" (
Xs0
) некоторые элементы исходного списка X
.
Если X
является членом , либо список, затем Ys
пропускает X
- это не уникально !
В противном случае X
является уникальным иэто происходит в Ys
(в качестве заголовка списка).
Давайте выполним некоторые из вышеуказанных запросов, используя SWI-Prolog 8.0.0:
?- list_uniques(Xs, Ys).
Xs = [], Ys = []
; Xs = [_A], Ys = [_A]
; Xs = [_A,_A], Ys = []
; Xs = [_A,_A,_A], Ys = []
...
?- list_uniques([], []).
true.
?- list_uniques([1,2,2,1,3,4], [3,4]).
true.
?- list_uniques([a,b,b,a], []).
true.
?- list_uniques([1,2,2,1,3,4], Xs).
Xs = [3,4].
?- list_uniques([n,i,x,o,n], Xs).
Xs = [i,x,o].
?- list_uniques([i,s,p,y,i,s,p,y], Xs).
Xs = [].
?- list_uniques([A,B], [X,Y]).
A = X, B = Y, dif(Y,X).
?- list_uniques([A,B,C], [D,E]).
false.
?- list_uniques([A,B,C,D], [X]).
A = B, B = C, D = X, dif(X,C)
; A = B, B = D, C = X, dif(X,D)
; A = C, C = D, B = X, dif(D,X)
; A = X, B = C, C = D, dif(D,X)
; false.