В вопросе говорится следующее:

В Прологе неотрицательные целые числа могут быть закодированы как числительные, задаваемые 0 и его преемниками (например, числительное s(s(s(0))) кодирует 3).

число(0).
numeral(s(X)) :- numeral(X).

Определите предикат less/2(X, Y), который имеет место, когда X и Y являются числительными, кодирующими неотрицательные целые числа x и y такие, что x < y. Например,

?- less(0, s(0)).
да.
?- less(s(s(0)), s(s(0))).
нет.

Я смог придумать решение для этого вопроса, однако оно страдает от ограничения. Вот мое решение:

less(X, s(X)) :- numeral(X).
less(X, Z) :- less(X, Y), less(Y, Z).

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

Помогите, пожалуйста.

Rocky

Ответов: 2

Ответы (2)

Попробуйте это:

less2(X, s(X)) :- numeral(X).
less2(X, s(Y)) :- less2(X,Y).

По-моему, это работает; однако ваше решение может бесконечно повторяться, потому что если не существует значения Y между X и Z, оно просто переберет все возможные варианты.

Я бы сделал это следующим образом:

less(0, s(Y)) :- цифра(Y).
less(s(X), s(Y)) :- less(X, Y).

?- less(0, s(0)).
true.

?- less(s(s(0)), s(s(0))).
false.

Идея заключается в том, что 0 меньше любого s(Y), где Y - числительное. Если X не 0, то X - это s(X'), и X = s(X') меньше, чем Y = s(Y'), если X' меньше, чем Y'.

Это работает, только если X и Y являются числительными. Если X не является числительным, то он застрянет где-то в рекурсии и "вернет" false. То же самое для Y, за исключением того, что в конце должна быть проверка, является ли остаток Y числительным.

2022 WebDevInsider