Clojure核心逻辑。我可以在事实和规则中使用复杂的数据结构吗?

Clojure核心逻辑。我可以在事实和规则中使用复杂的数据结构吗?,clojure,clojure-core.logic,Clojure,Clojure Core.logic,我正在努力掌握核心逻辑 我可以在事实和规则中使用复杂的数据结构吗 例如,我正在尝试这样做: (pldb/db-rel test a) (defn is-wibble? [a] (= true (:wibble a))) (def facts (pldb/db [test {:name "x" :wibble true}] [test {:name "y" :wibble false}] [test {:name "z" :wibble true}])) (defn -

我正在努力掌握核心逻辑

我可以在事实和规则中使用复杂的数据结构吗

例如,我正在尝试这样做:

(pldb/db-rel test a)

(defn is-wibble? [a] (= true (:wibble a)))

(def facts
  (pldb/db
   [test {:name "x" :wibble true}]
   [test {:name "y" :wibble false}]
   [test {:name "z" :wibble true}]))

(defn -main [& args]
  (doseq [x
          (pldb/with-db facts
            (run* [q]
              (is-wibble? q)))]
    (println x))))
但它抛出了一个错误:

Caused by: java.lang.ClassCastException: java.base/java.lang.Boolean cannot be cast to clojure.lang.IFn
    at clojure.core.logic.Substitutions.bind(logic.clj:425)
    at polvo.core$_main$fn__377$fn__378$fn__379$_inc__380.invoke(core.clj:223)
实际上是在排队

(is-wibble? q)

我尝试创建规则作为正常函数是错误的吗?或者将复杂数据放入事实中?

您可以检查
db
中的复杂数据结构,这里唯一缺少的是,在
是wibble?
谓词中,您将接收一个逻辑变量,而不是实际的具体值

core.logic中有一个
pred
目标,它将
投影
一个lvar,以便您可以检查它的值。我重命名了目标以匹配典型的目标名称
pred
接受一个lvar和一些将接收lvar值的函数,如果该谓词函数返回truth-y,
pred
目标成功

(defn wibbleo [a] (pred a :wibble))
或者您可以使用原始谓词这样定义它:

(defn wibbleo [a] (pred a is-wibble?))    
注意:您还需要将您的
db rel
作为目标
(test q)
,然后您的程序应该可以工作:

(pldb/with-db facts
  (run* [q]
    (test q)
    (wibbleo q)))
=> ({:name "x", :wibble true} {:name "z", :wibble true})