2013-04-27 35 views
2

我正在使用Clojure的core.logic CLP(FD)庫(core.logic版本0.8.3)的樸素平方包裝算法。Clojure core.logic CLP(FD)投影FD變量

正方形表示像這樣:

[[[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變量進行非關係運算提出任何建議?

謝謝!

回答

3

是的,你不能投影未被限制爲單一值的有限域變量。我建議您在Prolog中尋找現有解決方案,以利用CLP(FD)。很可能,我們不支持足夠的約束條件來簡化表達這個問題 - 我們正在研究這個問題。

+0

啊謝謝,很高興知道! – 2013-04-28 17:05:29

+0

需要一種量詞消去的形式來收縮約束的數量,當域是無限的時候這並不總是可能的。但是沒有人會阻止前面的量詞返回解決方案。如果量詞是一個存在量詞,你甚至不需要顯示它,除非要記住可能的消除選項。當變量沒有被標記時,它可以參與前向常量消除。這就是爲什麼新的Prolog變量(例如在使用CLP(FD)的遞歸謂詞中引入的變量)最常用。 – 2016-03-26 20:52:34