#prolog #clpfd
#пролог #clpfd
Вопрос:
Я новичок в мире Prolog, и я хотел бы написать правило, которое возвращает все элементы в определенном диапазоне.
Я намерен сделать что-то вроде
Пример:
foo(X, Low, High) :- X > Low, X < High.
И когда я набираю foo(X, 2, 5), он должен возвращать 3, а затем 4.
Кажется, что мой подход неверен, и я хотел бы знать, какой правильный способ сделать это.
Ответ №1:
При такой записи Prolog не знает, какие числа вам нужны (и нужны ли вам вообще числа).
Одним из способов реализации этого было бы:
range(X, L, H) :- X is L 1, X < H.
range(X, L, H) :- L1 is L 1, L1 < H, range(X, L1, H).
Ответ №2:
простой ответ: between/3
:
?- between(3,4,X).
X = 3 ;
X = 4.
реализация точного поведения довольно тривиальна таким образом.
причина, по которой ваш подход не работает, заключается в определении </2
: должны быть созданы экземпляры обоих аргументов. итак, если вы хотите реализовать это без использования between/3
, вы должны сделать что-то вроде предложения svick.
Ответ №3:
Используя SWI-Prolog и library(clpfd)
, вы можете написать
:- use_module(library(clpfd)).
foo(X,Low,High) :-
X #> Low,
X #< High,
label([X]).
Ответ №4:
Вы также могли бы сделать это (в значительной степени переопределение между / 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 ) .