次のコンパクトな例では、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]