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 に答える