Как выбрать из множества возможных значений в minikanren / clojure-core.logic?

Как я могу выразить ограничение, которое n переменные принимают разные значения из набора n ценности?

Например, может быть, я хочу найти выражение формы

(op1 a (op2 b c))

с наибольшим значением, когда a, b и c должны 1, 2 и 3 (в некотором порядке), в то время как op1 и op2 могут быть любым из * + - / exp?

Я вижу, как сделать a иметь значение от 1 2 3 (используя conde например). И то же самое для b а также c, Но тогда как исключить равенство? Нужно ли зацикливать все комбинации и явно исключать их?

Очевидно, что я могу сделать исключение "вручную", но мне интересно, есть ли лучший (более эффективный) способ или библиотека поддержки, которая включает в себя такие вещи (у меня немного больше опыта работы с библиотеками линейного программирования, и обычно они имеют куча вспомогательных функций, которые решают такие общие случаи).

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

И теперь я думаю об этом, как мне искать максимум? Есть ли хорошая книга или набор заметок по этому вопросу?

[Я использую clojure, но я понимаю, что clojure-core.logic и minikanren в значительной степени идентичны]

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

1 ответ

Решение
(run* [q] 
  (fresh [a b c]
    (== q [a b c])
    (fresh [x y z]
      (rembero a '(* + / - exp) x)
      (rembero b x y)
      (rembero c y z))))
Другие вопросы по тегам