<commit_before>(ns sample.core
  (:gen-class)
  (:require [clojure.core.logic :as cl]
            [clojure.core.logic.pldb :as cldb]

            #_[ow.factum.transport.embedded.client :as tc]
            #_[ow.factum.transport.embedded.server :as ts]
            #_[ow.factum.backend.memory :as bm]
            #_[ow.factum.dbpoller :as dbp]
            #_[ow.factum.clientstorage :as cs]
            #_[ow.factum.entities :as e]
            #_[ow.factum.logicdb :as l]))


#_(defn cltest1 []
  (cldb/db-rel man p)
  (cldb/db-rel woman p)
  (cldb/db-rel likes ^:index p1 ^:index p2)

  (let [facts0 (cldb/db
                [man 'Bob]
                [man 'John]

                [woman 'Mary]
                [woman 'Martha]

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

    (cldb/with-db facts0
      (cl/run* [q]
        (cl/fresh [x y]
          (likes x y)
          (man x)
          (woman y)
          (cl/== q [x y]))))))

;;; (cltest1)



(defn cltest2 []
  #_(cldb/db-rel fact e a v t)

  (defrecord Snapshot [entities t])

  (defn facts->snapshot [facts & {:keys [at-t]}]
    (let [;;;ldb (apply cldb/db facts)
          #_lres #_(cldb/with-db ldb
                 (cl/run* [q]
                   (cl/fresh [e a v t]
                     (fact e a v t)
                     (cl/== q [e a v t]))))
          maxt (volatile! 0)]
      (when (not-empty facts #_lres)
        (->Snapshot (->> facts #_lres
                         (reduce (fn [s [e a v t]]
                                   (if (or (not at-t) (<= t at-t))
                                     (do (when (> t @maxt)
                                           (vreset! maxt t))
                                         (update-in s [e a]
                                                    (fn [[t2 v2 :as oldval]]
                                                      (if (and t2 (> t2 t))
                                                        oldval
                                                        [t v]))))
                                     s))
                                 {})
             ;;; TODO: this can probably be optimized in terms of memory usage & performance.
             ;;;   instead of building a new map, can we somehow operate on the existing one in
             ;;;   the appropriate nested places?
                         (map (fn [[e am]]
                                [e (reduce (fn [am [k [t v]]]
                                             (assoc am k v))
                                           {}
                                           am)]))
                         (into {}))
                    (do (println "MAXT2" @maxt)@maxt)))))

  (defn snapshot+facts->snapshot [snapshot facts & {:keys [at-t]}]
    {:pre [(or (nil? at-t) (> at-t (:t snapshot)))]}
    (letfn [(merge-entities [es1 es2]
              (merge-with #(merge %1 %2)
                          es1 es2))
            (merge-snapshots [s1 s2]
              (->Snapshot (merge-entities (:entities s1) (:entities s2))
                          (:t s2)))]
      (merge-snapshots snapshot (facts->snapshot facts :at-t at-t))))

  (let [facts1 [[#_fact 200 :type     :address      1]
                [#_fact 200 :street   "street 111"  1]
                [#_fact 200 :number   111           1]

                [#_fact 100 :type     :person       2]
                [#_fact 100 :name     "foo"         2]
                [#_fact 100 :email    "<EMAIL>" 2]
                [#_fact 100 :address  200           2]

                [#_fact 101 :type     :person       2]
                [#_fact 101 :name     "bar1"        2]
                [#_fact 101 :email    "<EMAIL>" 2]
                [#_fact 101 :address  200           2]
                [#_fact 101 :name     "bar3"        4]
                [#_fact 101 :name     "bar5"        6]
                [#_fact 101 :name     "bar2"        3]
                [#_fact 101 :name     "bar4"        5]]

        facts2 [[#_fact 101 :name     "bar7"        8]
                [#_fact 101 :name     "bar6"        7]
                [#_fact 101 :name     "bar9"        10]
                [#_fact 101 :name     "bar8"        9]]]

    (snapshot+facts->snapshot (facts->snapshot facts1) facts2)))

;;; (cltest2)



(defn etest []
  (cldb/db-rel person p)
  (cldb/db-rel address a)
  (cldb/db-rel person->address p a)

  (let [facts1 [(address {:id 100
                          :type :address
                          :street "street 1"})
                (address {:id 101
                          :type :address
                          :street "street 2"})
                (person {:id 200
                         :type :person
                         :name "<NAME>"
                         :address_id 100})]]
    (cldb/with-db (cldb/db facts1)
      (cl/run* [q]
        (cl/fresh [p]
          (person {:id 100}))))))

;;; (etest)



(defn xftest []
  (let [r (range 50000000)
        f1 #(+ % %)
        f2 dec
        f3 #(* % 10)
        ;;;s1 (doall (->> r (map f1) (map f2) (map f3)))
        s2 (doall (sequence (comp (map f1) (map f2) (map f3)) r))
        ]
    (count s2)))

;;; (xftest)<commit_msg>playing around with core.logic db regarding matching of maps and<commit_after>(ns sample.core
  (:gen-class)
  (:require [clojure.core.logic :as cl]
            [clojure.core.logic.pldb :as cldb]

            #_[ow.factum.transport.embedded.client :as tc]
            #_[ow.factum.transport.embedded.server :as ts]
            #_[ow.factum.backend.memory :as bm]
            #_[ow.factum.dbpoller :as dbp]
            #_[ow.factum.clientstorage :as cs]
            #_[ow.factum.entities :as e]
            #_[ow.factum.logicdb :as l]))


#_(defn cltest1 []
  (cldb/db-rel man p)
  (cldb/db-rel woman p)
  (cldb/db-rel likes ^:index p1 ^:index p2)

  (let [facts0 (cldb/db
                [man 'Bob]
                [man 'John]

                [woman 'Mary]
                [woman 'Martha]

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

    (cldb/with-db facts0
      (cl/run* [q]
        (cl/fresh [x y]
          (likes x y)
          (man x)
          (woman y)
          (cl/== q [x y]))))))

;;; (cltest1)



(defn cltest2 []
  #_(cldb/db-rel fact e a v t)

  (defrecord Snapshot [entities t])

  (defn facts->snapshot [facts & {:keys [at-t]}]
    (let [;;;ldb (apply cldb/db facts)
          #_lres #_(cldb/with-db ldb
                 (cl/run* [q]
                   (cl/fresh [e a v t]
                     (fact e a v t)
                     (cl/== q [e a v t]))))
          maxt (volatile! 0)]
      (when (not-empty facts #_lres)
        (->Snapshot (->> facts #_lres
                         (reduce (fn [s [e a v t]]
                                   (if (or (not at-t) (<= t at-t))
                                     (do (when (> t @maxt)
                                           (vreset! maxt t))
                                         (update-in s [e a]
                                                    (fn [[t2 v2 :as oldval]]
                                                      (if (and t2 (> t2 t))
                                                        oldval
                                                        [t v]))))
                                     s))
                                 {})
             ;;; TODO: this can probably be optimized in terms of memory usage & performance.
             ;;;   instead of building a new map, can we somehow operate on the existing one in
             ;;;   the appropriate nested places?
                         (map (fn [[e am]]
                                [e (reduce (fn [am [k [t v]]]
                                             (assoc am k v))
                                           {}
                                           am)]))
                         (into {}))
                    (do (println "MAXT2" @maxt)@maxt)))))

  (defn snapshot+facts->snapshot [snapshot facts & {:keys [at-t]}]
    {:pre [(or (nil? at-t) (> at-t (:t snapshot)))]}
    (letfn [(merge-entities [es1 es2]
              (merge-with #(merge %1 %2)
                          es1 es2))
            (merge-snapshots [s1 s2]
              (->Snapshot (merge-entities (:entities s1) (:entities s2))
                          (:t s2)))]
      (merge-snapshots snapshot (facts->snapshot facts :at-t at-t))))

  (let [facts1 [[#_fact 200 :type     :address      1]
                [#_fact 200 :street   "street 111"  1]
                [#_fact 200 :number   111           1]

                [#_fact 100 :type     :person       2]
                [#_fact 100 :name     "foo"         2]
                [#_fact 100 :email    "<EMAIL>" 2]
                [#_fact 100 :address  200           2]

                [#_fact 101 :type     :person       2]
                [#_fact 101 :name     "bar1"        2]
                [#_fact 101 :email    "<EMAIL>" 2]
                [#_fact 101 :address  200           2]
                [#_fact 101 :name     "bar3"        4]
                [#_fact 101 :name     "bar5"        6]
                [#_fact 101 :name     "bar2"        3]
                [#_fact 101 :name     "bar4"        5]]

        facts2 [[#_fact 101 :name     "bar7"        8]
                [#_fact 101 :name     "bar6"        7]
                [#_fact 101 :name     "bar9"        10]
                [#_fact 101 :name     "bar8"        9]]]

    (snapshot+facts->snapshot (facts->snapshot facts1) facts2)))

;;; (cltest2)



(defn etest []
  (cldb/db-rel instance x)
  (cldb/db-rel person p)
  (cldb/db-rel address a)
  (cldb/db-rel person->address p a)

  (let [facts1 [[instance {:type :foo :a 1 :b 2}]
                [instance {:type :bar :a 2 :b 3}]
                [address {:id 100
                          :type :address
                          :street "street 1"}]
                [address {:id 101
                          :type :address
                          :street "street 2"}]
                [person {:id 200
                         :type :person
                         :name "<NAME>"
                         :address_id 100}]
                [person {:id 201
                         :type :person
                         :name "<NAME>"
                         :address_id 101}]]
        ldb (apply cldb/db facts1)]
    (cldb/with-db ldb
      (cl/run* [q]
        #_(foo q 22)
        (cl/fresh [p o a b]
          (instance q)
          (cl/featurec q {:type :foo})

          #_(person p)
          #_(cl/featurec p {:type :person})
          #_(cl/featurec p {:name "<NAME>"})
          #_(cl/featurec p {:id q})

          #_(cl/== q p)
          #_(foo q b)
          #_(cl/== q [a b])
          #_(cl/matcha [] ([(person {:id 200 :name q})]))
          #_(cl/== p {:a 1 :b 2 :c 3})
          #_(cl/matcha [p]
                     ([{:a 1 :b 2 :c q}])
                     #_([[_ . o]] (cl/== q ["second" o]))))))))

;;; (etest)



(defn xftest []
  (let [r (range 50000000)
        f1 #(+ % %)
        f2 dec
        f3 #(* % 10)
        ;;;s1 (doall (->> r (map f1) (map f2) (map f3)))
        s2 (doall (sequence (comp (map f1) (map f2) (map f3)) r))
        ]
    (count s2)))

;;; (xftest)
{'fraction_non_alphanumeric': 0.1355032725986202, 'fraction_numerical': 0.031222359808950998, 'mean_word_length': 1.0023021073136178, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 41, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 48, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2457775', 'n_tokens_mistral': 3854, 'n_tokens_neox': 3433, 'n_words': 1007}