2012-08-28 56 views
3

我想用core.logic寫入factorial。我發現這個序言段Clojure中的因子core.logic

factorial(0, 1). 
factorial(N, M):- N1 is N - 1, factorial (N1, M1), M is N*M1. 

,並試圖把它翻譯中失敗消息

clojure.core.logic.LVar cannot be cast to java.lang.Number 
    [Thrown class java.lang.ClassCastException] 

什麼是正確的方式通過以下方式

(defne factorialo [n m] 
    ([0 1]) 
    ([n m] (fresh [n1 m1] 
      (== (- n 1) n1) 
      (== (* n m1) m) 
      (factorialo n1 m1)))) 

(run* [q] 
    (factorialo 3 q)) 

到core.logic在core.logic中編寫階乘?

+0

這是一個假設的問題,還是有一個很好的理由不寫在Clojure? – Bill

+0

目標是學習邏輯編程和core.logic庫提供的可能性。 – mchlstckl

回答

3

Prolog中的算術通常表示隱式投影 - 您不再與邏輯變量有關係,而是與它們綁定的實際值有關。有沒有好的糖這又在core.logic,你必須使投影明確:

(defne factorialo [n m] 
    ([0 1]) 
    ([n m] 
    (fresh [n1 m1] 
     (project [n] 
     (== n1 (- n 1))) 
     (factorialo n1 m1) 
     (project [n m1] 
     (== m (* n m1)))))) 

(run 1 [q] 
    (factorialo 3 q)) 

在core.logic 0.8.0阿爾法也爲約束邏輯規劃在有限域的支持。這提高了運算故事序言:

(defne factorialfd [n m] 
    ([0 1]) 
    ([n m] 
    (fresh [n1 m1] 
     (infd n1 m1 (interval 0 Integer/MAX_VALUE)) 
     (+fd n1 1 n) 
     (factorialfd n1 m1) 
     (*fd n m1 m)))) 

(run 1 [q] 
    (infd q (interval 0 Integer/MAX_VALUE)) 
    (factorialfd 3 q)) 

注意,變量的域必須作出明確的,但我們不再需要用投影打擾。然而,這項工作是非常地位的,未來這種解決方案看起來像是可以改變的。

+0

太棒了!感謝您的詳細解釋。我非常喜歡學習邏輯編程以及如何使用core.logic。保持良好的工作! – mchlstckl