从地图中提取有限域 lvars
Extracting finite domain lvars from a map
我想将具有有限域的新鲜 lvar 放入映射中,并在我的另一部分代码中建立它们之间的关系。考虑以下代码段:
(l/run 1 [q]
(l/fresh [x y z a b c]
(fd/in x y z (fd/interval 0 100)) ; establish domain for x y z
(let [w {:a x :b y :c z}] ; store x y z in a map
(l/all
(l/featurec 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])))
==> Error printing return value at clojure.core.logic/verify-all-bound$verify-all-bound* (logic.clj:2136).
Constrained variable <lvar:a__5787> without domain
有没有办法做到这一点?
Featurec 未设计为允许派生值(请参阅 link's example in the core.logic/featurec documentation)。
通常,您可以期望以 'c' 结尾的 core.logic 函数 'constraint functions' 专门用于过滤 ('constraining') set/domain可能的值已经从以前的逻辑函数中导出。这是图书馆作者的一个有用的命名约定,据我所知,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可以在区间外)
如果你愿意,你可以列出你想要的 lvars 和相应的键,然后使用 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])
我想将具有有限域的新鲜 lvar 放入映射中,并在我的另一部分代码中建立它们之间的关系。考虑以下代码段:
(l/run 1 [q]
(l/fresh [x y z a b c]
(fd/in x y z (fd/interval 0 100)) ; establish domain for x y z
(let [w {:a x :b y :c z}] ; store x y z in a map
(l/all
(l/featurec 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])))
==> Error printing return value at clojure.core.logic/verify-all-bound$verify-all-bound* (logic.clj:2136).
Constrained variable <lvar:a__5787> without domain
有没有办法做到这一点?
Featurec 未设计为允许派生值(请参阅 link's example in the core.logic/featurec documentation)。
通常,您可以期望以 'c' 结尾的 core.logic 函数 'constraint functions' 专门用于过滤 ('constraining') set/domain可能的值已经从以前的逻辑函数中导出。这是图书馆作者的一个有用的命名约定,据我所知,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可以在区间外)
如果你愿意,你可以列出你想要的 lvars 和相应的键,然后使用 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])