diff --git a/.gitignore b/.gitignore index e92cbffe5..17c7ebaf5 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,4 @@ lib/ /bin *.csv *.json +.lein-failures diff --git a/development.md b/development.md deleted file mode 100644 index 15cd4d28c..000000000 --- a/development.md +++ /dev/null @@ -1,4 +0,0 @@ -# Clojush development ideas - -- Optimize using type hints and other approaches frequently discussed on clojure@googlegroups.com. - diff --git a/project.clj b/project.clj index ec5cdd8ec..93f4339e6 100644 --- a/project.clj +++ b/project.clj @@ -14,6 +14,7 @@ [org.clojure/data.json "0.1.3"] [clj-random "0.1.7"]] :dev-dependencies [[lein-ccw "1.2.0"]] + :profiles {:dev {:dependencies [[midje "1.6.3"]]}} ;;;;;;;;;; jvm settings for high performance, using most of the machine's RAM ; :jvm-opts ~(let [mem-to-use ; (long (* (.getTotalPhysicalMemorySize diff --git a/research.md b/research.md deleted file mode 100644 index 66b18e3ff..000000000 --- a/research.md +++ /dev/null @@ -1,4 +0,0 @@ -# Clojush research ideas - -- Analysis of parenthesis usage and modularity in pushgp runs. - diff --git a/src/clojush/problems/tozier/the_idea_of_numbers.clj b/src/clojush/problems/tozier/the_idea_of_numbers.clj new file mode 100644 index 000000000..d25e67fd5 --- /dev/null +++ b/src/clojush/problems/tozier/the_idea_of_numbers.clj @@ -0,0 +1,60 @@ +;; the_idea_of_numbers.clj +;; Bill Tozier, bill@vagueinnovation.com +;; +;; This implements a common pedagogic demonstration from classes I +;; teach in GP. The objective is a simple symbolic regression problem +;; except there are no numeric ERCs. +;; +;; Input and output are given as integers using the integer stack. + +(ns clojush.problems.tozier.the-idea-of-numbers + (:use clojush.pushgp.pushgp + [clojush pushstate interpreter random util] + [clojure.math.numeric-tower] + )) + + +(defn birthday-polynomial + "Returns a polynomial y = YYYY + MM * x * DD * x * x" + [x year month day] + (+ year (* month x) (* day x x)) + ) + + +(defn missing-numbers-error-function + "Returns the absolute error." + [number-test-cases] + (fn [program] + (doall + (for [input (range 0 number-test-cases)] + (let [final-state (run-push program + (push-item input :input + (make-push-state))) + result-output (top-item :integer final-state)] + (if (and (number? result-output)) + (abs (- result-output (birthday-polynomial input 1964 9 11))) ;; edit this so it's your birthday + 1000000000) + ))))) + +; Atom generators +(def missing-numbers-atom-generators + (cons 'in1 + (registered-for-stacks [:integer :code :boolean :exec :char :string :float]))) + + + +; Define the argmap +(def argmap + {:error-function (missing-numbers-error-function 20) + :atom-generators missing-numbers-atom-generators + :max-points 500 + :max-genome-size-in-initial-program 300 + :evalpush-limit 1000 + :population-size 1000 + :max-generations 300 + :parent-selection :lexicase + :final-report-simplifications 1000 + :genetic-operator-probabilities { + :alternation 0.5 + :uniform-mutation 0.5} + }) diff --git a/src/clojush/problems/tozier/winkler01.clj b/src/clojush/problems/tozier/winkler01.clj new file mode 100644 index 000000000..a85c6e1a1 --- /dev/null +++ b/src/clojush/problems/tozier/winkler01.clj @@ -0,0 +1,139 @@ +;; winkler01.clj +;; Bill Tozier, bill@vagueinnovation.com +;; +;; This is code for running Tozier's variant on Winkler's Zeros-and-Ones puzzle: +;; For any positive (non-zero) integer input, return a strictly positive integer which +;; when multiplied by the input value produces a result which contains only the +;; digits 0 and 1 (in base 10 notation) +;; +;; Input and output are given as integers using the integer stack. + +(ns clojush.problems.tozier.winkler01 + (:use clojush.pushgp.pushgp + [clojush pushstate interpreter random util] + [clojure.math.numeric-tower] + )) + +; Create the error function +(defn count-digits [num] (count (re-seq #"\d" (str num)))) + + +(defn proportion-not-01 + "Returns the proportion of digits in the argument integer which are not 0 or 1" + [num] + (let [counts (frequencies (re-seq #"\d" (str num)))] + (- 1 + (/ (+ (get counts "0" 0) + (get counts "1" 0)) + (count-digits num))))) + + +(defn kill-trailing-zeros + "Returns an integer with all trailing zeros stripped off" + [num] + (read-string (clojure.string/replace (str num) #"(0+)$" "")) + ) + + +;; "obvious" first attempt at an error function +(defn winkler-error-function-01 + "Returns the proportion of digits in the product of input * output that are not 0 or 1." + [number-test-cases] + (fn [program] + (doall + (for [input (range 1 number-test-cases)] + (let [final-state (run-push program + (push-item input :input + (make-push-state))) + result-output (top-item :integer final-state)] + (when false (println ;; change to true to print every result (which is awful) + (if (and (number? result-output) (pos? result-output)) + (* input result-output) + "N/A"))) + (if (and (number? result-output) (pos? result-output)) + (proportion-not-01 (* input result-output)) + 100) + ))))) + + +;; "obvious" second attempt at an error function; +;; accommodation to trivial strategy of multiplying by 10000000... +(defn winkler-error-function-02 + "Returns the proportion of digits in the product of input * output that are not 0 or 1, after trimming trailing zeros." + [number-test-cases] + (fn [program] + (doall + (for [input (range 1 number-test-cases)] + (let [final-state (run-push program + (push-item input :input + (make-push-state))) + result-output (top-item :integer final-state)] + (when false (println ;; change to true to print every result (which is awful) + (if (and (number? result-output) (pos? result-output)) + (* input result-output) + "N/A"))) + (if (and (number? result-output) (pos? result-output)) + (proportion-not-01 (kill-trailing-zeros (* input result-output))) + 100) + ))))) + + +;; trying to give it some raw materials it might want to use + +(defn prime-factors + "Return a vector of the prime factors of the argument integer; cadged from http://rosettacode.org/wiki/Prime_decomposition#Clojure" + ([num] + (prime-factors num 2 ())) + ([num k acc] + (if (= 1 num) + acc + (if (= 0 (rem num k)) + (recur (quot num k) k (cons k acc)) + (recur num (inc k) acc))))) + + +(defn prime-factors-as-sorted-vector + "Return the argument's prime factors as a sorted vector of integers; if the argument is 0, it returns (0); if the argument is negative, it returns the factors of the positive number with -1 added to the list;" + [num] + (cond + (pos? num) (into [] (sort (prime-factors num))) + (neg? num) (into [] (cons -1 (sort (prime-factors (abs num))))) + :else [0] + )) + + +; Define new instructions +(define-registered + integer_factors + ^{:stack-types [:integer :vector_integer]} + (fn [state] + (if (not (empty? (:integer state))) + (push-item (prime-factors-as-sorted-vector (stack-ref :integer 0 state)) + :vector_integer + (pop-item :integer state)) + state))) + + +; Atom generators +(def winkler-atom-generators + (concat (take 100 (repeat 'in1)) + (take 50 (repeat (fn [] (lrand-int 65536)))) ;Integer ERC [0,65536] + (registered-for-stacks [:integer :code :boolean :exec :vector_integer :char :string :float]))) + + + +; Define the argmap +(def argmap + {:error-function (winkler-error-function-02 44) ;; change the error function to follow along... + :atom-generators winkler-atom-generators + :max-points 1000 + :print-csv-logs true + :csv-columns [:generation :location :parent-uuids :genetic-operators :push-program-size :push-program :total-error :test-case-errors] + :csv-log-filename "log.csv" + :max-genome-size-in-initial-program 500 + :evalpush-limit 1000 + :population-size 1000 + :max-generations 1000 + :parent-selection :lexicase + :final-report-simplifications 1000 + }) diff --git a/src/clojush/pushgp/report.clj b/src/clojush/pushgp/report.clj index a7d5571db..ee23072cc 100644 --- a/src/clojush/pushgp/report.clj +++ b/src/clojush/pushgp/report.clj @@ -246,7 +246,7 @@ print-errors print-history print-cosmos-data print-timings problem-specific-report total-error-method parent-selection print-homology-data max-point-evaluations - print-error-frequencies-by-case normalization + print-error-frequencies-by-case normalization autoconstructive ;; The following are for CSV or JSON logs print-csv-logs print-json-logs csv-log-filename json-log-filename log-fitnesses-for-all-cases json-log-program-strings @@ -353,18 +353,22 @@ (count population)))) (printf "Average percent parens in population: %.3f\n" (/ (apply + (map #(double (/ (count-parens (:program %)) (count-points (:program %)))) sorted)) (count population))) + (println "--- Population Diversity Statistics ---") + (let [genome-frequency-map (frequencies (map :genome population))] + (println "Min copy number of one Plush genome:" (apply min (vals genome-frequency-map))) + (println "Median copy number of one Plush genome:" (nth (sort (vals genome-frequency-map)) (Math/floor (/ (count genome-frequency-map) 2)))) + (println "Max copy number of one Plush genome:" (apply max (vals genome-frequency-map))) + (println "Genome diversity (% unique Plush genomes):\t" (float (/ (count genome-frequency-map) (count population))))) (let [frequency-map (frequencies (map :program population))] - (println "Number of unique programs in population:" (count frequency-map)) - (println "Max copy number of one program:" (apply max (vals frequency-map))) - (println "Min copy number of one program:" (apply min (vals frequency-map))) - (println "Median copy number:" (nth (sort (vals frequency-map)) (Math/floor (/ (count frequency-map) 2))))) - (when (:autoconstructive argmap) - (println "Number of random replacements for reproductively incompetent individuals:" - (count (filter :random-replacement-for-reproductively-incompetent-genome population)))) + (println "Min copy number of one Push program:" (apply min (vals frequency-map))) + (println "Median copy number of one Push program:" (nth (sort (vals frequency-map)) (Math/floor (/ (count frequency-map) 2)))) + (println "Max copy number of one Push program:" (apply max (vals frequency-map))) + (println "Syntactic diversity (% unique Push programs):\t" (float (/ (count frequency-map) (count population))))) + (println "Total error diversity:\t\t\t\t" (float (/ (count (frequencies (map :total-error population))) (count population)))) + (println "Error (vector) diversity:\t\t\t" (float (/ (count (frequencies (map :errors population))) (count population)))) (when @global-print-behavioral-diversity (swap! population-behaviors #(take-last population-size %)) ; Only use behaviors during evaluation, not those during simplification - (println "Behavioral diversity:" (behavioral-diversity)) - ;(println "Number of behaviors:" (count @population-behaviors)) + (println "Behavioral diversity:\t\t\t\t" (behavioral-diversity)) (reset! population-behaviors ())) (when print-homology-data (let [num-samples 1000 @@ -378,6 +382,10 @@ (println "Median: " median-1) (println "Third quartile: " third-quart-1) )) + (when autoconstructive + (println "Number of random replacements for reproductively incompetent individuals:" + (count (filter :random-replacement-for-reproductively-incompetent-genome population)))) + (println "--- Run Statistics ---") (println "Number of program evaluations used so far:" @evaluations-count) (println "Number of point (instruction) evaluations so far:" point-evaluations-before-report) (reset! point-evaluations-count point-evaluations-before-report) diff --git a/src/clojush/pushstate.clj b/src/clojush/pushstate.clj index b5b14424c..eb36b01d7 100644 --- a/src/clojush/pushstate.clj +++ b/src/clojush/pushstate.clj @@ -138,3 +138,11 @@ (and (:stack-types (meta instr-fn)) (clojure.set/subset? (set (:stack-types (meta instr-fn))) (set types-list)))) @instruction-table))) + + +(defn push-state-from-stacks + "Takes a map of stack names and entire stack states, and returns a new push-state + with those stacks set." + [& {:as stack-assignments}] + (merge (make-push-state) stack-assignments) + ) diff --git a/test/clojush/midje/interpreter/literal_handling.clj b/test/clojush/midje/interpreter/literal_handling.clj new file mode 100644 index 000000000..c610b4000 --- /dev/null +++ b/test/clojush/midje/interpreter/literal_handling.clj @@ -0,0 +1,21 @@ +; To run these tests with autotest use: +; +; lein midje :autotest test +; +; This runs everything in the test sub-directory but +; _doesn't_ run all the stuff in src, which midje tries +; to run by default, which breaks the world. + +(ns clojush.midje.interpreter.literal-handling + (:use clojure.test + midje.sweet + clojush.interpreter + clojush.pushstate)) + +(fact "Evaluating a null instruction returns the same state" + (execute-instruction nil :test-state) => :test-state) + +(fact "Evaluating an integer constant as an instruction adds that value to the integer stack" + (let [test-state (make-push-state) + value 8] + (:integer (execute-instruction value (make-push-state))) => (list value))) diff --git a/test/clojush/midje/problems/tozier/the_idea_of_numbers.clj b/test/clojush/midje/problems/tozier/the_idea_of_numbers.clj new file mode 100644 index 000000000..05c1f764e --- /dev/null +++ b/test/clojush/midje/problems/tozier/the_idea_of_numbers.clj @@ -0,0 +1,46 @@ +; To run these tests with autotest use: +; +; lein midje :autotest test +; +; This runs everything in the test sub-directory but +; _doesn't_ run all the stuff in src, which midje tries +; to run by default, which breaks the world. + +(ns clojush.midje.problems.tozier.the-idea-of-numbers + (:use clojure.test + clojush.pushstate + clojush.interpreter + midje.sweet + clojush.problems.tozier.the-idea-of-numbers)) + +(facts "birthday-polynomial works as expected" + (birthday-polynomial 0 0 0 0) => 0 + (birthday-polynomial 1 1 1 1) => 3 ;; 1 + 1*1 + 1*1*1 + (birthday-polynomial 2 3 4 5) => 31 ;; 3 + 4*2 + 5*2*2 + (birthday-polynomial 0 1988 9 12) => 1988 + ) + +;; checking error function +;; + +(fact "missing-numbers-error-function responds with the number of cases indicated by the argument" + (count ((missing-numbers-error-function 5) '())) => 5 ;; (tests on 0,1,2,3,4) + ) + +(fact "missing-numbers-error-function produces the expected penalties when no answer is returned" + ((missing-numbers-error-function 2) '()) => (just 1000000000 1000000000) ;; empty program + ) + +(fact "missing-numbers-error-function produces the expected scores" + ((missing-numbers-error-function 3) '(0)) => (just 1964 1984 2026) ;; 1964+0; 1964+9+11; 1964+18+36 + ((missing-numbers-error-function 3) '(1000)) => (just 964 984 1026) ;; 1000 closer! + ((missing-numbers-error-function 3) + '(1964 9 in1 integer_mult 11 in1 in1 integer_mult integer_mult integer_add integer_add)) => (just 0 0 0) ;; the right answer + ) + +;; check atom-generators +(fact "atom-generators have no numbers" + missing-numbers-atom-generators => (has not-any? integer?)) + +(fact "atom-generators does include the input (always good to check)" + missing-numbers-atom-generators => (contains ['in1])) \ No newline at end of file diff --git a/test/clojush/midje/problems/tozier/winkler01.clj b/test/clojush/midje/problems/tozier/winkler01.clj new file mode 100644 index 000000000..a5e5160bb --- /dev/null +++ b/test/clojush/midje/problems/tozier/winkler01.clj @@ -0,0 +1,133 @@ +; To run these tests with autotest use: +; +; lein midje :autotest test +; +; This runs everything in the test sub-directory but +; _doesn't_ run all the stuff in src, which midje tries +; to run by default, which breaks the world. + +(ns clojush.midje.problems.tozier.winkler01 + (:use clojure.test + clojush.pushstate + clojush.interpreter + midje.sweet + clojush.problems.tozier.winkler01)) + +;; check count-digits +;; + +(facts "count-digits returns the number of digits in a number" + (count-digits 999) => 3 + (count-digits -123456789) => 9 + (count-digits -1.23) => 3 ;; you really shouldn't do this + (count-digits "foo") => 0) ;; or this + +;; check proportion-not-01 +;; + +(facts "proportion-not-01 returns the fraction of (all) digits not 0 or 1 in a number" + (proportion-not-01 999) => 1 + (proportion-not-01 111234) => 1/2 + (proportion-not-01 1001221330) => 4/10 + (proportion-not-01 1100110011) => 0 + (proportion-not-01 -1.23) => 2/3 + (proportion-not-01 "foo") => (throws Exception #"Divide by zero")) + +;; check kill-trailing-zeros +(facts "kill-trailing-zeros returns an integer with all trailing zeros trimmed off" + (kill-trailing-zeros 999) => 999 + (kill-trailing-zeros 110000) => 11 + (kill-trailing-zeros 100020003000) => 100020003 + (kill-trailing-zeros 1.23000) => 1.23) ;; yes, the interpreter already does this + + +(facts "prime-factors returns a cons containing the prime factors of the argument" + (type (prime-factors 2)) => clojure.lang.Cons + (prime-factors 7) => [7] + (prime-factors 256) => [2 2 2 2 2 2 2 2] + (sort (prime-factors 1000)) => [2 2 2 5 5 5] + (sort (prime-factors 11010011011100010)) => [2 3 3 5 7 13 199 1511 4470811] + ) + +(facts "prime-factors-as-sorted-vector should return the factors as a sorted vector" + (type (prime-factors-as-sorted-vector 2)) => clojure.lang.PersistentVector + (prime-factors-as-sorted-vector 1000) => [2 2 2 5 5 5] + (prime-factors-as-sorted-vector 11010011011100010) => [2 3 3 5 7 13 199 1511 4470811] +) + +(facts "prime-factors-as-sorted-vector returns 'reasonable' results for bad integer inputs" + (prime-factors-as-sorted-vector -2) => [-1 2] + (prime-factors-as-sorted-vector -21) => [-1 3 7] + (prime-factors-as-sorted-vector 0 ) => [0] + (prime-factors-as-sorted-vector -11010011011100010) => [-1 2 3 3 5 7 13 199 1511 4470811] + ) + +;; checking the instruction integer_factors +;; + +(fact "checking the new instruction is registered" + (registered-for-stacks [:integer :vector_integer]) => (contains 'integer_factors)) + +;; some convenience functions +;; + +(defn state-with-an-int [my-int] (push-item my-int :integer (make-push-state))) +(defn run-in-int-sandbox [program my-int] (run-push program (state-with-an-int my-int))) + +(fact + "integer_factors returns a vector_integer" + (vector? (first (:vector_integer (run-in-int-sandbox '(integer_factors) 7)))) => truthy +) + +(facts + "integer_factors returns a vector_integer containing the result of prime-factors-as-sorted-vector" + (first (:vector_integer (run-in-int-sandbox '(integer_factors) 7))) => (prime-factors-as-sorted-vector 7) + (first (:vector_integer (run-in-int-sandbox '(integer_factors) 88))) => (prime-factors-as-sorted-vector 88) + (first (:vector_integer (run-in-int-sandbox '(integer_factors) 0))) => (prime-factors-as-sorted-vector 0) + (first (:vector_integer (run-in-int-sandbox '(integer_factors) -1024))) => + (prime-factors-as-sorted-vector -1024) +) + + +;; checking winkler-error-function-01 +;; + +(fact "winkler-error-function-01 responds with the number of cases indicated by the argument" + (count ((winkler-error-function-01 5) '())) => 4 ;; (tests on 1,2,3,4) + ) + +(facts "winkler-error-function-01 counts 1s and 0s in the product of output * top integer" + ((winkler-error-function-01 12) '(1)) => [0 1 1 1 1 1 1 1 1 0 0] ;; 1, 10, and 11 + ((winkler-error-function-01 12) '(1000)) => [0 1/4 1/4 1/4 1/4 1/4 1/4 1/4 1/4 0 0] ;; 1000, 10000, 11000 + ) + +(fact "winkler-error-function-01 returns a score of 100 as a penalty for not answering" + ((winkler-error-function-01 5) '(integer_pop)) => [100 100 100 100] ;; no answer given + ) + +(fact "winkler-error-function-01 returns does not leave input 'hint' on :integer stack" + ((winkler-error-function-01 5) '()) => [100 100 100 100] ;; should not have answers from :integer stack + ) + + +;; checking winkler-error-function-02 +;; + +(fact "winkler-error-function-02 responds with the number of cases indicated by the argument" + (count ((winkler-error-function-02 5) '())) => 4 ;; (tests on 1,2,3,4) + ) + +(facts "winkler-error-function-02 counts 1s and 0s in the product of output * top integer" + ((winkler-error-function-02 12) '(1)) => [0 1 1 1 1 1 1 1 1 0 0] ;; 1, 10, and 11 + ((winkler-error-function-02 12) '(1000)) => [0 1 1 1 1 1 1 1 1 0 0 ] ;; 1000, 10000, 11000 + ) + +(fact "winkler-error-function-02 returns a score of 100 as a penalty for not answering" + ((winkler-error-function-02 5) '(integer_pop)) => [100 100 100 100] ;; no answer given + ) + +(fact "winkler-error-function-02 returns does not leave input 'hint' on :integer stack" + ((winkler-error-function-02 5) '()) => [100 100 100 100] ;; should not have answers from :integer stack + ) + +(println (count (registered-for-stacks [:integer :boolean :string :char :exec :print]))) \ No newline at end of file diff --git a/test/clojush/midje/pushstate/convenience_functions.clj b/test/clojush/midje/pushstate/convenience_functions.clj new file mode 100644 index 000000000..57578f79b --- /dev/null +++ b/test/clojush/midje/pushstate/convenience_functions.clj @@ -0,0 +1,63 @@ +; To run these tests with autotest use: +; +; lein midje :autotest test +; +; This runs everything in the test sub-directory but +; _doesn't_ run all the stuff in src, which midje tries +; to run by default, which breaks the world. + +(ns clojush.midje.pushstate.convenience-functions + (:use clojush.pushgp.pushgp + [clojush pushstate interpreter random util] + clojure.test + midje.sweet + )) + +(fact "push-state-from-stacks creates a push-state with all available stacks" + (keys (push-state-from-stacks)) => (just clojush.globals/push-types :in-any-order) + ) + +(fact "push-state-from-stacks creates a empty stacks if none are passed in" + (concat (vals (push-state-from-stacks))) => (has every? nil?) + ) + +(facts "push-state-from-stacks sets a named stack to the values passed in as arguments" + (:integer (push-state-from-stacks :integer '(1 2 3))) => (just 1 2 3) + (:boolean (push-state-from-stacks :boolean '(false true))) => (just false true ) + (:code (push-state-from-stacks :code '( 122 false integer_add))) => (contains #{ 122 false 'integer_add}) + (:vector_integer (push-state-from-stacks :vector_integer '([1 2 3] [4 5 6]))) => + (just [1 2 3] [4 5 6]) + ) + + +(facts "the unspecified stacks are still empty" + (:foo (push-state-from-stacks :foo '(:some :webgl :commands :here))) => (just :some :webgl :commands :here) + (:integer (push-state-from-stacks :foo '(:some :webgl :commands :here))) => nil + ) + +(def big-state (push-state-from-stacks :integer '(1 2) :boolean '(false) :char '(\f \w \i \w) :rational '(3/4 111/9))) + +(facts "push-state-from-stacks works for multiple stacks" + (:integer big-state) => (just 1 2) + (:boolean big-state) => (just false) + (:char big-state) => (just \f \w \i \w) + (:rational big-state) => (just 3/4 111/9)) + +(fact "passing in weird keys just drops them into the pushstate" + (:foo (push-state-from-stacks :foo '(:a :b :c))) => (just :a :b :c) ;; a victimless crime? + ) + +(fact "the result of push-state-from-stacks can be used to run code and stuff" + (:integer (run-push '(integer_add integer_add) (push-state-from-stacks :integer '(1 2 3 4)))) => (just 6 4) + ) + + +;; if I want to merge whole new stacks into a pre-existing push-state, +;; I just want to make sure there is a simple way of doing that... + +(def test-state (push-state-from-stacks :integer '(1 2))) + +(fact "I don't need to write a special merge-push-state to overwrite the stack in a push-state" + (:integer (merge test-state {:integer '(7 7 7)})) => (just 7 7 7) + ) + diff --git a/test/clojush/test/clojush_tests.clj b/test/clojush/test/clojush_tests.clj index 20f7e6343..6008a1dfb 100644 --- a/test/clojush/test/clojush_tests.clj +++ b/test/clojush/test/clojush_tests.clj @@ -1,562 +1,562 @@ -;; This is a file of commented-out informal tests (without outputs...) -;; of functions in coljush.clj. +;; ;; This is a file of commented-out informal tests (without outputs...) +;; ;; of functions in coljush.clj. -(ns clojush.test.clojush_tests - (:use [clojush.clojush] - [clojush.globals] - [clojush.random] - [clojush.util] - [clojush.pushstate])) - -;(in-ns 'clojush) - -;(println (random-element '(a b c d e))) -;(println (shuffle '(a b c d e))) -;(println (decompose 20 6)) -;(println (shuffle (decompose 20 6))) -;(println (random-code-with-size 20 '(1 2 3))) -;(println (random-code-with-size 20 (list 3.14 'squid))) -;(println (random-code-with-size 20 (list 3.14 'squid (fn [] (rand-int 100))))) -;(println (random-code 100 (list 3.14 'squid (fn [] (rand-int 100))))) - -#_(time (def p - (for [i (range 1000)] - (random-code 100 (list 'a 1))))) - -;(time (reduce + (map count (map ensure-list p)))) - -;(println (count-points '((this) program (contains (9 points))))) - -;(time (println (reduce + (map count-points p)))) - -#_(time (reduce + (for [i (range 100)] - (let [lst (for [j (range 1000)] j)] - (first (shuffle lst)))))) - -;(println (keep-number-reasonable 10E100)) -;(println (keep-number-reasonable -312987231987329187329187321987231987)) -;(println (count-points '((this) program (contains (9 points))))) - -;(dotimes [i 10] (println (code-at-point '(a (b c) d) i))) -;(println '---) -;(dotimes [i 10] (println (insert-code-at-point '(a (b c) d) i 'x))) -;(println '---) -;(dotimes [i 10] (println (remove-code-at-point '(a (b c) d) i))) -;(println '---) -;(dotimes [i 10] (println (remove-code-at-point '(a (b c (e)) d) i))) -;(println '---) -;(dotimes [i 10] (println (remove-code-at-point '(a (b c (e f)) d) i))) - -;(println (make-push-state)) - -;(register-instruction 'foo) -;(register-instruction 'bar) -;(println registered-instructions) - -;(println (macroexpand-1 '(define-registered schmoo (fn [] (println 'hello))))) - -;(define-registered schmoo (fn [] (println 'hello))) - -;(println registered-instructions) -;(println instruction-table) -;(schmoo) - -;(println (get-stack :integer (make-push-state))) - -;(println (state-pretty-print (make-push-state))) - -;(get-stack 'integer (make-schush-state)) - -#_(let [s (make-push-state)] - (println (push-item 'froggy :code s))) - -;(println (top-item :code (push-item 'froggy :code (make-push-state)))) - -;(println (top-item :integer (make-push-state))) - -#_(println (stack-ref :integer - 1 - (push-item 2 - :integer - (push-item 1 - :integer - (push-item 0 - :integer - (make-push-state)))))) - -#_(loop [n 0 - state (make-push-state)] - (if (> n 4) - (do (println state) - (println (pop-item :integer state))) - (recur (inc n) - (push-item n :integer state)))) - -;(define-registered integer.schmoo (fn [] 0)) -;(define-registered float.schmoo (fn [] 0)) -;(println (registered-for-type :integer)) - -;(println ((popper :integer) (push-item 2 :integer (push-item 3 :integer (make-push-state))))) - -;(println (->> (make-push-state) (push-item 23 :integer) (push-item 100 :integer) (integer_pop))) - -;(println (->> (make-push-state) (push-item 23 :integer) (integer_dup))) - -;(println (->> (make-push-state) (push-item 1 :integer) (push-item 2 :integer))) -;(println (->> (make-push-state) (push-item 1 :integer) (push-item 2 :integer) (integer_swap))) -;(println (->> (make-push-state) (push-item 1 :integer) (integer_swap))) - -#_(println (->> (make-push-state) - (push-item 'a :code) - (push-item 'b :code) - (push-item 'c :code) - (code_rot))) - -#_(println (->> (make-push-state) - (push-item 'a :code) - (push-item 'b :code) - (push-item 'c :code) - (code_flush))) - -#_(println (->> (make-push-state) - (push-item 'a :code) - (push-item 'b :code) - (code_eq))) - -#_(println (->> (make-push-state) - (push-item 'a :code) - (push-item 'a :code) - (code_eq))) - -#_(println (->> (make-push-state) - (push-item 'a :code) - (code_eq))) - -#_(println (->> (make-push-state) - (push-item 'a :code) - (push-item 'b :code) - (code_stackdepth))) - -#_(println (->> (make-push-state) - (push-item 'a :code) - (push-item 'b :code) - (push-item 'c :code) - (push-item 'd :code) - (push-item 2 :integer) - (code_yank))) - -#_(println (->> (make-push-state) - (push-item 101 :integer) - (push-item 102 :integer) - (push-item 103 :integer) - (push-item 104 :integer) - (push-item 2 :integer) - (integer_yank))) - -#_(println (->> (make-push-state) - (push-item 'a :code) - (push-item 'b :code) - (push-item 'c :code) - (push-item 'd :code) - (push-item 2 :integer) - (code_yankdup))) - -#_(println (->> (make-push-state) - (push-item 101 :integer) - (push-item 102 :integer) - (push-item 103 :integer) - (push-item 104 :integer) - (push-item 2 :integer) - (integer_yankdup))) - -;(println (run-push '(1 2 integer_dup) (make-push-state) true)) - -;(println (run-push '(1 2 integer_add) (make-push-state))) -;(println (run-push '(1 integer_add) (make-push-state))) - -;(println (run-push '(100 1 integer_sub) (make-push-state))) - -;(println (run-push '(10.0 5.0 float_mult) (make-push-state))) - -;(println (run-push '(10.0 6.0 float_div) (make-push-state))) -;(println (run-push '(-10.0 6.0 float_div) (make-push-state))) -;(println (run-push '(10 6 integer_div) (make-push-state))) -;(println (run-push '(-10 6 integer_div) (make-push-state))) -;(println (run-push '(10.0 0.0 float_div) (make-push-state))) -;(println (run-push '(10 0 integer_div) (make-push-state))) - -;(println (run-push '((10.0 (5.0 float_mult))) (make-push-state))) - -;(println (run-push '(10.0 6.0 float_mod) (make-push-state))) -;(println (run-push '(-10.0 6.0 float_mod) (make-push-state))) -;(println (run-push '(10 6 integer_mod) (make-push-state))) -;(println (run-push '(-10 6 integer_mod) (make-push-state))) -;(println (run-push '(10.0 0.0 float_mod) (make-push-state))) -;(println (run-push '(10 0 integer_mod) (make-push-state))) - -;(println (run-push '(10.0 11.0 float_lt) (make-push-state))) -;(println (run-push '(10.0 1.0 float_lt) (make-push-state))) -;(println (run-push '(10.0 11.0 float_gt) (make-push-state))) -;(println (run-push '(10.0 1.0 float_gt) (make-push-state))) - -;(println (run-push '(false integer_fromboolean) (make-push-state))) -;(println (run-push '(true integer_fromboolean) (make-push-state))) -;(println (run-push '(integer_fromboolean) (make-push-state))) - -;(println (run-push '(false float_fromboolean) (make-push-state))) -;(println (run-push '(true float_fromboolean) (make-push-state))) -;(println (run-push '(float_fromboolean) (make-push-state))) - -;(println (run-push '(3.14 integer_fromfloat) (make-push-state))) -;(println (run-push '(3 float_frominteger) (make-push-state))) - -;(println (run-push '(1 2 integer_min) (make-push-state))) -;(println (run-push '(2 1 integer_min) (make-push-state))) -;(println (run-push '(1.0 2.0 float_min) (make-push-state))) -;(println (run-push '(2.0 1.0 float_min) (make-push-state))) - -;(println (run-push '(1 2 integer_max) (make-push-state))) -;(println (run-push '(2 1 integer_max) (make-push-state))) -;(println (run-push '(1.0 2.0 float_max) (make-push-state))) -;(println (run-push '(2.0 1.0 float_max) (make-push-state))) - -;(println (run-push '(3.141592 float_sin) (make-push-state))) -;(println (run-push '(3.141592 float_cos) (make-push-state))) -;(println (run-push '(3.141592 float_tan) (make-push-state))) - -;(println (run-push '(true false boolean_and) (make-push-state))) -;(println (run-push '(true true boolean_and) (make-push-state))) -;(println (run-push '(true boolean_and) (make-push-state))) -;(println (run-push '(true false boolean_or) (make-push-state))) -;(println (run-push '(false false boolean_or) (make-push-state))) -;(println (run-push '(true boolean_or) (make-push-state))) -;(println (run-push '(true boolean_not) (make-push-state))) - -;(println (run-push '(0.0 boolean_fromfloat) (make-push-state))) -;(println (run-push '(10.0 boolean_fromfloat) (make-push-state))) -;(println (run-push '(0 boolean_frominteger) (make-push-state))) -;(println (run-push '(10 boolean_frominteger) (make-push-state))) - - - -;(dotimes [_ 100] -#_(println (let [c (random-code 100 (concat registered-instructions - (list (fn [] (- (rand 2) 1)) - (fn [] (- (rand-int 20) 10)))))] - (println c) - (run-push c - (make-push-state) - true - ))) -;) - - -;(defn new-pgm -; [] -; (random-code 100 (concat registered-instructions -; (list (fn [] (- (rand 2) 1)) -; (fn [] (- (rand-int 20) 10)))))) -; -;(def population (doall (for [i (range 1000)] (agent ['(), -1])))) -; -;(defn print-incomplete -; [] -; (printf "\nIncomplete: %s\n" (reduce + (map #(if (< (nth % 1) 0) 1 0) -; (map deref population))))) -; -;(time -; (do -; (print-incomplete) -; (dorun (map #(send % (fn [[p f]] [(new-pgm) f])) population)) -; (apply await population) -; (dorun (map #(send % (fn [[p f]] [p (count (:integer (run-push p (make-push-state))))])) population)) -; (apply await population) -; (print-incomplete) -; )) - - -;;;;;;;;;;;; -;; Integer symbolic regression of x^3 - 2x^2 - x (problem 5 from the trivial geography chapter) with -;; minimal integer instructions and an input instruction that uses the auxiliary stack. - - -;(define-registered in (fn [state] (push-item (stack-ref :auxiliary 0 state) :integer state))) -; -;(pushgp { -; :error-function -; (fn [program] -; (doall -; (for [input (range 10)] -; (let [state (run-push program -; (push-item input :auxiliary -; (push-item input :integer -; (make-push-state)))) -; top-int (top-item :integer state)] -; (if (number? top-int) -; (math/abs (- top-int (- (* input input input) (* 2 input input) input))) -; 1000))))) -; :atom-generators (list (fn [] (rand-int 10)) -; 'in -; 'integer_div -; 'integer_mult -; 'integer_add -; 'integer_sub) -; }) - -;;;;;;;;;;;; -;; Integer symbolic regression of factorial, using an input instruction and lots of -;; other instructions. Hard but solvable. - - -;(define-registered in (fn [state] (push-item (stack-ref :auxiliary 0 state) :integer state))) -; -;(defn factorial -; [n] -; ;; Returns the factorial of n. -; (if (< n 2) -; 1 -; (* n (factorial (- n 1))))) -; -;(pushgp {:error-function (fn [program] -; (doall -; (for [input (range 1 6)] -; (let [state (run-push program -; (push-item input :auxiliary -; (push-item input :integer -; (make-push-state)))) -; top-int (top-item :integer state)] -; (if (number? top-int) -; (math/abs (- top-int (factorial input))) -; 1000000000))))) ;; big penalty, since errors can be big -; :atom-generators (concat (registered-for-type :integer) -; (registered-for-type :exec) -; (registered-for-type :boolean) -; (list (fn [] (rand-int 100)) -; 'in)) -; :max-points 100 -; :population-size 10000 -; :reproduction-simplifications 2}) -; -;(let [population (into [] (for [_ (range 1000)] (struct-map individual :program (random-code 100 '(a b c)) -; :total-error (rand-int 100))))] -; (time (dotimes [_ 10000] (select population 7 0 0)))) -; -;(println (->> (make-push-state) -; (push-item 'a :code) -; (push-item 'b :code) -; (push-item 'c :code) -; (push-item 'd :code) -; (push-item 1 :integer) -; (code_shove) -; )) -; -;(println (->> (make-push-state) -; (push-item 'a :code) -; (push-item 'b :code) -; (push-item 'c :code) -; (push-item 'd :code) -; (push-item 3 :integer) -; (code_shove) -; )) -; -;(println (->> (make-push-state) -; (push-item 'a :code) -; (push-item 'b :code) -; (push-item 'c :code) -; (push-item 'd :code) -; (push-item 55 :integer) -; (code_shove) -; )) -; -;(println (->> (make-push-state) -; (push-item 'a :code) -; (push-item 'b :code) -; (push-item 'c :code) -; (push-item 'd :code) -; (push-item -2 :integer) -; (code_shove) -; )) -; -;(println (->> (make-push-state) -; (push-item 101 :integer) -; (push-item 102 :integer) -; (push-item 103 :integer) -; (push-item 0 :integer) -; (integer_shove) -; )) -; -;(println (->> (make-push-state) -; (push-item 101 :integer) -; (push-item 102 :integer) -; (push-item 103 :integer) -; (push-item 1 :integer) -; (integer_shove) -; )) - - -#_(println (->> (make-push-state) - (push-item '(a b c) :code) - (push-item 2 :integer) - (code_extract))) - -#_(println (->> (make-push-state) - (push-item '(a b c) :code) - (push-item '(x y z) :code) - (push-item 2 :integer) - (code_insert))) - -;(println (subst 1 2 '(1 2 3))) -;(println (subst '(a b) '(x y) '(1 2 (x y) (3 4 ((x y))) (x y)))) - - -;(in-ns 'clojush) -;(def top-level-push-code false) -;(def top-level-pop-code false) -;(in-ns 'clojush-tests) - -;(println (run-push '(code_quote (a b) code_quote (x y) code_quote (1 2 (x y) (3 4 ((x y))) (x y)) code_subst) (make-push-state))) - -#_(println (->> (make-push-state) - (push-item '(1 2 3) :code) - (push-item 'b :code) - (push-item '(a b (a b (a b) a b)) :code) - (code_subst))) - -#_(println (contains-subtree '(1 (2 3) 4) 3)) -#_(println (contains-subtree '(1 (2 (3 4)) x) '(3 4))) -#_(println (contains-subtree '(1 (2 (3 4)) x) '(2 3))) - -#_(println (->> (make-push-state) - (push-item '(1 (2 (a b) 3)) :code) - (push-item '(a b) :code) - (code_contains))) - -#_(println (->> (make-push-state) - (push-item '(1 (2 (a b) 3)) :code) - (push-item '(a) :code) - (code_contains))) - -#_(println (containing-subtree '(b (c (a)) (d (a))) '(a)) ) - -#_(println (->> (make-push-state) - (push-item '(a) :code) - (push-item '(b (c (a)) (d (a))) :code) - (code_container))) - -#_(println (->> (make-push-state) - (push-item 'a :code) - (push-item '(x x a x x x a x) :code) - (code_position))) - -#_(println (->> (make-push-state) - (push-item 'b :code) - (push-item '(x x a x x x a x) :code) - (code_position))) - -#_(println (discrepancy '(a b c d) '(a b c d))) -#_(println (discrepancy '(a b c d e) '(a b c d e))) -#_(println (discrepancy '(a b c d e) '(a b c d))) - -#_(println (->> (make-push-state) - (push-item '(a b c) :code) - (push-item '(a b) :code) - (code_discrepancy))) - -#_(println (->> (make-push-state) - (boolean_rand) - (integer_rand) - (float_rand) - (push-item 25 :integer) - (code_rand) - )) - -#_(do (def top-level-push-code false) - (def top-level-pop-code false) - (println (run-push '(code_quote (a b c) code_wrap) - (make-push-state))) - (println (run-push '(code_quote (a b c) code_map (code_dup code_list)) - (make-push-state))) - (println (run-push '(code_quote a code_map (code_dup code_list)) - (make-push-state))) - ) - -;; factorial example from push3 spec, translated into clojush -#_(def top-level-pop-code false) -#_(println (run-push '(code_quote - (integer_pop 1) - code_quote - (code_dup integer_dup 1 integer_sub code_do integer_mult) - integer_dup 2 integer_lt code_if) - (push-item 5 :integer (make-push-state)))) - -;; pathological quasiquine -#_(def top-level-push-code false) ;; don't push code initially, must construct -#_(def top-level-pop-code false) ;; don't pop resulting code -#_(println (run-push '(1 9 code_quote (integer_pop code_pop code_quote) code_do*range) - (make-push-state) - true)) - -;(println (run-push '(1 2 tag_integer_123) (make-push-state))) +;; (ns clojush.test.clojush_tests +;; (:use [clojush.clojush] +;; [clojush.globals] +;; [clojush.random] +;; [clojush.util] +;; [clojush.pushstate])) -;(println (run-push '(1 2 integer_add tag_integer_123 99 tagged_001) (make-push-state))) -;(println (run-push '(1 2 integer_add tag_integer_123 99 tagged_901) (make-push-state))) -;(println (run-push '(1 2 integer_add tag_integer_123 99 tagged_001 untag_222) (make-push-state))) -;(println (run-push '(1 2 integer_add tag_integer_123 99 tagged_001 untag_222 tagged_123) (make-push-state))) -;(println (run-push '(1 2 integer_add tag_integer_123 99 tagged_001 untag_222 tagged_123 integer_add tag_integer_12) (make-push-state))) - -;((tag-instruction-erc [:integer :float] 100)) +;; ;(in-ns 'clojush) -;(let [c '(+ (* 1 2) (/ 3 4))] (code-at-point c (choose-node-index-with-leaf-probability c))) -;(let [c (random-code-with-size 1000 '(1))] (time (dotimes [_ 10] (choose-node-index-with-leaf-probability c)))) -;(do (dotimes [_ 1000] (choose-node-index-with-leaf-probability (random-code 100 '(1)))) :no-failures) - -;(println (run-push '(1 2 integer_add tag_integer_123 99 tagged_code_001 code_dup) (make-push-state))) - -;(println (run-push '(1 2 tag_integer_123) (make-push-state))) +;; ;(println (random-element '(a b c d e))) +;; ;(println (shuffle '(a b c d e))) +;; ;(println (decompose 20 6)) +;; ;(println (shuffle (decompose 20 6))) +;; ;(println (random-code-with-size 20 '(1 2 3))) +;; ;(println (random-code-with-size 20 (list 3.14 'squid))) +;; ;(println (random-code-with-size 20 (list 3.14 'squid (fn [] (rand-int 100))))) +;; ;(println (random-code 100 (list 3.14 'squid (fn [] (rand-int 100))))) -#_(println ((tagged-code-macro-erc 'code_append 1000 2 1))) - -#_{:tagged_code_macro true :instruction 'clojush/code_append - :argument_tags [10 20] :result_tags [30]} - -#_(println (run-push '(tag_exec_15 (1 2 3) tag_exec_25 (4 5 6) - {:tagged_code_macro true :instruction code_append - :argument_tags [10 20] :result_tags [30]}) - (make-push-state))) -#_(println (run-push '(code_quote (1 2 3) code_quote (4 5 6) code_append code_swap) (make-push-state))) - -#_(println (run-push (concat '(tag_exec_0 (1 2 3) tag_exec_500 (4 5 6)) - (list ((tagged-code-macro-erc 'code_append 1000 2 1)))) - (make-push-state))) - -;(println (run-push '(1 (2) ((integer_add))) (make-push-state) false false)) +;; #_(time (def p +;; (for [i (range 1000)] +;; (random-code 100 (list 'a 1))))) -;(println (run-push '(1 (2) ((integer_add))) (make-push-state) false true)) - -;(println (run-push '(1 (2) float_add ((integer_add))) (make-push-state) false true)) +;; ;(time (reduce + (map count (map ensure-list p)))) -;(println (run-push '(1 (2) float_add ((integer_add))) (make-push-state) false :changes)) - -;(println (run-push '(true exec_when 1 2) (make-push-state))) - -;(println (run-push '(false exec_when 1 2) (make-push-state))) - -;(println (run-push '(1 2 3 tag_integer_123 4 5 6 true tagged_when_123) (make-push-state))) +;; ;(println (count-points '((this) program (contains (9 points))))) -;(println (run-push '(1 2 3 tag_integer_123 4 5 6 false tagged_when_123) (make-push-state))) - -(time (dotimes [i 1000] - (run-push '(123 245 integer_swap integer_swap integer_mult integer_dup integer_div) - (make-push-state)))) - -(time (dotimes [i 1000] - (run-push '(123 245 tag_integer_123 tagged_123 integer_mult integer_dup integer_div) - (make-push-state)))) +;; ;(time (println (reduce + (map count-points p)))) -(time (dotimes [i 1000] - (run-push '(123 245 integer_swap integer_swap) - (make-push-state)))) +;; #_(time (reduce + (for [i (range 100)] +;; (let [lst (for [j (range 1000)] j)] +;; (first (shuffle lst)))))) -(time (dotimes [i 1000] - (run-push '(123 245 tag_integer_123 tagged_123) - (make-push-state)))) +;; ;(println (keep-number-reasonable 10E100)) +;; ;(println (keep-number-reasonable -312987231987329187329187321987231987)) +;; ;(println (count-points '((this) program (contains (9 points))))) + +;; ;(dotimes [i 10] (println (code-at-point '(a (b c) d) i))) +;; ;(println '---) +;; ;(dotimes [i 10] (println (insert-code-at-point '(a (b c) d) i 'x))) +;; ;(println '---) +;; ;(dotimes [i 10] (println (remove-code-at-point '(a (b c) d) i))) +;; ;(println '---) +;; ;(dotimes [i 10] (println (remove-code-at-point '(a (b c (e)) d) i))) +;; ;(println '---) +;; ;(dotimes [i 10] (println (remove-code-at-point '(a (b c (e f)) d) i))) + +;; ;(println (make-push-state)) + +;; ;(register-instruction 'foo) +;; ;(register-instruction 'bar) +;; ;(println registered-instructions) + +;; ;(println (macroexpand-1 '(define-registered schmoo (fn [] (println 'hello))))) + +;; ;(define-registered schmoo (fn [] (println 'hello))) + +;; ;(println registered-instructions) +;; ;(println instruction-table) +;; ;(schmoo) + +;; ;(println (get-stack :integer (make-push-state))) + +;; ;(println (state-pretty-print (make-push-state))) + +;; ;(get-stack 'integer (make-schush-state)) + +;; #_(let [s (make-push-state)] +;; (println (push-item 'froggy :code s))) + +;; ;(println (top-item :code (push-item 'froggy :code (make-push-state)))) + +;; ;(println (top-item :integer (make-push-state))) + +;; #_(println (stack-ref :integer +;; 1 +;; (push-item 2 +;; :integer +;; (push-item 1 +;; :integer +;; (push-item 0 +;; :integer +;; (make-push-state)))))) + +;; #_(loop [n 0 +;; state (make-push-state)] +;; (if (> n 4) +;; (do (println state) +;; (println (pop-item :integer state))) +;; (recur (inc n) +;; (push-item n :integer state)))) + +;; ;(define-registered integer.schmoo (fn [] 0)) +;; ;(define-registered float.schmoo (fn [] 0)) +;; ;(println (registered-for-type :integer)) + +;; ;(println ((popper :integer) (push-item 2 :integer (push-item 3 :integer (make-push-state))))) + +;; ;(println (->> (make-push-state) (push-item 23 :integer) (push-item 100 :integer) (integer_pop))) + +;; ;(println (->> (make-push-state) (push-item 23 :integer) (integer_dup))) + +;; ;(println (->> (make-push-state) (push-item 1 :integer) (push-item 2 :integer))) +;; ;(println (->> (make-push-state) (push-item 1 :integer) (push-item 2 :integer) (integer_swap))) +;; ;(println (->> (make-push-state) (push-item 1 :integer) (integer_swap))) + +;; #_(println (->> (make-push-state) +;; (push-item 'a :code) +;; (push-item 'b :code) +;; (push-item 'c :code) +;; (code_rot))) + +;; #_(println (->> (make-push-state) +;; (push-item 'a :code) +;; (push-item 'b :code) +;; (push-item 'c :code) +;; (code_flush))) + +;; #_(println (->> (make-push-state) +;; (push-item 'a :code) +;; (push-item 'b :code) +;; (code_eq))) + +;; #_(println (->> (make-push-state) +;; (push-item 'a :code) +;; (push-item 'a :code) +;; (code_eq))) + +;; #_(println (->> (make-push-state) +;; (push-item 'a :code) +;; (code_eq))) + +;; #_(println (->> (make-push-state) +;; (push-item 'a :code) +;; (push-item 'b :code) +;; (code_stackdepth))) + +;; #_(println (->> (make-push-state) +;; (push-item 'a :code) +;; (push-item 'b :code) +;; (push-item 'c :code) +;; (push-item 'd :code) +;; (push-item 2 :integer) +;; (code_yank))) + +;; #_(println (->> (make-push-state) +;; (push-item 101 :integer) +;; (push-item 102 :integer) +;; (push-item 103 :integer) +;; (push-item 104 :integer) +;; (push-item 2 :integer) +;; (integer_yank))) + +;; #_(println (->> (make-push-state) +;; (push-item 'a :code) +;; (push-item 'b :code) +;; (push-item 'c :code) +;; (push-item 'd :code) +;; (push-item 2 :integer) +;; (code_yankdup))) + +;; #_(println (->> (make-push-state) +;; (push-item 101 :integer) +;; (push-item 102 :integer) +;; (push-item 103 :integer) +;; (push-item 104 :integer) +;; (push-item 2 :integer) +;; (integer_yankdup))) + +;; ;(println (run-push '(1 2 integer_dup) (make-push-state) true)) + +;; ;(println (run-push '(1 2 integer_add) (make-push-state))) +;; ;(println (run-push '(1 integer_add) (make-push-state))) + +;; ;(println (run-push '(100 1 integer_sub) (make-push-state))) + +;; ;(println (run-push '(10.0 5.0 float_mult) (make-push-state))) + +;; ;(println (run-push '(10.0 6.0 float_div) (make-push-state))) +;; ;(println (run-push '(-10.0 6.0 float_div) (make-push-state))) +;; ;(println (run-push '(10 6 integer_div) (make-push-state))) +;; ;(println (run-push '(-10 6 integer_div) (make-push-state))) +;; ;(println (run-push '(10.0 0.0 float_div) (make-push-state))) +;; ;(println (run-push '(10 0 integer_div) (make-push-state))) + +;; ;(println (run-push '((10.0 (5.0 float_mult))) (make-push-state))) + +;; ;(println (run-push '(10.0 6.0 float_mod) (make-push-state))) +;; ;(println (run-push '(-10.0 6.0 float_mod) (make-push-state))) +;; ;(println (run-push '(10 6 integer_mod) (make-push-state))) +;; ;(println (run-push '(-10 6 integer_mod) (make-push-state))) +;; ;(println (run-push '(10.0 0.0 float_mod) (make-push-state))) +;; ;(println (run-push '(10 0 integer_mod) (make-push-state))) + +;; ;(println (run-push '(10.0 11.0 float_lt) (make-push-state))) +;; ;(println (run-push '(10.0 1.0 float_lt) (make-push-state))) +;; ;(println (run-push '(10.0 11.0 float_gt) (make-push-state))) +;; ;(println (run-push '(10.0 1.0 float_gt) (make-push-state))) + +;; ;(println (run-push '(false integer_fromboolean) (make-push-state))) +;; ;(println (run-push '(true integer_fromboolean) (make-push-state))) +;; ;(println (run-push '(integer_fromboolean) (make-push-state))) + +;; ;(println (run-push '(false float_fromboolean) (make-push-state))) +;; ;(println (run-push '(true float_fromboolean) (make-push-state))) +;; ;(println (run-push '(float_fromboolean) (make-push-state))) + +;; ;(println (run-push '(3.14 integer_fromfloat) (make-push-state))) +;; ;(println (run-push '(3 float_frominteger) (make-push-state))) + +;; ;(println (run-push '(1 2 integer_min) (make-push-state))) +;; ;(println (run-push '(2 1 integer_min) (make-push-state))) +;; ;(println (run-push '(1.0 2.0 float_min) (make-push-state))) +;; ;(println (run-push '(2.0 1.0 float_min) (make-push-state))) + +;; ;(println (run-push '(1 2 integer_max) (make-push-state))) +;; ;(println (run-push '(2 1 integer_max) (make-push-state))) +;; ;(println (run-push '(1.0 2.0 float_max) (make-push-state))) +;; ;(println (run-push '(2.0 1.0 float_max) (make-push-state))) + +;; ;(println (run-push '(3.141592 float_sin) (make-push-state))) +;; ;(println (run-push '(3.141592 float_cos) (make-push-state))) +;; ;(println (run-push '(3.141592 float_tan) (make-push-state))) + +;; ;(println (run-push '(true false boolean_and) (make-push-state))) +;; ;(println (run-push '(true true boolean_and) (make-push-state))) +;; ;(println (run-push '(true boolean_and) (make-push-state))) +;; ;(println (run-push '(true false boolean_or) (make-push-state))) +;; ;(println (run-push '(false false boolean_or) (make-push-state))) +;; ;(println (run-push '(true boolean_or) (make-push-state))) +;; ;(println (run-push '(true boolean_not) (make-push-state))) + +;; ;(println (run-push '(0.0 boolean_fromfloat) (make-push-state))) +;; ;(println (run-push '(10.0 boolean_fromfloat) (make-push-state))) +;; ;(println (run-push '(0 boolean_frominteger) (make-push-state))) +;; ;(println (run-push '(10 boolean_frominteger) (make-push-state))) + + + +;; ;(dotimes [_ 100] +;; #_(println (let [c (random-code 100 (concat registered-instructions +;; (list (fn [] (- (rand 2) 1)) +;; (fn [] (- (rand-int 20) 10)))))] +;; (println c) +;; (run-push c +;; (make-push-state) +;; true +;; ))) +;; ;) + + +;; ;(defn new-pgm +;; ; [] +;; ; (random-code 100 (concat registered-instructions +;; ; (list (fn [] (- (rand 2) 1)) +;; ; (fn [] (- (rand-int 20) 10)))))) +;; ; +;; ;(def population (doall (for [i (range 1000)] (agent ['(), -1])))) +;; ; +;; ;(defn print-incomplete +;; ; [] +;; ; (printf "\nIncomplete: %s\n" (reduce + (map #(if (< (nth % 1) 0) 1 0) +;; ; (map deref population))))) +;; ; +;; ;(time +;; ; (do +;; ; (print-incomplete) +;; ; (dorun (map #(send % (fn [[p f]] [(new-pgm) f])) population)) +;; ; (apply await population) +;; ; (dorun (map #(send % (fn [[p f]] [p (count (:integer (run-push p (make-push-state))))])) population)) +;; ; (apply await population) +;; ; (print-incomplete) +;; ; )) + + +;; ;;;;;;;;;;;; +;; ;; Integer symbolic regression of x^3 - 2x^2 - x (problem 5 from the trivial geography chapter) with +;; ;; minimal integer instructions and an input instruction that uses the auxiliary stack. + + +;; ;(define-registered in (fn [state] (push-item (stack-ref :auxiliary 0 state) :integer state))) +;; ; +;; ;(pushgp { +;; ; :error-function +;; ; (fn [program] +;; ; (doall +;; ; (for [input (range 10)] +;; ; (let [state (run-push program +;; ; (push-item input :auxiliary +;; ; (push-item input :integer +;; ; (make-push-state)))) +;; ; top-int (top-item :integer state)] +;; ; (if (number? top-int) +;; ; (math/abs (- top-int (- (* input input input) (* 2 input input) input))) +;; ; 1000))))) +;; ; :atom-generators (list (fn [] (rand-int 10)) +;; ; 'in +;; ; 'integer_div +;; ; 'integer_mult +;; ; 'integer_add +;; ; 'integer_sub) +;; ; }) + +;; ;;;;;;;;;;;; +;; ;; Integer symbolic regression of factorial, using an input instruction and lots of +;; ;; other instructions. Hard but solvable. + + +;; ;(define-registered in (fn [state] (push-item (stack-ref :auxiliary 0 state) :integer state))) +;; ; +;; ;(defn factorial +;; ; [n] +;; ; ;; Returns the factorial of n. +;; ; (if (< n 2) +;; ; 1 +;; ; (* n (factorial (- n 1))))) +;; ; +;; ;(pushgp {:error-function (fn [program] +;; ; (doall +;; ; (for [input (range 1 6)] +;; ; (let [state (run-push program +;; ; (push-item input :auxiliary +;; ; (push-item input :integer +;; ; (make-push-state)))) +;; ; top-int (top-item :integer state)] +;; ; (if (number? top-int) +;; ; (math/abs (- top-int (factorial input))) +;; ; 1000000000))))) ;; big penalty, since errors can be big +;; ; :atom-generators (concat (registered-for-type :integer) +;; ; (registered-for-type :exec) +;; ; (registered-for-type :boolean) +;; ; (list (fn [] (rand-int 100)) +;; ; 'in)) +;; ; :max-points 100 +;; ; :population-size 10000 +;; ; :reproduction-simplifications 2}) +;; ; +;; ;(let [population (into [] (for [_ (range 1000)] (struct-map individual :program (random-code 100 '(a b c)) +;; ; :total-error (rand-int 100))))] +;; ; (time (dotimes [_ 10000] (select population 7 0 0)))) +;; ; +;; ;(println (->> (make-push-state) +;; ; (push-item 'a :code) +;; ; (push-item 'b :code) +;; ; (push-item 'c :code) +;; ; (push-item 'd :code) +;; ; (push-item 1 :integer) +;; ; (code_shove) +;; ; )) +;; ; +;; ;(println (->> (make-push-state) +;; ; (push-item 'a :code) +;; ; (push-item 'b :code) +;; ; (push-item 'c :code) +;; ; (push-item 'd :code) +;; ; (push-item 3 :integer) +;; ; (code_shove) +;; ; )) +;; ; +;; ;(println (->> (make-push-state) +;; ; (push-item 'a :code) +;; ; (push-item 'b :code) +;; ; (push-item 'c :code) +;; ; (push-item 'd :code) +;; ; (push-item 55 :integer) +;; ; (code_shove) +;; ; )) +;; ; +;; ;(println (->> (make-push-state) +;; ; (push-item 'a :code) +;; ; (push-item 'b :code) +;; ; (push-item 'c :code) +;; ; (push-item 'd :code) +;; ; (push-item -2 :integer) +;; ; (code_shove) +;; ; )) +;; ; +;; ;(println (->> (make-push-state) +;; ; (push-item 101 :integer) +;; ; (push-item 102 :integer) +;; ; (push-item 103 :integer) +;; ; (push-item 0 :integer) +;; ; (integer_shove) +;; ; )) +;; ; +;; ;(println (->> (make-push-state) +;; ; (push-item 101 :integer) +;; ; (push-item 102 :integer) +;; ; (push-item 103 :integer) +;; ; (push-item 1 :integer) +;; ; (integer_shove) +;; ; )) + + +;; #_(println (->> (make-push-state) +;; (push-item '(a b c) :code) +;; (push-item 2 :integer) +;; (code_extract))) + +;; #_(println (->> (make-push-state) +;; (push-item '(a b c) :code) +;; (push-item '(x y z) :code) +;; (push-item 2 :integer) +;; (code_insert))) + +;; ;(println (subst 1 2 '(1 2 3))) +;; ;(println (subst '(a b) '(x y) '(1 2 (x y) (3 4 ((x y))) (x y)))) + + +;; ;(in-ns 'clojush) +;; ;(def top-level-push-code false) +;; ;(def top-level-pop-code false) +;; ;(in-ns 'clojush-tests) + +;; ;(println (run-push '(code_quote (a b) code_quote (x y) code_quote (1 2 (x y) (3 4 ((x y))) (x y)) code_subst) (make-push-state))) + +;; #_(println (->> (make-push-state) +;; (push-item '(1 2 3) :code) +;; (push-item 'b :code) +;; (push-item '(a b (a b (a b) a b)) :code) +;; (code_subst))) + +;; #_(println (contains-subtree '(1 (2 3) 4) 3)) +;; #_(println (contains-subtree '(1 (2 (3 4)) x) '(3 4))) +;; #_(println (contains-subtree '(1 (2 (3 4)) x) '(2 3))) + +;; #_(println (->> (make-push-state) +;; (push-item '(1 (2 (a b) 3)) :code) +;; (push-item '(a b) :code) +;; (code_contains))) + +;; #_(println (->> (make-push-state) +;; (push-item '(1 (2 (a b) 3)) :code) +;; (push-item '(a) :code) +;; (code_contains))) + +;; #_(println (containing-subtree '(b (c (a)) (d (a))) '(a)) ) + +;; #_(println (->> (make-push-state) +;; (push-item '(a) :code) +;; (push-item '(b (c (a)) (d (a))) :code) +;; (code_container))) + +;; #_(println (->> (make-push-state) +;; (push-item 'a :code) +;; (push-item '(x x a x x x a x) :code) +;; (code_position))) + +;; #_(println (->> (make-push-state) +;; (push-item 'b :code) +;; (push-item '(x x a x x x a x) :code) +;; (code_position))) + +;; #_(println (discrepancy '(a b c d) '(a b c d))) +;; #_(println (discrepancy '(a b c d e) '(a b c d e))) +;; #_(println (discrepancy '(a b c d e) '(a b c d))) + +;; #_(println (->> (make-push-state) +;; (push-item '(a b c) :code) +;; (push-item '(a b) :code) +;; (code_discrepancy))) + +;; #_(println (->> (make-push-state) +;; (boolean_rand) +;; (integer_rand) +;; (float_rand) +;; (push-item 25 :integer) +;; (code_rand) +;; )) + +;; #_(do (def top-level-push-code false) +;; (def top-level-pop-code false) +;; (println (run-push '(code_quote (a b c) code_wrap) +;; (make-push-state))) +;; (println (run-push '(code_quote (a b c) code_map (code_dup code_list)) +;; (make-push-state))) +;; (println (run-push '(code_quote a code_map (code_dup code_list)) +;; (make-push-state))) +;; ) + +;; ;; factorial example from push3 spec, translated into clojush +;; #_(def top-level-pop-code false) +;; #_(println (run-push '(code_quote +;; (integer_pop 1) +;; code_quote +;; (code_dup integer_dup 1 integer_sub code_do integer_mult) +;; integer_dup 2 integer_lt code_if) +;; (push-item 5 :integer (make-push-state)))) + +;; ;; pathological quasiquine +;; #_(def top-level-push-code false) ;; don't push code initially, must construct +;; #_(def top-level-pop-code false) ;; don't pop resulting code +;; #_(println (run-push '(1 9 code_quote (integer_pop code_pop code_quote) code_do*range) +;; (make-push-state) +;; true)) + +;; ;(println (run-push '(1 2 tag_integer_123) (make-push-state))) + +;; ;(println (run-push '(1 2 integer_add tag_integer_123 99 tagged_001) (make-push-state))) +;; ;(println (run-push '(1 2 integer_add tag_integer_123 99 tagged_901) (make-push-state))) +;; ;(println (run-push '(1 2 integer_add tag_integer_123 99 tagged_001 untag_222) (make-push-state))) +;; ;(println (run-push '(1 2 integer_add tag_integer_123 99 tagged_001 untag_222 tagged_123) (make-push-state))) +;; ;(println (run-push '(1 2 integer_add tag_integer_123 99 tagged_001 untag_222 tagged_123 integer_add tag_integer_12) (make-push-state))) + +;; ;((tag-instruction-erc [:integer :float] 100)) + +;; ;(let [c '(+ (* 1 2) (/ 3 4))] (code-at-point c (choose-node-index-with-leaf-probability c))) +;; ;(let [c (random-code-with-size 1000 '(1))] (time (dotimes [_ 10] (choose-node-index-with-leaf-probability c)))) +;; ;(do (dotimes [_ 1000] (choose-node-index-with-leaf-probability (random-code 100 '(1)))) :no-failures) + +;; ;(println (run-push '(1 2 integer_add tag_integer_123 99 tagged_code_001 code_dup) (make-push-state))) + +;; ;(println (run-push '(1 2 tag_integer_123) (make-push-state))) + +;; #_(println ((tagged-code-macro-erc 'code_append 1000 2 1))) + +;; #_{:tagged_code_macro true :instruction 'clojush/code_append +;; :argument_tags [10 20] :result_tags [30]} + +;; #_(println (run-push '(tag_exec_15 (1 2 3) tag_exec_25 (4 5 6) +;; {:tagged_code_macro true :instruction code_append +;; :argument_tags [10 20] :result_tags [30]}) +;; (make-push-state))) +;; #_(println (run-push '(code_quote (1 2 3) code_quote (4 5 6) code_append code_swap) (make-push-state))) + +;; #_(println (run-push (concat '(tag_exec_0 (1 2 3) tag_exec_500 (4 5 6)) +;; (list ((tagged-code-macro-erc 'code_append 1000 2 1)))) +;; (make-push-state))) + +;; ;(println (run-push '(1 (2) ((integer_add))) (make-push-state) false false)) + +;; ;(println (run-push '(1 (2) ((integer_add))) (make-push-state) false true)) + +;; ;(println (run-push '(1 (2) float_add ((integer_add))) (make-push-state) false true)) + +;; ;(println (run-push '(1 (2) float_add ((integer_add))) (make-push-state) false :changes)) + +;; ;(println (run-push '(true exec_when 1 2) (make-push-state))) + +;; ;(println (run-push '(false exec_when 1 2) (make-push-state))) + +;; ;(println (run-push '(1 2 3 tag_integer_123 4 5 6 true tagged_when_123) (make-push-state))) + +;; ;(println (run-push '(1 2 3 tag_integer_123 4 5 6 false tagged_when_123) (make-push-state))) + +;; (time (dotimes [i 1000] +;; (run-push '(123 245 integer_swap integer_swap integer_mult integer_dup integer_div) +;; (make-push-state)))) + +;; (time (dotimes [i 1000] +;; (run-push '(123 245 tag_integer_123 tagged_123 integer_mult integer_dup integer_div) +;; (make-push-state)))) + +;; (time (dotimes [i 1000] +;; (run-push '(123 245 integer_swap integer_swap) +;; (make-push-state)))) + +;; (time (dotimes [i 1000] +;; (run-push '(123 245 tag_integer_123 tagged_123) +;; (make-push-state)))) diff --git a/test/clojush/test/stress_test.clj b/test/clojush/test/stress_test.clj index 081bdb8e2..5e23bf5a4 100644 --- a/test/clojush/test/stress_test.clj +++ b/test/clojush/test/stress_test.clj @@ -1,30 +1,30 @@ -(ns clojush.test.stress_test - (:use [clojush.random] - [clojush.pushstate] - [clojush.interpreter])) +;; (ns clojush.test.stress_test +;; (:use [clojush.random] +;; [clojush.pushstate] +;; [clojush.interpreter])) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; stress test +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; stress test -(defn stress-test - "Performs a stress test of the registered instructions by generating and running n - random programs. For more thorough testing and debugging of Push instructions you many - want to un-comment code in execute-instruction that will allow you to look at recently - executed instructions and the most recent state after an error. That code burns memory, - however, so it is normally commented out. You might also want to comment out the handling - of nil values in execute-instruction, do see if any instructions are introducing nils." - [n] - (let [completely-random-program - (fn [] - (random-code 100 (concat @registered-instructions - (list (fn [] (lrand-int 100)) - (fn [] (lrand))))))] - (loop [i 0 p (completely-random-program)] - (if (>= i n) - (println :no-errors-found-in-stress-test) - (let [result (run-push p (make-push-state) false)] - (if result - (recur (inc i) (completely-random-program)) - (println p))))))) +;; (defn stress-test +;; "Performs a stress test of the registered instructions by generating and running n +;; random programs. For more thorough testing and debugging of Push instructions you many +;; want to un-comment code in execute-instruction that will allow you to look at recently +;; executed instructions and the most recent state after an error. That code burns memory, +;; however, so it is normally commented out. You might also want to comment out the handling +;; of nil values in execute-instruction, do see if any instructions are introducing nils." +;; [n] +;; (let [completely-random-program +;; (fn [] +;; (random-code 100 (concat @registered-instructions +;; (list (fn [] (lrand-int 100)) +;; (fn [] (lrand))))))] +;; (loop [i 0 p (completely-random-program)] +;; (if (>= i n) +;; (println :no-errors-found-in-stress-test) +;; (let [result (run-push p (make-push-state) false)] +;; (if result +;; (recur (inc i) (completely-random-program)) +;; (println p))))))) -;(stress-test 10000) +;; ;(stress-test 10000) diff --git a/test/clojush/test/wiring_test.clj b/test/clojush/test/wiring_test.clj new file mode 100644 index 000000000..5954724c3 --- /dev/null +++ b/test/clojush/test/wiring_test.clj @@ -0,0 +1,19 @@ +; To run these tests with autotest use: +; +; lein midje :autotest test +; +; This runs everything in the test sub-directory but +; _doesn't_ run all the stuff in src, which midje tries +; to run by default, which breaks the world. + +(ns clojush.test.wiring-test + (:use clojure.test ;; No harm in retaining this + midje.sweet + )) + +(deftest wiring + (testing "Can we run tests?" + (is (= (+ 2 3) 5)))) + +(fact "addition works" + (+ 2 3) => 5)