2016-03-05 6 views
2

Я видел Prolog Prologue определения between/3:Может ли между/3 не быть рекурсивным?

between(Lower, Upper, Lower) :- 
    Lower =< Upper. 
between(Lower1, Upper, X) :- 
    Lower1 < Upper, 
    Lower2 is Lower1 + 1, 
    between(Lower2, Upper, X). 

Я не понимаю, почему он требует рекурсии. Логическое определение between может быть:

between(Lower, Upper, Something):- 
    Lower =< Upper, 
    Lower =< Something, 
    Something =< Upper. 

Я попробовал на gprolog и она работает, но только для простых запросов:

| ?- between(0,5,1). 

yes 

Для запросов с переменными я получаю:

| ?- between(0,5,X). 
uncaught exception: error(instantiation_error, (=<)/2) 

Я действительно не понимаю, почему.

I вид фигуры Пролог нуждается в каком-то ссылочном номере, чтобы объединить переменные против, но почему критическая ошибка на (=<)/2?

ответ

5

Ошибка не такая загадочная, как только вы знаете, что общая арифметика в Prolog. Короче говоря, просто нужно сделать нелогичный, «рассчитать это и дать мне ответ» вроде арифметики. Сравнения (поэтому все </2, =</2, =:=/2 и т. Д.) Требуют, чтобы у вас были арифметические выражения с обеих сторон; is/2 предполагает, что он имеет арифметическое выражение слева и свободную переменную справа. Таким образом, вы можете делать такие вещи, как:

?- X is 3^1.3. 
X = 4.171167510947728. 

?- 1 =:= sin(pi/2). 
true. 

Если вы на самом деле читать руководство по GNU-Пролог достаточно тщательно, вы должны найти, в начале relevant section, следующие два предложения:

An арифметическое выражение - это термин Пролог, построенный из чисел, переменных и функторов (или операторов), которые представляют арифметические функции. Когда выражение оценивается , каждая переменная должна быть привязана к непеременному выражению.

(выделено мной)

Предикаты как between/3, plus/3 или succ/2 являются примерами специального назначения целочисленной арифметики. Они используют их. Однако большинство применений для выполнения фактической целочисленной математики были заменены CLPFD. Для GNU-Prolog, вы должны consult the documentation, но за короткий пример, подражать between/3, вы могли бы сказать:

?- fd_domain(X, 0, 2), fd_labeling(X). 
X = 0 ? ; 
X = 1 ? ; 
X = 2 
yes 

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

Смежные вопросы