                                   [next-novelty-archive nil])
           :else [nil (final-report generation best @push-argmap)])))
 
-
-
 (defn pushgp
   "The top-level routine of pushgp."
   ([] (pushgp '()))

      (reset! timer-atom (System/currentTimeMillis))
      (swap! timing-map assoc step (+ current-time-for-step (- @timer-atom start-time))))))


(defn process-generation
  "Processes the generation, returning [new novelty archive, return val],
   where new novelty archive will be nil if we are done."

  (println "Computing errors... ")
  (compute-errors pop-agents rand-gens novelty-archive @push-argmap)
  (println "Done computing errors.")
  (println "Preserving frontier... ")
  (when (and (:preserve-frontier argmap)
             (or (not (:autoconstructive argmap))
                 (> generation 0)))
    (let [filtered-candidates
          (if (:autoconstructive argmap)
            (let [diversifying-children (filter :diversifying (map deref pop-agents))
                  diversifying-frontier (filter :diversifying @frontier)
                  verified-frontier (filter (fn [parent]
                                              (some (fn [child]
                                                      (= (:parent1-genome child)
                                                         (:genome parent)))
                                                    diversifying-children))
                                            diversifying-frontier)
                  diversifying-candidates (concat diversifying-children verified-frontier)]
              (println "Number of diversifying candidates for frontier preservation:"
                       (count diversifying-candidates))
              (if (empty? diversifying-candidates)
                (map deref pop-agents)
                (if (< (count diversifying-candidates) (count pop-agents))
                  (take (count pop-agents) (cycle diversifying-candidates))
                  diversifying-candidates)))
            (concat (map deref pop-agents)
                    @frontier))]
      (if (= (count filtered-candidates) (count pop-agents))
        (do (dotimes [i population-size]
              ((if use-single-thread swap! send) (nth pop-agents i) (fn [_] (nth filtered-candidates i))))
            (when-not use-single-thread (apply await pop-agents)) ;; SYNCHRONIZE
            (reset! frontier filtered-candidates))
        (loop [preserved 0
               new-frontier []
               candidates filtered-candidates]
          (if (= preserved population-size)
            (do (dotimes [i population-size]
                  ((if use-single-thread swap! send) (nth pop-agents i) (fn [_] (nth new-frontier i))))
                (when-not use-single-thread (apply await pop-agents)) ;; SYNCHRONIZE
                (reset! frontier new-frontier))
            (let [to-preserve (select candidates argmap)
                  without-meta-errors (update-in to-preserve
                                                 [:errors]
                                                 #(drop-last (count (:meta-errors to-preserve)) %))]
              (recur (inc preserved)
                     (conj new-frontier without-meta-errors)
                     (remove-one to-preserve candidates))))))))
  (timer @push-argmap :fitness)
  ;; calculate solution rates if necessary for historically-assessed hardness
  (calculate-hah-solution-rates pop-agents @push-argmap)
