请在美国州Clojure调查问卷中分享您的想法:2024 Clojure状态调查!

欢迎!请参阅关于页面以了解更多关于如何使用该页面信息。

+1
Clojure

核心逻辑可以像prolog一样提问吗?

commits(Person, Crime) :-

crime(Crime),
format('is ~w ?', [commits(Person, Crime)]),
read(yes).

See on stackoverflow 链接.

1 答案

+1

被选中
 
最佳答案

作为一个不善长使用minikanren或core.logic的用户,我最终这样找到了一个解决方案

(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),或者理想情况下,在搜索过程中实时更新事实数据库。但我不太了解。

by
我认为核心逻辑可能没有一种方式可以选择(类似于显著性)某一行的一个问题而牺牲另一行的,或者这可能可以通过对语句进行排序来解决。感谢这次的良好开端。
...