6

これは、(願わくば) 単純な論理プログラムで、私がしばらくの間行き詰っています。

親ノードのリストを生成するときに、core.logic のエッジ リレーションによって表される DAG があります。グラフに「ダイヤモンド シェイプ」があると、重複が発生します (ここではサイクルについて話しているわけではありません)。

この場合、親の個別のリストを生成する方法はありますか (parento を書き直すなど)?

(defrel edge a b)
(fact edge :a :b)
(fact edge :a :c)
(fact edge :b :d)
(fact edge :c :d)

(defne parento [x y]
  ([x y] (edge y x))   
  ([x y] (fresh [z]
           (edge z x)
           (parento z y))))

(run* [q] (parento :d q))
;; => (:b :c :a :a)

(:b :c :a) を取得したいのですが、run* ステートメント内で実行したいと考えています (つまり、結果をセットにラップすることは、私が目指していることではありません)。

また、「^:tabled」をparentoに追加するとうまくいくようですが、tabledが導入するメモ化はしたくありません。

4

1 に答える 1

1

これまで行ってきたように、エッジの個々のファクトを定義する場合、リレーショナル プログラミングを終了せずにこれを行う方法はありません。1 つの解決策は、単純に結果のリスト全体を Clojure の set コンストラクターに渡すことです。もう 1 つのオプションは、ロジック プログラムの 1 回のパスですべてのノードを操作することです。

この問題に対する既存の Prolog ソリューションを調べて、見つけたものを翻訳すると役立つ場合があります。

于 2012-09-26T20:34:07.713 に答える