Author SHA1 Message Date
Roman Volosovskyi d48a3379fc quest rules 2016-04-09 12:59:55 +03:00
Roman Volosovskyi 76cb5536c1 exclude :matcher key from derivation 2016-04-09 12:51:59 +03:00
Roman Volosovskyi faf010a846 fix empty "when" inside derivers code 2016-04-08 23:48:46 +03:00
Roman Volosovskyi 6508e881bb fix reduce-similarity 2016-04-08 18:38:45 +03:00
Roman Volosovskyi 91bcaa0d0b fix d-identity 2016-04-08 12:00:43 +03:00
24 changed files with 241 additions and 929 deletions
-8
View File
@@ -1,8 +0,0 @@
language: clojure
# Notify #nars
notifications:
slack:
secure: eI5hj2PABtAUkpeYwiAHcFMa5pNvHFuU87uqe4qBtv0upPtu22/dLpw8l6EhhcMZlW6C8D2irrj6W5C1lujCy7u3Vpu1FeBPZbqzapyU1Hpe8YgSRdCY1dbygawZp/Av/HWzpi0aTket83F5/0dvTZK0fQTBRmAfyx17DEJscYEBH61dKVqdwBy5OVYvhQ1+QtEnt1TRJcT0AA8von9lanzx5/mWdQ6O+3BrKURWG6vvQUYEMZH43NU6lNGNV+PBGV1PSqZqbzCh/6C6/d6HauQdewr4Oubez90OquyCDpCZDoVG8eCAsZtZt+tzfJ5gjtz8+HA6GQeQB6QMLAp89m1bPwSZCqdnmQp9S8TNgm8Io3jREBh+5JIdpDXwukKT1kMPFrdDiPTEhHNJojyK3/BERGyrhf8azow+brPq0EIM9Fi/SkGa0gb9mUXY/BZ1MF7ulxxbzpLxHJYlT9QVlV9Q09/uhH4tIh0kPQhe+ntkMT1uLTfDur7CZakB5270ibreRSeK4RKdpy5SjaIN70hSwyrWoZHiED6aKEJJSO1t9Ve1jTDyWbcUZYewtBi+APcqAraja9NIlFApjBRO1jUneS4/BzNqxWZAFS7MOwMrk1xFft47hMIHoNYd7IgyB7TWSxhloNTwMyOWkdOhnPIqqCvds6M0yQCDKNBiVeM=
services:
- redis-server
+1 -4
View File
@@ -9,10 +9,7 @@
[org.clojure/tools.nrepl "0.2.12"]
[org.clojure/data.priority-map "0.0.7"]
[org.clojure/core.match "0.3.0-alpha4"]
[org.clojure/core.unify "0.5.5"]
[org.clojure/core.async "0.2.374"]
[com.taoensso/carmine "2.12.2"]
[mount "0.1.10"]]
[org.clojure/core.unify "0.5.5"]]
:main ^:skip-aot narjure.core
:plugins [[lein-cloverage "1.0.6"]
[jonase/eastwood "0.2.3"]
+3 -3
View File
@@ -7,12 +7,12 @@
(if (>= c1 c2) [f1 c1] [f2 c2]))
(defn inference
[rules {:keys [task-type] :as task} belief]
(generate-conclusions (rules task-type) task belief))
[{:keys [task-type] :as task} belief]
(generate-conclusions (r/rules task-type) task belief))
(def revision t/revision)
(comment
:shift-occurrence-forward ;pre
:shift-occurrence-backward ;pre
:shift-occurrence-backward ;pre
:linkage-temporal)
+1 -2
View File
@@ -8,8 +8,7 @@
(defn get-matcher [rules p1 p2]
(let [matchers (->> (mall-paths p1 p2)
(filter rules)
(map rules)
(map (fn [el] (:matcher el))))]
(map rules))]
(case (count matchers)
0 (constantly [])
1 (first matchers)
+15 -11
View File
@@ -19,11 +19,11 @@
#{`= `not= `seq? `first `and `let `pos? `> `>= `< `<= `coll? `set `quote
`count 'aops `- `not-empty-diff? `not-empty-inter? `walk `munification-map
`substitute `sets `some `deref `do `vreset! `volatile! `fn `mapv `if
`sort-commutative `n/reduce-ext-inter `n/reduce-symilarity `complement
`sort-commutative `n/reduce-ext-inter `n/reduce-similarity `complement
`n/reduce-int-dif `n/reduce-and `n/reduce-ext-dif `n/reduce-image
`n/reduce-int-inter `n/reduce-neg `n/reduce-or `nil? `not `or `abs
`implications-and-equivalences `get-terms `empty? `intersection
`n/reduce-seq-conj `clojure.core.match/match})
`n/reduce-seq-conj})
(defn operators->placeholders
[statement]
@@ -67,19 +67,24 @@
(defn traverse-node
"Generates code for precondition node."
[vars result {:keys [conclusions children condition]}]
`(when ~(quote-operators condition)
~(when-not (zero? (count conclusions))
`(vswap! ~result concat
~@(set (map #(mapv (partial form-conclusion vars) %)
(quote-operators conclusions)))))
~@(map (fn [n] (traverse-node vars result n)) children)))
(let [conclusions (remove
nil?
[(when-not (zero? (count conclusions))
`(vswap! ~result concat
~@(set (map #(mapv (partial form-conclusion vars) %)
(quote-operators conclusions)))))])
children (mapcat (fn [n] (traverse-node vars result n)) children)]
(if (true? condition)
(concat conclusions children)
[`(when ~(quote-operators condition)
~@(concat conclusions children))])))
(defn traversal
"Walk through preconditions tree and generates code for matcher."
[vars tree]
(let [results (gensym)]
`(let [~results (volatile! [])]
~(traverse-node vars results tree)
~@(traverse-node vars results tree)
@~results)))
(defn replace-occurrences
@@ -340,6 +345,5 @@
match-fn-code (-> main-pattern
(gen-rules rules)
(match-rules main-pattern task-type))]
[k (assoc v :matcher (eval match-fn-code)
:matcher-code match-fn-code)])))
[k (eval match-fn-code)])))
(into {})))
+3 -3
View File
@@ -111,7 +111,7 @@
[_ ['ext-set & l1] ['ext-set & l2]] (diff 'ext-set l1 l2)
:else st))
(defn reduce-symilarity
(defn reduce-similarity
[st]
(m/match st
['<-> ['ext-set s] ['ext-set p]] ['<-> s p]
@@ -169,7 +169,7 @@
'| `reduce-int-inter
'- `reduce-ext-dif
'int-dif `reduce-int-dif
'<-> `reduce-symilarity
'<-> `reduce-similarity
'* `reduce-production
'int-image `reduce-image
'ext-image `reduce-image
@@ -185,7 +185,7 @@
| (reduce-int-inter st)
- (reduce-ext-dif st)
int-dif (reduce-int-dif st)
<-> (reduce-symilarity st)
<-> (reduce-similarity st)
* (reduce-production st)
int-image (reduce-image st)
ext-image (reduce-image st)
+8 -8
View File
@@ -5,7 +5,7 @@
[nal.deriver.substitution :refer [substitute munification-map]]
[nal.deriver.terms-permutation :refer [implications equivalences]]
[clojure.set :refer [union intersection]]
[narjure.defaults :refer [temporal-window-duration]]
[narjure.defaults :refer [duration]]
[clojure.core.match :as m]
[nal.deriver.normalization :refer [reduce-seq-conj]]))
@@ -88,11 +88,11 @@
[_]
[`(not= :eternal :t-occurrence)
`(not= :eternal :b-occurrence)
`(<= ~temporal-window-duration (abs (- :t-occurrence :b-occurrence)))])
`(<= ~duration (abs (- :t-occurrence :b-occurrence)))])
(defmethod compound-precondition :concurrent
[_]
[`(> ~temporal-window-duration (abs (- :t-occurrence :b-occurrence)))])
[`(> ~duration (abs (- :t-occurrence :b-occurrence)))])
;-------------------------------------------------------------------------------
(defmulti precondition-transformation (fn [arg1 _] (first arg1)))
@@ -164,11 +164,11 @@
(m/match (mapv #(if (and (coll? %) (= 'quote (first %)))
(second %) %) (rest args))
[(:or '=|> '==>)] concl
['pred-impl] `(let [:t-occurrence (+ :t-occurrence ~temporal-window-duration)] ~concl)
['retro-impl] `(let [:t-occurrence (- :t-occurrence ~temporal-window-duration)] ~concl)
['pred-impl] `(let [:t-occurrence (+ :t-occurrence ~duration)] ~concl)
['retro-impl] `(let [:t-occurrence (- :t-occurrence ~duration)] ~concl)
[sym (:or '=|> '==>)] (shift-forward-let sym concl)
[sym 'pred-impl] (shift-forward-let sym `+ concl temporal-window-duration)
[sym 'retro-impl] (shift-forward-let sym `- concl temporal-window-duration)))
[sym 'pred-impl] (shift-forward-let sym `+ concl duration)
[sym 'retro-impl] (shift-forward-let sym `- concl duration)))
(defn backward-interval-check [sym]
`(and (coll? ~sym) (= (first ~sym) (quote ~'seq-conj))
@@ -190,7 +190,7 @@
(defmethod conclusion-transformation :shift-occurrence-backward
[args concl]
(let [duration (- temporal-window-duration)]
(let [duration (- duration)]
(m/match (mapv #(if (and (coll? %) (= 'quote (first %)))
(second %) %) (rest args))
[(:or '=|> '==>)] concl
+14 -5
View File
@@ -57,6 +57,12 @@
[{:keys [pre]}]
(some #{:question?} pre))
(defn quest?
"Return true if rule allows only quest as task."
[{:keys [pre] [{post :post}] :conclusions}]
(and (some #{:question?} pre)
(every? #(not (#{:p/judgement} %)) post)))
(defn goal?
"Return true if rule allows only goal as task."
[{pre :pre [{post :post}] :conclusions}]
@@ -134,10 +140,13 @@
allow-backward? expand-backward-rules)
judgement-rules# (check-duplication (filter judgement? rules))
question-rules# (check-duplication (filter question? rules))
goal-rules# (check-duplication (filter goal? rules))]
(println "Q rules:" (count question-rules#))
(println "J rules:" (count judgement-rules#))
(println "G rules:" (count goal-rules#))
goal-rules# (check-duplication (filter goal? rules))
quest-rules# (check-duplication (filter quest? rules))]
(println "Beliefs rules:" (count judgement-rules#))
(println "Questions rules:" (count question-rules#))
(println "Goal rules:" (count goal-rules#))
(println "Quests rules:" (count quest-rules#))
{:judgement (rules-map judgement-rules# :judgement)
:question (rules-map question-rules# :question)
:goal (rules-map goal-rules# :goal)})))
:goal (rules-map goal-rules# :goal)
:quest (rules-map quest-rules# :quest)})))
+3 -1
View File
@@ -108,6 +108,8 @@
(defn t-identity [p1 _] p1)
(defn d-identity [p1 _] p1)
(defn belief-identity [p1 p2] (when p2 p1))
(defn belief-structural-deduction [_ p2]
@@ -166,6 +168,6 @@
:d/deduction intersection
:d/weak desire-weak
:d/induction desire-induction
:d/identity identity
:d/identity d-identity
:d/negation negation
:d/structural-strong desire-structural-strong})
+15
View File
@@ -450,3 +450,18 @@
; compound composition one premise
#R[(|| B :list/A) B |- (|| B :list/A) :pre (:question?) :post (:t/belief-structural-deduction :p/judgement)]
)
(def rules (compile-rules all-rules))
(defn freq [task-type]
"Check frequency"
(into {} (map (fn [[k v]] [(str k) (count (:rules v))]) (task-type rules))))
(defn stats [task-type]
(let [fr (freq task-type)]
(println "Total" (reduce + (vals fr)))
(println "Total keys" (count (task-type rules)))
(println "Freq" (sort (frequencies (vals fr))))
(println "Min" (reduce min (vals fr)))
(println "Max" (reduce (fn [[_ v1 :as p] [_ v :as n]]
(if (> v1 v) p n)) fr))))
-31
View File
@@ -1,31 +0,0 @@
(ns narjure.control.buffer
(:require [clojure.core.async.impl.protocols :as impl])
(:import [java.util LinkedList]
[clojure.lang Fn Counted]))
(deftype PanickingSlidingBuffer
[^LinkedList buf ^long n ^Fn warning-callback ^long warning-n]
impl/UnblockingBuffer
impl/Buffer
(full? [this]
false)
(remove! [this]
(.removeLast buf))
(add!* [this itm]
(let [size (.size buf)]
(when (>= size warning-n)
(warning-callback size)
(when (= size n)
(impl/remove! this))))
(.addFirst buf itm)
this)
(close-buf! [this])
Counted
(count [this]
(.size buf)))
(defn panicking-sliding-buffer
([n callback]
(panicking-sliding-buffer n callback (Math/round (* 0.9 n))))
([n callback warning-n]
(PanickingSlidingBuffer. (LinkedList.) n callback warning-n)))
-110
View File
@@ -1,110 +0,0 @@
(ns narjure.control.flow
(:require [clojure.core.async :refer [go-loop <! >! chan]]
[clojure.set :as set]))
(defn check-element-in-map
"Checks if elements exist in map, if not
assocs elements to map with default value."
([s m] (check-element-in-map s 0 m))
([s default m]
(reduce (fn [ac k]
(if (ac k)
ac
(assoc ac k default)))
m s)))
(defn all
"Returns set aff all functions from workflow."
[wf]
(set (flatten wf)))
(defn kw->fn
"Transform function's keyword to var."
[kw]
(->> (str kw)
(drop 1)
(apply str)
symbol
resolve))
(defn vertex
"Creates vertex of flow graph. Arguments:
- functions: collection of collections, where first element is function
and second (optional) is output port
- inputs: ports (edges) that should be listened by vertex
- p: number of parallelism"
[functions inputs p]
(doseq [in inputs
_ (range (* p (count functions)))]
(go-loop []
(when-let [val (<! in)]
(doseq [[f out] functions]
(let [results (f val)]
(when out
(doseq [res (if (map? results)
[results]
results)]
(>! out res)))))
(recur)))))
(defn check-output
"Creates output port for function if it is necessary."
[buffer [function output-cnt]]
[function (when (pos? output-cnt) (chan buffer))])
(defn fn-outputs
"Generates map where keys are functions and values are ports which
will be used to send result of execution of functions."
[workflow buffer]
(->> (group-by first workflow)
(map (fn [[n t]] [n (count t)]))
(into {})
(check-element-in-map (all workflow))
(map #(check-output buffer %))
(into {})))
(defn fn-inputs [workflow]
"Groups functions to identify vertexes and edges that they should listen.
Returns map {vertexes edges ...}
in: [[:a :b]
[:a :c]
[:c :d]
[:b :d]]
out: {[:c :b] [:a], [:d] [:b :c]}"
(->> workflow
(reduce (fn [ac [k v]]
(update ac k conj v))
{})
(reduce (fn [ac [k v]]
(update ac v conj k))
{})))
(defn generate-flow
"Generates flow of functions which is discribed by pairs of functions,
where result of fisrt function will be sent to input of the second function.
Optionally map of configuration params can be passed.
Possible configs:
- parallelism: map where keys are functions and values
are parallelization numbers
- default-p: defaulp parallelization number
- buffer: capacity of fixed buffer for all channels"
;TODO configuration for custom buffers
([workflow] (generate-flow workflow {}))
([workflow {:keys [parallelism default-p buffer]
:or {parallelism {}
default-p 1
buffer 100}}]
(let [in (chan buffer)
outputs (assoc (fn-outputs workflow buffer) :in in)
inputs (fn-inputs workflow)
all-inputs (set (mapcat key inputs))
input-tasks (set/difference (all workflow) all-inputs)
it2 (assoc inputs input-tasks [:in])]
(doseq [[tasks from] it2]
(vertex
(map (fn [f] [(kw->fn f) (outputs f)]) tasks)
(map outputs from)
(apply max (map #(parallelism % default-p) tasks))))
in)))
-69
View File
@@ -1,69 +0,0 @@
(ns narjure.control.general-inference
(:require [narjure.system :refer [memory inference]]
[narjure.control.flow :as f]
[narjure.memory.api :as m]))
;; select-concepts
;; | | | |
;; v v v ... v
;; select-task-link --> update-tasklink-budget
;; |
;; v
;; select-term-link --> update-termlink-budget
;; |
;; v
;; do-inference
(def workflow
[[::select-concepts ::select-task-link]
[::select-task-link ::update-tasklink-budget]
[::select-task-link ::select-term-link]
[::select-term-link ::update-termlink-budget]
[::select-term-link ::do-inference]])
(defn select-concept [_]
(m/pull-activated-concepts memory))
(defn select-task-link [concept]
(let [{task-id :task} (m/select-tasklink memory concept)
task (m/task memory task-id)]
{:task task
:concept concept}))
;(defn update-concept-budget [data] data)
(defn select-term-link [{:keys [concept task] :as data}]
(let [{linked-concept :concept} (m/select-termlink memory concept)
occurrence (:occurrence task)
truth (m/select-truth memory linked-concept occurrence)]
(assoc data :truth truth
:term (m/term memory linked-concept))))
;(defn update-tasklink-budget [data] data)
;(defn update-termlink-budget [data] data)
(defn do-inference [{:keys [task truth term]}]
(let [{statement :term
:keys [frequency confidence plausibility
desirability task-type occurrence]}
task
task {:statement statement
:desire [plausibility desirability]
:truth [frequency confidence]
:task-type task-type
:occurrence occurrence}
truth (assoc truth :statement term)
results (inference task truth)]
(doseq [res results]
(m/push-task memory res))))
(def default-parallelism {::do-inference 4})
(defn general-inference-flow
[{:keys [parallelism]
:or {parallelism default-parallelism}
:as options}]
(f/generate-flow workflow options))
-37
View File
@@ -1,37 +0,0 @@
(ns narjure.control.local-inference)
(def workflow
[[:read-task :answer-yn-question]
[:read-task :answer-general-question]
[:answer-yn-question :out-answers]
[:answer-general-question :out-answers]
[:read-task :find-related-concepts]
[:find-related-concepts :out-update-tasklinks]
[:find-related-concepts :out-check-tasklinks-capacity]
[:read-task :belief-revision]
[:belief-revision :out-update-beliefs]
[:read-task :goal-revision]
[:goal-revision :out-update-goals]])
(defn answer-yn-question [{:keys [task] :as segment}]
(println :yn)
{})
(defn answer-general-question [{:keys [task] :as segment}]
(println :general)
{})
(defn find-related-concepts [{:keys [task] :as segment}]
(println :rel)
{})
(defn belief-revision [{:keys [task] :as segment}]
(println :bel)
{})
(defn goal-revision [{:keys [task] :as segment}]
(println :goal)
{})
+1 -1
View File
@@ -32,4 +32,4 @@
(def ^{:type double} horizon 1)
(def temporal-window-duration 80)
(def duration 80)
-32
View File
@@ -1,32 +0,0 @@
(ns narjure.memory.api)
(defprotocol Memory
(term [mem concept])
(select-truth [mem concept occurrence])
(truths [mem concept])
(desires [mem concept])
(tasklinks [mem concept])
(select-tasklink [mem concept])
(termlinks [mem concept])
(select-termlink [mem concept])
(budget [mem concept])
(add-term [mem concept])
(add-truth [mem concept truth])
(add-desire [mem concept desire])
(add-tasklink [mem concept link])
(add-termlink [mem concept link])
(remove-truth [mem concept id])
(remove-desire [mem concept id])
(remove-tasklink [mem concept id])
(remove-termlink [mem concept id])
(update-budget [mem update-fn])
(task [mem id])
(push-task [mem task])
(pop-task [mem])
(activate-concept [mem concept])
(pull-activated-concepts [mem]))
-174
View File
@@ -1,174 +0,0 @@
(ns narjure.memory.redis
(:require [taoensso.carmine :as c]
[narjure.memory.api :refer [Memory]])
(:import (java.util UUID)))
;postfixes for keys
(def truths-pr "_t")
(def desires-pr "_d")
(def tasklinks-pr "_tkl")
(def termlinks-pr "_tml")
(def budget-pr "_bg")
(def task-pr "_tsk")
(def parse-float #(Float/parseFloat %))
(def parse-int #(Integer/parseInt %))
(def parse-boolean #(Boolean/parseBoolean %))
(def truth-schema
{:frequency :float
:confidence :float
:occurrence :int
:evidences :any})
(def desire-schema
{:plausibility :float
:desirability :float
:occurrence :int
:evidences :any})
(def task-schema
{:task-type :keyword
:evidences :vector
:eternal :boolean
:occurrence :int
:frequency :float
:confidence :float
:plausibility :float
:desirability :float
:term :any})
(def termlink-schema
{:priority :float
:durability :float
:quality :float
:concept :string})
(def tasklink-schema
{:priority :float
:durability :float
:quality :float
:task :string})
(def deserialization-fn
{:float parse-float
:int parse-int
:boolean parse-boolean})
(defn apply-schema [val]
(->> val
(map (fn [[k v]]
[k (get deserialization-fn v identity)]))
(into {})))
(def deserialization-map
(reduce (fn [ac [key val]] (assoc ac key (apply-schema val)))
{}
{truths-pr truth-schema
desires-pr desire-schema
task-pr task-schema
tasklinks-pr tasklink-schema
termlinks-pr termlink-schema}))
(defn- check-hash [val]
(if (or (integer? val) (string? val)) val (hash val)))
(defn get-key [concept postfix]
(str (check-hash concept) postfix))
(defn- get-maps-ids [conn concept postfix]
(->> (get-key concept postfix)
c/smembers
(c/wcar conn)))
(defn xf [trans-map]
(comp (partition-all 2)
(map (fn [[k v]]
(let [k (keyword k)
tf (get trans-map k identity)]
[k (tf v)])))))
(defn- get-map-by-key [conn trans-map k]
(into {} (xf trans-map) (c/wcar conn (c/hgetall k))))
(defn- get-maps [conn concept postfix]
(map (partial get-map-by-key conn (deserialization-map postfix))
(get-maps-ids conn concept postfix)))
(defn- get-map [conn concept postfix]
(get-map-by-key conn (deserialization-map postfix) (get-key concept postfix)))
(defn- add-map [conn concept postfix data]
(let [id (str (UUID/randomUUID) postfix)]
(c/wcar conn (c/sadd (get-key concept postfix) id))
(c/wcar conn (c/hmset* id (assoc data :id id)))))
(defn- remove-map [conn concept postfix id]
(c/wcar conn (c/srem (get-key concept postfix) id))
(c/wcar conn (c/del id)))
(defn- push [conn task]
(let [id (str (UUID/randomUUID) "_tsk")]
(c/wcar conn (c/lpush "tasks" id))
(c/wcar conn (c/hmset* id task))))
(defn- tpop [conn]
(let [id (c/wcar conn (c/rpop))]
(get-map-by-key conn (deserialization-map task-pr) id)))
(defn pull-concepts [conn]
(-> (c/wcar
conn
(c/multi)
(c/smembers :active-concepts)
(println val)
(c/del :active-concepts)
(c/exec))
last
first))
(defn- activate-concept* [conn concept]
(c/wcar conn (c/sadd :active-concepts (check-hash concept))))
(defn- select-link [conn concept prefix]
(let [id (->> prefix
(get-key concept)
c/srandmember
(c/wcar conn))]
(get-map-by-key conn (deserialization-map prefix) id)))
(defn get-task [conn id]
(get-map-by-key conn (deserialization-map task-pr) id))
(defrecord RedisMemory
[conn]
Memory
(term [_ concept] (c/wcar conn (c/get (check-hash concept))))
(select-truth [_ concept occurrence] (select-link conn concept truths-pr))
(truths [_ concept] (get-maps conn concept truths-pr))
(desires [_ concept] (get-maps conn concept desires-pr))
(tasklinks [_ concept] (get-maps conn concept tasklinks-pr))
(select-tasklink [_ concept] (select-link conn concept tasklinks-pr))
(termlinks [_ concept] (get-maps conn concept termlinks-pr))
(select-termlink [_ concept] (select-link conn concept termlinks-pr))
(budget [_ concept] (get-map conn concept budget-pr))
(add-term [_ concept] (c/wcar conn (c/set (hash concept) concept)))
(add-truth [_ concept truth] (add-map conn concept truths-pr truth))
(add-desire [_ concept desire] (add-map conn concept desires-pr desire))
(add-tasklink [_ concept link] (add-map conn concept tasklinks-pr link))
(add-termlink [_ concept link] (add-map conn concept termlinks-pr link))
(remove-truth [_ concept id] (remove-map conn concept truths-pr id))
(remove-desire [_ concept id] (remove-map conn concept desires-pr id))
(remove-tasklink [_ concept id] (remove-map conn concept tasklinks-pr id))
(remove-termlink [_ concept id] (remove-map conn concept termlinks-pr id))
(update-budget [_ update-fn])
(task [_ id] (get-task conn id))
(push-task [_ task] (push conn task))
(pop-task [_] (tpop conn))
(activate-concept [_ concept] (activate-concept* conn concept))
(pull-activated-concepts [_] (pull-concepts conn)))
-15
View File
@@ -1,15 +0,0 @@
(ns narjure.system
(:require [mount.core :refer [defstate]]
[narjure.memory.redis :as r]
[nal.deriver.rules :refer [compile-rules]]
[nal.rules :refer [all-rules]]
[nal.core :as c]))
(declare memory inference)
(def redis-config
{:spec {:host "127.0.0.1" :port 6379}})
(defstate memory :start (r/->RedisMemory redis-config))
(defstate inference :start #(let [rules (compile-rules all-rules)]
(partial c/inference rules)))
+72 -185
View File
@@ -1,28 +1,25 @@
(ns nal.test.core
(:require [clojure.test :refer :all]
[nal.core :as c]
[nal.rules :as r]
[nal.deriver.rules :refer [compile-rules]]))
(def inference (partial c/inference (compile-rules r/all-rules)))
[nal.core :refer :all]))
(deftest test-inference
(are [a1 a2] (= (set a1) (set (apply inference a2)))
'({:statement [==>
[&| [--> [ext-set tim] [int-set driving]]]
[--> [ext-set tim] [int-set dead]]]
:truth [1.0 0.81]
:task-type :judgement
'({:statement [==>
[&| [--> [ext-set tim] [int-set driving]]]
[--> [ext-set tim] [int-set dead]]]
:truth [1.0 0.81]
:task-type :judgement
:occurrence 1})
'[{:statement [--> [ext-set tim] [int-set drunk]]
:truth [1 0.9]
:task-type :judgement
'[{:statement [--> [ext-set tim] [int-set drunk]]
:truth [1 0.9]
:task-type :judgement
:occurrence 1}
{:statement [==> [&| [--> [ind-var X] [int-set drunk]] [--> [ind-var X] [int-set driving]]]
[--> [ind-var X] [int-set dead]]]
:truth [1 0.9]
{:statement [==> [&| [--> [ind-var X] [int-set drunk]] [--> [ind-var X] [int-set driving]]]
[--> [ind-var X] [int-set dead]]]
:truth [1 0.9]
:occurrence 0}]
'({:occurrence 1
@@ -50,38 +47,38 @@
:task-type :judgement
:truth [1
0.44751381215469616]})
'[{:statement [--> [* a1 a2 a3] m]
:truth [1 0.9]
:task-type :judgement
'[{:statement [--> [* a1 a2 a3] m]
:truth [1 0.9]
:task-type :judgement
:occurrence 1}
{:statement a1
:truth [1 0.9]
{:statement a1
:truth [1 0.9]
:occurrence 0}]
'[{:statement [=|> [--> [* a1 a2 a3] m] a1],
:task-type :judgement,
'[{:statement [=|> [--> [* a1 a2 a3] m] a1],
:task-type :judgement,
:occurrence 1,
:truth [1 0.44751381215469616]}
{:statement [<|> a1 [--> [* a1 a2 a3] m]],
:task-type :judgement,
:truth [1 0.44751381215469616]}
{:statement [<|> a1 [--> [* a1 a2 a3] m]],
:task-type :judgement,
:occurrence 1,
:truth [1.0 0.44751381215469616]}
{:statement [&| [--> [* a1 a2 a3] m] a1],
:task-type :judgement,
:truth [1.0 0.44751381215469616]}
{:statement [&| [--> [* a1 a2 a3] m] a1],
:task-type :judgement,
:occurrence 1,
:truth [1.0 0.81]}
{:statement [=|> a1 [--> [* a1 a2 a3] m]],
:task-type :judgement,
:truth [1.0 0.81]}
{:statement [=|> a1 [--> [* a1 a2 a3] m]],
:task-type :judgement,
:occurrence 1,
:truth [1 0.44751381215469616]}]
'[{:statement a1
:truth [1 0.9]
:task-type :judgement
:truth [1 0.44751381215469616]}]
'[{:statement a1
:truth [1 0.9]
:task-type :judgement
:occurrence 1}
{:statement [--> [* a1 a2 a3] m]
:truth [1 0.9]
{:statement [--> [* a1 a2 a3] m]
:truth [1 0.9]
:occurrence 0}]
'({:occurrence 1
@@ -106,166 +103,56 @@
:statement a1
:task-type :judgement
:truth [1 0.44751381215469616]})
'[{:statement [conj a1 a2 a3]
:truth [1 0.9]
:task-type :judgement
'[{:statement [conj a1 a2 a3]
:truth [1 0.9]
:task-type :judgement
:occurrence 1}
{:statement a1
:truth [1 0.9]
{:statement a1
:truth [1 0.9]
:occurrence 0}]
'[{:statement [=|> [--> M S] [[--> M S] [--> M P]]],
:task-type :judgement,
'[{:statement [=|> [--> M S] [[--> M S] [--> M P]]],
:task-type :judgement,
:occurrence 1,
:truth [1 0.44751381215469616]}
{:statement [<|> [--> M S] [[--> M S] [--> M P]]],
:task-type :judgement,
:truth [1 0.44751381215469616]}
{:statement [<|> [--> M S] [[--> M S] [--> M P]]],
:task-type :judgement,
:occurrence 1,
:truth [1.0 0.44751381215469616]}
{:statement [&| [--> M S] [[--> M S] [--> M P]]],
:task-type :judgement,
:truth [1.0 0.44751381215469616]}
{:statement [&| [--> M S] [[--> M S] [--> M P]]],
:task-type :judgement,
:occurrence 1,
:truth [1.0 0.81]}
{:statement [=|> [[--> M S] [--> M P]] [--> M S]],
:task-type :judgement,
:truth [1.0 0.81]}
{:statement [=|> [[--> M S] [--> M P]] [--> M S]],
:task-type :judgement,
:occurrence 1,
:truth [1 0.44751381215469616]}]
'[{:statement [[--> M S] [--> M P]]
:truth [1 0.9]
:task-type :judgement
:truth [1 0.44751381215469616]}]
'[{:statement [[--> M S] [--> M P]]
:truth [1 0.9]
:task-type :judgement
:occurrence 1}
{:statement [--> M S]
:truth [1 0.9]
{:statement [--> M S]
:truth [1 0.9]
:occurrence 0}]
'({:statement [conj [--> [dep-var Y] [int-set B]]
[==> [--> [ext-set A] [int-set Y]] [--> [dep-var Y] P]]]
:truth [1.0 0.81]
:task-type :judgement
'({:statement [conj [--> [dep-var Y] [int-set B]]
[==> [--> [ext-set A] [int-set Y]] [--> [dep-var Y] P]]]
:truth [1.0 0.81]
:task-type :judgement
:occurrence 1}
{:statement [==>
[conj [--> [ext-set A] [int-set Y]] [--> [ind-var X] [int-set B]]]
[--> [ind-var X] P]]
:truth [1 0.44751381215469616]
:task-type :judgement
{:statement [==>
[conj [--> [ext-set A] [int-set Y]] [--> [ind-var X] [int-set B]]]
[--> [ind-var X] P]]
:truth [1 0.44751381215469616]
:task-type :judgement
:occurrence 1})
'[{:statement [==> [--> [ext-set A] [int-set Y]] [--> [ext-set A] P]]
:truth [1 0.9]
:task-type :judgement
'[{:statement [==> [--> [ext-set A] [int-set Y]] [--> [ext-set A] P]]
:truth [1 0.9]
:task-type :judgement
:occurrence 1}
{:statement [--> [ext-set A] [int-set B]]
:truth [1 0.9]
:occurrence 1}]
'({:statement [</>
[seq-conj [--> chess competition] [:interval 1000]]
[--> sport competition]],
:task-type :judgement,
:occurrence 1000,
:truth [1.0 0.44751381215469616]}
{:statement [seq-conj
[--> chess competition]
[:interval 1000]
[--> sport competition]],
:task-type :judgement,
:occurrence 1000,
:truth [1.0 0.81]}
{:statement [pred-impl
[seq-conj [--> chess competition] [:interval 1000]]
[--> sport competition]],
:task-type :judgement,
:occurrence 1000,
:truth [1 0.44751381215469616]}
{:statement [retro-impl
[--> sport competition]
[seq-conj [--> chess competition] [:interval 1000]]],
:task-type :judgement,
:occurrence 1000,
:truth [1 0.44751381215469616]}
{:statement [--> sport chess],
:task-type :judgement,
:occurrence 1000,
:truth [1 0.44751381215469616]}
{:statement [--> chess sport],
:task-type :judgement,
:occurrence 1000,
:truth [1 0.44751381215469616]}
{:statement [<=> [--> chess [ind-var X]] [--> sport [ind-var X]]],
:task-type :judgement,
:occurrence 1000,
:truth [1.0 0.44751381215469616]}
{:statement [conj [--> chess [dep-var Y]] [--> sport [dep-var Y]]],
:task-type :judgement,
:occurrence 1000,
:truth [1.0 0.81]}
{:statement [<-> sport chess],
:task-type :judgement,
:occurrence 1000,
:truth [1.0 0.44751381215469616]}
{:statement [==> [--> chess [ind-var X]] [--> sport [ind-var X]]],
:task-type :judgement,
:occurrence 1000,
:truth [1 0.44751381215469616]}
{:statement [==> [--> chess [ind-var X]] [--> sport [ind-var X]]],
:task-type :judgement,
:occurrence 1000,
:truth [1 0.44751381215469616]}
{:statement [==> [--> sport [ind-var X]] [--> chess [ind-var X]]],
:task-type :judgement,
:occurrence 1000,
:truth [1 0.44751381215469616]}
{:statement [==> [--> sport [ind-var X]] [--> chess [ind-var X]]],
:task-type :judgement,
:occurrence 1000,
:truth [1 0.44751381215469616]}
{:statement [--> [int-dif chess sport] competition],
:task-type :judgement,
:occurrence 1000,
:truth [0.0 0.81]}
{:statement [--> [| chess sport] competition],
:task-type :judgement,
:occurrence 1000,
:truth [1.0 0.81]}
{:statement [--> [int-dif sport chess] competition],
:task-type :judgement,
:occurrence 1000,
:truth [0.0 0.81]}
{:statement [--> [ext-inter chess sport] competition],
:task-type :judgement,
:occurrence 1000,
:truth [1.0 0.81]}
{:statement [pred-impl
[seq-conj [--> chess [ind-var X]] [:interval 1000]]
[--> sport [ind-var X]]],
:task-type :judgement,
:occurrence 1000,
:truth [1 0.44751381215469616]}
{:statement [</>
[seq-conj [--> chess [ind-var X]] [:interval 1000]]
[--> sport [ind-var X]]],
:task-type :judgement,
:occurrence 1000,
:truth [1.0 0.44751381215469616]}
{:statement [retro-impl
[--> sport [ind-var X]]
[seq-conj [--> chess [ind-var X]] [:interval 1000]]],
:task-type :judgement,
:occurrence 1000,
:truth [1 0.44751381215469616]}
{:statement [seq-conj
[--> chess [dep-var Y]]
[:interval 1000]
[--> sport [dep-var Y]]],
:task-type :judgement,
:occurrence 1000,
:truth [1.0 0.81]})
['{:statement [--> sport competition]
:truth [1 0.9]
:task-type :judgement
:occurrence 1000}
'{:statement [--> chess competition]
:truth [1 0.9]
:occurrence 0}]))
{:statement [--> [ext-set A] [int-set B]]
:truth [1 0.9]
:occurrence 1}]))
+105 -10
View File
@@ -1,21 +1,116 @@
(ns nal.test.deriver
(:require [clojure.test :refer :all]
[nal.deriver :refer :all]
[nal.deriver.rules :refer [compile-rules]]
[nal.rules :as r]))
(def rules
(compile-rules '([(P --> M) (S --> M) |- (S <-> P)
:post (:t/comparison :d/weak :allow-backward)
:pre ((:!= S P))])))
(def result
'({:statement [</>
[seq-conj [--> chess competition] [:interval 1000]]
[--> sport competition]],
:task-type :judgement,
:occurrence 1000,
:truth [1.0 0.44751381215469616]}
{:statement [seq-conj
[--> chess competition]
[:interval 1000]
[--> sport competition]],
:task-type :judgement,
:occurrence 1000,
:truth [1.0 0.81]}
{:statement [pred-impl
[seq-conj [--> chess competition] [:interval 1000]]
[--> sport competition]],
:task-type :judgement,
:occurrence 1000,
:truth [1 0.44751381215469616]}
{:statement [retro-impl
[--> sport competition]
[seq-conj [--> chess competition] [:interval 1000]]],
:task-type :judgement,
:occurrence 1000,
:truth [1 0.44751381215469616]}
{:statement [--> sport chess],
:task-type :judgement,
:occurrence 1000,
:truth [1 0.44751381215469616]}
{:statement [--> chess sport],
:task-type :judgement,
:occurrence 1000,
:truth [1 0.44751381215469616]}
{:statement [<=> [--> chess [ind-var X]] [--> sport [ind-var X]]],
:task-type :judgement,
:occurrence 1000,
:truth [1.0 0.44751381215469616]}
{:statement [conj [--> chess [dep-var Y]] [--> sport [dep-var Y]]],
:task-type :judgement,
:occurrence 1000,
:truth [1.0 0.81]}
{:statement [<-> sport chess],
:task-type :judgement,
:occurrence 1000,
:truth [1.0 0.44751381215469616]}
{:statement [==> [--> chess [ind-var X]] [--> sport [ind-var X]]],
:task-type :judgement,
:occurrence 1000,
:truth [1 0.44751381215469616]}
{:statement [==> [--> chess [ind-var X]] [--> sport [ind-var X]]],
:task-type :judgement,
:occurrence 1000,
:truth [1 0.44751381215469616]}
{:statement [==> [--> sport [ind-var X]] [--> chess [ind-var X]]],
:task-type :judgement,
:occurrence 1000,
:truth [1 0.44751381215469616]}
{:statement [==> [--> sport [ind-var X]] [--> chess [ind-var X]]],
:task-type :judgement,
:occurrence 1000,
:truth [1 0.44751381215469616]}
{:statement [--> [int-dif chess sport] competition],
:task-type :judgement,
:occurrence 1000,
:truth [0.0 0.81]}
{:statement [--> [| chess sport] competition],
:task-type :judgement,
:occurrence 1000,
:truth [1.0 0.81]}
{:statement [--> [int-dif sport chess] competition],
:task-type :judgement,
:occurrence 1000,
:truth [0.0 0.81]}
{:statement [--> [ext-inter chess sport] competition],
:task-type :judgement,
:occurrence 1000,
:truth [1.0 0.81]}
{:statement [pred-impl
[seq-conj [--> chess [ind-var X]] [:interval 1000]]
[--> sport [ind-var X]]],
:task-type :judgement,
:occurrence 1000,
:truth [1 0.44751381215469616]}
{:statement [</>
[seq-conj [--> chess [ind-var X]] [:interval 1000]]
[--> sport [ind-var X]]],
:task-type :judgement,
:occurrence 1000,
:truth [1.0 0.44751381215469616]}
{:statement [retro-impl
[--> sport [ind-var X]]
[seq-conj [--> chess [ind-var X]] [:interval 1000]]],
:task-type :judgement,
:occurrence 1000,
:truth [1 0.44751381215469616]}
{:statement [seq-conj
[--> chess [dep-var Y]]
[:interval 1000]
[--> sport [dep-var Y]]],
:task-type :judgement,
:occurrence 1000,
:truth [1.0 0.81]}))
(deftest test-generate-conclusions
(is (= (set [{:occurrence 1000
:statement '[<-> sport chess]
:task-type :judgement
:truth [1.0 0.44751381215469616]}])
(is (= (set result)
(set (generate-conclusions
(rules :judgement)
(r/rules :judgement)
'{:statement [--> sport competition]
:truth [1 0.9]
:task-type :judgement
-64
View File
@@ -1,64 +0,0 @@
(ns nal.test.underiver
(:require nal.reader
[nal.deriver.rules :as r]
[nal.deriver.matching :as m]
[nal.deriver.utils :as u]
[clojure.core.unify :as un]
[clojure.core.match :as omg]
[clojure.set :as cs]
[nal.core :as c]))
(r/defrules rls
#R[(P ==> M) (S ==> M) |- (S ==> P) :post (:t/induction :allow-backward) :pre ((:!= S P))])
(def compiled (r/compile-rules rls))
(def r-map (first (r/rule (first rls))))
(defn sym-map [m p1 p2]
(let [vals (set (vals m))
all (cs/difference (set (remove u/operator? (flatten [p1 p2])))
vals)]
(->> all
(map (fn [el] [`(quote ~el) el]))
(into {})
(merge m))))
(defn underiver [{:keys [p1 p2 conclusions]}]
(let [concl (vec (:conclusion (first conclusions)))
[m pattern] (m/find-and-replace-symbols concl "x")
m (sym-map m p1 p2)
p1 (m/replace-symbols p1 m)
p2 (m/replace-symbols p2 m)]
(eval (m/quote-operators
`(fn [xn#] (omg/match xn#
~pattern [~p1 ~p2]
:else []))))))
(defn deriver [rls]
(let [compiled (r/compile-rules rls)]
(fn [[p1 p2]]
(let [t {:statement p1
:desire [1 0.9]
:task-type :judgement
:occurrence 1}
b {:statement p2
:truth [1 0.9]
:occurrence 0}]
(c/inference compiled t b)))))
(comment
((underiver r-map) '[==> wut ahh?])
=> [[==> ahh? M] [==> wut M]]
((deriver rls) '[[==> ahh? M] [==> wut M]])
(let [[{st :statement}] (c/inference compiled
{:statement '[==> ahh? M]
:truth [1 0.9]
:task-type :judgement
:occurrence 1}
{:statement '[==> wut M]
:truth [1 0.9]
:occurrence 0})]
((underiver r-map) st))
)
-41
View File
@@ -1,41 +0,0 @@
(ns narjure.test.control.buffer
(:require
[clojure.test :refer :all]
[narjure.control.buffer :refer :all]
[clojure.core.async.impl.protocols :refer [full? add! remove! close-buf!]]))
(defmacro throws? [expr]
`(try
~expr
false
(catch Throwable _# true)))
(def warn-cnt (atom 0))
(defn panick! [_]
(swap! warn-cnt inc))
(deftest sliding-buffer-tests
(let [fb (panicking-sliding-buffer 2 panick! 1)]
(reset! warn-cnt 0)
(is (= 0 (count fb)))
(add! fb :1)
(is (= 1 (count fb)))
(add! fb :2)
(is (= 2 (count fb)))
(is (= 1 @warn-cnt))
(is (not (full? fb)))
(is (not (throws? (add! fb :3))))
(is (= 2 (count fb)))
(is (= :2 (remove! fb)))
(is (not (full? fb)))
(is (= 1 (count fb)))
(is (= :3 (remove! fb)))
(is (= 0 (count fb)))
(is (throws? (remove! fb)))))
-65
View File
@@ -1,65 +0,0 @@
(ns narjure.test.control.flow
(:require
[clojure.test :refer :all]
[narjure.control.flow :refer :all]
[clojure.core.async :as as]))
(deftest test-check-element-in-map
(let [m {:a 1 :b 2}]
(is (= 0 (:c (check-element-in-map [:c] m))))
(is (= [] (:c (check-element-in-map [:c] [] m))))
(is (= nil (:k (check-element-in-map [:c] [] m))))))
(deftest test-all
(is (= #{:a :b :c :d :e}
(all [[:a :b]
[:a :c]
[:c :d]
[:c :e]]))))
(defn some-var [])
(deftest test-kw->var
(is (var? (kw->fn :narjure.control.flow/all)))
(is (var? (kw->fn ::some-var)))
(is (nil? (kw->fn ::wrong-var))))
(def wf [[:a :b]
[:a :c]
[:a :d]
[:b :d]])
(deftest test-fn-outputs
(let [outputs (fn-outputs wf 1)]
(is (= 4 (count (keys outputs))))
(is (every? nil? (map outputs [:c :d])))))
(deftest test-fn-inputs
(is (= {[:d :c :b] [:a]
[:d] [:b]}
(fn-inputs wf)))
(is (= {[:d :c :b] [:a]
[:k :d] [:c :b]}
(fn-inputs (concat wf [[:c :d]
[:c :k]
[:b :k]])))))
(def out (as/chan 2))
(defn first-fn [data] (assoc data :fn1 :ok))
(defn second-fn [data] (assoc data :fn2 :ok))
(defn third-fn [data]
(as/>!! out (assoc data :fn3 :ok)))
(def test-flow [[::first-fn ::second-fn]
[::second-fn ::third-fn]
[::first-fn ::third-fn]])
(deftest test-generate-flow
(let [in (generate-flow test-flow {:buffer 2})]
(as/>!! in {})
(let [res [(as/<!! out) (as/<!! out)]]
(is (= #{{:fn1 :ok
:fn3 :ok}
{:fn1 :ok
:fn2 :ok
:fn3 :ok}}
(set res))))))
-50
View File
@@ -1,50 +0,0 @@
(ns narjure.test.memory.redis
(:require [clojure.test :refer :all]
[narjure.memory.redis :as r]
[narjure.memory.api :as m]
[taoensso.carmine :as c]))
(def config
{:pool {}
:spec {:host "127.0.0.1" :port 6379}})
(def mem (r/->RedisMemory config))
(def concept1 '[--> tim cat])
(def concept2 'tim)
(def truth1 {:frequency (float 0.9)
:confidence (float 0.2)
:occurrence 1})
(def truth2 {:frequency (float 0.5)
:confidence (float 0.8)
:occurrence 2})
(defn termlink [c]
{:priority (float 0.1)
:durability (float 0.1)
:quality (float 0.1)
:concept (str (hash c))})
(deftest test-redis
(c/wcar config (c/flushall))
(m/add-term mem concept1)
(is (= concept1 (m/term mem (hash concept1))))
(m/add-truth mem concept1 truth1)
(m/add-truth mem concept1 truth2)
(is (= (set [truth1 truth2])
(set (map #(dissoc % :id) (m/truths mem concept1)))))
(m/remove-truth mem concept1 (:id (last (m/truths mem concept1))))
(is (:id (first (m/truths mem concept1))))
(is ((set [truth1 truth2]) (dissoc (first (m/truths mem concept1)) :id)))
(m/add-term mem concept2)
(m/add-termlink mem concept1 (termlink concept2))
(is (= [(termlink concept2)]
(map #(dissoc % :id) (m/termlinks mem concept1))))
(is (= concept2 (m/term mem (:concept (first (m/termlinks mem concept1)))))))