Что вычисляет X во втором операнде предиката, например «example ([X | L1], [X, X | L2])» - PullRequest
0 голосов
/ 24 октября 2019

Я пытаюсь решить проблему, в которой дублируется каждый элемент списка, для которого решение выглядит следующим образом:

duplicate([],[]).
duplicate([X|Xs],[X,X|Ys]) :-
   duplicate(Xs,Ys).

Я знаю, что Prolog объединяет X с первым элементом списка Xs, но что он объединяет с / делать во втором операнде / списке, если он уже объединен с первым списком?

1 Ответ

1 голос
/ 24 октября 2019

Я попытаюсь объяснить, как работает этот предикат, потому что я думаю, что в ваших ожиданиях того, что собирается делать Пролог, что-то не так, и я не совсем уверен, что это такое. Зачастую новые пользователи Prolog ожидают, что последний аргумент предиката как-то особенный, в эмуляции возвращаемого значения в обычном языке с семантикой вычисления выражений. Ваша формулировка заставляет меня думать, что вы можете подумать, что в Прологе есть что-то процедурное, заставляющее его обрабатывать аргументы слева направо. Ничто из этого не является правдой. Здесь действительно важно то, что создается, когда Пролог идет, чтобы доказать цель.

Самый тупой, но, вероятно, самый конкретный способ увидеть, как Пролог рассуждает об этой цели, - это вызвать его с двумя переменными и посмотреть, что вы получите:

?- duplicate(X,Y).
X = Y, Y = [] ;

X = [_8100],
Y = [_8100, _8100] ;

X = [_8100, _8118],
Y = [_8100, _8100, _8118, _8118] ;

X = [_8100, _8118, _8136],
Y = [_8100, _8100, _8118, _8118, _8136, _8136] .

Вы можете продолжать спрашивать ответы, но, вероятно, вы уже поняли суть. Стоит отметить, что Prolog генерирует оба списка, один со списком уникальных переменных, а второй с дублированными теми же переменными. Это удается сделать, ничего не зная о том, что эти переменные на самом деле. Говоря прямо, это все примеры унификации, которые может выполнять Prolog:

?- X = [Y1,Y2|Ys].
X = [Y1, Y2|Ys].

?- [Y1,Y2|Ys] = X.
X = [Y1, Y2|Ys].

Здесь нет ничего направленного, и у Prolog нет проблем с отрывом кусочков структуры. Вы можете также связать эти переменные в последующем:

?- [Y1,Y2|Ys] = X, Y2 = foo, Ys = [].
Y2 = foo,
Ys = [],
X = [Y1, foo].

То есть выполнение чего-либо с одной и той же переменной несколько раз действительно не проблема вообще:

?- L1 = [X|Xs], L2 = [X,X|Ys].
L1 = [X|Xs],
L2 = [X, X|Ys].

?- L1 = [X|Xs], L2 = [X,X|Ys], X = foo.
L1 = [foo|Xs],
X = foo,
L2 = [foo, foo|Ys].

?- L2 = [X,X|Ys], L1 = [X|Xs], L1 = [1,2,3,4].
L2 = [1, 1|Ys],
X = 1,
L1 = [1, 2, 3, 4],
Xs = [2, 3, 4].

Не знаювижу там что-нибудь удивительное, но я не вижу ничего удивительного и в duplicate/2. Вы нашли что-нибудь из этого удивительного? Если это так, это может помочь мне сузить недоразумение.

Кроме того, вас не должно, но может удивить, увидеть этот другой образец воплощения:

?- duplicate(A, [1,1,2,2,3,3]).
A = [1, 2, 3].

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...