2

emptyリスト2の要素をリスト1に含まれている場合に呼び出されるアトムに置き換えるために、いくつかのPrologを作成しました。

replace_build([], _Inv, _Res).

replace_build([A| B], Inv, Res) :-
    replace_build2(A, Inv, Res), replace_build(B, Inv, Res).

replace_build2(_BuildItem, [], _NewInv) :- !.

replace_build2(BuildItem, [BuildItem| T], NewInv) :-
    replace_build2(BuildItem, T, NewInv1),
    append([empty], NewInv1, NewInv).

replace_build2(BuildItem, [H| T], NewInv) :-
    replace_build2(BuildItem, T, NewInv1),
    append([H], NewInv1, NewInv).

ただし、実行すると、次の例のように、異常な匿名変数(正しい用語ですか?)が表示されます。

?- replace_build([item3], [empty, item5, item1, item3, empty], X).
X = [empty, item5, item1, empty, empty|_G467]

(また、それは私が望んでいないことを満足させますが、うまくいけばそれを解決することができます!)

|_G467結果のリストにが含まれているのはなぜですか?

4

2 に答える 2

2

問題の1つは、次の句です。

replace_build2(_BuildItem, [], _NewInv) :- !.

[]あなたはforを置くことによってそれを修正することができます_NewInv

replace_build2(_BuildItem, [], []) :- !.

問題は、インスタンス化されていない変数が追加されていることだけです。

?- replace_build([item3], [empty, item5, item1, item3, empty], X).
X = [empty, item5, item1, empty, empty] ;
X = [empty, item5, item1, item3, empty].

あなたが2つの答えを持っている理由は、replace_build2一致の2番目の節の両方のためです。それがあなたがそこemptyに入る理由ですitem3。Prologは、2つの変数を同じ値に喜んで統合します。ここでは、同じ値を参照することを止めBuildItemたりH、参照したりすることはできません。これらが異なることをPrologに明示的に伝える必要があるため、最後のreplace_build2句を次のように変更します。

replace_build2(BuildItem, [H| T], NewInv) :-
  BuildItem \= H,
  replace_build2(BuildItem, T, NewInv1),
  append([H], NewInv1, NewInv).

今、あなたはあなたが望む解決策だけを手に入れます:

?- replace_build([item3], [empty, item5, item1, item3, empty], X).
X = [empty, item5, item1, empty, empty] ;
false.

dif/2一部のプロローグでも使用できます。

于 2013-03-26T14:55:39.490 に答える
2

'list transform'タスクがあり、'item at once'ロジックを処理する場合は、maplist /Nを使用できます。

それで

replace_build(Items, Inv, Res) :-
    maplist(replace_build_item(Inv), Items, Res).

replace_build_item(Inv, Item, Res) :-
    memberchk(Item, Inv) -> Res = empty ; Res = Item.

しかし、Prologを学ぶために、あなたは正しい方向に進んでおり、ダニエルはあなたの問題についてよく説明しました。基本的なリスト処理タスクを把握することが重要です。

于 2013-03-26T18:01:11.453 に答える