Basically you write a program to test global implication:
forall N, if N < 10 then N > 5
and you want to know for which domain domain N
Now you correctly rewrite this in the prolog as:
\+ ( N < 10, \+ ( N > 5 ) ).
But if you try to pass this request to the prolog interpreter, it will throw an error:
?- \+ ( N < 10, \+ ( N > 5 ) ). ERROR: </2: Arguments are not sufficiently instantiated
because the arguments < not created. The same thing happens with a simple query, for example N < 3 . Of course, if you create an instance before the request, the problem goes away:
?- N=5, \+ ( N < 10, \+ ( N > 5 ) ). false.
(statement does not hold for N = 5)
?- N=6, \+ ( N < 10, \+ ( N > 5 ) ). N = 6.
(but this is true for N = 6).
You can also put a predicate that generates multiple assignments for N using backtracking instead of N=6 :
?- between(1, 12, N), \+ ( N < 10, \+ ( N > 5 ) ). N = 6 ; N = 7 ; N = 8 ; N = 9 ; N = 10 ; N = 11 ; N = 12.
but for a large area this will be extremely inefficient (reverse tracking will be required for each domain element).
If you want to talk about destination domains (i.e. integers), you can use the CLPFD library, as @lurker suggested. This approach is more effective because it has rules for reasoning about intervals, intersection at intervals, and many others.
You must replace < , > ,,, \+ the CLP operators #< , #> , #/\ , #\ . Let's try:
?- use_module(library(clpfd)). ?- #\ ( N #< 10 #/\ #\ ( N #> 5 ) ). N+1#=_G11193, N#>=6#<==>_G11205, 10#>=_G11193#<==>_G11217, _G11217 in 0..1, _G11217#/\_G11244#<==>0, _G11244 in 0..1, #\_G11205#<==>_G11244, _G11205 in 0..1.
which may be a little hard to read, but among many other things, it tells you the answer you are looking for, that is, area N: N #>= 6 .