本文介绍了在 SWI-Prolog 中实现部分评估的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为 Prolog 查询编写一个部分求值器.我尝试使用 expand_goal/2 扩展查询,但在这种情况下,它只是将 InputOutput 统一起来:

I'm writing a partial-evaluator for Prolog queries. I tried to expand a query using expand_goal/2, but it simply unifies the Input with the Output in this case:

:- initialization(main).
main :-
    Input=is_between(1,A,3),expand_goal(Input,Output),writeln(Output).
is_between(A,B,C) :-
    B>A,B<C.

我也尝试使用 term_expansion/2,但这会导致程序失败:

I also tried using term_expansion/2, but this causes the program to fail:

:- initialization(main).
main :-
    Input=is_between(1,A,3),term_expansion(Input,Output),writeln(Output).
is_between(A,B,C) :-
    B>A,B<C.

SWI-Prolog 是否有一个内置谓词可以在运行时执行查询的宏扩展,就像我在这里尝试做的那样?

Does SWI-Prolog have a built-in predicate that can perform macro-expansion of queries at runtime, as I tried to do here?

推荐答案

可以使用内置的 clause/2 谓词.这个谓词像卫生宏一样扩展子句:

It is possible to expand a Prolog clause using the built-in clause/2 predicate. This predicate expands the clause like a hygienic macro:

:- initialization(main).
main :- clause(is_between(1,2,3),B),writeln(B).
is_between(A,B,C) :- A<B,C>B.

这个例子打印12.

可以使用 findall/3 谓词:

It is possible to exand multiple clauses using the findall/3 predicate:

:- initialization(main).
main :- find_all_clauses(is_between(1,2,3),B),writeln(B).

find_all_clauses(Predicate,Output) :-
    findall(Predicate1,clause(Predicate,Predicate1),Output1),
    list_to_disjunction(Output1,Output).

list_to_disjunction([A],A).
list_to_disjunction([A|B],(A;B1)) :- list_to_disjunction(B,B1).

is_between(A,B,C) :- A<B,C>B.
is_between(A,B,C) :- B>A,B<C.

此示例打印 12;2>1,2.

我还编写了另一个部分评估器,以递归方式扩展目标.Prolog 中还有其他一些用于部分评估的开源库,例如 eccelogen.

I also wrote another partial evaluator that expands the goals recursively. There are a few other open-source libraries for partial evaluation in Prolog, such as ecce and logen.

这篇关于在 SWI-Prolog 中实现部分评估的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-11 19:47