Вы написали точку с запятой (;
) после разреза (!
) вместо запятой (,
).Точка с запятой в некоторой степени эквивалентна «логическому» или «логическому», поэтому вы написали что-то вроде:
range(A, A, [A]).
range(A, B, [C|E]) :-
( A>B, !
; C is A,
D is A+1,
range(D, B, E)
).
Для range(1, 2, L)
в основном есть два пути, которые дают решение (это не стандартная записьздесь он используется только для того, чтобы дать некоторое представление о том, как Пролог получает результаты:
range(1, 2, [C|E])
C is 1,
D is 2,
range(2, 2, E) :-
range(2, 2, [2]). % we found a solution
range(2, 2, [C|E])
C is 2,
D is 3,
range(3, 2, E) :-
range(3, 2, [C|E])
3 > 2. % we found a solution
Срез не останавливает выполнение предложения, а срез означает, что Пролог не будетрассмотрим следующие предложения для этого конкретного вызова (поэтому, если мы выполняем рекурсию, разрез не влияет на саму рекурсию). Поскольку других предложений нет, то отсечение здесь, таким образом, не оказывает влияния.
Мы можем упростить код до:
range(A, A, [A]).
range(A, B, [A|T]) :-
A < B,
A1 is A+1,
range(A1, B, T).
Или мы можем использовать встроенный between/3
[swi-doc] и использоватьfindall/3
[swi-doc] сверх этого:
range(A, B, L) :-
findall(X, between(A, B, X), L).