在Prolog Interpreter中更改目标执行顺序

时间:2013-03-25 08:37:15

标签: prolog metaprogramming

我正在尝试编写一个Prolog元解释器来选择目标执行的顺序,例如用最少的参数执行所有目标。

我从vanilla元解释器开始:

solve2(true).
solve2(A) :- builtin(A), !, A.
solve2((A,B)) :- solve2(A), solve2(B).
solve2(A) :- clause(A,B), solve2(B).

然后我去了

之类的东西
solve2(true).
solve2(A) :- builtin(A), !, A.
solve2((A,B)) :- count(A,Args), count(B,Args2), Args<Args2, solve2(A), solve2(B).
solve2((A,B)) :- count(A,Args), count(B,Args2), Args>Args2, solve2(B), solve2(A).
solve2(A) :- clause(A,B), solve2(B).

但是如果执行第4行,则在A之前执行整个块B,这是错误的。

实施例。 A = a(x,y),B =(b(x,y,z),c(x))我想执行c,然后是a,然后是b。 - 在这种方法中我会得到c,b然后是a。 我正在考虑在列表中改变目标,但我不太确定。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

这是一个(未经测试的)vanilla元解释器,其连接顺序已更改。如果您可以尝试使用您的数据,我会很高兴。

solve2(true).
solve2(A) :- builtin(A), !, A.
solve2((A,B)) :- ordering(A,B, C,D), ! /* needed */, solve2(C), solve2(D).
solve2(A) :- clause(A,B), solve2(B).

ordering(A,B, C,D) :-
    minargs(A, NA),
    minargs(B, NB),
    ( NA =< NB -> C/D=A/B ; C/D=B/A ).

minargs((A,B), N) :-
    minargs(A, NA),
    minargs(B, NB),
    !, ( NA =< NB -> N=NA ; N=NB ).
minargs(T, N) :-
    functor(T, _, N).

编辑我使用此设置进行了测试:

builtin(writeln(_)).

a(1):-writeln(1).
b(1,2):-writeln(2).
c(1,2,3):-writeln(3).

test :-
    solve2((c(A,B,_),a(A),b(A,B))).

并获得预期的输出:

?- test.
1
2
3
true .

编辑我不得不求助于列表表示,但是预处理子句并在之前获得正确的顺序是有意义的,然后坚持使用简单的vanilla解释器:

test :-
    sortjoin((b(A,B),a(A),c(A,B,_)), X),
    solve2(X).

sortjoin(J, R) :-
    findall(C-P, (pred(J, P), functor(P,_,C)), L),
    sort(L, T),
    pairs_values(T, V),
    join(V, R).

join([C], C).
join([H|T], (H,R)) :- join(T, R).

pred((A, _), C) :-
    pred(A, C).
pred((_, B), C) :-
    !, pred(B, C).
pred(C, C).

其中solve2((A,B)) :- ...是原始solve2(A),solve2(B)