Moved macros and helpers to push/instructions.cljc
This commit is contained in:
parent
0d58508bae
commit
d8c97e29e8
@ -3,7 +3,7 @@
|
|||||||
[propeller.genome :as genome]
|
[propeller.genome :as genome]
|
||||||
[propeller.push.interpreter :as interpreter]
|
[propeller.push.interpreter :as interpreter]
|
||||||
[propeller.utils :as utils]
|
[propeller.utils :as utils]
|
||||||
[propeller.push.utils.helpers :refer [get-stack-instructions]]
|
[propeller.push.instructions :refer [get-stack-instructions]]
|
||||||
[propeller.push.state :as state]
|
[propeller.push.state :as state]
|
||||||
[propeller.tools.math :as math]
|
[propeller.tools.math :as math]
|
||||||
[propeller.gp :as gp]
|
[propeller.gp :as gp]
|
||||||
|
@ -3,9 +3,8 @@
|
|||||||
[propeller.genome :as genome]
|
[propeller.genome :as genome]
|
||||||
[propeller.push.interpreter :as interpreter]
|
[propeller.push.interpreter :as interpreter]
|
||||||
[propeller.utils :as utils]
|
[propeller.utils :as utils]
|
||||||
[propeller.push.utils.helpers :refer [get-stack-instructions]]
|
[propeller.push.instructions :refer [get-stack-instructions]]
|
||||||
[propeller.push.state :as state]
|
[propeller.push.state :as state]
|
||||||
[clojure.pprint :as pprint]
|
|
||||||
[propeller.tools.math :as math]
|
[propeller.tools.math :as math]
|
||||||
[propeller.gp :as gp]
|
[propeller.gp :as gp]
|
||||||
#?(:cljs [cljs.reader :refer [read-string]])))
|
#?(:cljs [cljs.reader :refer [read-string]])))
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
[propeller.genome :as genome]
|
[propeller.genome :as genome]
|
||||||
[propeller.push.interpreter :as interpreter]
|
[propeller.push.interpreter :as interpreter]
|
||||||
[propeller.utils :as utils]
|
[propeller.utils :as utils]
|
||||||
[propeller.push.utils.helpers :refer [get-stack-instructions]]
|
[propeller.push.instructions :refer [get-stack-instructions]]
|
||||||
[propeller.push.state :as state]
|
[propeller.push.state :as state]
|
||||||
[propeller.tools.math :as math]
|
[propeller.tools.math :as math]
|
||||||
[propeller.gp :as gp]
|
[propeller.gp :as gp]
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
[propeller.genome :as genome]
|
[propeller.genome :as genome]
|
||||||
[propeller.push.interpreter :as interpreter]
|
[propeller.push.interpreter :as interpreter]
|
||||||
[propeller.utils :as utils]
|
[propeller.utils :as utils]
|
||||||
[propeller.push.utils.helpers :refer [get-stack-instructions]]
|
[propeller.push.instructions :refer [get-stack-instructions]]
|
||||||
[propeller.push.state :as state]
|
[propeller.push.state :as state]
|
||||||
[propeller.tools.metrics :as metrics]
|
[propeller.tools.metrics :as metrics]
|
||||||
[propeller.gp :as gp]
|
[propeller.gp :as gp]
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
[propeller.genome :as genome]
|
[propeller.genome :as genome]
|
||||||
[propeller.push.interpreter :as interpreter]
|
[propeller.push.interpreter :as interpreter]
|
||||||
[propeller.utils :as utils]
|
[propeller.utils :as utils]
|
||||||
[propeller.push.utils.helpers :refer [get-stack-instructions]]
|
[propeller.push.instructions :refer [get-stack-instructions]]
|
||||||
[propeller.push.state :as state]
|
[propeller.push.state :as state]
|
||||||
[propeller.tools.math :as math]
|
[propeller.tools.math :as math]
|
||||||
[propeller.gp :as gp]
|
[propeller.gp :as gp]
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
[propeller.genome :as genome]
|
[propeller.genome :as genome]
|
||||||
[propeller.push.interpreter :as interpreter]
|
[propeller.push.interpreter :as interpreter]
|
||||||
[propeller.utils :as utils]
|
[propeller.utils :as utils]
|
||||||
[propeller.push.utils.helpers :refer [get-stack-instructions]]
|
[propeller.push.instructions :refer [get-stack-instructions]]
|
||||||
[propeller.push.state :as state]
|
[propeller.push.state :as state]
|
||||||
[propeller.tools.metrics :as metrics]
|
[propeller.tools.metrics :as metrics]
|
||||||
[propeller.gp :as gp]
|
[propeller.gp :as gp]
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
[propeller.genome :as genome]
|
[propeller.genome :as genome]
|
||||||
[propeller.push.interpreter :as interpreter]
|
[propeller.push.interpreter :as interpreter]
|
||||||
[propeller.utils :as utils]
|
[propeller.utils :as utils]
|
||||||
[propeller.push.utils.helpers :refer [get-stack-instructions]]
|
[propeller.push.instructions :refer [get-stack-instructions]]
|
||||||
[propeller.push.state :as state]
|
[propeller.push.state :as state]
|
||||||
[propeller.tools.math :as math]
|
[propeller.tools.math :as math]
|
||||||
[propeller.gp :as gp]
|
[propeller.gp :as gp]
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
[propeller.genome :as genome]
|
[propeller.genome :as genome]
|
||||||
[propeller.push.interpreter :as interpreter]
|
[propeller.push.interpreter :as interpreter]
|
||||||
[propeller.utils :as utils]
|
[propeller.utils :as utils]
|
||||||
[propeller.push.utils.helpers :refer [get-stack-instructions]]
|
[propeller.push.instructions :refer [get-stack-instructions]]
|
||||||
[propeller.push.state :as state]
|
[propeller.push.state :as state]
|
||||||
[propeller.tools.math :as math]
|
[propeller.tools.math :as math]
|
||||||
[propeller.gp :as gp]
|
[propeller.gp :as gp]
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
[propeller.genome :as genome]
|
[propeller.genome :as genome]
|
||||||
[propeller.push.interpreter :as interpreter]
|
[propeller.push.interpreter :as interpreter]
|
||||||
[propeller.utils :as utils]
|
[propeller.utils :as utils]
|
||||||
[propeller.push.utils.helpers :refer [get-stack-instructions]]
|
[propeller.push.instructions :refer [get-stack-instructions]]
|
||||||
[propeller.push.state :as state]
|
[propeller.push.state :as state]
|
||||||
[propeller.tools.math :as math]
|
[propeller.tools.math :as math]
|
||||||
[propeller.gp :as gp]
|
[propeller.gp :as gp]
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
[propeller.genome :as genome]
|
[propeller.genome :as genome]
|
||||||
[propeller.push.interpreter :as interpreter]
|
[propeller.push.interpreter :as interpreter]
|
||||||
[propeller.utils :as utils]
|
[propeller.utils :as utils]
|
||||||
[propeller.push.utils.helpers :refer [get-stack-instructions]]
|
[propeller.push.instructions :refer [get-stack-instructions]]
|
||||||
[propeller.push.state :as state]
|
[propeller.push.state :as state]
|
||||||
[propeller.tools.metrics :as metrics]
|
[propeller.tools.metrics :as metrics]
|
||||||
[propeller.gp :as gp]
|
[propeller.gp :as gp]
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
[propeller.genome :as genome]
|
[propeller.genome :as genome]
|
||||||
[propeller.push.interpreter :as interpreter]
|
[propeller.push.interpreter :as interpreter]
|
||||||
[propeller.utils :as utils]
|
[propeller.utils :as utils]
|
||||||
[propeller.push.utils.helpers :refer [get-stack-instructions]]
|
[propeller.push.instructions :refer [get-stack-instructions]]
|
||||||
[propeller.push.state :as state]
|
[propeller.push.state :as state]
|
||||||
[propeller.tools.math :as math]
|
[propeller.tools.math :as math]
|
||||||
[propeller.gp :as gp]
|
[propeller.gp :as gp]
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
[propeller.genome :as genome]
|
[propeller.genome :as genome]
|
||||||
[propeller.push.interpreter :as interpreter]
|
[propeller.push.interpreter :as interpreter]
|
||||||
[propeller.utils :as utils]
|
[propeller.utils :as utils]
|
||||||
[propeller.push.utils.helpers :refer [get-stack-instructions]]
|
[propeller.push.instructions :refer [get-stack-instructions]]
|
||||||
[propeller.push.state :as state]
|
[propeller.push.state :as state]
|
||||||
[propeller.tools.math :as math]
|
[propeller.tools.math :as math]
|
||||||
[propeller.gp :as gp]
|
[propeller.gp :as gp]
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
[propeller.genome :as genome]
|
[propeller.genome :as genome]
|
||||||
[propeller.push.interpreter :as interpreter]
|
[propeller.push.interpreter :as interpreter]
|
||||||
[propeller.utils :as utils]
|
[propeller.utils :as utils]
|
||||||
[propeller.push.utils.helpers :refer [get-stack-instructions]]
|
[propeller.push.instructions :refer [get-stack-instructions]]
|
||||||
[propeller.push.state :as state]
|
[propeller.push.state :as state]
|
||||||
[propeller.tools.math :as math]
|
[propeller.tools.math :as math]
|
||||||
[propeller.gp :as gp]
|
[propeller.gp :as gp]
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
[propeller.genome :as genome]
|
[propeller.genome :as genome]
|
||||||
[propeller.push.interpreter :as interpreter]
|
[propeller.push.interpreter :as interpreter]
|
||||||
[propeller.utils :as utils]
|
[propeller.utils :as utils]
|
||||||
[propeller.push.utils.helpers :refer [get-stack-instructions]]
|
[propeller.push.instructions :refer [get-stack-instructions]]
|
||||||
[propeller.push.state :as state]
|
[propeller.push.state :as state]
|
||||||
[propeller.gp :as gp]
|
[propeller.gp :as gp]
|
||||||
#?(:cljs [cljs.reader :refer [read-string]])))
|
#?(:cljs [cljs.reader :refer [read-string]])))
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
[propeller.genome :as genome]
|
[propeller.genome :as genome]
|
||||||
[propeller.push.interpreter :as interpreter]
|
[propeller.push.interpreter :as interpreter]
|
||||||
[propeller.utils :as utils]
|
[propeller.utils :as utils]
|
||||||
[propeller.push.utils.helpers :refer [get-stack-instructions]]
|
[propeller.push.instructions :refer [get-stack-instructions]]
|
||||||
[propeller.push.state :as state]
|
[propeller.push.state :as state]
|
||||||
[propeller.tools.metrics :as metrics]
|
[propeller.tools.metrics :as metrics]
|
||||||
[propeller.gp :as gp]
|
[propeller.gp :as gp]
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
[propeller.genome :as genome]
|
[propeller.genome :as genome]
|
||||||
[propeller.push.interpreter :as interpreter]
|
[propeller.push.interpreter :as interpreter]
|
||||||
[propeller.utils :as utils]
|
[propeller.utils :as utils]
|
||||||
[propeller.push.utils.helpers :refer [get-stack-instructions]]
|
[propeller.push.instructions :refer [get-stack-instructions]]
|
||||||
[propeller.push.state :as state]
|
[propeller.push.state :as state]
|
||||||
[propeller.tools.metrics :as metrics]
|
[propeller.tools.metrics :as metrics]
|
||||||
[propeller.gp :as gp]
|
[propeller.gp :as gp]
|
||||||
|
@ -3,9 +3,8 @@
|
|||||||
[propeller.genome :as genome]
|
[propeller.genome :as genome]
|
||||||
[propeller.push.interpreter :as interpreter]
|
[propeller.push.interpreter :as interpreter]
|
||||||
[propeller.utils :as utils]
|
[propeller.utils :as utils]
|
||||||
[propeller.push.utils.helpers :refer [get-stack-instructions]]
|
[propeller.push.instructions :refer [get-stack-instructions]]
|
||||||
[propeller.push.state :as state]
|
[propeller.push.state :as state]
|
||||||
[propeller.tools.math :as math]
|
|
||||||
[propeller.tools.metrics :as metrics]
|
[propeller.tools.metrics :as metrics]
|
||||||
[propeller.gp :as gp]
|
[propeller.gp :as gp]
|
||||||
#?(:cljs [cljs.reader :refer [read-string]])))
|
#?(:cljs [cljs.reader :refer [read-string]])))
|
||||||
|
@ -3,9 +3,8 @@
|
|||||||
[propeller.genome :as genome]
|
[propeller.genome :as genome]
|
||||||
[propeller.push.interpreter :as interpreter]
|
[propeller.push.interpreter :as interpreter]
|
||||||
[propeller.utils :as utils]
|
[propeller.utils :as utils]
|
||||||
[propeller.push.utils.helpers :refer [get-stack-instructions]]
|
[propeller.push.instructions :refer [get-stack-instructions]]
|
||||||
[propeller.push.state :as state]
|
[propeller.push.state :as state]
|
||||||
[propeller.tools.math :as math]
|
|
||||||
[propeller.tools.metrics :as metrics]
|
[propeller.tools.metrics :as metrics]
|
||||||
[propeller.gp :as gp]
|
[propeller.gp :as gp]
|
||||||
#?(:cljs [cljs.reader :refer [read-string]])))
|
#?(:cljs [cljs.reader :refer [read-string]])))
|
||||||
|
@ -2,9 +2,8 @@
|
|||||||
(:require [propeller.genome :as genome]
|
(:require [propeller.genome :as genome]
|
||||||
[propeller.push.interpreter :as interpreter]
|
[propeller.push.interpreter :as interpreter]
|
||||||
[propeller.push.state :as state]
|
[propeller.push.state :as state]
|
||||||
[propeller.push.utils.helpers :refer [get-stack-instructions]]
|
[propeller.push.instructions :refer [get-stack-instructions]]
|
||||||
[propeller.utils :as utils]
|
[propeller.utils :as utils]
|
||||||
[propeller.push.state :as state]
|
|
||||||
[propeller.tools.math :as math]
|
[propeller.tools.math :as math]
|
||||||
[propeller.gp :as gp]
|
[propeller.gp :as gp]
|
||||||
#?(:cljs [cljs.reader :refer [read-string]])))
|
#?(:cljs [cljs.reader :refer [read-string]])))
|
||||||
|
@ -2,9 +2,8 @@
|
|||||||
(:require [propeller.genome :as genome]
|
(:require [propeller.genome :as genome]
|
||||||
[propeller.push.interpreter :as interpreter]
|
[propeller.push.interpreter :as interpreter]
|
||||||
[propeller.push.state :as state]
|
[propeller.push.state :as state]
|
||||||
[propeller.push.utils.helpers :refer [get-stack-instructions]]
|
[propeller.push.instructions :refer [get-stack-instructions]]
|
||||||
[propeller.utils :as utils]
|
[propeller.utils :as utils]
|
||||||
[propeller.push.state :as state]
|
|
||||||
[propeller.gp :as gp]
|
[propeller.gp :as gp]
|
||||||
#?(:cljs [cljs.reader :refer [read-string]])))
|
#?(:cljs [cljs.reader :refer [read-string]])))
|
||||||
|
|
||||||
|
@ -1,4 +1,9 @@
|
|||||||
(ns propeller.push.instructions)
|
(ns propeller.push.instructions
|
||||||
|
(:require [clojure.set]
|
||||||
|
[propeller.push.state :as state]
|
||||||
|
[propeller.utils :as u]
|
||||||
|
#?(:cljs [goog.string :as gstring])
|
||||||
|
#?(:cljs [goog.string.format])))
|
||||||
|
|
||||||
;; PushGP instructions are represented as keywords, and stored in an atom. They
|
;; PushGP instructions are represented as keywords, and stored in an atom. They
|
||||||
;; can be either constant literals or functions that take and return a Push state
|
;; can be either constant literals or functions that take and return a Push state
|
||||||
@ -13,3 +18,117 @@
|
|||||||
:exec_k 2
|
:exec_k 2
|
||||||
:exec_s 3
|
:exec_s 3
|
||||||
:exec_y 1})
|
:exec_y 1})
|
||||||
|
|
||||||
|
|
||||||
|
#?(:clj
|
||||||
|
(def cls->type
|
||||||
|
{Boolean :boolean
|
||||||
|
Short :integer
|
||||||
|
Integer :integer
|
||||||
|
Long :integer
|
||||||
|
BigInteger :integer
|
||||||
|
Double :float
|
||||||
|
BigDecimal :float
|
||||||
|
Float :float
|
||||||
|
Character :char
|
||||||
|
String :string}))
|
||||||
|
|
||||||
|
#?(:cljs
|
||||||
|
(def pred->type
|
||||||
|
[[boolean? :boolean]
|
||||||
|
[int? :integer]
|
||||||
|
[float? :float]
|
||||||
|
[string? :string]
|
||||||
|
[char? :char]]))
|
||||||
|
|
||||||
|
(defn get-literal-type
|
||||||
|
"If a piece of data is a literal, return its corresponding stack name
|
||||||
|
e.g. `:integer`. Otherwise, return `nil`."
|
||||||
|
[data]
|
||||||
|
(or (when (vector? data)
|
||||||
|
(if (empty? data)
|
||||||
|
:generic-vector
|
||||||
|
(keyword (str "vector_" (name (get-literal-type (u/first-non-nil data)))))))
|
||||||
|
#?(:clj (cls->type (type data))
|
||||||
|
:cljs (loop [remaining pred->type]
|
||||||
|
(let [[pred d-type] (first remaining)]
|
||||||
|
(cond
|
||||||
|
(empty? remaining) nil
|
||||||
|
(pred data) d-type
|
||||||
|
:else (recur (rest remaining))))))))
|
||||||
|
|
||||||
|
(defn get-vector-literal-type
|
||||||
|
"Returns the literal stack corresponding to some vector stack."
|
||||||
|
[vector-stack]
|
||||||
|
(get state/vec-stacks vector-stack))
|
||||||
|
|
||||||
|
(defn def-instruction
|
||||||
|
"Defines a Push instruction as a keyword-function pair, and adds it to the
|
||||||
|
instruction table"
|
||||||
|
[instruction function]
|
||||||
|
(swap! instruction-table assoc instruction function))
|
||||||
|
|
||||||
|
(defn make-metadata
|
||||||
|
"Given a generic function, e.g. _dup, and a stack type to instantiate it for,
|
||||||
|
e.g. :char, returns the appropriate stack metadata for that function instance"
|
||||||
|
[function stack]
|
||||||
|
(->> (:stacks (meta function))
|
||||||
|
(replace {:elem (get-vector-literal-type stack)})
|
||||||
|
(cons stack)
|
||||||
|
set
|
||||||
|
(assoc-in (meta function) [:stacks])
|
||||||
|
(#(dissoc % :name))))
|
||||||
|
|
||||||
|
(defn generate-instructions
|
||||||
|
"Given a sequence of stacks, e.g. [:float :integer], and a sequence of suffix
|
||||||
|
function strings, e.g. [_add, _mult, _eq], automates the generation of all
|
||||||
|
possible combination instructions, which here would be :float_add, :float_mult,
|
||||||
|
:float_eq, :integer_add, :integer_mult, and :integer_eq, also transferring
|
||||||
|
and updating the generic function's stack-type metadata. For some vector
|
||||||
|
instructions, the placeholder :elem will be replaced with the stack of the
|
||||||
|
corresponding element type (e.g. for :vector_integer, with :integer)"
|
||||||
|
[stacks functions]
|
||||||
|
(doseq [stack stacks
|
||||||
|
func functions]
|
||||||
|
(let [instruction-name (keyword (str (name stack) (:name (meta func))))
|
||||||
|
metadata (make-metadata func stack)
|
||||||
|
new-func (with-meta (partial func stack) metadata)]
|
||||||
|
(def-instruction instruction-name new-func))))
|
||||||
|
|
||||||
|
|
||||||
|
(defn make-instruction
|
||||||
|
"A utility function for making Push instructions. Takes a state, a function
|
||||||
|
to apply to the args, the stacks to take the args from, and the stack to
|
||||||
|
return the result to. Applies the function to the args (popped from the
|
||||||
|
given stacks), and pushes the result onto the return-stack.
|
||||||
|
|
||||||
|
If the function returns :ignore-instruction, then we will return the
|
||||||
|
initial state unchanged. This allows instructions to fail gracefully
|
||||||
|
without consuming stack values."
|
||||||
|
[state function arg-stacks return-stack]
|
||||||
|
(let [popped-args (state/get-args-from-stacks state arg-stacks)]
|
||||||
|
(if (= popped-args :not-enough-args)
|
||||||
|
state
|
||||||
|
(let [result (apply function (:args popped-args))
|
||||||
|
new-state (:state popped-args)]
|
||||||
|
(if (= result :ignore-instruction)
|
||||||
|
state
|
||||||
|
(state/push-to-stack new-state return-stack result))))))
|
||||||
|
|
||||||
|
(defn get-stack-instructions
|
||||||
|
"Given a set of stacks, returns all instructions that operate on those stacks
|
||||||
|
only. Won't include random instructions unless :random is in the set as well"
|
||||||
|
[stacks]
|
||||||
|
(doseq [[instruction-name function] @instruction-table]
|
||||||
|
(assert
|
||||||
|
(:stacks (meta function))
|
||||||
|
#?(:clj (format
|
||||||
|
"ERROR: Instruction %s does not have :stacks defined in metadata."
|
||||||
|
(name instruction-name))
|
||||||
|
:cljs (gstring/format
|
||||||
|
"ERROR: Instruction %s does not have :stacks defined in metadata."
|
||||||
|
(name instruction-name)))))
|
||||||
|
(for [[instruction-name function] @instruction-table
|
||||||
|
:when (clojure.set/subset? (:stacks (meta function)) stacks)]
|
||||||
|
instruction-name))
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
(ns propeller.push.instructions.bool
|
(ns propeller.push.instructions.bool
|
||||||
#?(:cljs (:require-macros [propeller.push.utils.macros :refer [def-instruction]]))
|
(:require [propeller.push.instructions :refer [def-instruction
|
||||||
(:require [propeller.push.utils.helpers :refer [make-instruction]]
|
make-instruction]]))
|
||||||
#?(:clj [propeller.push.utils.macros :refer [def-instruction]])))
|
|
||||||
|
|
||||||
;; =============================================================================
|
;; =============================================================================
|
||||||
;; BOOLEAN Instructions
|
;; BOOLEAN Instructions
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
(ns propeller.push.instructions.character
|
(ns propeller.push.instructions.character
|
||||||
#?(:cljs (:require-macros [propeller.push.utils.macros :refer [def-instruction]]))
|
|
||||||
(:require [propeller.push.state :as state]
|
(:require [propeller.push.state :as state]
|
||||||
[propeller.push.utils.helpers :refer [make-instruction]]
|
|
||||||
[propeller.tools.character :as char]
|
[propeller.tools.character :as char]
|
||||||
#?(:clj [propeller.push.utils.macros :refer [def-instruction]])))
|
[propeller.push.instructions :refer [def-instruction
|
||||||
|
make-instruction]]))
|
||||||
|
|
||||||
;; =============================================================================
|
;; =============================================================================
|
||||||
;; CHAR Instructions
|
;; CHAR Instructions
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
(ns propeller.push.instructions.code
|
(ns propeller.push.instructions.code
|
||||||
#?(:cljs (:require-macros [propeller.push.utils.macros :refer [def-instruction]]))
|
|
||||||
(:require [propeller.utils :as utils]
|
(:require [propeller.utils :as utils]
|
||||||
[propeller.push.state :as state]
|
[propeller.push.state :as state]
|
||||||
[propeller.push.utils.helpers :refer [make-instruction]]
|
[propeller.push.instructions :refer [def-instruction
|
||||||
#?(:clj [propeller.push.utils.macros :refer [def-instruction]])))
|
make-instruction]]))
|
||||||
|
|
||||||
;; =============================================================================
|
;; =============================================================================
|
||||||
;; CODE Instructions
|
;; CODE Instructions
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
(ns propeller.push.instructions.input-output
|
(ns propeller.push.instructions.input-output
|
||||||
#?(:cljs (:require-macros
|
|
||||||
[propeller.push.utils.macros :refer [def-instruction
|
|
||||||
generate-instructions]]))
|
|
||||||
(:require [propeller.push.state :as state]
|
(:require [propeller.push.state :as state]
|
||||||
[propeller.push.utils.helpers :refer [make-instruction]]
|
[propeller.push.instructions :refer [def-instruction
|
||||||
[propeller.push.utils.macros :refer [def-instruction
|
|
||||||
generate-instructions]]))
|
generate-instructions]]))
|
||||||
|
|
||||||
;; =============================================================================
|
;; =============================================================================
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
(ns propeller.push.instructions.numeric
|
(ns propeller.push.instructions.numeric
|
||||||
(:require [propeller.push.utils.helpers :refer [make-instruction]]
|
(:require [propeller.tools.math :as math]
|
||||||
[propeller.tools.math :as math]
|
[propeller.push.instructions :refer [def-instruction
|
||||||
[propeller.push.utils.macros :refer [def-instruction
|
generate-instructions
|
||||||
generate-instructions]]))
|
make-instruction]]))
|
||||||
|
|
||||||
;; =============================================================================
|
;; =============================================================================
|
||||||
;; FLOAT and INTEGER Instructions (polymorphic)
|
;; FLOAT and INTEGER Instructions (polymorphic)
|
||||||
|
@ -1,13 +1,10 @@
|
|||||||
(ns propeller.push.instructions.polymorphic
|
(ns propeller.push.instructions.polymorphic
|
||||||
#?(:cljs (:require-macros
|
|
||||||
[propeller.push.utils.macros :refer [def-instruction
|
|
||||||
generate-instructions]]))
|
|
||||||
(:require [propeller.utils :as utils]
|
(:require [propeller.utils :as utils]
|
||||||
[propeller.push.state :as state]
|
[propeller.push.state :as state]
|
||||||
[propeller.push.utils.helpers :refer [make-instruction]]
|
|
||||||
[propeller.push.limits :as limit]
|
[propeller.push.limits :as limit]
|
||||||
#?(:clj [propeller.push.utils.macros :refer [def-instruction
|
[propeller.push.instructions :refer [def-instruction
|
||||||
generate-instructions]])))
|
generate-instructions
|
||||||
|
make-instruction]]))
|
||||||
|
|
||||||
;; =============================================================================
|
;; =============================================================================
|
||||||
;; Polymorphic Instructions
|
;; Polymorphic Instructions
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
(ns propeller.push.instructions.string
|
(ns propeller.push.instructions.string
|
||||||
#?(:cljs (:require-macros
|
|
||||||
[propeller.push.utils.macros :refer [def-instruction]]))
|
|
||||||
(:require [clojure.string :as string]
|
(:require [clojure.string :as string]
|
||||||
[propeller.push.utils.helpers :refer [make-instruction]]
|
|
||||||
[propeller.push.state :as state]
|
[propeller.push.state :as state]
|
||||||
#?(:clj [propeller.push.utils.macros :refer [def-instruction]])))
|
[propeller.push.instructions :refer [def-instruction
|
||||||
|
make-instruction]]))
|
||||||
|
|
||||||
;; =============================================================================
|
;; =============================================================================
|
||||||
;; STRING Instructions
|
;; STRING Instructions
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
(ns propeller.push.instructions.vector
|
(ns propeller.push.instructions.vector
|
||||||
#?(:cljs (:require-macros [propeller.push.utils.macros :refer [generate-instructions]]))
|
|
||||||
(:require [clojure.string]
|
(:require [clojure.string]
|
||||||
[propeller.utils :as utils]
|
[propeller.utils :as utils]
|
||||||
[propeller.push.state :as state]
|
[propeller.push.state :as state]
|
||||||
[propeller.push.utils.helpers :refer [get-vector-literal-type
|
[propeller.push.instructions :refer [generate-instructions
|
||||||
make-instruction]]
|
make-instruction
|
||||||
#?(:clj [propeller.push.utils.macros :refer [generate-instructions]])))
|
get-vector-literal-type]]))
|
||||||
|
|
||||||
;; =============================================================================
|
;; =============================================================================
|
||||||
;; VECTOR Instructions
|
;; VECTOR Instructions
|
||||||
|
@ -1,15 +1,14 @@
|
|||||||
(ns propeller.push.interpreter
|
(ns propeller.push.interpreter
|
||||||
(:require [propeller.push.instructions :as instructions]
|
(:require [propeller.push.instructions :as instructions]
|
||||||
[propeller.push.state :as state]
|
[propeller.push.state :as state]
|
||||||
[propeller.push.instructions.input-output :as io]
|
[propeller.push.instructions.input-output :as io]))
|
||||||
[propeller.push.utils.helpers :refer [get-literal-type]]))
|
|
||||||
|
|
||||||
(defn interpret-one-step
|
(defn interpret-one-step
|
||||||
"Takes a Push state and executes the next instruction on the exec stack."
|
"Takes a Push state and executes the next instruction on the exec stack."
|
||||||
[state]
|
[state]
|
||||||
(let [popped-state (state/pop-stack state :exec)
|
(let [popped-state (state/pop-stack state :exec)
|
||||||
instruction (first (:exec state))
|
instruction (first (:exec state))
|
||||||
literal-type (get-literal-type instruction)] ; nil for non-literals
|
literal-type (instructions/get-literal-type instruction)] ; nil for non-literals
|
||||||
(cond
|
(cond
|
||||||
;;
|
;;
|
||||||
;; Recognize functional instruction or input instruction
|
;; Recognize functional instruction or input instruction
|
||||||
|
@ -1,86 +0,0 @@
|
|||||||
(ns propeller.push.utils.helpers
|
|
||||||
(:require [clojure.set]
|
|
||||||
[propeller.push.instructions :as instructions]
|
|
||||||
[propeller.push.state :as state]
|
|
||||||
[propeller.utils :as u]
|
|
||||||
#?(:cljs [goog.string :as gstring])
|
|
||||||
#?(:cljs [goog.string.format])))
|
|
||||||
|
|
||||||
;; A utility function for making Push instructions. Takes a state, a function
|
|
||||||
;; to apply to the args, the stacks to take the args from, and the stack to
|
|
||||||
;; return the result to. Applies the function to the args (popped from the
|
|
||||||
;; given stacks), and pushes the result onto the return-stack.
|
|
||||||
;;
|
|
||||||
;; If the function returns :ignore-instruction, then we will return the
|
|
||||||
;; initial state unchanged. This allows instructions to fail gracefully
|
|
||||||
;; without consuming stack values.
|
|
||||||
(defn make-instruction
|
|
||||||
[state function arg-stacks return-stack]
|
|
||||||
(let [popped-args (state/get-args-from-stacks state arg-stacks)]
|
|
||||||
(if (= popped-args :not-enough-args)
|
|
||||||
state
|
|
||||||
(let [result (apply function (:args popped-args))
|
|
||||||
new-state (:state popped-args)]
|
|
||||||
(if (= result :ignore-instruction)
|
|
||||||
state
|
|
||||||
(state/push-to-stack new-state return-stack result))))))
|
|
||||||
|
|
||||||
;; Given a set of stacks, returns all instructions that operate on those stacks
|
|
||||||
;; only. Won't include random instructions unless :random is in the set as well
|
|
||||||
(defn get-stack-instructions
|
|
||||||
[stacks]
|
|
||||||
(doseq [[instruction-name function] @instructions/instruction-table]
|
|
||||||
(assert
|
|
||||||
(:stacks (meta function))
|
|
||||||
#?(:clj (format
|
|
||||||
"ERROR: Instruction %s does not have :stacks defined in metadata."
|
|
||||||
(name instruction-name))
|
|
||||||
:cljs (gstring/format
|
|
||||||
"ERROR: Instruction %s does not have :stacks defined in metadata."
|
|
||||||
(name instruction-name)))))
|
|
||||||
(for [[instruction-name function] @instructions/instruction-table
|
|
||||||
:when (clojure.set/subset? (:stacks (meta function)) stacks)]
|
|
||||||
instruction-name))
|
|
||||||
|
|
||||||
|
|
||||||
#?(:clj
|
|
||||||
(def cls->type
|
|
||||||
{Boolean :boolean
|
|
||||||
Short :integer
|
|
||||||
Integer :integer
|
|
||||||
Long :integer
|
|
||||||
BigInteger :integer
|
|
||||||
Double :float
|
|
||||||
BigDecimal :float
|
|
||||||
Float :float
|
|
||||||
Character :char
|
|
||||||
String :string}))
|
|
||||||
|
|
||||||
#?(:cljs
|
|
||||||
(def pred->type
|
|
||||||
[[boolean? :boolean]
|
|
||||||
[int? :integer]
|
|
||||||
[float? :float]
|
|
||||||
[string? :string]
|
|
||||||
[char? :char]]))
|
|
||||||
|
|
||||||
(defn get-literal-type
|
|
||||||
"If a piece of data is a literal, return its corresponding stack name
|
|
||||||
e.g. `:integer`. Otherwise, return `nil`."
|
|
||||||
[data]
|
|
||||||
(or (when (vector? data)
|
|
||||||
(if (empty? data)
|
|
||||||
:generic-vector
|
|
||||||
(keyword (str "vector_" (name (get-literal-type (u/first-non-nil data)))))))
|
|
||||||
#?(:clj (cls->type (type data))
|
|
||||||
:cljs (loop [remaining pred->type]
|
|
||||||
(let [[pred d-type] (first remaining)]
|
|
||||||
(cond
|
|
||||||
(empty? remaining) nil
|
|
||||||
(pred data) d-type
|
|
||||||
:else (recur (rest remaining))))))))
|
|
||||||
|
|
||||||
(defn get-vector-literal-type
|
|
||||||
"Returns the literal stack corresponding to some vector stack."
|
|
||||||
[vector-stack]
|
|
||||||
(get state/vec-stacks vector-stack))
|
|
@ -1,36 +0,0 @@
|
|||||||
(ns propeller.push.utils.macros
|
|
||||||
(:require [propeller.push.instructions :as instructions]
|
|
||||||
[propeller.push.utils.helpers :refer [get-vector-literal-type]]))
|
|
||||||
|
|
||||||
(defn def-instruction
|
|
||||||
"Defines a Push instruction as a keyword-function pair, and adds it to the
|
|
||||||
instruction table"
|
|
||||||
[instruction function]
|
|
||||||
(swap! instructions/instruction-table assoc instruction function))
|
|
||||||
|
|
||||||
(defn make-metadata
|
|
||||||
"Given a generic function, e.g. _dup, and a stack type to instantiate it for,
|
|
||||||
e.g. :char, returns the appropriate stack metadata for that function instance"
|
|
||||||
[function stack]
|
|
||||||
(->> (:stacks (meta function))
|
|
||||||
(replace {:elem (get-vector-literal-type stack)})
|
|
||||||
(cons stack)
|
|
||||||
set
|
|
||||||
(assoc-in (meta function) [:stacks])
|
|
||||||
(#(dissoc % :name))))
|
|
||||||
|
|
||||||
(defn generate-instructions
|
|
||||||
"Given a sequence of stacks, e.g. [:float :integer], and a sequence of suffix
|
|
||||||
function strings, e.g. [_add, _mult, _eq], automates the generation of all
|
|
||||||
possible combination instructions, which here would be :float_add, :float_mult,
|
|
||||||
:float_eq, :integer_add, :integer_mult, and :integer_eq, also transferring
|
|
||||||
and updating the generic function's stack-type metadata. For some vector
|
|
||||||
instructions, the placeholder :elem will be replaced with the stack of the
|
|
||||||
corresponding element type (e.g. for :vector_integer, with :integer)"
|
|
||||||
[stacks functions]
|
|
||||||
(doseq [stack stacks
|
|
||||||
func functions]
|
|
||||||
(let [instruction-name (keyword (str (name stack) (:name (meta func))))
|
|
||||||
metadata (make-metadata func stack)
|
|
||||||
new-func (with-meta (partial func stack) metadata)]
|
|
||||||
(def-instruction instruction-name new-func))))
|
|
@ -7,8 +7,7 @@
|
|||||||
[propeller.problems.string-classification :as string-classif]
|
[propeller.problems.string-classification :as string-classif]
|
||||||
[propeller.push.instructions :as instructions]
|
[propeller.push.instructions :as instructions]
|
||||||
[propeller.push.interpreter :as interpreter]
|
[propeller.push.interpreter :as interpreter]
|
||||||
[propeller.push.state :as state]
|
[propeller.push.state :as state]))
|
||||||
[propeller.push.utils.helpers :refer [get-stack-instructions]]))
|
|
||||||
|
|
||||||
#_(interpreter/interpret-program
|
#_(interpreter/interpret-program
|
||||||
'(1 2 :integer_add) state/empty-state 1000)
|
'(1 2 :integer_add) state/empty-state 1000)
|
||||||
@ -36,7 +35,7 @@
|
|||||||
; 1000)
|
; 1000)
|
||||||
;
|
;
|
||||||
;#_(genome/plushy->push
|
;#_(genome/plushy->push
|
||||||
; (genome/make-random-plushy (get-stack-instructions #{:float :integer :exec :boolean}) 20))
|
; (genome/make-random-plushy (instructions/get-stack-instructions #{:float :integer :exec :boolean}) 20))
|
||||||
;
|
;
|
||||||
;#_(gp/gp {:instructions propeller.problems.software.number-io/instructions
|
;#_(gp/gp {:instructions propeller.problems.software.number-io/instructions
|
||||||
; :error-function propeller.problems.software.number-io/error-function
|
; :error-function propeller.problems.software.number-io/error-function
|
||||||
|
Loading…
x
Reference in New Issue
Block a user