Implementing partial evaluation in SWI-Prolog

为君一笑 提交于 2019-12-08 17:43:20

问题


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.

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.

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


回答1:


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.

This example prints 1<2,3>2.

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.

This example prints 1<2,3>2;2>1,2<3.

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



来源:https://stackoverflow.com/questions/46614561/implementing-partial-evaluation-in-swi-prolog

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!