diff --git a/.gitignore b/.gitignore index 1501004..1b10558 100644 --- a/.gitignore +++ b/.gitignore @@ -13,4 +13,5 @@ pom.xml.asc *.iml *~ \#*\# -.\#* \ No newline at end of file +.\#* +*experiments.clj diff --git a/project.clj b/project.clj index fab8965..8a60a99 100644 --- a/project.clj +++ b/project.clj @@ -11,7 +11,8 @@ [org.clojure/data.priority-map "0.0.7"] [co.paralleluniverse/pulsar "0.7.4"] [org.immutant/immutant "2.1.2"] - [clj-time "0.11.0"]] + [clj-time "0.11.0"] + [com.taoensso/timbre "4.3.1"]] :java-agents [[co.paralleluniverse/quasar-core "0.7.4"]] :main ^:skip-aot narjure.core :plugins [[lein-cloverage "1.0.6"] diff --git a/src/narjure/actor/active_concept_collator_actor.clj b/src/narjure/actor/active_concept_collator_actor.clj deleted file mode 100644 index 7f52607..0000000 --- a/src/narjure/actor/active_concept_collator_actor.clj +++ /dev/null @@ -1,31 +0,0 @@ -(ns narjure.actor.active-concept-collator-actor - (:require - [co.paralleluniverse.pulsar - [core :refer :all] - [actors :refer :all] - ]) - (:refer-clojure :exclude [promise await]) - ) - -(declare process-inference-tick) -(declare process-active-concept) -(declare active-concept-collator-actor) - -(defsfn active-concept-collator-actor - "state is collection of active concepts" - [] - (register! :active-concept-collator @self) - (set-state! []) - (loop [] - (receive [msg] - :inference-tick-msg (set-state! (process-inference-tick @state)) - [:active-concept-msg active-concept] (process-active-concept active-concept @state) - :else (! :logger [:log-msg :log-debug :active-concept-collator "unhandled msg"])) - (recur))) - -(defn process-inference-tick [state] - ;(! :logger [:log-msg :log-debug :active-concept-collator "process-inference-tick"]) - []) - -(defn process-active-concept [_ _] - (! :logger [:log-msg :log-debug :active-concept-collator "process-active-concept"])) \ No newline at end of file diff --git a/src/narjure/actor/anticipated_event_actor.clj b/src/narjure/actor/anticipated_event_actor.clj deleted file mode 100644 index 4e78078..0000000 --- a/src/narjure/actor/anticipated_event_actor.clj +++ /dev/null @@ -1,38 +0,0 @@ -(ns narjure.actor.anticipated-event-actor - (:require - [co.paralleluniverse.pulsar - [core :refer :all] - [actors :refer :all] - ]) - (:refer-clojure :exclude [promise await]) - ) - -(declare process-system-time) -(declare process-input-task) -(declare process-anticipated-event) -(declare anticipated-event-actor) - -(defsfn anticipated-event-actor - "state is system-time and collection of anticipated events" - [] - (register! :anticipated-event @self) - (set-state! {:time 0 :anticipated-events {}}) - (loop [] - (receive [msg] - [:system-time-msg time] (set-state! (process-system-time time @state)) - [:input-task-msg input-task] (set-state! (process-input-task input-task @state)) - [:anticipated-event-msg anticipated-event] (set-state! (process-anticipated-event anticipated-event @state)) - :else (! :logger [:log-msg :log-debug :anticipated-event (str "unhandled msg:" msg)])) - (recur))) - -(defn process-system-time [time state] - (! :logger [:log-msg :log-debug :anticipated-event "process-system-time"]) - {:time time :anticipated-events (state :percepts)}) - -(defn process-anticipated-event [_ _] - ;(! :logger [:log-msg :log-debug :anticipated-event "process-anticipated-event"]) - ) - -(defn process-input-task [input-task _] - ;(! :logger [:log-msg :log-debug :anticipated-event "process-input-task"]) - (! :task-dispatcher [:task-msg input-task])) diff --git a/src/narjure/actor/concept.clj b/src/narjure/actor/concept.clj deleted file mode 100644 index 96e4491..0000000 --- a/src/narjure/actor/concept.clj +++ /dev/null @@ -1,41 +0,0 @@ -(ns narjure.actor.concept - (:require - [co.paralleluniverse.pulsar - [core :refer :all] - [actors :refer :all] - ]) - (:refer-clojure :exclude [promise await]) - ) - -(declare process-task) -(declare process-belief-req) -(declare process-inference-req) -(declare process-persistence-req) -(declare concept-actor) - -(defsfn concept-actor - "state is a map {:name :budget :activation-level :belief-tab :goal-tab :task-bag :term-bag} - (this list may not be complete)" - [] - (set-state! {}) - (loop [] - (receive [msg] - [:task-msg task] (set-state! (process-task task @state)) - [:belief-request-msg belief-req] (set-state! (process-belief-req belief-req @state)) - [:inference-request-msg inference-req] (set-state! (process-inference-req inference-req @state)) - [:persistence-request-msg presistence-req] (set-state! (process-persistence-req presistence-req @state)) - :else (! :logger [:log-msg :log-debug :concept (str "unhandled msg:" msg)])) - (recur))) - -(defn process-task [_ _] - ;(! :logger [:log-msg :log-debug :concept "process-task"]) - ) - -(defn process-belief-req [_ _] - (! :logger [:log-msg :log-debug :concept "process-belief-req"])) - -(defn process-inference-req [_ _] - (! :logger [:log-msg :log-debug :concept "process-inference-req"])) - -(defn process-persistence-req [_ _] - (! :logger [:log-msg :log-debug :concept "process-persistence-req"])) diff --git a/src/narjure/actor/concept_creator_actor.clj b/src/narjure/actor/concept_creator_actor.clj deleted file mode 100644 index e86e157..0000000 --- a/src/narjure/actor/concept_creator_actor.clj +++ /dev/null @@ -1,50 +0,0 @@ -(ns narjure.actor.concept-creator-actor - (:require - [co.paralleluniverse.pulsar - [core :refer :all] - [actors :refer :all] - ] - [narjure.actor.concept :refer [concept-actor]] - ) - (:refer-clojure :exclude [promise await]) - ) - -(declare create-concept) -(declare process-task) -(declare concept-creator-actor) - -(defsfn concept-creator-actor - "" - [] - - (register! :concept-creator @self) - (loop [] - (receive [msg] - [:create-concept-msg from task c-map] (process-task from task c-map) - :else (! :logger [:log-msg :log-debug :concept-creator (str "unhandled msg:" msg)])) - (recur))) - -(defn create-concept - "TODO: update state for concept-actor to state initialiser - TODO: Create required sub-term concepts and propogate budget - " - [task c-map] - (let [{term :term} task] - (swap! c-map assoc term (spawn concept-actor)) - ;(! :logger [:log-msg :log-debug :concept-creator (str "Created concept: " term)]) - ) - ) - -(defn process-task - "When concept-map does not contain :term, create concept actor for term - then post task to task-dispatcher either way - " - [from task c-map] - (let [term (task :term)] - ; when concept not exist then create - goes here - (when (not (contains? @c-map term)) - (create-concept task c-map))) - - (! from [:task-msg task]) - ;(! :logger [:log-msg :log-debug :concept-creator "concept-creator - process-task"]) - ) diff --git a/src/narjure/actor/cross_modal_integrator_actor.clj b/src/narjure/actor/cross_modal_integrator_actor.clj deleted file mode 100644 index 93a2662..0000000 --- a/src/narjure/actor/cross_modal_integrator_actor.clj +++ /dev/null @@ -1,33 +0,0 @@ -(ns narjure.actor.cross-modal-integrator-actor - (:require - [co.paralleluniverse.pulsar - [core :refer :all] - [actors :refer :all] - ] - [narjure.defaults :refer [serial-no]]) - (:refer-clojure :exclude [promise await]) - ) - -(declare process-system-time) -(declare process-percept-sentence) -(declare cross-modal-integrator-actor) - -(defsfn cross-modal-integrator-actor - "state is system-time and collection of precepts from current duration window" - [] - (register! :cross-modal-integrator @self) - (set-state! {:time 0 :percepts []}) - (loop [] - (receive [msg] - [:system-time-msg time] (set-state! (process-system-time time @state)) - [:percept-sentence-msg percept-sentence] (set-state! (process-percept-sentence percept-sentence @state)) - :else (! :logger [:log-msg :log-debug :cross-modal-integrator (str "unhandled msg:" msg)])) - (recur))) - -(defn process-system-time [time state] - (! :logger [:log-msg :log-debug :cross-modal-integrator "process-system-time"]) - {:time time :percepts (state :percepts)}) - -(defn process-percept-sentence [_ _] - (! :logger [:log-msg :log-debug :cross-modal-integrator "process-percept-sentence"])) - diff --git a/src/narjure/actor/derived_task_creator_actor.clj b/src/narjure/actor/derived_task_creator_actor.clj deleted file mode 100644 index cba83be..0000000 --- a/src/narjure/actor/derived_task_creator_actor.clj +++ /dev/null @@ -1,32 +0,0 @@ -(ns narjure.actor.derived-task-creator-actor - (:require - [co.paralleluniverse.pulsar - [core :refer :all] - [actors :refer :all] - ]) - (:refer-clojure :exclude [promise await]) - ) - -(declare process-system-time) -(declare process-inference-result) -(declare derived-task-creator-actor) - -(defsfn derived-task-creator-actor - "state is system-time" - [] - (register! :derived-task-creator @self) - (set-state! {:time 0}) - (loop [] - (receive [msg] - [:system-time-msg time] (set-state! (process-system-time time @state)) - [:inference-result-msg inference-result] (process-inference-result inference-result @state) - :else (! :logger [:log-msg :log-debug :derived-task-creator (str "unhandled msg:" msg)])) - (recur))) - -(defn process-system-time [time state] - (! :logger [:log-msg :log-debug :derived-task-creator "process-system-time"]) - {:time time}) - -(defn process-inference-result [_ _] - (! :logger [:log-msg :log-debug :derived-task-creator "process-inference-result"])) - diff --git a/src/narjure/actor/forgettable_concept_collator_actor.clj b/src/narjure/actor/forgettable_concept_collator_actor.clj deleted file mode 100644 index 6b3bbaa..0000000 --- a/src/narjure/actor/forgettable_concept_collator_actor.clj +++ /dev/null @@ -1,31 +0,0 @@ -(ns narjure.actor.forgettable-concept-collator-actor - (:require - [co.paralleluniverse.pulsar - [core :refer :all] - [actors :refer :all] - ]) - (:refer-clojure :exclude [promise await]) - ) - -(declare process-forgetting-tick) -(declare process-forgettable-concept) -(declare forgettable-concept-collator-actor) - -(defsfn forgettable-concept-collator-actor - "state is collection of forgettable concepts" - [] - (register! :forgettable-concept-collator @self) - (set-state! []) - (loop [] - (receive [msg] - :forgetting-tick-msg (set-state! (process-forgetting-tick @state)) - [:forgettable-concept-msg forgettable-concept] (process-forgettable-concept forgettable-concept @state) - :else (! :logger [:log-msg :log-debug :forgettable-concept-collator (str "unhandled msg:" msg)])) - (recur))) - -(defn process-forgetting-tick [_] - ;(! :logger [:log-msg :log-debug :forgettable-concept-collator "process-forgetting-tick"]) - ) - -(defn process-forgettable-concept [_ _] - (! :logger [:log-msg :log-debug :forgettable-concept-collator "process-forgettable-concept"])) diff --git a/src/narjure/actor/general_inferencer_actor.clj b/src/narjure/actor/general_inferencer_actor.clj deleted file mode 100644 index 8d33981..0000000 --- a/src/narjure/actor/general_inferencer_actor.clj +++ /dev/null @@ -1,25 +0,0 @@ -(ns narjure.actor.general-inferencer-actor - (:require - [co.paralleluniverse.pulsar - [core :refer :all] - [actors :refer :all] - ]) - (:refer-clojure :exclude [promise await]) - ) - -(declare process-do-inference) -(declare general-inferencer-actor) - -(defsfn general-inferencer-actor - "state is inference rule trie or equivalent" - [] - (register! :general-inferencer @self) - (set-state! {:trie 0}) - (loop [] - (receive [msg] - [:do-inference-msg inference-package] (set-state! (process-do-inference inference-package @state)) - :else (! :logger [:log-msg :log-debug :general-inferencer (str "unhandled msg:" msg)])) - (recur))) - -(defn process-do-inference [_ _] - (! :logger [:log-msg :log-debug :general-inferencer "process-do-inference"])) diff --git a/src/narjure/actor/logger.clj b/src/narjure/actor/logger.clj deleted file mode 100644 index 7fdc4d9..0000000 --- a/src/narjure/actor/logger.clj +++ /dev/null @@ -1,73 +0,0 @@ -(ns narjure.actor.logger - (:require - [co.paralleluniverse.pulsar - [core :refer :all] - [actors :refer :all] - ] - [clj-time.local :as l]) - (:refer-clojure :exclude [promise await]) - ) - -(declare log-level-string) -(declare print-log-msg) -(declare process-log-msg) -(declare logger) - -(defsfn logger - "Actor that provides a message log to stdio service. - Ensures multiple thread println do not clash - - useage: (! :logger [msg-type args]) - - where msg-type can be: - - :log-level - sets the logger logging level - arg - :log-debug | :log-error | :log-warning | :log-info - - :log-msg - prints a log message to stdio specifying the requesting actor - args - log-level - :log-debug | :log-error | :log-warning | :log-info - from - key representing the actor that sent the :log-msg, can be :anon - msg-string - string message to output - - Examples :- - (! :logger [:log-level :log-info]) - (! :logger [:log-msg :log-debug :task-dispatcher \"processing task\"]) - (! :logger [:log-msg :log-debug :anon \"processing task\"]) - " - [in-log-level] - - ; register logger actor as :logger - (register! :logger @self) - ; set state to input arg - (set-state! in-log-level) - (loop [] - (receive [msg] - [:log-level level] (set-state! level) - [:log-msg log-level from msg-string] (process-log-msg log-level from msg-string) - :else (print-log-msg :log-info :logger (str "unhandled msg" msg))) - (recur))) - -(def log-level-string {:log-debug "[DEBUG]" :log-error "[ERROR]" :log-warning "[WARNING]" :log-info "[INFO]" }) - -(defn print-log-msg - "Print local time, log-level, requesting actor and log-msg to standard out - " - [log-level from msg-string] - (if (= from :anon) - (println (str (l/local-now)) (log-level-string log-level) msg-string) - (println (str (l/local-now)) (log-level-string log-level) (str from) msg-string)) - ) - -(defn process-log-msg - "If msg log-level is in log level set (state) then output log-msg. - state is the curently set global log-level and can be: - :log-debug :log-warning :log-error :log-info - " - [log-level from msg-string] - (case @state - :log-debug (when (#{:log-debug :log-warning :log-error :log-info} log-level) (print-log-msg log-level from msg-string)) - :log-error (when (#{:log-warning :log-error :log-info} log-level) (print-log-msg log-level from msg-string)) - :log-warning (when (#{:log-warning :log-info} log-level) (print-log-msg log-level from msg-string)) - :log-info (when (#{:log-info} log-level) (print-log-msg log-level from msg-string)))) diff --git a/src/narjure/actor/operator_executor_actor.clj b/src/narjure/actor/operator_executor_actor.clj deleted file mode 100644 index 9be7d1a..0000000 --- a/src/narjure/actor/operator_executor_actor.clj +++ /dev/null @@ -1,35 +0,0 @@ -(ns narjure.actor.operator-executor-actor - (:require - [co.paralleluniverse.pulsar - [core :refer :all] - [actors :refer :all] - ] - [narjure.defaults :refer [serial-no]]) - (:refer-clojure :exclude [promise await]) - ) - -(declare process-system-time) -(declare process-operator-execution-req) -(declare operator-executor-actor) - -(defsfn operator-executor-actor - "state is system-time" - [] - (register! :operator-executor @self) - (set-state! {:time 0}) - (loop [] - (receive [msg] - [:system-time-msg time] (set-state! (process-system-time time @state)) - [:operator-execution-req-msg operator-execution-req] (process-operator-execution-req operator-execution-req @state) - :else (! :logger [:log-msg :log-debug :operator-executor (str "unhandled msg:" msg)])) - (recur))) - -(defn process-system-time [time state] - (! :logger [:log-msg :log-debug :operator-executor "process-system-time"]) - {:time time}) - -(defn process-operator-execution-req [_ _] - (! :logger [:log-msg :log-debug :operator-executor "process-operator-execution-req"])) - - - diff --git a/src/narjure/actor/persistence_manager_actor.clj b/src/narjure/actor/persistence_manager_actor.clj deleted file mode 100644 index 689df31..0000000 --- a/src/narjure/actor/persistence_manager_actor.clj +++ /dev/null @@ -1,25 +0,0 @@ -(ns narjure.actor.persistence-manager-actor - (:require - [co.paralleluniverse.pulsar - [core :refer :all] - [actors :refer :all] - ]) - (:refer-clojure :exclude [promise await]) - ) - -(declare process-concept-state) -(declare persistence-manager-actor) - -(defsfn persistence-manager-actor - "state is file system handles" - [in-state] - (register! :persistence-manager @self) - (set-state! in-state) - (loop [] - (receive [msg] - [:concept-state-msg concept-state] (set-state! (process-concept-state concept-state @state)) - :else (! :logger [:log-msg :log-debug :persistence-manager (str "unhandled msg:" msg)])) - (recur))) - -(defn process-concept-state [_ _] - (! :logger [:log-msg :log-debug :persistence-manager "process-concept-state"])) diff --git a/src/narjure/actor/sentence_parser_actor.clj b/src/narjure/actor/sentence_parser_actor.clj deleted file mode 100644 index 31fd89f..0000000 --- a/src/narjure/actor/sentence_parser_actor.clj +++ /dev/null @@ -1,45 +0,0 @@ -(ns narjure.actor.sentence-parser-actor - (:require - [co.paralleluniverse.pulsar - [core :refer :all] - [actors :refer :all] - ] - [narjure.narsese :refer [parse]] - [narjure.defaults :refer [serial-no]]) - (:refer-clojure :exclude [promise await]) - ) - -(declare process-system-time) -(declare process-narsese-string) -(declare sentence-parser-actor) - -(defsfn sentence-parser-actor - "Example format for using actor with set-state! on recursion. - Usage: (def actor (spawn actor [state])) - This example uses a map for state {:id 0} and increments value on recursion - state is system-time" - [] - (register! :sentence-parser @self) - (set-state! {:time 0}) - (loop [] - (receive [msg] - [:system-time-msg time] (set-state! (process-system-time time @state)) - [:narsese-string-msg string] (set-state! (process-narsese-string string @state)) - :else (! :logger [:log-msg :log-debug :sentence-parser (str "unhandled msg:" msg)])) - (recur))) - -(defn process-system-time [time state] - (! :logger [:log-msg :log-debug :sentence-parser "process-system-time"]) - {:time time}) - -(defn create-stamp-for-input-task [system-time serial-no] - {:id serial-no :creation-time system-time :occurence-time system-time :trail [serial-no]}) - -(defn process-narsese-string - "Parses a narsese string and converts tense to occurence time - and adds a stamp {id: id :creation-time system-time :occurence-time occurence-time :trail []} - " - [string state] - (let [task (assoc (parse string) :stamp (create-stamp-for-input-task (:time state) (swap! serial-no inc)))] - (! :anticipated-event [:input-task-msg task]) - (! :logger [:log-msg :log-info :sentence-parser (str "process-narsese-string" task)]))) diff --git a/src/narjure/actor/system_time_actor.clj b/src/narjure/actor/system_time_actor.clj deleted file mode 100644 index bae65a0..0000000 --- a/src/narjure/actor/system_time_actor.clj +++ /dev/null @@ -1,26 +0,0 @@ -(ns narjure.actor.system-time-actor - (:require - [co.paralleluniverse.pulsar - [core :refer :all] - [actors :refer :all] - ]) - (:refer-clojure :exclude [promise await]) - ) - -(declare process-system-time-tick) -(declare system-time-actor) - -(defsfn system-time-actor - "state is system-time" - [] - (register! :system-time @self) - (set-state! 0) - (loop [] - (receive [msg] - :system-time-tick-msg (set-state! (process-system-time-tick @state)) - :else (! :logger [:log-msg :log-debug :system-time (str "unhandled msg:" msg)])) - (recur))) - -(defn process-system-time-tick [state] - ;(! :logger [:log-msg :log-debug :system-time (str "process-system-time-tick " state)]) - (inc state)) diff --git a/src/narjure/actor/task_dispatcher_actor.clj b/src/narjure/actor/task_dispatcher_actor.clj deleted file mode 100644 index df0277d..0000000 --- a/src/narjure/actor/task_dispatcher_actor.clj +++ /dev/null @@ -1,54 +0,0 @@ -(ns narjure.actor.task-dispatcher-actor - (:require - [co.paralleluniverse.pulsar - [core :refer :all] - [actors :refer :all] - ]) - (:refer-clojure :exclude [promise await]) - ) - -(declare c-map) -(declare process-task) -(declare process-forget-concept) -(declare process-concept-count) -(declare task-dispatcher-actor) - -(defsfn task-dispatcher-actor - "concept-map is atom {:term :actor-ref} shared between - task-dispatcher and concept-creator - " - [] - - (register! :task-dispatcher @self) - (def concept-creator (whereis :concept-creator)) - (loop [] - (receive [msg] - [:task-msg input-task] (process-task input-task c-map concept-creator) - [:forget-concept-msg forget-concept] (process-forget-concept forget-concept) - :concept-count (process-concept-count c-map) - :else (! :logger [:log-msg :log-debug :task-dispatcher (str "unhandled msg:" msg)])) - (recur))) - -(def c-map (atom {})) - -(defn process-task - - "Takes inut task and checks to see if concept exists, - if not sends task to concept-creator else posts task to - relevant concept actor - " - [input-task c-map concept-creator] - (let [term (input-task :term)] - (if (contains? @c-map term) - (! (@c-map term) :task-msg input-task) - (! concept-creator [:create-concept-msg @self input-task c-map]))) - ;(! :logger [:log-msg :log-debug :task-dispatcher (str "process-task" input-task)]) - ) - -(defn process-forget-concept [forget-concept] - (! :logger [:log-msg :log-debug :task-dispatcher "process-forget-concept"])) - -(defn process-concept-count [c-map] - ;(println (str (keys @c-map))) - (! :logger [:log-msg :log-info :task-dispatcher (str "Concept count[" (count @c-map) "]")]) - ) diff --git a/src/narjure/actor/utils.clj b/src/narjure/actor/utils.clj new file mode 100644 index 0000000..952427e --- /dev/null +++ b/src/narjure/actor/utils.clj @@ -0,0 +1,38 @@ +(ns narjure.actor.utils + (:require + [co.paralleluniverse.pulsar + [core :refer [defsfn]] + [actors :refer [set-state! state receive ! self register!]]] + [taoensso.timbre :refer [debug]])) + +(defn create-actor + ([name handlers] + (create-actor name "" {} handlers)) + ([name doc handlers] + (create-actor name doc {} handlers)) + ([name doc default-state handlers] + (let [aname (keyword name) + has-args (and (vector? default-state) + (symbol? (first default-state)))] + `(defsfn ~name ~doc ~(if has-args default-state []) + ~@(when (not= 'concept name) [`(register! ~aname @self)]) + (set-state! ~(if has-args + (first default-state) + default-state)) + (loop [] + (let [msg# (receive) + handler# (get ~handlers (first msg#) :unhandled)] + (if (= :unhandled handler#) + (debug ~name (str "unhandled msg:" msg#)) + (set-state! (handler# msg# @state))) + (recur))))))) + +(defn side-effect! + "Wraps handler which generates side effect. Returns state without changes." + [handler] + (fn [message state] + (handler message state) + state)) + +(defmacro defactor [& args] + (apply create-actor args)) diff --git a/src/narjure/core.clj b/src/narjure/core.clj index d39e6a1..0c79325 100644 --- a/src/narjure/core.clj +++ b/src/narjure/core.clj @@ -2,146 +2,151 @@ (:require [co.paralleluniverse.pulsar [core :refer :all] - [actors :refer :all] - ] + [actors :refer :all]] [immutant.scheduling :refer :all] - [narjure.actor.active-concept-collator-actor :refer [active-concept-collator-actor]] - [narjure.actor.anticipated-event-actor :refer [anticipated-event-actor]] - [narjure.actor.concept-creator-actor :refer [concept-creator-actor]] - [narjure.actor.cross-modal-integrator-actor :refer [cross-modal-integrator-actor]] - [narjure.actor.derived-task-creator-actor :refer [derived-task-creator-actor]] - [narjure.actor.forgettable-concept-collator-actor :refer [forgettable-concept-collator-actor]] - [narjure.actor.general-inferencer-actor :refer [general-inferencer-actor]] - [narjure.actor.operator-executor-actor :refer [operator-executor-actor]] - [narjure.actor.persistence-manager-actor :refer [persistence-manager-actor]] - [narjure.actor.sentence-parser-actor :refer [sentence-parser-actor]] - [narjure.actor.system-time-actor :refer [system-time-actor]] - [narjure.actor.task-dispatcher-actor :refer [task-dispatcher-actor]] - [narjure.actor.logger :refer [logger]]) + [narjure.memory-management + [concept-creator :refer [concept-creator]] + [forgettable-concept-collator :refer [forgettable-concept-collator]] + [persistence-manager :refer [persistence-manager]] + [task-dispatcher :refer [task-dispatcher]]] + [narjure.general-inference + [active-concept-collator :refer [active-concept-collator]] + [derived-task-creator :refer [derived-task-creator]] + [general-inferencer :refer [general-inferencer]]] + [narjure.perception-action + [anticipated-event :refer [anticipated-event]] + [cross-modal-integrator :refer [cross-modal-integrator]] + [operator-executor :refer [operator-executor]] + [sentence-parser :refer [sentence-parser]] + [system-time :refer [system-time]]] + [taoensso.timbre :refer [info set-level!]]) (:refer-clojure :exclude [promise await]) + (:import (ch.qos.logback.classic Level) + (org.slf4j LoggerFactory)) (:gen-class)) + +;co.paralleluniverse.actors.JMXActorMonitor +(def actors-names + #{:active-concept-collator + :anticipated-event + :concept-creator + :cross-modal-integrator + :derived-task-creator + :forgettable-concept-collator + :general-inferencer + :operator-executor + :persistence-manager + :sentence-parser + :system-time + :task-dispatcher}) + (defn create-system-actors - "spawns all actors which self register! - " - [] - (spawn active-concept-collator-actor) - (spawn anticipated-event-actor) - (spawn concept-creator-actor) - (spawn cross-modal-integrator-actor) - (spawn derived-task-creator-actor) - (spawn forgettable-concept-collator-actor) - (spawn general-inferencer-actor) - (spawn operator-executor-actor) - (spawn persistence-manager-actor :state) - (spawn sentence-parser-actor) - (spawn system-time-actor) - (spawn task-dispatcher-actor) - (spawn logger :log-info) - ) - -(defn check-actors-registered - " - " + "Spawns all actors which self register!" [] + (spawn active-concept-collator) + (spawn anticipated-event) + (spawn concept-creator) + (spawn cross-modal-integrator) + (spawn derived-task-creator) + (spawn forgettable-concept-collator) + (spawn general-inferencer) + (spawn operator-executor) + (spawn persistence-manager :state) + (spawn sentence-parser) + (spawn system-time) + (spawn task-dispatcher)) + +(defn check-actor [actor-name] + (info (if (whereis actor-name) "\t[OK]" "\t[FAILED]") (str actor-name))) + +(defn check-actors-registered [] + (info "Checking all services are registered...") + (doseq [actor-name actors-names] + (check-actor actor-name)) + (info "All services registered.")) + +(def inference-tick-interval 2500) +(def forgetting-tick-interval 3000) +(def system-tick-interval 2000) + +(defn inference-tick [] + (! :active-concept-collator [:inference-tick-msg])) + +(defn forgetting-tick [] + (! :forgettable-concept-collator [:forgetting-tick-msg])) + +(defn system-tick [] + (! :system-time [:system-time-tick-msg])) + +(defn prn-ok [msg] (info (format "\t[OK] %s" msg))) + +(defn start-timers [] + (info "Initialising system timers...") + (schedule inference-tick {:in inference-tick-interval + :every inference-tick-interval}) + (prn-ok :system-timer) + + (schedule forgetting-tick {:in forgetting-tick-interval + :every forgetting-tick-interval}) + (prn-ok :forgetting-timer) + + (schedule system-tick {:every system-tick-interval}) + (prn-ok :inference-timer) + + (info "System timer initialisation complete.")) + +(defn disable-third-party-loggers [] + (doseq [logger ["co.paralleluniverse.actors.JMXActorMonitor" + "org.quartz.core.QuartzScheduler" + "co.paralleluniverse.actors.LocalActorRegistry" + "co.paralleluniverse.actors.ActorRegistry" + "org.projectodd.wunderboss.scheduling.Scheduling"]] + (.setLevel (LoggerFactory/getLogger logger) Level/OFF))) + +(defn setup-logging [] + (set-level! :debug) + (disable-third-party-loggers)) + +(defn start-nars [& _] + (setup-logging) + (info "NARS initialising...") - (defn check-actor [actor-name] - (if (whereis actor-name) - (println "\t[OK]" (str actor-name)) - (println "\t[FAILED]" (str actor-name))) - ) - - (println "\nChecking all services are registered...") - (check-actor :logger) - (check-actor :active-concept-collator) - (check-actor :anticipated-event) - (check-actor :concept-creator) - (check-actor :cross-modal-integrator) - (check-actor :derived-task-creator) - (check-actor :forgettable-concept-collator) - (check-actor :general-inferencer) - (check-actor :operator-executor) - (check-actor :persistence-manager) - (check-actor :sentence-parser) - (check-actor :system-time) - (check-actor :task-dispatcher)) - (println "\nAll services registered.") - -(defn start-timers - " - " - [] - (println "\nInitialising system timers...") - (def inference-tick-interval 2500) - (defn inference-tick [] (! :active-concept-collator :inference-tick-msg)) - (schedule inference-tick (-> {:in inference-tick-interval :every inference-tick-interval})) - (println "\t[OK] ":system-timer "") - - (def forgetting-tick-interval 3000) - (defn forgetting-tick [] (! :forgettable-concept-collator :forgetting-tick-msg)) - (schedule forgetting-tick (-> {:in forgetting-tick-interval :every forgetting-tick-interval})) - (println "\t[OK] ":forgetting-timer "") - - (def system-tick-interval 2000) - (defn system-tick [] (! :system-time :system-time-tick-msg)) - (schedule system-tick (-> {:every system-tick-interval})) - (println "\t[OK] ":inference-timer "") - - (println "\nSystem timer initialisation complete.") - ) - -(defn start-nars - " - " - [& args] - - (println "NARS initialising...") ; spawn all actors except concepts (create-system-actors) - (Thread/sleep 1000) ; allow delay for all actors to be initialised + ; allow delay for all actors to be initialised + (sleep 1 :sec) (check-actors-registered) (start-timers) ; update user with status - (! :logger [:log-msg :log-info :anon "NARS initialised."]) - + (info "NARS initialised.") ; *** Test code - (def task-dispatcher (whereis :task-dispatcher)) - (! :logger [:log-msg :log-info :anon "Beginning test..."]) - (time - (loop [n 0] - (when (< n 1000000) - (let [n1 (if (< (rand) 0.01) n (rand-int (/ n 10)))] ; select approximately 90% from existing concepts - (! task-dispatcher [:task-msg {:term (format "a --> %d" n1) :other "other"}]) - (when (== (mod n 100000) 0) - (! :logger [:log-msg :log-info :anon (str "processed [" n "] messages")]) - )) - (recur (inc n))))) - (Thread/sleep 100) ; allow delay for all actors to process their queues - (! :logger [:log-msg :log-info :anon "Test complete."]) + (let [task-dispatcher (whereis :task-dispatcher)] + (info "Beginning test...") + (time + (loop [n 0] + (when (< n 1000000) + ; select approximately 90% from existing concepts + (let [n1 (if (< (rand) 0.01) n (rand-int (/ n 10)))] + (! task-dispatcher [:task-msg {:term (format "a --> %d" n1) + :other "other"}]) + (when (== (mod n 100000) 0) + (info (format "processed [%s] messages" n)))) + (recur (inc n)))))) + ; allow delay for all actors to process their queues + (Thread/sleep 100) + (info "Test complete.") ; *** End test code ; join all actors so the terminate cleanly - (join (whereis :active-concept-collator)) - (join (whereis :anticipated-event)) - (join (whereis :concept-creator)) - (join (whereis :cross-modal-integrator)) - (join (whereis :derived-task-creator)) - (join (whereis :forgettable-concept-collator)) - (join (whereis :general-inferencer)) - (join (whereis :new-input-task-creator)) - (join (whereis :operator-executor)) - (join (whereis :persistence-manager)) - (join (whereis :sentence-parser)) - (join (whereis :serialiser)) - (join (whereis :system-time)) - (join (whereis :task-dispatcher)) - (join (whereis :logger)) + (doseq [actor-name actors-names] + (join (whereis actor-name))) ; cancel schedulers - (stop) - ) + (stop)) ; call main function -(start-nars) \ No newline at end of file +(defn run [] + (future (start-nars))) diff --git a/src/narjure/defaults.clj b/src/narjure/defaults.clj index 10be69a..74b6938 100644 --- a/src/narjure/defaults.clj +++ b/src/narjure/defaults.clj @@ -1,7 +1,5 @@ (ns narjure.defaults) -(def serial-no (atom 0)) - (def judgement-frequency 1.0) (def judgement-confidence 0.9) diff --git a/src/narjure/general_inference/active_concept_collator.clj b/src/narjure/general_inference/active_concept_collator.clj new file mode 100644 index 0000000..a45abfd --- /dev/null +++ b/src/narjure/general_inference/active_concept_collator.clj @@ -0,0 +1,21 @@ +(ns narjure.general-inference.active-concept-collator + (:require + [narjure.actor.utils :refer [defactor]] + [taoensso.timbre :refer [debug]]) + (:refer-clojure :exclude [promise await])) + +(declare inference-tick active-concept active-concept-collator) + +(defactor active-concept-collator + "State is collection of active concepts." + {:inference-tick-msg inference-tick + :active-concept-msg active-concept}) + +(def aname :active-concept-collator) + +(defn inference-tick [_ _] + ;(debug aname "process-inference-tick") + []) + +(defn active-concept [_ _] + (debug aname "process-active-concept")) diff --git a/src/narjure/general_inference/derived_task_creator.clj b/src/narjure/general_inference/derived_task_creator.clj new file mode 100644 index 0000000..f6aaca1 --- /dev/null +++ b/src/narjure/general_inference/derived_task_creator.clj @@ -0,0 +1,22 @@ +(ns narjure.general-inference.derived-task-creator + (:require + [narjure.actor.utils :refer [defactor]] + [taoensso.timbre :refer [debug]]) + (:refer-clojure :exclude [promise await])) + +(declare derived-task-creator system-time inference-result) + +(defactor derived-task-creator + "State is system-time." + {:time 0} + {:system-time-msg system-time + :inference-result-msg inference-result}) + +(def aname :derived-task-creator) + +(defn system-time [[_ time] _] + (debug aname "process-system-time") + {:time time}) + +(defn inference-result [_ _] + (debug aname "process-inference-result")) diff --git a/src/narjure/general_inference/general_inferencer.clj b/src/narjure/general_inference/general_inferencer.clj new file mode 100644 index 0000000..8c4a28b --- /dev/null +++ b/src/narjure/general_inference/general_inferencer.clj @@ -0,0 +1,17 @@ +(ns narjure.general-inference.general-inferencer + (:require + [narjure.actor.utils :refer [defactor]] + [taoensso.timbre :refer [debug]]) + (:refer-clojure :exclude [promise await])) + +(declare general-inferencer do-inference) + +(defactor general-inferencer + "State is inference rule trie or equivalent." + {:trie 0} + {:do-inference-msg do-inference}) + +(defn do-inference [_ _] + (debug :general-inferencer "process-do-inference")) + + diff --git a/src/narjure/memory_management/concept.clj b/src/narjure/memory_management/concept.clj new file mode 100644 index 0000000..df3f369 --- /dev/null +++ b/src/narjure/memory_management/concept.clj @@ -0,0 +1,30 @@ +(ns narjure.memory-management.concept + (:require + [narjure.actor.utils :refer [defactor]] + [taoensso.timbre :as t]) + (:refer-clojure :exclude [promise await])) + +(declare concept task-req belief-req inference-req persistence-req) + +(defactor concept + "State is a map + {:name :budget :activation-level :belief-tab :goal-tab :task-bag :term-bag} + (this list may not be complete)." + {:task-msg task-req + :belief-req-msq belief-req + :inference-req-msq inference-req + :persistence-req-msg persistence-req}) + +(defn debug [msg] (t/debug :concept msg)) + +(defn task-req [_ _] + #_(debug "process-task")) + +(defn belief-req [_ _] + (debug "process-belief-req")) + +(defn inference-req [_ _] + (debug "process-inference-req")) + +(defn persistence-req [_ _] + (debug "process-persistence-req")) diff --git a/src/narjure/memory_management/concept_creator.clj b/src/narjure/memory_management/concept_creator.clj new file mode 100644 index 0000000..14397d0 --- /dev/null +++ b/src/narjure/memory_management/concept_creator.clj @@ -0,0 +1,33 @@ +(ns narjure.memory-management.concept-creator + (:require + [co.paralleluniverse.pulsar.actors :refer [! spawn]] + [narjure.memory-management.concept :refer [concept]] + [narjure.actor.utils :refer [defactor]] + [taoensso.timbre :refer [debug]]) + (:refer-clojure :exclude [promise await])) + +(declare concept-creator task) + +(defactor concept-creator {:create-concept-msg task}) + +(def aname :concept-creator) + +(defn create-concept + ;TODO: update state for concept-actor to state initialiser + ;TODO: Create required sub-term concepts and propogate budget + [task c-map] + (let [{term :term} task] + (swap! c-map assoc term (spawn concept)) + #_(debug aname (str "Created concept: " term)))) + +(defn task + "When concept-map does not contain :term, create concept actor for term + then post task to task-dispatcher either way." + [[_ from task c-map] _] + (let [term (task :term)] + ; when concept not exist then create - goes here + (when (not (contains? @c-map term)) + (create-concept task c-map))) + + (! from [:task-msg task]) + #_(debug aname "concept-creator - process-task")) diff --git a/src/narjure/memory_management/forgettable_concept_collator.clj b/src/narjure/memory_management/forgettable_concept_collator.clj new file mode 100644 index 0000000..81797c7 --- /dev/null +++ b/src/narjure/memory_management/forgettable_concept_collator.clj @@ -0,0 +1,20 @@ +(ns narjure.memory-management.forgettable-concept-collator + (:require + [narjure.actor.utils :refer [defactor]] + [taoensso.timbre :refer [debug]]) + (:refer-clojure :exclude [promise await])) + +(declare forgettable-concept-collator forgetting-tick forgettable-concept) + +(defactor forgettable-concept-collator + "State is collection of forgettable concepts." + {:forgetting-tick-msg forgetting-tick + :forgettable-concept-msg forgettable-concept}) + +(def aname :forgettable-concept-collator) + +(defn forgetting-tick [_ _] + #_(debug aname "process-forgetting-tick")) + +(defn forgettable-concept [_ _] + (debug aname "process-forgettable-concept")) diff --git a/src/narjure/memory_management/persistence_manager.clj b/src/narjure/memory_management/persistence_manager.clj new file mode 100644 index 0000000..a06e2ae --- /dev/null +++ b/src/narjure/memory_management/persistence_manager.clj @@ -0,0 +1,15 @@ +(ns narjure.memory-management.persistence-manager + (:require + [narjure.actor.utils :refer [defactor]] + [taoensso.timbre :refer [debug]]) + (:refer-clojure :exclude [promise await])) + +(declare concept-state persistence-manager) + +(defactor persistence-manager + "State is file system handles" + [in-state] + {:concept-state-msg concept-state}) + +(defn concept-state [_ _] + (debug :persistence-manager "process-concept-state")) diff --git a/src/narjure/memory_management/task_dispatcher.clj b/src/narjure/memory_management/task_dispatcher.clj new file mode 100644 index 0000000..256a391 --- /dev/null +++ b/src/narjure/memory_management/task_dispatcher.clj @@ -0,0 +1,34 @@ +(ns narjure.memory-management.task-dispatcher + (:require + [co.paralleluniverse.pulsar.actors :refer [self ! whereis]] + [narjure.actor.utils :refer [defactor]] + [taoensso.timbre :refer [debug info]]) + (:refer-clojure :exclude [promise await])) + +(declare task-dispatcher task forget-concept concept-count) + +(def c-map (atom {})) + +(defactor task-dispatcher + "Concept-map is atom {:term :actor-ref} shared between + task-dispatcher and concept-creator" + {:task-msg task + :forget-concept-msg forget-concept + :concept-count-msg concept-count}) + +(def aname :task-dispatcher) + +(defn task + [[_ input-task] _] + (let [concept-creator (whereis :concept-creator) + term (input-task :term)] + (if-let [concept (@c-map term)] + (! concept :task-msg input-task) + (! concept-creator [:create-concept-msg @self input-task c-map]))) + #_(debug aname (str "process-task" input-task))) + +(defn forget-concept [[_ forget-concept] _] + (debug aname "process-forget-concept")) + +(defn concept-count [_ _] + (info aname (format "Concept count[%s]" (count @c-map)))) diff --git a/src/narjure/perception_action/anticipated_event.clj b/src/narjure/perception_action/anticipated_event.clj new file mode 100644 index 0000000..1f343f2 --- /dev/null +++ b/src/narjure/perception_action/anticipated_event.clj @@ -0,0 +1,32 @@ +(ns narjure.perception-action.anticipated-event + (:require + [co.paralleluniverse.pulsar.actors :refer [!]] + [narjure.actor.utils :refer [defactor]] + [taoensso.timbre :refer [debug]]) + (:refer-clojure :exclude [promise await])) + +(declare anticipated-event anticipated-event-handler system-time input-task) + +(def aname :anticipated-event) + +(defactor anticipated-event + "State is system-time and collection of anticipated events." + {:time 0 :anticipated-events {}} + {:system-time-msg system-time + :anticipated-event-msg anticipated-event-handler + :input-task-msg input-task}) + +(defn system-time + [[_ time] state] + (debug aname "process-system-time") + {:time time :anticipated-events (state :percepts)}) + +(defn anticipated-event-handler + [_ _] + #_(debug aname "process-anticipated-event")) + +(defn input-task + [[_ input-task] _] + #_(debug aname "process-input-task") + (! :task-dispatcher [:task-msg input-task])) + diff --git a/src/narjure/perception_action/cross_modal_integrator.clj b/src/narjure/perception_action/cross_modal_integrator.clj new file mode 100644 index 0000000..fff1181 --- /dev/null +++ b/src/narjure/perception_action/cross_modal_integrator.clj @@ -0,0 +1,22 @@ +(ns narjure.perception-action.cross-modal-integrator + (:require + [narjure.actor.utils :refer [defactor]] + [taoensso.timbre :refer [debug]]) + (:refer-clojure :exclude [promise await])) + +(declare cross-modal-integrator system-time percept-sentence) + +(defactor cross-modal-integrator + "State is system-time and collection of precepts from current duration window." + {:time 0 :percepts []} + {:system-time-msg system-time + :percept-sentence-msg percept-sentence}) + +(def aname :cross-modal-integrator) + +(defn system-time [[_ time] state] + (debug aname "process-system-time") + {:time time :percepts (state :percepts)}) + +(defn percept-sentence [_ _] + (debug aname "process-percept-sentence")) diff --git a/src/narjure/perception_action/operator_executor.clj b/src/narjure/perception_action/operator_executor.clj new file mode 100644 index 0000000..08df78c --- /dev/null +++ b/src/narjure/perception_action/operator_executor.clj @@ -0,0 +1,25 @@ +(ns narjure.perception-action.operator-executor + (:require + [co.paralleluniverse.pulsar + [core :refer [defsfn]] + [actors :refer [register! set-state! self]]] + [narjure.actor.utils :refer [defactor]] + [taoensso.timbre :refer [debug]]) + (:refer-clojure :exclude [promise await])) + +(declare operator-executor process system-time operator-execution-req) + +(defactor operator-executor + "State is system-time" + {:time 0} + {:system-time-msg system-time + :operator-execution-req-msg operator-execution-req}) + +(def aname :operator-executor) + +(defn system-time [[_ time] _] + (debug aname "process-system-time") + {:time time}) + +(defn operator-execution-req [_ _] + (debug aname "process-operator-execution-req")) diff --git a/src/narjure/perception_action/sentence_parser.clj b/src/narjure/perception_action/sentence_parser.clj new file mode 100644 index 0000000..9ef7d71 --- /dev/null +++ b/src/narjure/perception_action/sentence_parser.clj @@ -0,0 +1,39 @@ +(ns narjure.perception-action.sentence-parser + (:require + [co.paralleluniverse.pulsar.actors :refer [!]] + [narjure.narsese :refer [parse]] + [narjure.actor.utils :refer [defactor]] + [taoensso.timbre :refer [debug info]]) + (:refer-clojure :exclude [promise await])) + +(declare sentence-parser system-time narsese-string) + +(def serial-no (atom 0)) + +(defactor sentence-parser + {:time 0} + {:system-time-msg system-time + :narsese-string-msg narsese-string}) + +(def aname :sentence-parser) + +(defn system-time [[_ time] _] + (debug aname "process-system-time") + {:time time}) + +(defn parse-task + "Parses a narsese string." + [string system-time] + (assoc (parse string) + :stamp + {:id (swap! serial-no inc) + :creation-time system-time + :occurrence-time system-time + :trail [serial-no]})) + +(defn narsese-string + [[_ string] {time :time :as state}] + (let [task (parse-task string time)] + (! :anticipated-event [:input-task-msg task]) + (info aname (str "process-narsese-string" task))) + state) diff --git a/src/narjure/perception_action/system_time.clj b/src/narjure/perception_action/system_time.clj new file mode 100644 index 0000000..7126290 --- /dev/null +++ b/src/narjure/perception_action/system_time.clj @@ -0,0 +1,16 @@ +(ns narjure.perception-action.system-time + (:require + [narjure.actor.utils :refer [defactor]] + [taoensso.timbre :refer [debug]]) + (:refer-clojure :exclude [promise await])) + +(declare system-time system-time-tick) + +(defactor system-time + "State is system-time." + 0 + {:system-time-tick-msg system-time-tick}) + +(defn system-time-tick [_ state] + ;(debug :system-time (str "process-system-time-tick " state)) + (inc state))