Clojure事实反向链接

Clojure事实反向链接,clojure,clojure-core.logic,clara-rule-engine,Clojure,Clojure Core.logic,Clara Rule Engine,我们使用的是前向链接规则系统,我们必须向系统提供决策所需的数据。我希望规则系统能够提出问题,以获得决策所需的数据。在中,这似乎可以通过神奇的“需要”前缀实现: 使用此解决方案,不会获取不需要的事实。另外,显著性可以用来帮助避免更昂贵的事实查找(例如远程调用),也可以保留代码 尽管Jess似乎解决了这个问题,但首选无许可证的Clojure解决方案。然而,以clojure.logic为例,如何实现这一点还不清楚。Clara使用前向链接,这似乎是不可能的,但通过规则生成,像Jess一样的黑客攻击是可能

我们使用的是前向链接规则系统,我们必须向系统提供决策所需的数据。我希望规则系统能够提出问题,以获得决策所需的数据。在中,这似乎可以通过神奇的“需要”前缀实现:

使用此解决方案,不会获取不需要的事实。另外,显著性可以用来帮助避免更昂贵的事实查找(例如远程调用),也可以保留代码

尽管Jess似乎解决了这个问题,但首选无许可证的Clojure解决方案。然而,以clojure.logic为例,如何实现这一点还不清楚。Clara使用前向链接,这似乎是不可能的,但通过规则生成,像Jess一样的黑客攻击是可能的吗


正在寻找在Clojure中执行类似操作的示例。

从这里链接,有人在询问Clojure时回答了Joel这个问题:

答案如下:

我不是一个优秀的minikanren或core.logic用户,所以我能够 通过这种方式提出一个小解决方案:

如果您在repl处对其进行评估,您应该会得到一个交互式提示 如果姓名与已知人员无关:

我相信也有一种方法可以保留以交互方式收集的事实 (可能术语是tabling),或者理想情况下,更新事实数据库 在搜索过程中实时进行。但我目前还不知道


正因为如此,有人在询问Clojure时回答了Joel这个问题:

答案如下:

我不是一个优秀的minikanren或core.logic用户,所以我能够 通过这种方式提出一个小解决方案:

如果您在repl处对其进行评估,您应该会得到一个交互式提示 如果姓名与已知人员无关:

我相信也有一种方法可以保留以交互方式收集的事实 (可能术语是tabling),或者理想情况下,更新事实数据库 在搜索过程中实时进行。但我目前还不知道

(defrule create-member
    (need-member $?)
    =>
    (assert (member A B))) ; eg. DB call to check membership, if needed for goal finding.

(defrule rule-1
    (member ?A ?B)
    =>
    (printout t member crlf))
(ns logos.demo
  (:require [clojure.core.logic :as l]
            [clojure.core.logic.pldb :as pldb]))


;; guilty(X) :-
;; commits(X,Y),
;; crime(Y).
;; crime(murder).
;; crime(theft)

(pldb/db-rel person x)
(pldb/db-rel crime x)
(pldb/db-rel commits x y)

(def facts
  (pldb/db-facts pldb/empty-db
                 [person "bill"]
                 [crime :murder]
                 [crime :theft]
                 [commits "bill" :theft]))

(defn ask! [person act]
  (println  (str "Does " person " commit " act "?"))
  (-> (read-line)
      clojure.string/trim
      clojure.string/lower-case
      #{"y" "yes"}
      some? ))

(defn commitso
  [p act]
  (l/conda
   [(person p) (commits p act)]
   [(l/project [p act]
             (l/==  (ask! p act) true))]))

(defn crimes [name]
  (->> (l/run-db* facts [p c]
                (l/== p name)
                (crime c)
                (commitso p c))
       (map second)))
logos.demo=> (crimes "bill")
(:theft)
logos.demo=> (crimes "tom")
Does tom commit :theft?  
y
Does tom commit :murder?
y
(:theft :murder)
logos.demo=> (crimes "tom")
Does tom commit :theft?
n
Does tom commit :murder?
n
()