Как де-структурировать карту в core.logic?
Я считаю, что у меня проблемы с удалением карты в core.logic. У меня есть следующий код:
... used clojure.core.logic
... required clojure.core.logic.arithmetic as logic.arithmetic.
(def hand ({:rank 9, :suit :hearts}
{:rank 13, :suit :clubs}
{:rank 6, :suit :spades}
{:rank 8, :suit :hearts}
{:rank 12, :suit :clubs}))
(run* [q]
(fresh [v w x y z] ;;cards
(== q [v w x y z])
(membero v hand)
(membero w hand)
(membero x hand)
(membero y hand)
(membero z hand)
(fresh [a b c d e] ;;ranks
(== {:rank a} v)
(== {:rank b} w)
(== {:rank c} x)
(== {:rank d} y)
(== {:rank e} z)
(logic.arithmetic/>= a b)
(logic.arithmetic/>= b c)
(logic.arithmetic/>= c d)
(logic.arithmetic/>= d e))
(distincto q)))
Возвращает пустой список (), указывая, что не найдено совпадений. Я считаю, что это проблема в (== {:rank a} v) части кода. Я пытаюсь просто вернуть q, где q - вектор карт в порядке убывания ранга.
3 ответа
Теперь гораздо более краткое решение можно написать с использованием последней версии core.logic 0.8.3:
(ns cards
(:refer-clojure :exclude [==])
(:use [clojure.core.logic])
(:require [clojure.core.logic.fd :as fd]))
(def hand
[{:rank 9, :suit :hearts}
{:rank 13, :suit :clubs}
{:rank 6, :suit :spades}
{:rank 8, :suit :hearts}
{:rank 12, :suit :clubs}])
(defn ranko [card rank]
(featurec card {:rank rank}))
(run* [v w x y z :as q]
(permuteo hand q)
(fresh [a b c d e]
(ranko v a) (ranko w b) (ranko x c)
(fd/>= a b) (fd/>= b c)
(ranko y d) (ranko z e)
(fd/>= c d) (fd/>= d e)))
Если вам не нужно ссылаться на логическую переменную, вам на самом деле не нужно называть ее:
(== {:rank a :suit (lvar)} v)
Я использую (lvar)
все больше и больше. Обычно это делает код более понятным, чем одноразовая неиспользуемая переменная, но мне бы хотелось, чтобы был лучший способ выразить это.
Очевидно, вы должны делать точные совпадения на картах. Это означает, что вы можете создавать мусорные переменные для захвата значений всего, что вас не интересует. Кажется странным, но хорошо.
(run* [q]
(fresh [v w x y z] ;;cards
(== q [v w x y z])
(membero v hand)
(membero w hand)
(membero x hand)
(membero y hand)
(membero z hand)
(fresh [a b c d e, f g h i j] ;;ranks, garbage
(== {:rank a :suit f } v)
(== {:rank b :suit g } w)
(== {:rank c :suit h } x)
(== {:rank d :suit i } y)
(== {:rank e :suit j } z)
(logic.arithmetic/>= a b)
(logic.arithmetic/>= b c)
(logic.arithmetic/>= c d)
(logic.arithmetic/>= d e))
(distincto q)))
Наконец, вот немного более краткая, быстрая и более искаженная версия вышеупомянутого.
(run* [q]
(fresh [v w x y z] ;;cards
(permuteo hand q)
(== q [v w x y z])
(fresh [a b c d e, f g h i j] ;;ranks, garbage
(== {:rank a :suit f } v)
(== {:rank b :suit g } w)
(logic.arithmetic/>= a b)
(== {:rank c :suit h } x)
(logic.arithmetic/>= b c)
(== {:rank d :suit i } y)
(logic.arithmetic/>= c d)
(== {:rank e :suit j } z)
(logic.arithmetic/>= d e))))