6

core.logic を使って階乗を書きたいと思います。このプロローグスニペットを見つけました

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

次の方法でcore.logicに変換しようとしました

(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))

メッセージで失敗します

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

core.logic で階乗を記述する適切な方法は何ですか?

4

1 に答える 1

6

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 alpha では、有限ドメインに対する制約ロジック プログラミングがサポートされています。これにより、Prolog の算術ストーリーが改善されます。

(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))

変数の定義域を明示する必要がありますが、射影を気にする必要がないことに注意してください。ただし、この作業は非常にアルファ ステータスであり、このソリューションが将来どのように見えるかは変更される可能性があります。

于 2012-08-30T13:28:38.747 に答える