1

次のコンパクトな例では、3 つのパラメーター L1、L2、L3 を取り、L1 と L2 を L3 に追加します (L3 が L1 と L2 の連結であることを確認します)。

私はこのコードを持っています(うまくいきます):

myappend([], L, L).
myappend([X|L1], L2, [X|L]) :- myappend(L1,L2,L).

事実は基本的なケースであり、最初のリストが空リストである場合、最初のリストと 2 番目のリストの連結は 2 番目のリストだけであると言います。

わかりました、これは明らかです...ルールは私にとってはかなり明確です(しかし、まったくそうではありません)このルールは、1番目、2番目、3番目の引数が1番目と2番目の連結の関係を持っているかどうかをテストする述語として考えることができます口論

ルールの先頭自体が満たされるように、前に満たされなければならない (TRUE でなければならない) すべての述語を表すこのルールの本体を持つ拡張形式で前のコードを表現しようとしています。 .

このコードを SWI Prolog に実装するには問題があります。これが私のコードです。

concatena([],L,L).

/* REGOLA */

concatena(L1,L2,L3) :- L1 = [_|T],          /* Always true: anonymous variable: "_" unifies everything */
               concatena(T,L2,L3).     /* Recursively call on the tail of L1 */
           [X|L1],
           [X|L3].

事実は基本ケースです(前の作業例のように)

私の実験では、ルールは異なります。

ルールのヘッドが検証されるように、その本体のすべての述語が true でなければなりません...

基本的なケースに到達するまでは、私のアイデアは良いと思います。実際には次のようにします。

L1 = [_|T],         /* It is always true */
concatena(T,L2,L3)  /* Call recursively on a subproblem of the original problem, this problem have one less element

OK、このようにして基本ケースに到達し、L3 は L2 と正しく統合されます

実際、私が持っているトレースでは:

[trace] 3 ?- concatena([a,b],[c,d],L3).
   Call: (6) concatena([a, b], [c, d], _G1514) ? creep
   Call: (7) [a, b]=[_G1592|_G1593] ? creep
   Exit: (7) [a, b]=[a, b] ? creep
   Call: (7) concatena([b], [c, d], _G1514) ? creep
   Call: (8) [b]=[_G1595|_G1596] ? creep
   Exit: (8) [b]=[b] ? creep
   Call: (8) concatena([], [c, d], _G1514) ? creep
   Exit: (8) concatena([], [c, d], [c, d]) ? 

(これは、元の動作例のトレースを見ると発生するのと同じことです...したがって、ここまでは修正する必要があります)

問題は、プログラムがバックトラックを行うときです。動作しません!!!

実際、トレースにはこれがあります(これは、以前の不完全なトレースを終了する方法です):

Exit: (7) concatena([b], [c, d], [c, d]) ? creep
   Exit: (6) concatena([a, b], [c, d], [c, d]) ? creep
L3 = [c, d] 
4

1 に答える 1

2

ここで何をしようとしているのか完全にはわかりません: すべての引数が単純な変数項になるように myappend ルールの 2 番目の部分を書き直してください。その場合、元の myappend の引数を = 演算子で書き直すことができます。

concatena(L1,L2,L3) :- L1=[X|T], L3=[X|L4], concatena(T,L2,L4).

ここに書いたように、ルールの 2 番目の部分は、

[X|L1],
[X|L3].

. に続くため、ルールの一部としてカウントされていないため、バックトラックはなく、再帰が巻き戻されても何も起こりません。

于 2012-12-20T17:31:58.180 に答える