2012-03-19 17 views
1

[_、[X、_]、_]は[d、[X、a]、s]のようなリストと一致します。 1つ以上の匿名変数があるパターンに一致させる方法はありますか?すなわち、 [[X、a]、s]と[[d、a]、[p、z]、[X、b]]は一致するでしょうか?Prolog:1つ以上の匿名変数を一致させる

私はリスト内の要素を数えるプログラムを作成しようとしています。 [、、、B、A、B] => [[4]、[B]、[2]]が、私立ち往生しています:

listcount(L, N) :- listcountA(LS, [], N). 
listcountA([X|Tail], [? [X, B], ?], N) :- B is B+1, listcountA(Tail, [? [X,B] ?], N). 
listcountA([X|Tail], AL, N) :- listcountA(Tail, [[X,0]|AL], N). 

感謝を。

答えて

2

変数試合用語、およびanonimus変数は例外ではありません。リストは、頭と尾の間のバイナリリレーションの構文砂糖です。したがって、変数はリスト、頭、または尾に一致することができますが、不特定の順序には一致しません。

私はあなたを助けることを願っていますいくつかの注意事項:

listcount(L、N): - listcountA(LS、[]、N)。プロローグで

、述語はそうファンクタアリティ呼ばれ、名前 num.of.argumentsによって識別されます。したがって、通常、追加された引数を持つ 'service'述部は同じ名前を保持します。

listcountA([X |テール]、N [X、B]、?]): - Bは、B + 1であるlistcountA(尾、N [X、B]?] )。

Bは成功しません。は新しい変数を使用する必要があります。そしてあなたがしているように、ワイルドカードを使ってリスト内で一致させる方法はありません。代わりに、カウンターを見つけて更新する述部を記述します。

最後の注記:通常の対の要素は、バイナリリレーション、便利には(任意の)演算子を使用して表示されます。たとえば、ほとんどがダッシュです。

だから私は、更新/ 3は再帰「を内部に移動する」、いくつかのライブラリの述語を使用して簡略化することができ

listcount(L, Counters) :- 
    listcount(L, [], Counters). 

listcount([X | Tail], Counted, Counters) :- 
    update(X, Counted, Updated), 
    !, listcount(Tail, Updated, Counters). 
listcount([], Counters, Counters). 

update(X, [X - C | R], [X - S | R]) :- 
    S is C + 1. 
update(X, [H | T], [H | R]) :- 
    update(X, T, R). 
update(X, [], [X - 1]). % X just inserted 

を記述します。選択/ 3を使用して、例えば:

listcount([X | Tail], Counted, Counters) :- 
    (select(X - C, Counted, Without) 
    -> S is C + 1 
    ; S = 1, Without = Counted 
    ), 
    listcount(Tail, [X - S | Without], Counters). 
listcount([], Counters, Counters). 
+0

+1:これは基本的に、アキュムレータを使用してこれを解決する方法です。 – sharky

0

[_、[X、_]、_]は3つの要素を持つリストと一致します。1番目と3番目はアトムまたはリストです.2番目の要素は長さ2のリストでなければなりません。 2つの要素リストに一致しません。要素を見つけて結果リストに挿入するために、頭から尾までの再帰を使用する方がよいでしょう。 相続人述語スケッチ、私は文句を言わないコピーペースト場合は動作賭けWICH;)

% find_and_inc(+element_to_search, +list_to_search, ?result_list) 
find_and_inc(E, [], [[E, 1]]); 
find_and_inc(E, [[E,C]|T1], [[E,C1]|T2]) :- C1 is C+1; 
find_and_inc(E, [[K,C]|T1], [[K,C]|T2]) :- find_and_inc(E, T1, T2). 
1

すると私はあなたがこの回答のように、この答えは彼らのものに基づいている@chacに正しい答えを授与考慮すれば、と言って、この記事を序文ます。

は、ここでも、アキュムレータを使用していますし、あなたが直接を求め、出力期間構造を与え、入力リスト内の変数を扱うバージョンです:

listcount(L, C) :- 
    listcount(L, [], C). 
listcount([], PL, PL). 
listcount([X|Xs], Acc, L) :- 
    select([X0,C], Acc, RAcc), 
    X == X0, !, 
    NewC is C + 1, 
    listcount(Xs, [[X0, NewC]|RAcc], L). 
listcount([X|Xs], Acc, L) :- 
    listcount(Xs, [[X, 1]|Acc], L). 

なお、アキュムレータベースのバージョンにlistcount/2延期、 listcount/3は、アキュムレータのカウントを維持し、入力順またはグラウンド入力リスト(名前付き/ラベル付きの変数は正常に機能します)を想定しません。

関連する問題