事实的Clojure反向链接



我们使用的是前向链接规则系统,在该系统中,我们必须向系统提供决策所需的数据。我更希望规则系统能够提出问题,以获得决策所需的数据。在Jess身上,这似乎与神奇的";需要-";前缀:

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

有了这个解决方案,就不会提取不必要的事实。此外,显著性可以用来帮助避免更昂贵的事实查询(例如远程呼叫(,也可以保持代码DRY

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

真的在寻找一个在Clojure中做类似事情的例子。

正是因为它从这里链接起来,有人在Ask Clojure上回答了Joel这个问题:Ask Clojure:core.logic能提问吗?

答案如下:

我不是一个优秀的minikanren或core.local用户,我能够说服通过这种方式找到一个小解决方案:

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

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

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

我相信也有一种方法可以保留交互式收集的事实(也许这个词是tabling(,或者理想情况下,更新事实数据库在搜索过程中实时显示。不过我目前还不知道。

相关内容

  • 没有找到相关文章

最新更新