2

のコストを避けたいのでappend/3、差分/オープン リストを使用します。

ただし、開いたリストの問題はmember/2、要素を末尾に追加することによって開いたリストに反応することです。例えば:

?- L=[a|_],member(b,L).
L = [a, b|_G1196] ;
L = [a, _G1195, b|_G1199] ;
L = [a, _G1195, _G1198, b|_G1202] ;
L = [a, _G1195, _G1198, _G1201, b|_G1205] ;
L = [a, _G1195, _G1198, _G1201, _G1204, b|_G1208] ;
L = [a, _G1195, _G1198, _G1201, _G1204, _G1207, b|_G1211] 

開いているリストには無制限の「テール」があり、member/2関数はこのテール/ホール (変数) を member の最初の引数と統合するため、これは正しい動作です。

ただし、開いているリストに特定の要素と等しい要素があるかどうかを確認できる方法を探しています。これどうやってするの?

4

1 に答える 1

3

member/2: member_open/2:の独自のバージョンを作成できます。

member_open(_,X) :-
    var(X),
    !,
    fail.
member_open(X,[X|_]).
member_open(X,[_|T]) :-
    member_open(X,T).

またはより純粋なアプローチ:

member_open(X,Y) :-
    \+var(Y),
    Y = [X|_].
member_open(X,Y) :-
    \+var(Y),
    Y = [_|T],
    member_open(X,T).

Predicate は、開いているリストの末尾が であると仮定しますvar/1。述語がそのような末尾を見つけた場合、カット ( !) を実行して失敗します。

デモ:

?- member_open(a,[]).
false.

?- member_open(a,[a]).
true ;
false.

?- member_open(a,[a,a]).
true ;
true ;
false.

?- member_open(a,[a,a|_]).
true ;
true ;
false.

?- member_open(b,[a,a|_]).
false.

?- member_open(X,[X,a|_]).
true ;
X = a ;
false.

?- member_open(X,[c,a|_]).
X = c ;
X = a ;
false.
于 2016-06-07T11:17:26.993 に答える