                                  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))))
+

          state))
      state)))

(define-registered ;; push primary tape's instruction to code stack
  gtm_instruction
  ^{:stack-types [:gtm :code]}

      (trace 'gtm_tape1
             (-> state
                 (assoc-in [:gtm :secondary] (:primary (:gtm state)))
                 (assoc-in [:gtm :primary] 1)))
      state)))

(define-registered ;; set primary to tape2, secondary to prior primary
