Ваша проблема в том, что вы не можете создать экземпляр переменной, для которой уже создан другой термин.Таким образом, если Count уже создан (скажем, с помощью 2), вы не можете сделать Count is Count - 1.
Оператору is / 2 требуется, чтобы левая переменная не была создана (или была создана с фактическим значением выражения)и правильное выражение для полной оценки.То же самое относится и к рекурсивному вызову.После создания экземпляра Res для целого числа вы не можете изменить его значение на другое целое число.
Вот еще одна реализация:
rand_val(Count, Rng, Res):-
rand_val(Count, Rng, -1, Res).
rand_val(0, _, Value, Value):-
!,
Value >= 0.
rand_val(Count, Rng, MValue, Value) :-
succ(NCount, Count),
X is random(Rng), %rand_int(Rng, X),
NValue is max(X, MValue),
rand_val(NCount, Rng, NValue, Value).
Первое замечание, что я написал два предиката rand_val / 3 и rand_val / 4,Первый - тот, с подписью которого вы хотите.У последнего есть еще один аргумент, который будет содержать максимальное значение, найденное в тот момент.
Первый предикат просто вызывает rand_val / 4, присваивая значение -1 как максимальное найденное значение.
ТеперьПервое предложение rand_val / 4 проверяет, равен ли его входной аргумент «Count» 0. В этом случае он запрещает возврат (используя вырез) и проверяет, является ли Value допустимым значением.Если это <0, то это потому, что вы вызвали rand_val / 3 с Count = 0, поэтому он действительно никогда не выдавал случайное число. </p>
Если это> 0, он просто объединяет третий и четвертый аргумент (обратите внимание, чточетвертый аргумент - это значение, которое вы ожидаете получить на выходе).
Теперь перейдем ко второму предложению: сначала выполняется succ (NCount, Count), где NCount - новая переменная.Он будет создан с предшественником Count (Count-1).
Затем мы вычисляем случайное число.Я использую пролог SWI, поэтому я называю random (Max), чтобы получить случайное число.Это создает новую переменную X вместе с ней.
В этот момент у нас есть выбор наибольшего значения между промежуточным результатом (MValue) и X.
Наконец, мы делаем рекурсивный шаг, теперь вызываемrand_val / 4 с новыми вычисленными значениями NCount и NValue.
Обратите внимание, что переменная Value создается, когда мы возвращаемся из рекурсии (она становится связанной в первом предложении rand_val / 4).