0

私は2つのリストの交差を作ろうとしています(つまり、リストCにはAとBにある要素のみが含まれています)が、私が理解しているように、2つのリスト+ Cの要素の任意の量の分離を取得します.

次のように動作することを意図しています:

  • X が C にある場合、A と B の両方にある必要があります (X は C のすべてのメンバーを反復する必要があると思います!?)
  • 述語:d(A,B,C) :- (member(X,D)->member(X,A),member(X,B)).

あなたは言うことができますか: 私の文と述語は等しくありませんか、それとも別の間違いを犯しましたか?

例:

?- [user].

|: d(A,B,C) :- (member(X,D)->(member(X,A),member(X,B))).
|: % user://1 compiled 0.01 sec, 612 bytes
true.

?- d([a,b],[b,c],C)
|    .
C = [b|_G21] .

?- d([a,b],[b,c],[b]).
true .
4

3 に答える 3

1

@salva が提案した解決策が気に入っていますが、より単純な並べ替えとマージを行い、代わりに一致しないものをすべてチャックします。

intersect( As , Bs , Cs ) :-
  sort( As , SortedAs ) ,
  sort( Bs , SortedBs ) ,
  merge( SortedAs , SortedBs , Cs )
  .

merge( []     , []     , [] ).
merge( []     , [_|_]  , [] ).
merge( [_|_]  , []     , [] ).
merge( [C|As] , [C|Bs] , [C|Cs] ) :-          merge(    As ,     Bs  , Cs ) .
merge( [A|As] , [B|Bs] , Cs     ) :- A @< B , merge(    As  , [B|Bs] , Cs ) .
merge( [A|As] , [B|Bs] , Cs     ) :- A @> B , merge( [A|As] ,    Bs  , Cs ) .
于 2013-11-06T18:56:06.413 に答える