Как написать свою собственную простую функцию ограничения в core.logic?

Я только что прочитал учебник для core.logic. Пока что это имеет смысл, но я не уверен, куда идти, чтобы узнать больше.

Допустим, я хотел написать собственное ограничение, вроде как membero показано в учебнике. Этот называется vectoro и ограничивает вещи, чтобы быть вектором.

(defn vectoro [s] ???)

(run* [q]
  (conde
    [(== q [1 2])]
    [(== q :a)])
  (vectoro q))

Теперь я хочу, чтобы вернуться [1 2], Как ты пишешь vectoro? Это где-нибудь задокументировано?

2 ответа

Решение

Там есть core.logic predмакрос, который делает это легко:

(run* [q]
  (== q [1 2])
  (pred q vector?))
=> ([1 2])

(run* [q]
  (== q '(1 2))
  (pred q vector?))
=> ()

Вот как вы можете определитьvectoroфункция / противопоказание (но понимаю, что это по сути то же самое pred делает)

(defn vectoro [a]
  (project [a]
    (== true (vector? a))))

project используется для работы с фактическим / конкретным значением логической переменной (LVar). Затем мы можем использовать простой старый предикат vector? и требуют, чтобы результат был правдой. Это также работает с вашей программой-примером:

(run* [q]
  (conde
    [(== q [1 2])]
    [(== q :a)])
  (vectoro q))
=> ([1 2])

(run* [q]
  (conde
    [(== q '(1 2))]
    [(== q :a)])
  (vectoro q))
=> ()

Чтобы продолжить обучение, я предлагаю поискать проекты, использующие core.logic, и посмотреть, научит ли их исходный код чему-либо.

Что касается вашего конкретного вопроса о vectoro функция " проект " (как в "проекции"), вероятно, выполнит то, что вы хотите, что-то вроде

(defn vectoro [s v]
  (core.logic/project [v]
    (core.logic/== s (vector? v)))
Другие вопросы по тегам