[m-users.] Confusion with inferencing for determinism

artem.kozlov at posteo.net artem.kozlov at posteo.net
Wed Apr 19 00:59:32 AEST 2017


Hi Everyone,

I'm trying to learn Mercury and along the way decided to work on "99 
Prolog Problems". And immediately get confused with inferencing for the 
determinism. I'm trying to write my_last predicate which should return 
last element of a list.
The first immediate solution that I tried was:
my_last([X], X) .
my_last([_ | XS], X) :- my_last(XS, X) .

Which works OK but Mercury infers that my_last is nondet, but it should 
be semidet because it doesn't cover empty list case, but otherwise 
produce only one result. I looked into Mercurly standard lib where last 
predicate indeed has semidet determinism. I tried to ask in IRC and 
people suggested that I should have only one clause for predicate, but 
apparently that is not the main issue with my version. Even if I rewrite 
my function to:

my_last(YS, X) :- (YS = [X] ; YS = [_ | XS], my_last(XS, X)) .

it still nondet. In comparison to built in one:

my_last([H | T], Last) :- ( T = [], Last = H ; T = [_ | _], my_last(T, 
Last)).

which is semidet.

Maybe that is a silly question, but could someone explain how these 
versions of my_last are different and why only the last one is inferred 
as semidet.

Thanks,

Artem


More information about the users mailing list