Reputation: 119
I am new to prolog and have am trying to write a program that will do the following tell me if a number is between 2 values I can do the following:
between(L, X, R) :-
X > L, X < R.
and doing between(1, 3, 5) works, but I would like it to be able to do between(1, X, 5) and have prolog return all the values in between so in this case X = 2, X = 3, X = 4, I get why my solution doesn't because it needs to be have been initialised, but I cannot think of a solution to this problem, can this type of thing just not be done in prolog?, and help would be great thanks
Upvotes: 1
Views: 1757
Reputation: 3736
In case you don't want to predefine all numbers: let prolog create a list with possible entries and state your X
has to be one of them. To understand the code you have to have knowledge about lists in prolog, especially Head and Tail notation of lists.
betweenList(L,R,[]):-
L>=R.
betweenList(L,R,[L|Rest]):-
L<R,
LL is L+1,
betweenList(LL,R,Rest).
between(L, X, R) :-
betweenList(L, R, [L| List]),
member(X, List).
?- between(1,X,5).
X = 2 ;
X = 3 ;
X = 4 ;
false.
betweenList(L,R,List)
creates a List of all numbers between L
and R
, including L
(as head element), excluding R
. So if you want to generate a List without L
, it is the easiest to just call betweenList(L, R, [L| List])
so List
will not include L
. Now X
just has to be a member of List
. The member/2
predicate can be easily written as well if you don't want to use the inbuild predicate.
Upvotes: 1
Reputation: 12567
One way to approach this:
digit(0).
digit(1).
digit(2).
digit(3).
digit(4).
digit(5).
digit(6).
digit(7).
digit(8).
digit(9).
between(L, X, U) :- digit(L), digit(X), digit(U), L < X, X < U.
Tests:
?- between(2, X, 5).
X = 3 ;
X = 4 ;
false.
?- between(2, 7, U).
U = 8 ;
U = 9.
Alternatively, you may want to look into Constraint logic programming.
Incidentally, Prolog already has a between/3
:
?- between(1, 5, X).
X = 1 ;
X = 2 ;
X = 3 ;
X = 4 ;
X = 5.
although it's "illogical": you can't run it backwards, as the above definition.
Upvotes: 1