Featurec 并非旨在允许派生值(请参阅core.logic/featurec 文档中的链接示例)。
通常,您可以期望以“c”结尾的 core.logic 函数是“约束函数”,专门用于过滤(“约束”)已经从以前的逻辑函数派生的可能值的集合/域。这是库作者的一个有用的命名约定,而且据我所见,core.logic 的用户也试图坚持使用它。
但是,正常的统一对于这个特定的问题很有效。
(l/run* [q]
(l/fresh [x y z a b c]
(fd/in x y z (fd/interval 0 3)) ; establish domain for x y z
(let [w {:a x :b y :c z}] ; store x y z in a map
(l/all
(l/== w {:a a :b b :c c}) ; extract x y z as a b c
(fd/+ a b c))) ; a relationship
(l/== q [a b c])))
=> ([0 0 0] [1 0 1] [0 1 1] [0 2 2] [2 0 2] [1 1 2])
或者,如果您只想要某些值,只需提取 lvar 并单独统一:
(l/run* [q]
(l/fresh [x y z a b c]
(fd/in x y z (fd/interval 0 2)) ; establish domain for x y z
(let [w {:a x :b y :c z}] ; store x y z in a map
(l/all
(l/== a (w :a)) (l/== b (w :b)) ; extract x y z as a b c
(fd/+ a b c))) ; a relationship
(l/== q [a b c]) ))
=> ([0 0 0] [1 0 1] [0 1 1] [0 2 2] [2 0 2] [1 1 2] [1 2 3] [2 1 3] [2 2 4])
(还要注意我们没有统一c和z,所以c可以在区间之外)
如果需要,可以列出所需的 lvar 和相应的键,然后使用everyg为每对添加关系:
(l/run* [q]
(l/fresh [x y z a b c]
(fd/in x y z (fd/interval 0 2)) ; establish domain for x y z
(let [w {:a x :b y :c z}
targlist [a b c]
wantedlist [:a :b :c]] ; store x y z in a map
(l/all
(everyg #(l/==
(get targlist %)
(w (get wantedlist %)))
(range (count targlist))) ; extract x y z as a b c
(apply fd/+ [a b c]))) ; a relationship
(l/== q [a b c])))
=> ([0 0 0] [1 0 1] [0 1 1] [0 2 2] [2 0 2] [1 1 2])