    :evalpush-limit 1600
    :population-size 1000
    :max-generations 300
-   ;:parent-selection :lexicase
    :parent-selection :leaky-lexicase ;:lexicase
    :lexicase-leakage 0.5
-   ;:genetic-operator-probabilities {:alternation 0.2
-   ;                                 :uniform-mutation 0.2
-   ;                                 :uniform-close-mutation 0.1
-   ;                                 [:alternation :uniform-mutation] 0.5
-   ;                                 ;:genesis 0.1 ;***
-   ;                                 }
-   ;:genetic-operator-probabilities {:uniform-addition-and-deletion 0.45
-   ;                                 :uniform-combination-and-deletion 0.45
-   ;                                 :genesis 0.1}
-   ;:genetic-operator-probabilities {:uniform-addition-and-deletion 0.9
-   ;                                 :uniform-combination-and-deletion 0.1}
    :genetic-operator-probabilities {:uniform-addition-and-deletion 0.5
                                     :alternation 0.5}
-   :uniform-addition-and-deletion-rate [0.01 0.1]
-   :uniform-combination-and-deletion-rate 1 ;[1 1/2 1/4 1/8]
-   :alternation-rate [0.01 0.1]
-   :alignment-deviation [1 10 100]
-   :uniform-mutation-rate [0.01 0.1]
+   :uniform-addition-and-deletion-rate [0.001 0.01 0.1]
+   :alternation-rate [0.001 0.01 0.1]
+   :alignment-deviation [0 1 10 100]
    :problem-specific-report penn-report
    :problem-specific-initial-report penn-initial-report
    ;:print-behavioral-diversity true ;; requires maintaining @population-behaviors 
    :report-simplifications 0
-   :final-report-simplifications 5000
+   :final-report-simplifications 1000
+   ;; === parameters for experimenting with age-mediated parent selection (AMPS)
    ;:age-mediated-parent-selection [0.05 0.5]
    ;:age-combining-function :max
    ;:age-combining-function :proportionate 
    ;:age-combining-function :first-reuse 
+   ;; === parameters for experimenting with autoconstruction
    ;:autoconstructive true
    ;:autoconstructive-genome-instructions :uniform
    ;:autoconstructive-diversification-test :three-gens-size-and-instruction

  (:require [clojure.string :as string]
            [clojure-csv.core :as csv]))

(defn rmse
  "Returns the root of the mean square error for use in error reporting."
  [errors]
  (sqrt (/ (apply + (map #(* % %)
                         errors))
           (count errors))))

(defn read-data []
  "Reads data into a sequence of sequences."
  (let [f (slurp* (str "src/clojush/problems/classification/data/"  ;; todo?: allow command-line arg
                       ;"GAMETES_Epistasis_2-Way_20atts_0.4H_EDM-1_1.txt"
                       ;"a_5000s_2000her_0.1__maf_0.2_EDM-1_01.txt"
                       "xor_2_a_20s_1600_EDM-1_01.txt"
                       ;"xor_3_a_20s_1600_EDM-1_01.txt"
                       ;"xor_4_a_20s_1600_EDM-1_01.txt"
                       ))
        lines (csv/parse-csv f :delimiter \tab)]
    (println "Total number of data lines:" (count lines))
    (mapv #(mapv read-string %) lines)))

(def training-proportion 0.1) ;; proportion of training cases to use each generation

(def resampling true)

(defn define-fitness-cases
  "Returns a map with two keys: train and test. Train maps to a

             #(assoc % :train (vec (take (count (:train %))
                                         (lshuffle (:all-train %))))))
      (println "New training cases:")
      (println (:train @penn-fitness-cases)))))

(defn penn-initial-report
  "Initial report function for the penn problem, which prints the training and testing cases."
  [argmap]
  (println "Train and test cases:")
  (println @penn-fitness-cases)
  (println ";;******************************"))

(defn cycle-to-longest
  "A utility for producing a collection with equal representation from multiple sequences.
  The longest sequence will be included in its entirety, and shorter ones will be cycled
  as necessary to produce the same number of elements."
  [& sequences]
  (let [max-count (apply max (map count sequences))]
    (vec (apply concat (map #(take max-count (cycle %)) sequences)))))

(def penn-atom-generators
  (cycle-to-longest 
    ;; input instructions 
    (for [n (map inc (range (count (:inputs (first (:train @penn-fitness-cases))))))]
      (symbol (str "in" n)))
    ;; output class strings
    (distinct (mapv :target (:all-train @penn-fitness-cases)))
    ;; other instructions and ephemeral random constants
    (concat (registered-for-stacks [:exec :integer :boolean :parentheses])
            ;; for strings, which are used only for output class literals, just stack instructions
            '[string_pop string_dup string_dup_times string_dup_items  string_swap string_rot 
              string_flush string_eq string_stackdepth string_yank string_yankdup string_shove 
              string_empty]
            [(tag-instruction-erc [:exec :integer :boolean :string] 1000)
             (tagged-instruction-erc 1000)
             (fn [] (lrand-int 1000))])
    ;; more of anything that uses booleans
    (map first 
         (filter (fn [[instr instr-fn]]
                   (some #{boolean} (:stack-types (meta instr-fn))))
                 @instruction-table))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Main call
