我曾经尝试实现一个类似于(map + list1 list2) -> list3的关系
我的代码是
(require '[clojure.core.logic :as l])
(require '[clojure.core.logic.fd :as fd])
(defn zip+o [x y z]
(l/conde
[(l/== () x) (l/== () y) (l/== () z)]
[(l/fresh [fx rx fy ry fz rz]
(l/conso fx rx x)
(l/conso fy ry y)
(l/conso fz rz z)
(fd/in fx fy fz (fd/interval 10))
(fd/+ fx fy fz)
(zip+o rx ry rz))]))
(def expected-solutions
#{{:x [0 0] :y [1 1]}
{:x [0 1] :y [1 0]}
{:x [1 1] :y [0 0]}
{:x [1 0] :y [0 1]}})
(l/run* [q]
(l/fresh [x y]
(l/== q {:x x :y y})
(zip+o x y [1 1])))
;=> ({:x (1 0), :y (0 1)}
; {:x (0 0), :y (1 1)})
通过删除clojure.core.logic/enforce-constraints中的onceo调用来管理预期的行为(我认为...)
(defn enforce-constraints [x]
(all
(force-ans x)
(fn [a]
(let [constrained (enforceable-constrained a)]
(verify-all-bound a constrained)
((force-ans constrained) a) ;; <--- 这里
#_((onceo (force-ans constrained)) a)))))
遗憾的是,它破坏了一个测试...
在(test-simplefd-in-last) (tests.clj:1797)中失败
预期:(= (run* [q] (fresh [x y z p0 p1] (== q [x y]) (fd/+ x y 9) (fd/* x 2 p0) (fd/* y 4 p1) (fd/+ p0 p1 24) (fd/in x y z (fd/interval 0 9)))) ([6 3]))
实际:(not (= ([6 3] [6 3] [6 3] [6 3] [6 3] [6 3] [6 3] [6 3] [6 3] [6 3]) ([6 3])))
希望这至少能帮您找到真正的问题。