I want to unit test a non-deterministic predicate in Prolog with PL-Unit.
I want to "assert" that the solutions I specify in my tests are the only solutions for the predicate.
I'm not concerned about the order that each solution is specified in the test.
What the SWI-Prolog manual says:
The SWI-Prolog manual has a great section called testing non-deterministic predicates...
2.2.3 Testing non-deterministic predicates
Non-deterministic predicates succeed zero or more times. Their results are tested either using findall/3 or setof/3 followed by a value-check or using the all or set options. The following are equivalent tests:
test(member) :-
findall(X, member(X, [a,b,c]), Xs),
Xs == [a,b,c].
test(member, all(X == [a,b,c])) :-
member(X, [a,b,c]).
This is almost exactly what I need. However, for these tests to pass, the output has to be specified in the correct order: [a, b, c]
. I'd like to be able to specify it in any order and still have the test pass.
An example of what I'm trying:
Let's say I'm testing this (hypothetical) predicate that has two solutions.
specialNumber(X) :-
X is 2;
X is 4.
I could write a passing unit test like so...
% PASSES!
test(specialNumber, all(X == [2, 4])) :-
specialNumber(X).
But it would fail if I swapped the order of the solutions...
% FAILS!
test(specialNumber, all(X == [4, 2])) :-
specialNumber(X).
How can I make this test pass regardless of the order that the solutions are found?