的Clojure core.logic CLP(FD)突出FD变量(Clojure core.log

2019-09-01 06:36发布

我正在使用Clojure的core.logic CLP(FD)库(core.logic版本0.8.3)一个天真的方形包装算法。

正方形表示,像这样:

[[[x11 y11] [x12 y12]] 
 [[x21 y21] [x22 y22] ...]]

与表示为它的左上角和右下角的坐标的每个正方形。

坐标是FD变量,在一定的时间间隔内。

我想定义的解决方案作为最接近和最远的正方形的右上角和右下角之间的距离原点的大小,分别

(defne solution-size-o [size squares]
  ([s sqrs]
    (fresh [closest farthest 
            x11 y11 x22 y22 _1 _2]
    (closest-square   [[x11 y11] _1] sqrs)
    (farthest-square  [_2 [x22 y22]] sqrs)
    (project [x11 y11 x22 y22]
      (let [a (- y22 y11)
            b (- x22 x11)]
        (== s (-> (+ (* a a) (* b b)) Math/sqrt Math/ceil int)))))))

这似乎很好地工作与普通整数:

(run 1 [q]
  (solution-size-o q [[[0 0] [1 1]] [[1 1] [2 2]]]))
=> (3)

甚至与完全受限FD变量

(defn constrained-solution-size []
  (run 1 [q] 
    (fresh [size x11 y11 
                 x12 y12 
                 x21 y21 
                 x22 y22 squares]
      (fd/in x11 y11 x12 y12 x21 y21 x22 y22 (fd/interval 0 2))
      (fd/eq 
        (= x11 0) (= y11 0) (= x21 1) (= y21 1)
        (= x12 (+ x11 1)) (= y12 (+ y11 1))
        (= x22 (+ x21 1)) (= y22 (+ y21 1)))
      (== squares [[[x11 y11] [x12 y12]] [[x21 y21] [x22 y22]]])
      (solution-size-o size squares)
      (== q {:squares squares :size size}))))

(constrained-solution-size)
=> ({:squares [[[0 0] [1 1]] [[1 1] [2 2]]], :size 3})

但它似乎打破,当变量的域不完全约束。 例如,如果删除了约束y21 = 1 ,这意味着y11y21在它们的结构域左多于一个值:

(defn unconstrained-solution-size []
  (run 1 [q] 
    (fresh [size x11 y11 
                 x12 y12 
                 x21 y21 
                 x22 y22 squares]
      (fd/in x11 y11 x12 y12 x21 y21 x22 y22 (fd/interval 0 2))
      (fd/eq 
        (= x11 0) (= y11 0) (= x21 1)
        (= x12 (+ x11 1)) (= y12 (+ y11 1))
        (= x22 (+ x21 1)) (= y22 (+ y21 1)))
      (== squares [[[x11 y11] [x12 y12]] [[x21 y21] [x22 y22]]])
      (solution-size-o size squares)
      (== q {:squares squares :size size}))))

我得到

(unconstrained-solution-size)
=> ClassCastException clojure.core.logic.LVar cannot be cast to java.lang.Number     clojure.lang.Numbers.minus (Numbers.java:135)

看来, project仅适用于FD变量时,其域完全约束。 这是应该如何? 如果是,有没有人对如何开展非关系运算上的FD变量有什么建议?

谢谢!

Answer 1:

是的,你无法预计,也没有被限制为单个值有限域瓦尔。 我建议在寻找现有的解决方案,您的问题在序言,充分利用电(FD)。 这很可能是我们不支持足够的约束,以使这个问题简单的表达 - 我们正在这一点。



文章来源: Clojure core.logic CLP(FD) projecting FD variables