2

我想知道是否有一个只有一条规则的纯 Prolog 元解释器。通常的 Prolog vanilla 元解释器有两个规则。内容如下:

solve(true).
solve((A, B)) :- solve(A), solve(B). /* rule 1 */
solve(H) :- program(H, B), solve(B). /* rule 2 */

这个 Prolog vanilla 元解释器使用两个规则/* rule 1 *//* rule 2 */. 剩下的就是事实。执行的程序由程序事实表示。这是一个示例程序:

program(append([], X, X), true).
program(append([X|Y], Z, [X|T]), append(Y, Z, T)).
program(nrev([], []), true).
program(nrev([H|T], R), (nrev(T, S), append(S, [H], R))).

还有一个示例查询:

?- solve(nrev([1,2,3], X)).
X = [3, 2, 1] .

有没有办法将程序以不同的方式表示为事实,然后编写一个不同的元解释器,它只使用事实,除了一个规则而不是两个规则?适用于所有纯 Prolog 程序的东西,而不仅仅是 nrev 示例?

4

3 回答 3

3

Here is one idea, using a list to hold the rest of the computation:

solve([]).
solve([X|Xs]) :- program(X, Ys, Xs), solve(Ys).

program(true, Xs, Xs).
program(append([],X,X), Xs, Xs).
program(append([X|Y], Z, [X|T]), [append(Y,Z,T)|Xs], Xs).
program(nrev([],[]), Xs, Xs).
program(nrev([H|T],R), [nrev(T,S),append(S,[H],R)|Xs], Xs).

With test call (where one needs to wrap the call in a list).

?- solve([nrev([1,2,3],X)]).
X = [3,2,1] ? ;
no

Arguably, one could represent the program/3 facts as a DCG instead, for increased readability (but then it might not be considered a "fact" any more).

于 2020-12-23T16:05:19.863 回答
0

这是另一种方法,称为连续二值化。它来自 Paul Tarau (2021)
的这篇逻辑转换器论文。

solve(true).
solve(X) :- program(X, Y), solve(Y).

program(append([],X,X,C), C).
program(append([X|Y],Z,[X|T],C), append(Y,Z,T,C)).
program(nrev([],[],C), C).
program(nrev([H|T],R,C), nrev(T,S,append(S,[H],R,C))).

一点点健全性检查表明它在工作:

?- solve(nrev([1,2,3], X, true)).
X = [3, 2, 1] ;
No
于 2021-01-19T02:19:37.327 回答
-1

如果;/2允许,那么这似乎有效:

solve(true).
solve(H) :- ((X, Y) = H, solve(X), solve(Y)); (program(H :- B), solve(B)).

program(append([], X, X) :- true).
program(append([X|Y], Z, [X|T]) :- append(Y, Z, T)).
program(nrev([], []) :- true).
program(nrev([H|T], R) :- (nrev(T, S), append(S, [H], R))).

测试:

?- solve(nrev([1,2,3], X)).
X = [3, 2, 1] ;
false.
于 2020-12-23T15:34:11.220 回答