vendredi 27 février 2015

Declaring facts that are true only within the scope of a single unit test in SWI-Prolog

As an example for this question, I have a very simple Prolog file main.pl, in which I've defined the colours of some shapes.



colour(circle, red).
colour(triangle, red).
colour(square, blue).


Now below that I define a predicate same_colour/2, which is true if both S1 and S2 are the same colour.



same_colour(S1, S2) :-
colour(S1, C),
colour(S2, C).


Testing at the top level indicates that this predicate works as expected.



?- same_colour(circle, triangle).
true.

?- same_colour(circle, square).
false.


I am trying to write unit tests using SWI-Prologs unit testing framework plunit for same_colour/2, but I want to declare facts within each individual test that are only true within the scope of that test. I've tried using the setup option for individual tests, as well as asserta, neither of which work. All of the below tests fail.



:- begin_tests(same_colour).

test(same_colour) :-
colour(shape_a, colour_1),
colour(shape_b, colour_1),
same_colour(shape_a, shape_b).

test(same_colour) :-
asserta(colour(shape_a, colour_1)),
asserta(colour(shape_b, colour_1)),
same_colour(shape_a, shape_b).

test(same_colour, [
setup(colour(shape_a, colour_1)),
setup(colour(shape_b, colour_1))
]) :-
same_colour(shape_a, shape_b).

:- end_tests(same_colour).


I've also tried:



test(same_colour, [
setup(asserta(colour(shape_a, colour_1))),
setup(asserta(colour(shape_b, colour_1))),
cleanup(retract(colour(shape_a, colour_1))),
cleanup(retract(colour(shape_b, colour_1)))
]) :-
same_colour(shape_a, shape_b).


that is, first declare that colour(shape_a, colour_1) and colour(shape_b, colour_1) are facts, do the test, then 'undeclare' them. However, this test fails as well. Using trace it seems that colour(shape_a, colour_1) is never asserted (or at least is not true while my test is running.)



Call: (18) plunit_same_colour:'unit body'('same_colour@line 13', vars) ? creep
Call: (19) same_colour(shape_a, shape_b) ? creep
Call: (20) colour(shape_a, _G738) ? creep
Fail: (20) colour(shape_a, _G738) ? creep
Fail: (19) same_colour(shape_a, shape_b) ? creep
Fail: (18) plunit_same_colour:'unit body'('same_colour@line 13', vars) ? creep


I can understand now why the first two tests do not work. In the first I am testing whether colour(shape_a, colour_1) is true, when it hasn't been declared before, and in the second I just don't think it is correct to use asserta from within a predicate definition. Though it feels like something similar to my third or fourth test should be able to achieve what I am trying to do?


Aucun commentaire:

Enregistrer un commentaire