Как я могу получить пары последовательных элементов в Прологе? - PullRequest
0 голосов
/ 25 апреля 2020

Мне нужно решить задачу, в которой одной задачей является получение последовательных пар массива.

Например, если массив [1, 2, 3], результат должен быть X = 1 Y = 2 и X = 2 Y = 3

До этого момента мой код работает нормально, но после этого он не выдает «нет». Вместо этого он придерживается бесконечного l oop. Сложность в том, что Я должен сделать это без рекурсии .

Мой код на данный момент следующий:

part_of(X, Y, List):-
    length(X, 1),
    append(_, X, Part),
    length(Y, 1),
    append(Part, Y, Part2),
    append(Part2, _, List).

Я не знаком с логи c программирование. Все, что приходит мне в голову, связано с возвращением значений, что, конечно, здесь не так.

Ответы [ 3 ]

3 голосов
/ 27 апреля 2020

X и Y являются последовательными элементами некоторого List, если List имеет следующую форму: некоторый список Prefix, затем X, затем Y, затем некоторый список Rest .

Это то, что вы пытались express, но вы запутались в некоторых деталях. Сначала одноэлементный список , содержащий X, записывается как [X]. Вероятно, это то, что вы пытались сказать с помощью length(X, 1), но это не сработало бы так, как написано.

Во-вторых, вы запутались в использовании append/3. То, как вы пытаетесь его использовать, последний аргумент - это весь список, который вы пытаетесь разложить. Таким образом, в этом сценарии третьим аргументом всегда должен быть список, который уже известен - либо потому, что он передан в качестве аргумента, либо потому, что он был вычислен по более ранней цели. В вашем коде первая append/3 цель - append(_, X, Part), где оба _ и Part неизвестны. В этих обстоятельствах существует бесконечное количество решений, которые вызывают неопределенность, которую вы видите:

?- append(_, X, Part).
X = Part ;
Part = [_G2897|X] ;
Part = [_G2897, _G2903|X] ;
Part = [_G2897, _G2903, _G2909|X] ;
Part = [_G2897, _G2903, _G2909, _G2915|X] ;
Part = [_G2897, _G2903, _G2909, _G2915, _G2921|X] .

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

?- List = [1, 2, 3], append(Prefix, Part1, List), append([X], Part2, Part1), append([Y], Rest, Part2).
List = Part1, Part1 = [1, 2, 3],
Prefix = [],
X = 1,
Part2 = [2, 3],
Y = 2,
Rest = [3] ;
List = [1, 2, 3],
Prefix = [1],
Part1 = [2, 3],
X = 2,
Part2 = [3],
Y = 3,
Rest = [] ;
false.

Сначала разбивает известный список List = [1, 2, 3] на части, которых только конечное число. Это связывает Part1 с конечным списком. Затем он разбивает конечный список Part1, связывая Part2 с конечным списком, и, наконец, разделяет его. Нет места для нетерминирования, если начальный List является конечным списком.

Все это говорит о том, что существует более простой способ выражения "некоторого списка, чем два смежных элемента X и Y, тогда какой-то другой список ":

?- append(_Prefix, [X, Y | _Rest], [1, 2, 3]).
_Prefix = [],
X = 1,
Y = 2,
_Rest = [3] ;
_Prefix = [1],
X = 2,
Y = 3,
_Rest = [] ;
false.
0 голосов
/ 27 апреля 2020

Вот как я бы это сделал:

pairs([X,Y|_],X,Y).
pairs([_,Y|T],A,B) :- pairs([Y|T],A,B).

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

Второй предикат успешно выполняется, когда он может убрать первый элемент из списка и рекурсивно вызвать pairs/2, чтобы получить следующую пару.

Вот вывод моего прогона:

?- pairs([a,b,c],X,Y).
X = a,
Y = b ;
X = b,
Y = c ;
false.
0 голосов
/ 26 апреля 2020

Вот мое очень простое решение.

show_elements([X|[]],  _, _).
show_elements([X, Y|Q], A, B):- A is X, B is Y; show_elements([Y|Q], A,B).

Вот фотография результата, я не знаю, правильно ли я понял задачу.

Program output

Как видите, я использовал рекурсию для решения проблемы. Убедитесь, что вы правильно понимаете рекурсию. Это часто используется в Прологе.

Также проверьте концепцию объединения. Необходимо начать писать программы на прологе.

В Интернете много материала, и вы можете проверить это очень полезное руководство: Lean Prolog сейчас!

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