0

そのため、私はこれを理解するために多くの時間を費やしましたが、ほとんど進歩がありませんでした. あなたが私を助けてくれることを願っています。目標は、次のようなリストを取得することです(ベースリストと呼びましょう): [[[feesc,11],[podshare,11]],[[feesc,11]],[]]. And make it become this: [[feesc,22],[podshare,11]].

結果のリストに追加または合計する述語があります。コードは次のとおりです。

place_key([Key,Value], [], [Key,Value]).
place_key([Key,Value], [[Key,V]|Rest], [[Key,V1]|Rest]) :- V1 is V+Value.
place_key([Key,Value], [[K,V]|Rest], [[K,V]|List2]) :- Key \= K, place_key([Key,Value], Rest, List2)."

再帰をシミュレートするためにこのメソッドを手動で呼び出すと、希望どおりに機能します。例:

 place_key([feesc,11], [], R), place_key([feesc,11],R,J). 
So J is = [[feesc,22]]. 

期待される結果は正しいです。問題は再帰の問題です。

したがって、基本的に私がする必要があるのは、ベースリストを反復処理し、各キー/パーリストに到達したら、place_key を呼び出してスタックに保持し、再帰が最後まで保持するようにすることです。指摘しておくと、追加したくありません。place_key からの最新の結果が必要なだけです。

私がこれまでに行ったこと:

fe([HO|T],NL,R) :- write(HO), place_key(HO,NL,RESULT), fe(T,RESULT,R).
fe(S,R):- fe(S,[],R).
fe([],[]).
feg([HO,T],R) :- fe(HO,RESULT), feg(T,RESULT), R = RESULT.
feg([],[]).

私が実行すると:

[trace] 57 ?- feg([[[feesc,11]],[[feesc,11]]],R).
   Call: (6) feg([[[feesc, 11]], [[feesc, 11]]], _G21384) ? creep
   Call: (7) fe([[feesc, 11]], _G21484) ? creep
   Call: (8) fe([[feesc, 11]], [], _G21485) ? creep
   Call: (9) place_key([feesc, 11], [], _G21485) ? creep
   Exit: (9) place_key([feesc, 11], [], [[feesc, 11]]) ? creep //Until here, I think this is correct.
   Call: (9) fe([], [[feesc, 11]], _G21494) ? creep 
   Fail: (9) fe([], [[feesc, 11]], _G21494) ? creep
   Redo: (9) place_key([feesc, 11], [], _G21485) ? creep
   Fail: (9) place_key([feesc, 11], [], _G21485) ? creep
   Fail: (8) fe([[feesc, 11]], [], _G21485) ? creep
   Fail: (7) fe([[feesc, 11]], _G21484) ? creep
   Fail: (6) feg([[[feesc, 11]], [[feesc, 11]]], _G21384) ? creep
false.

私は何を間違っていますか?

4

2 に答える 2

0

Keep your key/pairs as a tuple, a simple term with an arity of 2. Something like K-V or K:V or even tuple(K,V) is preferable to [K,V]. There's a simple reason for this:

  • K-V, K:V and tuple(K,V) all map to simple structures: -(K,V), :(K,V) and tuple(K,V) respectively, while...

  • [K,V] is syntactic sugar for a rather more complicated structure .(K,.(V,[])).

Further, you might realize that your key/value pairs are hard to distinguish from the nested list-of-lists. Keeping the Key/Value pairs as tuples makes that distincation clear.

So, let us assume your key/value pairs are represented as K:V. It sounds to me that what you're essentially wanting to do is walk your nested list-of-lists (essentially, a tree), enumerate the key/value pairs it contains and produce the set (unique). Here's one way to do that.

First, a simple predicate to identify a non-empty list:

nonnempty_list( L ) :- nonvar(L) , L = [_|_] .

Then, a simple predicate to walk the nested list of lists and enumerate each key/value pair it finds:

visit( [ K:R | Ls ] , K:R ) . % succeed if the head of the list is a key/value pair.
visit( [ L | Ls ] , KVP ) :-  % otherwise...
  nonempty_list(L) ,          % - if the head is a non-empty list ,
  visit( L , KVP )            % - visit it.
  .                           %
visit( [_|Ls] , KVP ) :-      % finally...
  visit( Ls , KVP )           % - recurse down on the tail.
  .                           %

Then you can use the magic of setof/3 to get what you want:

flattened_set( LoL , KVPs ) :-
  setof( KVP , visit(LoL,KVP) , KVPs )
  .
于 2015-05-07T17:42:45.220 に答える