Реализация частичной оценки в SWI-Prolog


Я пишу частичный оценщик для запросов пролога. Я попытался расширить запрос с помощью expand_goal/2, но он просто объединяет Input с Output в этом случае:

:- 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, но это приводит к сбою программы:

:- 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 встроенный предикат, который может выполнять макрорасширение запросов во время выполнения, как я пытался сделать здесь?

1 6

1 ответ:

Можно расширить предложение пролога, используя встроенный clause/2 сказуемое:

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

В этом примере выводится 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.

В этом примере выводится 1<2,3>2;2>1,2<3.