Hi, freeze/2 and when/2 seem to have the same problem, with _
(an anonymous variable):
In SWI-Prolog (threaded, 64 bits, version 9.0.3), running in Void Linux:
?- freeze(F, N=1).
freeze(F, N=1). % As expected
?- freeze(_, N=1).
true. % Bad - ignores Goal
?- when(nonvar(F), N=1).
when(nonvar(F), N=1). % As expected
?- when(nonvar(_), N=1).
true. % Bad - ignores goal
My use-case is:
max_member_freeze(Max, [H|T]) :-
( T == []
% Only 1 element
-> Max = H
% Start with Upto unknown
; freeze(H, max_member_freeze_([H|T], _, Max))
).
max_member_freeze_([], Max, Max).
max_member_freeze_([H|T], Upto, Max) :-
(var(Upto) -> Upto = H ; true),
when((nonvar(H), nonvar(Upto)),
( (nonvar(Max) -> Max @>= H ; true),
max(H, Upto, Upto1),
freeze(T, max_member_freeze_(T, Upto1, Max))
)
).
max(X, Y, Max) :-
( X @< Y
-> Max = Y
; Max = X
).
… which gives:
?- max_member_freeze(1, [1, N]).
when(nonvar(N), ((nonvar(1)->1@>=N;true), max(N, 1, _A), freeze([], max_member_freeze_([], _A, 1)))).
% As expected
?- max_member_freeze(1, [1, _]).
true. % Wrongly ignores the potential value of the 2nd element in the list
Is this a bug? Shouldn’t _
be converted by the system into a variable such as _A
?
Perhaps this is a useful trick, to “prevent” an anonymous variable:
?- _ = f(F), freeze(F, N=1).
freeze(F, N=1).
… or is there some workaround?