Пролог, считая с интервала; (SWI-Prolog) - PullRequest
0 голосов
/ 19 октября 2010

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

Вот мой код (SWI-PROLOG)

count(O, _, O).
count(A, B, C) :- count(A, B, D), C is D+1, C =< B.

Это работает вроде как, я могу получить результаты C=1, C=2, C=3, C=4, если наберу count(1, 4, C). Однако, если я застряну в конце, это приведет к ошибке с переполнением стека.

Вопрос в том, как мне это остановить? Я перепробовал почти все. = (

Спасибо за ваш ответ!

Ответы [ 3 ]

2 голосов
/ 19 октября 2010

SWI-Prolog имеет встроенную функцию для этого ...

?- help(between).
between(+Low, +High, ?Value)
    Low  and High are  integers, High >=Low.   If  Value is an  integer,
    Low=< Value=< High.   When Value  is a  variable it is  successively
    bound  to  all integers  between  Low and  High.    If High  is  inf
    or  infinite between/3 is  true iff Value>= Low,  a feature that  is
    particularly  interesting  for generating  integers from  a  certain
    value.

true.

?- between(1, 4, Value).
Value = 1 ;
Value = 2 ;
Value = 3 ;
Value = 4.

?- 
0 голосов
/ 07 февраля 2014

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

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

countAtoB(A,B,A) :-
    A =:= B, !.

countAtoB(A,B,A) :-
    A < B.

countAtoB(A,B,I) :- 
    A < B, 
    X is A+1,  
    countAtoB(X,B,I).

Тогда запросы будут выглядеть так. Для сравнения я повторил тот же набор тестовых запросов, используя между / 3 , сразу после.

?- countAtoB(1,4,I).
I = 1 ;
I = 2 ;
I = 3 ;
I = 4.

?- countAtoB(4,4,I).
I = 4.

?- countAtoB(4,1,I).
false.

?- countAtoB(4,1,1000).
false.

?- between(1,4,I).
I = 1 ;
I = 2 ;
I = 3 ;
I = 4.

?- between(4,4,I).
I = 4.

?- between(4,1,I).
false.

?- between(4,1,1000).
false.

?-
0 голосов
/ 19 октября 2010

Это

count(A, B, C) :- count(A, B, D), ...

вызывает бесконечную рекурсию.

Просто измените порядок предикатов, например:

count(A, B, A) :- A =< B.
count(A, B, C) :- A < B, A2 is A+1, count(A2, B, C).
...