1

私はアルゴリズムを書き、それをPrologに実装しようとしましたが、括弧が期待どおりに機能しないことがわかりました。括弧を終了する前に、書き込まれた内容がすべて完了しているわけではありません。コードは次のとおりです。

%1. If the first member of L1 is smaller than L2
%     A. If the first member of L1 is not equal to Last
%            Than: A.1 Add the first member of L1 to the first member of NL
%                  Begin recurssion on the resumption of L1, L2 resumption of NL
%                  and Last from L1.
%            Else: A.2  begin the recursion on resumption of L1, L2 with the
%                       first member and L3 with the first member.
%  2. If the first member in L1 is equal to the first member of L2,
%             Than: Start recursion on resumption of L1 and L2 (with its first
%                   member) and Last = *.
%  3. If the first member of L1 is bigger than the first membber of L2
%             Than: begin recursion on L1 with the first member, resumption of
%             L2 and Last = x. %(x != * only for debugging)
%  

                              */
make_list([X1|L1], [X2|L2], [X3|NewL], Last) :-
    (
        X1 < X2,
        (
            X1 \= Last,   %A
            X3=X1;
            make_list(L1, [X2|L2], NewL, X1) %B
        ),  %Why those parenthesis do not work as expected?

        ! %green cut
    );
    (
        X1=X2,
        make_list(L1, [X2|L2], [X3|NewL], *)
    ),
    !
    ;
    make_list([X1|L1], L2, [X3|NewL], *).

B私の質問は、それを期待どおりに機能させる方法と、一度実行すると機能しないのはなぜAですか?結局のところ、それも同じ括弧内にあります。例:

?- make_list([6,6,10,20],[10,25,30],L, -).
L = [6|_G849]  % (should be [6,20]).

EDIT1:make_listは、にL1含まれていないすべてのメンバーを検索L2してNewLに配置し、解析されLastた最後のメンバーを格納する必要がありL1ます。

EDIT2:いいえ->は許可されています(これはhowmeworkです)。誰かが私にそれ以外の場合はプロローグで表現する方法を教えてくれるなら、それは素晴らしいことかもしれません。

4

2 に答える 2

1

あなたの「グリーンカット」はまったくグリーンではないのではないかと思います。あなたが持っている

( A ; B ), !

したがって(A ; B)、最初の終了時に、Aが成功した場合、Bそれはもう試行されません。これは、カット!がここで言っていることです。これ以上試行しないでください。

あなたBも試してみたい場合は、カットを削除して!ください。

If-then-elseは次のとおりです。

ifte(A,B,C):- A, B.
ifte(A,B,C):- \+A, C.

notを使用して私たちを惜しまないことができますcut

ifte(A,B,C):- A, !, B.
ifte(A,B,C):- C.

あなたのコードについて:私たちand thenはコンマで表現します:A,B。Lastを出力するには、「seen-last」という追加の引数を指定して、作業述語を使用するのが最も簡単です。そしてベースケースでは、最終的に最後に見られ、出力が統一されます。

于 2012-08-11T15:02:33.270 に答える
1

つまり!/0、述語レベルで適用されます。ここでは、ブロックがとで区切られるブロックレベルに適用する必要が(あり)ます。ブロックに適用されるカットのこの概念は、Prologには存在しません。カットは、述語内の位置まで、遭遇したすべての選択ポイントを消去します。

そして、多くの使用法でコードを書く(;)/2代わりに、読みやすくするために、代わりに新しい句を導入することを検討してください(かっこや理解(;)/2(,)/2優先順位が好きではないためです):

c :- A; B.

書くことができます

c :- A.
c :- B.

多くの場合、この方法の方が優れています。コードを簡単に作成し、保守し、読み取り、拡張する方がよいでしょう。

私はあなたの述語を深く見たりはしませんでした、ただそれらの2つのことについて言及したかっただけです。

于 2012-08-11T16:06:57.780 に答える