user852689
user852689

Reputation: 751

Retrieving all the numbers from a given interval in Prolog

I am new into the world of Prolog, and I would like to write a rule that return all the elements in a specific range.

I intend to do something like

Ex:

foo(X, Low, High) :- X > Low, X < High.

And when I type foo(X, 2, 5), it should return 3, and then 4.

It seems that my approach is wrong, and I would like to know which is the correct way to do it.

Upvotes: 4

Views: 4757

Answers (4)

Nicholas Carey
Nicholas Carey

Reputation: 74277

You could also do this (pretty much a reimplementatio of between/3:

range( X , Y , Z ) :-
  integer(X) ,
  integer(Y) ,
  range1(X,Y,Z)
  .

range1( X , X , X ) .              % X equals Y
range1( X , Y , X ) :- X < Y .
range1( X , Y , Z ) :- X < Y , X1 is X+1 , range( X1 , Y , Z ) .
range1( X , Y , X ) :- X > Y .
range1( X , Y , Z ) :- X > Y , X1 is X-1 , range( X1 , Y , Z ) .

Upvotes: 1

joel76
joel76

Reputation: 5675

Using SWI-Prolog and library(clpfd), you can write

:- use_module(library(clpfd)).

foo(X,Low,High) :-
    X #> Low,
    X #< High,
    label([X]).

Upvotes: 2

thanos
thanos

Reputation: 5858

the easy answer: between/3:

?- between(3,4,X).
X = 3 ;
X = 4.

implementing the exact behaviour is kinda trivial this way.

the reason that your approach doesn't work is the definition of </2: both arguments should be instantiated. so, if you want to implement it without using between/3 you should do something like svick's suggestion.

Upvotes: 6

svick
svick

Reputation: 244837

When written like that, Prolog doesn't know what kind of numbers do you want (and whether you even want numbers).

One way to implement this would be:

range(X, L, H) :- X is L + 1, X < H.
range(X, L, H) :- L1 is L + 1, L1 < H, range(X, L1, H).

Upvotes: 7

Related Questions