0

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

我从原版元解释器开始:

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 行,那么整个块 B 在 A 之前执行,这是错误的。

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

有任何想法吗?

4

1 回答 1

1

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

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 .

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

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)

于 2013-03-25T10:46:41.820 回答