Вопрос

Today I came across this query:

?- member(b,X).

The program was:

member(X,[X|_]).   
member(X,[_|T]) :- 
    member(X,T),
    !.

When I ran the query, I got these answers:

?- member(b,X).
X = [b|_G1560] ;
X = [_G1559, b|_G1563].

What exactly is that? What does this query do?

Это было полезно?

Решение

The query member(b,X) generates lists containing b. As the second argument is not instantiated, you have a (theoretically) infinite number of solutions. The first solution will have b in the first position, the second solution will have b in the second position and so on. Moreover, if you look closely to any of the solutions, you see that it represents any list with a b on that position. For example, the first solution is [b| _]. As the list tail is not instantiated (see the member/2 predicate base case), this solution unifies with any list with b in the head position.

If you want to make the member/2 deterministic, i.e. if you want to use the predicate only to check if a term is a member of a list, you will need to add a cut in the base clause, not in the recursive clause as @false noted:

member(Head, [Head| _]) :-
    !.
member(Head, [_| Tail]) :-
    member(Head, Tail).

The resulting predicate is usually named memberchk/2 and available as such as a library predicate.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top