swipl-devel
swipl-devel copied to clipboard
Semantic singleton in branch detection doesn't work in meta-calls
Using the current development version of SWI-Prolog (cf65970368eaac32017afe819f68bce2af2ee9b3). The semantic singleton variable detection doesn't work correctly for if-then-else constructs in meta-calls - it seems that only syntactic singletons are detected, and semantic singletons are incorrectly considered non-singletons. For example:
nonmeta_1 :- member(a, [a]) -> X = 1 ; X = 2.
nonmeta_2 :- member(a, [a]) -> _X = 1 ; _X = 2.
meta_1 :- call((member(a, [a]) -> X = 1 ; X = 2)).
meta_2 :- call((member(a, [a]) -> _X = 1 ; _X = 2)).
Warning: .../singletons.pl:1:
Warning: Singleton variable in branch: X
Warning: .../singletons.pl:5:
Warning: Singleton-marked variable appears more than once: _X
The warnings shown for the meta_... predicates should be the same as for the nonmeta_... ones, but they aren't.
This also happens with other meta-predicates, e. g. call_cleanup, not just call.
Semantic singleton detection is done by the low-level compiler. Meta-calls are just terms to this level of the compiler, so you just get the syntactic singleton analysis. I don't see the point for call/1 as the whole point for using call/1 is that the argument is not instantiated (enough) at compile time. Would be nice to have this for catch/3, call_cleanup/2, etc. That would require a totally different approach though.
I don't see the point for call/1 as the whole point for using call/1 is that the argument is not instantiated (enough) at compile time. Would be nice to have this for catch/3, call_cleanup/2, etc.
Right - I used call here only to keep the example short. In the actual code where I ran into this problem, the if-then-else is inside calls to call_cleanup and custom meta-predicates.
It's not a huge issue, because the problem only comes up in a few places in our code, so I can simply rename the singleton-marked variables to different names to make the warning go away.