2024 年 Clojure 状态调查中分享您的想法!

欢迎!请查看关于页面以获取更多关于如何工作的信息。

0

我四处看了看,没看到任何明显的东西。但是,我对 Clojure 和 core.logic 比较新。只是想看看是否有简单的方法将逻辑数据库存储到文件中。我想在逻辑数据库中存储/撤回事实,并偶尔将整个数据库保存下来以便恢复。然后,将来可能将那个数据库恢复到内存中。

非常感谢任何帮助。

1 个回答

0

看起来nippy 可以配合标准序列化一起使用,因为 Prolog 事实数据库使用的是已经可以序列化的 Clojure 类型来实现。

(ns logos.serial
  (:require [taoensso.nippy :as nippy]
            [clojure.core.logic.pldb :as pldb]
            [clojure.core.logic :as log]
            [clojure.java.io]))

(defn freeze-to! [o target & {:keys [compressor] :or {compressor nippy/lz4hc-compressor}}]
  (with-open [buff (clojure.java.io/output-stream target)
              dos (java.io.DataOutputStream. buff)]
    (nippy/freeze-to-out! dos  o)))

(defn thaw-from! [target & {:keys [compressor] :or {compressor nippy/lz4hc-compressor}}]
  (with-open [fis (clojure.java.io/input-stream target)
              dis (java.io.DataInputStream. fis)]
    (nippy/thaw-from-in! dis )))

(pldb/db-rel man p)
(pldb/db-rel woman p)
(pldb/db-rel likes p1 p2)
(pldb/db-rel fun p)

(def facts0
  (pldb/db
   [man 'Bob]
   [man 'John]
   [man 'Ricky]

   [woman 'Mary]
   [woman 'Martha]
   [woman 'Lucy]

   [likes 'Bob 'Mary]
   [likes 'John 'Martha]
   [likes 'Ricky 'Lucy]))


(def facts1 (-> facts0 (pldb/db-fact fun 'Lucy)))

查询和测试

(defn simple-query [db]
  (pldb/with-db db
    (log/run* [q]
      (log/fresh [x y]
        (fun y)
        (likes x y)
        (log/== q [x y])))))

;;logos.serial>(simple-query facts1)
;;([Ricky Lucy])

(freeze-to! facts1 "facts.lz4")
(def facts-thawed (thaw-from! "facts.lz4"))

;;logos.serial>(= facts1 facts-thawed)
;;logos.serial> (simple-query facts-thawed)
;;([Ricky Lucy])
谢谢。 我之前没有看过那个。 那样是可以用的。

我也用 spit/slurp 命令运行起来了。 所以,我不知道之前我在做什么。 很可能是犯了些愚蠢的错误。

再次感谢回答。 我要去看看 nippy 了...
由于实现细节基于map/record且具有可读表示,spit/slurp将可以工作。根据你序列化对象的尺寸,冻结/解冻的频率以及其他如压缩等问题,我认为nippy在很多情况下都会占上风(除了spit/slurp已经是捆绑的之外)。尽管如此,使用spit/slurp进行不佳的序列化出人意料地很有用。
欢迎使用Clojure问答区,在这里你可以向Clojure社区成员提问并获取答案。
...