Any Property Based Testing Tool for SWI Prolog?

As the title said, is there any property based testing tool for SWI Prolog?
plunit proivdes unit testing, but not property based testing.
By looking at the different topics here, I’ve found only an implementation in Logtalk. I’m curious whether there are other alternatives.

Thanks

Hey damiazz94,

Saw your question about property-based testing in SWI-Prolog and thought I’d share some tricks on how you might simulate QuickCheck-style testing with plunit. It’s not out-of-the-box, but with a little creativity, you can get pretty close.

Testing List Reversal

Let’s say you want to check that reversing a list twice gets you back to the original. Here’s a snippet showing how you could do this with plunit:

:- begin_tests(list_reversal).

my_reverse([], []).
my_reverse([H|T], Reversed) :-
    my_reverse(T, RevT),
    append(RevT, [H], Reversed).

test(reverse_twice, [nondet]) :-
    generate_random_list(10, List),
    my_reverse(List, RevList),
    my_reverse(RevList, DoubleRevList),
    assertion(List == DoubleRevList).

:- end_tests(list_reversal).

generate_random_list(0, []).
generate_random_list(N, [H|T]) :-
    N > 0, M is N - 1, H is random(100), % pick your range
    generate_random_list(M, T).

Determinism Check

Or say you want to make sure a predicate, like is_prime/1, behaves deterministically across a range. You might write a test like this:

:- begin_tests(prime_check).

is_prime(2).
is_prime(3).
is_prime(X) :- X > 3, X mod 2 =\= 0, \+ has_factor(X,3).
has_factor(N,L) :- N mod L =:= 0.
has_factor(N,L) :- L * L < N, L2 is L + 2, has_factor(N,L2).

test(prime_determinism, [forall(between(2, 100, X)), nondet]) :-
    findall(1, is_prime(X), Results),
    length(Results, Length),
    assertion(Length == 1).

:- end_tests(prime_check).

What’s cool here is using plunit to roll your own property-based tests. You generate inputs (like random lists or a range of numbers) and then check properties (like “reversing twice gets me back where I started” or “my predicate only succeeds once for any given input”).

It’s a bit more manual than having QuickCheck do the heavy lifting, but it’s a neat way to get broader coverage than just example-based tests. Plus, it’s pretty fun to see what kind of weird edge cases you can catch this way.

Hope this helps spark some ideas for your testing

Cheers

2 Likes

I wanted to try implementing such a library from scratch, so I did :slight_smile:
Here is a first implementation: GitHub - damianoazzolini/probat: Property based testing Prolog programs. any comment is welcome, since it can surely be improved (and maybe there are bugs in a bug finding library)!

1 Like