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

Я новичок в использовании арифметики в Прологе.

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

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

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

Обновление 1: Это то, что я придумал до сих пор.Я новичок в этом синтаксисе и все еще получаю сообщение об ошибке в моем коде, но я надеюсь, что он передает общее представление о том, что я пытаюсь сделать.

diff([X,Y|Rest], Result):-
    diff([Y,Z|Rest], Result2):-
       Result2 = Result,
       Z - Y = Result.

Обновление 2: я знаю, что мне еще многое предстоит сделать с этим кодом, но здесь я останусь до этих выходных, у меня есть еще кое-что сделать.Я думаю, что понимаю логику этого немного больше, и я думаю, что мне нужно выяснить, как запустить последнюю строку функции, только если в остальной части списка есть еще как минимум две вещи для обработки.

diff([X,Y|Rest], Result):-
    number(Y),
    Y-X=Result,
    diff([Rest], Result).

Обновление 3: Я полагаю, что у меня есть такая функция, которую я хочу.Единственное, что я заметил, это то, что при запуске и вводе: sameSeqDiffs([3,5,7],2). я сразу получаю значение true, за которым следует false.Это правильная операция, или я все еще что-то упускаю?

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

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

Обновление 4: я отправил новый вопрос об этом .... вот ссылка: Вывод, кажется, только проверить самупоследний в списке для функции разности

Ответы [ 2 ]

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

Вы были очень близки со второй попыткой.Это должно было быть

samediffs( [X,  Y | Rest], Result):-
    Result is Y - X,
    samediffs( [Y | Rest], Result).

И вам даже не нужно «выделять первые два элемента из списка».Это позаботится о себе.

Как?Все просто: вызов samediffs( List, D) для первой записи в предикате означает, что , еще не созданный D = Result, будет создан для вычисленной разницы между вторым и первым элементом в списке с помощью вызова Result is Y - X.

При каждой последующей записи в предикат, то есть для каждой последующей пары элементов X, Y в списке, вызов Result is Y - X будетвычислите разницу для этой пары и проверит числовое равенство для нее и Result, которая в этой точке содержит ранее вычисленное значение.

В случае, если они не равны,предикат потерпит неудачу.

В этом случае рекурсия продолжится.

Единственное, чего не хватает, это базового случая для этой рекурсии:

samediffs( [_], _Result).  
samediffs( [], _Result).

В случае, если онобыл одноэлементным (или даже пустым) списком все это время, это оставит аргумент различия _Result необоснованным.В таком случае это может быть интерпретировано как предикат проверки.Разумеется, нет никаких неравных различий между элементами в одноэлементном (или, тем более, в пустом) списке.


В общем, ......

recursion(A, B):- base_case( A, B).

recursion(  Thing,  NewThing):-
  combined( Thing,             Shell, Core),
  recursion(                          Core, NewCore),
  combined(         NewThing,  Shell,       NewCore).

...... рекурсия!

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

Синтаксис Пролога

Синтаксис немного отключен: обычно у предложения есть заголовок, подобный foo(X, Y, Z), затем стрелка (:-), за которой следует тело.Это тело обычно не содержит стрелок :-.Поэтому вторая стрелка :- не имеет особого смысла.

Предикаты и объединение

Во-вторых, в предикатах Пролога нет входных или выходных данных , aпредикат - true или false (ну, он также может ошибаться или застревать в бесконечном цикле, но это типичное поведение, которое мы хотим избежать).Он передает ответы с помощью , объединяющих переменных.Например, звонок sameSeqDiffs([3, 5, 7, 9], X).может преуспеть, объединив X с 2, и тогда предикат - при условии, что он реализован правильно - вернет true..

Индуктивные определения

ВДля разработки предиката, как правило, в первую очередь ставится задача создать индуктивное определение : определение, состоящее из одного или нескольких базовых случаев и одного или нескольких «рекурсивных» случаев (где предикат определенчастями самого себя).

Например, здесь мы можем сказать:

(базовый случай) Для списка из ровно двух элементов [X, Y],Предикат sameSeqDiffs([X, Y], D) выполняется, учитывая, что D - это разница между Y и X.

В Прологе это будет выглядеть следующим образом:

sameSeqDiffs([X, Y], D) :-
    ___.

___ заполняется).

Теперь для индуктивного случая мы можем определить sameSeqDiffs/2 в терминах самого себя, хотя не с теми же параметрами, конечно.В математике иногда определяют функцию f , например, f (i) = 2 × f (i-1) ;например, f (0) = 1 в качестве базы.Аналогичным образом можно определить индуктивный регистр для sameSeqDiffs/2:

(индуктивный регистр) Для списка из более чем двух элементов все элементы в списке имеютта же разница, учитывая, что первые два элемента имеют разницу D, а в списке элементов, кроме первого, все элементы также имеют эту разницу D.

В Прологе это будетвыглядят так:

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

Арифметика в Прологе

Распространенная ошибка, которую люди, начинающие программировать на Прологе, заключаются в том, что они думают, что, как это принято во многих языках программирования, Пролог добавляет семантику к определеннымфункторы.

Например, можно подумать, что A - 1 будет уменьшать A.Для Пролога это, однако, всего лишь -(A, 1), это не минус или что-то еще, просто функтор.В результате Prolog будет не оценивать такие выражения.Итак, если вы напишите X = A - 1, тогда X будет просто X = -(A,1).

Тогда как мы можем выполнять числовые операции?Системы Prolog имеют предикат is/2, который оценивает правую часть, добавляя семантику к правой стороне.Таким образом, предикат is/2 будет интерпретировать функторы (+)/2, (-)/2 и т. Д. ((+)/2 как плюс, (-)/2 как минус и т. Д.).

Итакмы можем оценить выражение как:

A = 4, is(X, A - 1).

и тогда X будет установлено в 3, , а не 4-1.Пролог также позволяет записывать инфикс is, например:

A = 4, X is A - 1.

Здесь вам понадобится вычислить разницу между двумя элементами.

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