Singleton: bogus warning with optimise on

:- set_prolog_flag(optimise,true).
ss:-
   forall( (between(0,3,N), Y is N*3),
            assertion(Y is N*3)
         ).
?- make.
Warning: /tmp/t1.pl:2:
Warning:    Singleton variable in \+: Y
% /tmp/t1 compiled 0.00 sec, -1 clauses
true.

If you comment out the optimise on line the warning dissappears.

?- make.
% /tmp/t1 compiled 0.00 sec, 0 clauses

Optimisation turns assertion/1 into a no-op, which is why there’s a singleton warning - the assertion check has disappeared and the code has become equivalent to forall((between(0,3,N), Y is N*3), true).

ahhh…thanks. Hmm…this makes many plunit tests useless when optimization is turned on…

The documentation for assertion/1 (and some other predicates) in library(debug) needs to be improved to point out that optimisation turns them off – it is documented in the overview section of the documentation. You can control this behavior with Prolog flag optimise_debug.

1 Like

You can use

:- set_prolog_flag(optimise_debug, false).

to stop optimizing debug/3 and assertion, even in debug mode. In this case it is about the intended semantics, so the warning is ok. If it is correct to optimize the assertion/1 away (or debug/3), you can use the variable _0Name, as _<Digit>* variables are never subject to singleton or “multiton” messages.

1 Like