Given this program:
a(1). a(2). a(3).
b(1). b(2). b(3).
ab(A, B) :- a(A), b(B).
This query returns 9 items:
ab(A, B).
How do I remove some specific rows, for example the rows (1,2) and (3,1) and get this result?
1 1
1 3
2 1
2 2
2 3
3 2
3 3
You can encode a list of values for A and B you do not want, like:
not_ab(1,2).
not_ab(3,1).
Then you can use the \+/1 predicate [swi-doc] that acts as negation:
ab(A, B) :-
a(A),
b(B),
\+ not_ab(A, B).
Note that Prolog's negation is negation as finite failure. It thus means that \+ Goal succeeds, geven all attempts to satisfy Goal fail, and that these attempts are finite (as in, the program does not get stuck in an infinite loop, and the number of brenches is finite).
The above is a generate-and-test approach: we first generate values for A and B and then test if these are valid. If you however can already know if for a given value for A all values of B will fail, then it is better to interleave testing. Here however it looks as if we can only test if both A and B are known.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With