Update: It’s the foreach/2 actually. If I replace it with forall/2, there are no open choicepoints left in 8.3.5 and 8.3.4. I have to run some more tests I guess.
After compiling 8.3.5 I ran my library test cases and was surprised to see a test emitting a warning that “Test succeeded with choicepoint”.
I have poked around the test case and found that for some reason a call to append/3
is not well-behaved (that’s the technical term as I understand it); it leaves a useless choicepoint in one 8.3.5, but none in 8.3.4. Running the append on the toplevel however gives a deterministic answer in both versions.
The source of the nondeterminism is ghostly though. I try to simplify things and it disappears or appears.
Is wandering non-determinism expected (maybe due to compiler optimizations?) Should I continue giving myself a headache?
The code, pared down:
:- begin_tests(what).
test(list_and_suffix_known) :-
List = [a],
length(List,ListLen),!,
succ(SuffixLen_max,ListLen),!,
foreach(between(0,SuffixLen_max,SuffixLen),list_and_suffix_known(List,SuffixLen)).
list_and_suffix_known(List,SuffixLen) :-
length(Suffix,SuffixLen),!,
debug(splinter_test),
debug(splinter_test,"List=~q Suffix=~q",[List,Suffix]),
nodebug(splinter_test),
append([_,Suffix],List),
! % A cut here makes things deterministic in 8.3.5, whereas they already are in 8.3.4
.
:- end_tests(what).
Bizzardedly, this pre-digested code has open choicepoints in both version. Am I going crazy?
:- begin_tests(what).
test(list_and_suffix_known) :-
/*
List = [a],
length(List,ListLen),!,
succ(SuffixLen_max,ListLen),!,
foreach(between(0,SuffixLen_max,SuffixLen),list_and_suffix_known(List,SuffixLen)).
*/
list_and_suffix_known([a],0).
list_and_suffix_known(List,SuffixLen) :-
length(Suffix,SuffixLen),!,
debug(splinter_test),
debug(splinter_test,"List=~q Suffix=~q",[List,Suffix]),
nodebug(splinter_test),
append([_,Suffix],List)
.
:- end_tests(what).