Open list and member

别等时光非礼了梦想. 提交于 2019-12-11 01:45:49

问题


Since I want to avoid cost of append/3, I use difference/open lists.

The problem with an open list however is that member/2 reacts with an open list by adding the element to the tail. For example:

?- 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] 

This is correct behavior since an open list has an unbounded "tail" and the member/2 function unifies this tail/hole ( variable) with the first argument of member.

I'm looking however for a way I can check if there is an element in the open list that is equal to the given element. How can I do this?


回答1:


You could write your own version of member/2: member_open/2:

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

or a more purer aproach:

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

The Predicate makes the assumption that an open list has a tail that is var/1. If the predicate finds such a tail, it performs a cut (!) and fails.

Demo:

?- 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.


来源:https://stackoverflow.com/questions/37676839/open-list-and-member

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!