Вывод, кажется, проверяет только самую последнюю в списке функцию разности - PullRequest
0 голосов
/ 30 сентября 2018

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

Я опубликовал свой прогресс в другом посте с вопросом, но вот мой код, моя проблема, которой я являюсьпытаюсь решить в прологе.Я хотел бы, чтобы моя функция возвращала результат sameSeqDiffs ([3,5,7], 2) в зависимости от того, совпадает ли разница между каждым числом с моим последним аргументом.Вот то, с чем я пока что справляюсь:

sameSeqDiffs([X,Y], Result):-
    A is Y - X,
    A = Result.

sameSeqDiffs([X,Y,Z|T], Result):-
    sameSeqDiffs([Y,Z|T], Result).

Когда я тестирую этот код, кажется, что он работает для некоторых входных данных, но явно не работает для других:

enter image description here

Ответы [ 3 ]

0 голосов
/ 30 сентября 2018

По сути, вы забыли одну вещь: вычислить разницу в рекурсивном случае:

sameSeqDiffs([X,Y], Result):-
    A is Y - X,
    A = Result.

sameSeqDiffs([X,Y,Z|T], Result):-
    <b>Result is Y - X,</b>
    sameSeqDiffs([Y,Z|T], Result).

Так что здесь мы объединяем Result с разницей между Y и X.Мы делаем повторный вызов с этим различием, так что «более глубокий» рекурсивный вызов объединится с уже обоснованным различием.Если различия не совпадают, то предикат потерпит неудачу.

Вы также можете сделать первое предложение более элегантным, немедленно используя Result в вызове предиката is/2 вместо первого использованияпеременная (A), а затем объединяя ее, так:

sameSeqDiffs([X,Y], Result):-
    <b>Result</b> is Y - X.

sameSeqDiffs([X,Y,Z|T], Result):-
    Result is Y - X,
    sameSeqDiffs([Y,Z|T], Result).

Затем мы получаем следующие результаты:

?- sameSeqDiffs([3, 5, 7], D).
D = 2 ;
false.

?- sameSeqDiffs([3, 5, 7], 2).
true ;
false.

?- sameSeqDiffs([3, 5, 7], 4).
false.

?- sameSeqDiffs([2, 3, 4], 1).
true ;
false.

?- sameSeqDiffs([2, 3, 4, 6], 2).
false.

?- sameSeqDiffs([2, 3, 4, 6], 1).
false.

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

0 голосов
/ 01 октября 2018

Для подобных проблем самое время узнать о CLP (FD), который является частью Prolog, используемой для рассуждения целых чисел:

same_seq_dif([X,Y], R) :- Y - X #= R.
same_seq_dif([X,Y,Z|T], R) :-
    Y - X #= R,
    same_seq_dif([Y,Z|T], R).

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

| ?- same_seq_dif([X,5,7], R).

R = 2
X = 3 ? ;

no
| ?- length(L,3), same_seq_dif(L, 3), fd_labeling(L).

L = [0,3,6] ? ;

L = [1,4,7] ? ;

L = [2,5,8] ? ;

L = [3,6,9] ? ;

L = [4,7,10] ?
...

Я использую GNU Prolog, таким образом, предикат fd_labeling/1.SWI имеет аналогичный предикат, label/1.

0 голосов
/ 30 сентября 2018

У вашего решения есть несколько проблем:

sameSeqDiffs([X,Y,Z|T], Result):-
    sameSeqDiffs([Y,Z|T], Result).

Здесь вы полностью игнорируете переменную X и разницу XY.

sameSeqDiffs([X,Y], Result):-
    Result is Y - X.

sameSeqDiffs([X,Y,Z|T], Result):-
    Result is Y - X,
    sameSeqDiffs([Y,Z|T], Result).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...