Реализация предиката Пролога 'is/2'
-
20-12-2019 - |
Вопрос
Как реализуется предикат Пролога is/2?я знаю это
X is 3*4
эквивалентно
is(X, 3*4)
Но реализован ли предикат с помощью императивного программирования?Другими словами, эквивалентна ли реализация следующему коду C?
if(uninstantiated(x))
{
X = 3*4;
}
else
{
//signal an error
}
Или это реализовано с помощью декларативного программирования и других предикатов?
Решение
зависит от вашего пролога, очевидно, но любая практическая реализация сделает свою грязную работу в C или другом императивном языке.Часть генеракодицетагкода может быть смоделирована в чистом прологе:
is(X, Expr) :-
evaluate(Expr, Value),
(var(X) ->
X = Value
;
X =:= Value
).
.
Где is/2
является огромным предикатом, который знает о арифметических выражениях.Существуют способы реализации больших частей его в чистого прологе, но это будет как медленно, так и больно.Например.Если у вас есть предикат, который добавляет целые числа, вы можете умножить их, а также использовать следующий (глупый) алгоритм:
evaluate(X + Y, Value) :-
% even this can be done in Prolog using an increment predicate,
% but it would take O(n) time to do n/2 + n/2.
add(X, Y, Value).
evaluate(X * Y, Value) :-
(X == 0 ->
Value = 0
;
evaluate(X + -1, X1),
evaluate(X1, Y, Value1),
evaluate(Y + Value1, Value)
).
.
Ничто из этого не гарантируется практичным, либо правильным;Я просто показывая, как арифметика может быть реализована в прологе.
Другие советы
будет зависеть от версии пролога;Например, CPROLS (неудивительно), написанный в C, поэтому все встроенные предикаты реализованы на императивном языке.
Пролог был разработан для синтаксического анализа языка.Итак, арифметическое выражение вида
3 + - ( 4 * 12 ) / 2 + 7
после синтаксического анализа — это просто термин пролога (представляющий дерево синтаксического анализа), с operator/3
предоставление семантики для управления работой синтаксического анализатора.Для основных арифметических выражений используются термины
'-'/2
.Отрицание'*'/2
,'/'/2
.Умножение, деление'+'/2
,'-'/2
.Сложение, вычитание
Пример выражения выше анализируется как
'+'( '+'( 3 , '/'( '-'( '*'(4,12) ) , 2 ) ) , 7 )
'is'/2
просто выполняет рекурсивный обход дерева синтаксического анализа, представляющего правую часть, оценивая каждый термин почти так же, как это делает калькулятор RPN (обратная польская нотация).Как только это выражение вычислено, результат объединяется с левой частью.
Каждая основная операция — сложение, вычитание, умножение, деление и т. д.— должно выполняться в машинном коде, поэтому в конце дня вызывается некоторая подпрограмма машинного кода для вычисления результата каждой элементарной операции.
Ли is/2
написан полностью на собственном коде или написан в основном на прологе, и только листовые операции написаны на собственном коде, это в значительной степени выбор реализации.