 
 ;; some tests
 
-(let [genome (random-plush-genome 10 [1 'exec_noop 'integer_add]
+;; load and dump a random program
+#_(let [genome (random-plush-genome 10 [1 'exec_noop 'integer_add]
                                   {:epigenetic-markers [:close :silent]})]
   (println "Before:" genome)
   (println "After loading and dumping:"

      (trace 'gtm_tape2
             (-> state
                 (assoc-in [:gtm :secondary] (:primary (:gtm state)))
                 (assoc-in [:gtm :primary 2])))
      state)))



                                 genome)
                      1)))

;; use namespaces for following tests
(do 
  (use 'clojush.interpreter)
  (use 'clojush.instructions.code)
  (use 'clojush.instructions.boolean)
  (use 'clojush.instructions.random-instructions))

;; uniform crossover
#_(let [g0 (random-plush-genome 20 [0])
      g1 (random-plush-genome 20 [1])
      pgm '(gtm_tape0              ;; initial source is tape0
             exec_y                ;; repeatedly
             (gtm_tape2            ;;   set destination to tape2
               gtm_copy            ;;   copy a gene
               gtm_tape0 gtm_right ;;   move all heads to right
               gtm_tape1 gtm_right ;;
               gtm_tape2 gtm_right ;;
               boolean_rand        ;;   make next source randomly tape0 or tape1
               exec_if gtm_tape0 gtm_tape1))
      run-pgm #(run-push pgm %)]
  (println "g0:" g0)(newline)
  (println "g1:" g1)(newline)
  (println "result:"
           (-> (make-push-state)
               (init-gtm 3)
               (load-tape 0 g0)
               (load-tape 1 g1)
               (run-pgm)
               (dump-tape 2))))

;; back and forth on one parent
#_(let [g [{:instruction 1}{:instruction 2}{:instruction 3}]
      pgm '(true                  ;; top boolean indicates if moving right
             exec_y               ;; repeatedly
             (gtm_tape0           ;;   source is tape0
               gtm_tape2          ;;   destination is tape2
               gtm_copy           ;;   copy a gene
               gtm_right          ;;   move destination to right
               gtm_tape0          ;;   advance source in current direction
               exec_if
               (true gtm_right)
               (false gtm_left)
               gtm_blank          ;;   if blank, reverse and move twice
               exec_if
               (exec_if false true
                        exec_if
                        (true gtm_right gtm_right)
                        (false gtm_left gtm_left))
               ()))
      run-pgm #(run-push pgm %)]
  (println "g:" g)(newline)
  (println "result:"
           (-> (make-push-state)
               (init-gtm 3)
               (load-tape 0 g)
               (run-pgm)
               (dump-tape 2))))

;; following test requires global-atom-generators to be set
#_(reset! global-atom-generators [1 2 3])

;; 50% uniform mutation
#_(let [g (vec (repeat 20 {:instruction 0}))
      pgm '(gtm_tape0                 ;; source is tape0
             gtm_tape2                ;; destination is tape2
             exec_y                   ;; repeatedly
             (boolean_rand            ;;   randomly either
               exec_if                ;;
               (100 code_rand         ;;     set instruction randomly
                 gtm_set_instruction)
               gtm_copy               ;;     or copy it
               gtm_tape0 gtm_right    ;;   in either case advance both tapes
               gtm_tape2 gtm_right))
      run-pgm #(run-push pgm %)]
  (println "g:" g)(newline)
  (println "result:"
           (-> (make-push-state)
               (init-gtm 3)
               (load-tape 0 g)
               (run-pgm)
               (dump-tape 2))))

