简体   繁体   English

具有一条规则的纯 Prolog 元解释器

[英]Pure Prolog Meta-Interpreter with one Rule

I wonder whether there is a pure Prolog meta-interpreter with only one rule.我想知道是否有一个只有一个规则的纯 Prolog 元解释器。 The usual Prolog vanilla meta-interpreter has two rules.通常的 Prolog 香草元解释器有两个规则。 It reads as follows:内容如下:

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

This Prolog vanilla meta-interpreter uses two rules /* rule 1 */ and /* rule 2 */ .这个 Prolog 香草元解释器使用两条规则/* rule 1 *//* rule 2 */ And the rest is facts. rest 是事实。 The program that is executed is represented by program facts.被执行的程序由程序事实表示。 Here is an example program:这是一个示例程序:

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))).

And an example query:和一个示例查询:

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

Is there a way to represent the program differently as facts, and then code a different meta-interpreter, which would use only facts except for a single rule instead of two rules?有没有一种方法可以将程序以不同的方式表示为事实,然后编写一个不同的元解释器,它只使用事实,除了一条规则而不是两条规则? Something that would work for all pure Prolog programs, not only the nrev example?适用于所有纯 Prolog 程序的东西,而不仅仅是 nrev 示例?

Here is one idea, using a list to hold the rest of the computation:这是一个想法,使用一个列表来保存计算的 rest:

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).可以说,可以将 program/3 事实表示为 DCG,以提高可读性(但这样它可能不再被视为“事实”)。

Here is another approach, known as binarization with continuation.这是另一种方法,称为连续二值化。
Its from this logic transformers paper here by Paul Tarau (2021).它来自 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))).

A little sanity check shows that it wurks:一点完整性检查表明它有效:

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

If ;/2 is allowed, then this seems to work:如果;/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))).

Test:测试:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM