Предикат для объявления нисходящих / восходящих координат с использованием конечных доменов

Я хотел бы написать предикат downndo, который объявляет, что первая заданная координата [y, x] нисходит до второй заданной координаты (представьте доску с [0, 0] в левом верхнем углу).

Очень простая реализация в Прологе может выглядеть так:

descending(B, A) :-
  B = [B1,B2],
  A = [A1,A2],
  B1 is A1 + 1,
  B2 is A2 + 1.

Я не могу реализовать это в core.logic, хотя. Я уже пробовал много разных вещей (==/=fd/conso/appendo и +fd/+). Одна из вещей, которые я попробовал:

(defn descendo
  [b a]
  (l/fresh [b1 b2 a1 a2]
           (l/== b [b1 b2])
           (l/== a [a1 a2])
           (l/+fd b1 1 a1)
           (l/+fd b2 1 a2)))

Большинство из них просто ничего не возвращают, когда запускают их так:

(l/run* [q]
  (l/fresh [a]
    (l/infd a (l/domain [0 0] [1 0] [0 1] [1 1]))
    (descendo a [0 0])
    (l/== q a)))

=> () ; expected output: ([1 1])

У меня такое ощущение, что слишком много думать в Прологе нехорошо при использовании core.logic... любой совет приветствуется. Заранее спасибо.

РЕДАКТИРОВАТЬ: нашел обходной путь, где downndo остается прежним, но при его запуске мы не используем домен:

(l/run* [q]
  (l/fresh [a]
    (l/membero a [[0 0] [1 0] [0 1] [1 1]])
    (l/membero q [[0 0] [1 0] [0 1] [1 1]])
    (descendo a q)))

=> ([1 1])

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

1 ответ

Решение

Найден обходной путь, при котором downndo остается прежним, но при его запуске мы не используем домен:

(l/run* [q]
  (l/fresh [a]
    (l/membero a [[0 0] [1 0] [0 1] [1 1]])
    (l/membero q [[0 0] [1 0] [0 1] [1 1]])
    (descendo a q)))

=> ([1 1])

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

Другие вопросы по тегам