 
 ; Define the argmap
 (def argmap
-  {:error-function (wc-error-function 50)
+  {:error-function (wc-error-function wc-data-domains)
    :atom-generators wc-atom-generators
    :max-points 200
    :max-points-in-initial-program 50

    'boolean_dup))

;; Define test cases
(defn random-wc-inputs
  "Returns a list of n random inputs. Each will have size between 0 and 100."
  [n]
  (let [chars (map char (range 32 127))
        max-len 100]
    (repeatedly n
                (fn []
                  (apply str
                         (repeatedly (lrand-int (inc max-len))
                                     (fn []
                                       (let [rand-cond (lrand)]
                                         (cond
                                           (< rand-cond 0.05) \tab
                                           (< rand-cond 0.1) \newline
                                           (< rand-cond 0.35) \space
                                           :else (lrand-nth chars))))))))))

(defn wc-char-count
  "Takes a wc input and returns the char count output"

  (get (frequencies input) \newline 0))

(defn wc-test-cases
  "Takes a sequence of inputs and gives IO test cases of the form
   [input output-char output-word output-line]."
  [inputs]
  (map #(vector %
                (wc-char-count %)
                (wc-word-count %)
                (wc-line-count %))
       inputs))

;; Define error function. For now, each run uses different random inputs
(defn wc-error-function
  "Returns the error function for the wc problem. Takes as
   input WC data domains."
  [data-domains]
  (let [[train-cases test-cases] (map wc-test-cases
                                      (test-and-train-data-from-domains wc-data-domains))]
    (fn [program]
      (flatten
        (doall
          (for [[input out-char out-word out-line] train-cases]
            (let [final-state (run-push program
                                        (->> (make-push-state)
                                          (push-item nil :auxiliary)
                                          (push-item nil :auxiliary)
                                          (push-item nil :auxiliary)
                                          (push-item input :auxiliary)
                                          (push-item input :auxiliary)))
                  result-char (stack-ref :auxiliary 2 final-state)
                  result-word (stack-ref :auxiliary 3 final-state)
                  result-line (stack-ref :auxiliary 4 final-state)]
