Гилог термины в (XSB) Пролог

Термины Hilog (то есть соединения, имеющие в качестве функторов произвольные термины) по-прежнему считаются мощной функцией в Прологе XSB (или любом другом Прологе)? Много ли проектов XSB в настоящее время используют эту функцию? какой из них например?

Я спрашиваю, поскольку, насколько я понимаю, программирование высшего порядка в равной степени возможно с использованием встроенного вызова ISO /N.

В частности, я хотел бы понять, использует ли XSB термины Hilog только по историческим причинам или термины Hilog имеют значительные преимущества по сравнению с текущим стандартом ISO.

1 ответ

Решение

В XSB термины Hilog очень сильно связаны с модульной системой, которая уникальна для XSB. XSB имеет модульную систему на основе функторов. То есть в пределах одной и той же области length(X) может принадлежать одному модулю, тогда как length(L, N) может принадлежать другому. Как следствие, call(length(L), N) может относиться к одному модулю и call(length(L, N)) другому:

[Patch date: 2013/02/20 06:17:59]
| ?- use_module(basics,length/2).
yes
| ?- length(Xs,2).             
Xs = [_h201,_h203]
yes
| ?- call(length(Xs),2).
Xs = [_h217,_h219]
yes
| ?- use_module(inex,length/1). 
yes
| ?- length(Xs,2).
Xs = [_h201,_h203]
yes
| ?- call(length(Xs),2).
++Error[XSB/Runtime/P]: [Existence (No module inex exists)]  in arg 1 of predicate load
| ?- call(call(length,Xs),2).
Xs = [_h228,_h230];

Возможно, в таком контексте существуют различия между call/N и Hilog условия. Я, однако, до сих пор не нашел ни одного.

Исторически, термины Hilog были введены в 1987-1989 гг. В тот момент времени, call/N уже существовали как встроенные в NU и как library(call) в Quintus Prolog только с краткой документацией. Это было предложено в 1984 году Ричардом О'Кифом. С другой стороны, call/N было явно неизвестно авторам Hilog, как это показано на с.1101 Вейдонга Чена, Майкла Кифера, Дэвида Скотта Уоррена: HiLog: семантика первого порядка для логических программных конструкций более высокого порядка. НАКЛП 1989. 1090-1114. MIT-Press.

... Общее транзитивное замыкание также можно определить в Прологе:

    closure(R, X, Y) :- C =.. [R, X, Y], call(C).
    closure(R, X, Y) :- C =.. [R, X, Z], call(C), closure(R, Z, Y). 

Тем не менее, это явно не элегантно по сравнению с HiLog (см. Раздел 2.1), так как это включает в себя как создание термина из списка, так и отражение этого термина в атомарной формуле с использованием "вызова". Смысл этого примера в том, что отсутствие теоретических основ для конструкций более высокого порядка в Прологе привело к неясному синтаксису, что частично объясняет, почему программы Пролога, использующие такие конструкции, как известно, трудно понять.

Теперь это можно сделать с call/N вот так:

closure(R, X, Y) :- call(R, X, Y).
closure(R, X, Y) :- call(R, X, Z), closure(R, Z, Y).

Что является еще более общим, чем (=..)/2-версия потому что R больше не ограничен тем, чтобы быть атомом. Кроме того, я бы предпочел написать:

closure(R_2, X0,X) :- call(R_2, X0,X1), closure0(R_2, X1,X).

closure0(_R_2, X,X).
closure0(R_2, X0,X) :- call(R_2, X0,X1), closure0(R_2, X1,X).

HiLog позволяет цели, такие как

foo(X(a, Y(b))). 

а ISO Prolog - нет. В ISO Prolog вам нужно будет написать

foo(T), T=..[X, a, R], R=..[Y, b].

что менее удобно и может быть медленнее.

Другие вопросы по тегам