在SWI-Prolog中实施部分评估

And*_*een 7 prolog swi-prolog

我正在为Prolog查询编写部分评估程序.我试图使用扩展查询expand_goal/2,但它简单地将其InputOutput本例结合:

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

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

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

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

And*_*een 5

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

:- initialization(main).
main :- clause(is_between(1,2,3),B),writeln(B).
is_between(A,B,C) :- A<B,C>B.
Run Code Online (Sandbox Code Playgroud)

此示例打印1<2,3>2.

可以使用findall/3谓词扩展多个子句:

:- 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.
Run Code Online (Sandbox Code Playgroud)

此示例打印1<2,3>2;2>1,2<3.

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