簡體   English   中英

在Clojure core.logic中搜索樹

[英]Tree search in Clojure core.logic

一段時間以來我一直對模型化問題感到困惑,我不得不承認我不知道如何在core.logic “正確”解決它。

很容易說明:給定一個樹(非循環單向導向圖)和其中的頂點,如何使用core.logic定義一個目標,允許lvar成為來自給定頂點的任何可到達頂點?

我開始時盡可能簡單:

(defrel vertex x)
(defrel child)
(def facts
  (pldb/db
    [vertex 'a]
    [vertex 'b] [child 'a 'b]
    [vertex 'c] [child 'b 'c]
    [vertex 'd] [child 'c 'd]))

鑒於這種配置,我的目標是定義一個允許lvar在['a'b'c'd]中取值的目標。 使用“1 hop”獲得可到達的頂點非常簡單:

(defn reachableo
  [a]
  (fresh [q]
    (child a q)))

並且你可以添加2跳等變量,但是......可以推廣嗎? 我曾經想過用類似的東西定義一個lvar列表

(let [vars (repeatedly lvar)]
  (map #(child (nth vars %) (nth vars (inc %)))
       (-> vars count dec range))
  (all
    ...))

但是后來幾次嘗試,我必須承認我不確定這是正確的方法。

(pldb/db-rel vertex x)
(pldb/db-rel child parent child)
(def facts
  (pldb/db
    [vertex 'a]
    [vertex 'b] [child 'a 'b]
    [vertex 'c] [child 'b 'c]
    [vertex 'd] [child 'c 'd]))

遞歸目標:

(defn reachable° [from to]
  (l/fresh [v]
    (l/conde
      [(child from to)]
      [(child from v) (reachable° v to)])))

測試

=> (pldb/with-db facts
     (vec (l/run* [to] (reachable° 'a to))))
[b c d]

謝謝你的幫助!

其實我得到了

(defn order-relationo
  "Abstract the general pattern of a order relation in a logic, relational way."
  [relation x y]
  (conde
   [(relation x y)]
   [(fresh [z]
      (relation x z)
      (order-relationo relation z y))]))

(def kino
  "A goal where the two inputs x and y share kinship: x is an ancestor of y and
  y a descandant of x."
  (partial order-relationo child))

我問了這個問題,因為很長一段時間我沒有練過邏輯編程,但現在我覺得它又來了^^

無論如何,非常感謝你的回答,這給了我一個額外的觀點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM