Пролог итерация / рекурсия для детализации до минимального значения

Я пытаюсь создать предикат в прологе, который останется верным, если он достигнет наименьшего числового значения из набора значений.

Например:
У меня сейчас как то так

Базовый шаг

lowest(Object, Value) :- \+ lessThan(Object, Value, NewValue).

Рекурсивный шаг

lowest(Object, Value) :- lessThan(Object, Value, NewValue), lowest(Object, NewValue).

Где Object - это некоторый абстрактный объект, к которому может быть прикреплено несколько числовых значений.
lessThan возвращает значения (NewValue) для объекта, которые меньше входного значения.

И поскольку NewValue будет ниже, чем ввод значения, я могу предположить, что с каждым рекурсивным шагом значение будет уменьшаться.

Я абстрагировал эту проблему от другой, которую я пытаюсь решить, но в основном происходит то, что я ожидаю только 2 вывода из всей рекурсивной функции, но вместо этого я получаю столько же результатов, сколько lessThan(Object, Initial, X) + 2

Я не уверен, что этот вопрос ясен, пожалуйста, дайте мне знать, чтобы я мог уточнить.

Я считаю, что мой базовый шаг правильный, так как я делаю предположение, что если Value является наименьшим в сочетании с Object, то нет других значений, меньших, чем Value.

Я не уверен, где прекратить рекурсию также, что добавляет мое замешательство. Я предполагаю, что он прекратит работу, как только достигнет состояния, в котором нет более низких значений для объекта.

1 ответ

Решение

Этот пример должен работать, переименовывая значение /2 в соответствии с вашим доменом.

value(a, 10).
value(a, 3).
value(a, 100).

lowest(Object, L) :-
    value(Object, First), !, lowest(Object, First, L).
lowest(Object, LowestSoFar, Lowest) :-
    value(Object, Try), Try < LowestSoFar, !,
    lowest(Object, Try, Lowest).
lowest(_, Lowest, Lowest).

это дает

?- lowest(a,X).
X = 3.

Обратите внимание, что оно повторяет значение "peek" каждый раз, а затем неэффективно. Возможной альтернативой является сохранение более низкого значения и запуск цикла, управляемого отказом. В противном случае SWI-Prolog (и YAP) имеет библиотеку ( агрегат):

?- aggregate(min(V), value(a,V), M).
M = 3.
Другие вопросы по тегам