Mutex recursion issue?

A simple recursive predicate seems to behave differently when using mutex (in SWI 8.2.1, 64bits).
Below, I’ve listed two predicates, which are the same except one is without mutex check, and the other is with the mutex check.

The predicate does a recursive check of group membership, where groups can be members of other groups (i.e. a hierarchy of groups). In the asserted example, ‘john’ is a member of the group ‘staff’, and ‘staff’ is a member of the group ‘groups’.

:- dynamic(group/2).
:- assert(group(john,staff)).
:- assert(group(staff,groups)).

% simple recursive membership check
is_member(Entity,Group):- group(Entity,Group).
is_member(Entity,Group):-
    group(Entity,G),
    is_member(G,Group).

% same as is_member, but with mutex
mutex_member(Entity,Group):- with_mutex( test, group(Entity,Group)).
mutex_member(Entity,Group):-
    with_mutex( test, group(Entity,G)),
    mutex_member(G,Group).

When I run the query is_member(E,G) I get the following (expected) results:

?- is_member(E,G).
E = john,
G = staff ;
E = staff,
G = groups ;
E = john,
G = groups ;
false.

But when I run mutex_member(E,G) I get the following:

?- mutex_member(E,G).
E = john,
G = staff ;
E = john,
G = groups ;
false.

The mutex version seems to be incomplete. What am I missing here?

Hmm, re-reading the docs (always a good idea :slight_smile: ), it probably has to do with the use of once/1 in mutex.

1 Like