我正在努力掌握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 -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)
我错误地尝试将规则创建为正常功能吗?还是将复杂的数据变成事实?
答案 0 :(得分:4)
您可以在db
中检查复杂的数据结构,这里唯一缺少的部分是在is-wibble?
谓词中,您将收到一个逻辑变量而不是一个实际的具体价值。
core.logic中有一个pred
目标,它将project
一个lvar,以便您检查其价值。我重命名了目标以匹配典型的目标名称。 pred
接受一个lvar和一些将接收lvar值的函数,并且如果该谓词函数返回true-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})