我正在尝试编写一个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。 我正在考虑在列表中改变目标,但我不太确定。
有什么想法吗?
答案 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)