          [tree])
        (grow (rest trees))))))
 
+(defn frontier
+  "get the next path to which to adjoin within _tree_."
+  [tree]
+  (cond
+    (= (u/get-in tree [::done?]) true)
+    []
+    
+    (and (= (u/get-in tree [:phrasal]) true)
+         (not (u/get-in tree [::done?]))
+         (= true (u/get-in tree [::started?]))
+         (not (u/get-in tree [:head ::done?])))
+    (cons :head (frontier (u/get-in tree [:head])))
+
+    (and (= (u/get-in tree [:phrasal]) true)
+         (= true (u/get-in tree [::started?])))
+    (cons :comp (frontier (u/get-in tree [:comp])))
+    
+    true []))
+
+(defn parent-with-head
+  "Return every possible tree of depth 1 from the given spec and model."
+  [spec depth]
+  ;; get all rules that match input _spec_:
+  (if (nil? spec) (throw (Exception. (str "nope: spec was nil."))))
+  (let [matching-rules
+        (shuffle (->> (:grammar model)
+                      (map #(unify % spec))
+                      (filter #(not (= :fail %)))))]
+    (->> matching-rules
+         ;; 2. try to add heads to each matching rule:
+         (parent-with-head-1 spec depth)
+         (filter #(not (= % :fail)))
+         (map #(u/assoc-in! % [::started?] true)))))
+
+(defn parent-with-head-1 [spec depth parent-rules]
+  (if (not (empty? parent-rules))
+    (let [parent-rule (first parent-rules)
+          phrases-with-phrasal-head #(map (fn [child]
+                                            (u/assoc-in parent-rule [:head] child))
+                                          (:grammar model))
+          phrases-with-lexical-heads #(map (fn [child]
+                                             (u/assoc-in parent-rule [:head] child))
+                                           (get-lexemes (unify
+                                                         (u/get-in spec [:head] :top)
+                                                         (u/get-in parent-rule [:head] :top))))]
+      (log/debug (str "pwh-1:" (:rule parent-rule)))
+      (cond
+        (branch? depth)
+        (lazy-cat
+         ;; phrases that could be the head child, then lexemes that could be the head child.
+         (phrases-with-phrasal-head)
+         (phrases-with-lexical-heads)
+         (parent-with-head-1 spec depth (rest parent-rules)))
+
+        true
+        (lazy-cat
+         ;; lexemes that could be the head child, then phrases that could be the head child.
+         (phrases-with-lexical-heads)
+         (phrases-with-phrasal-head)
+         (parent-with-head-1 spec depth (rest parent-rules)))))))
+
+(defn get-lexemes 
+  "Get lexemes matching the spec. Use a model's index if available, where the index 
+   is a function that we call with _spec_ to get a set of indices. 
+   Otherwise use the model's entire lexeme."
+  [spec]
+  (->>
+   (if-let [index-fn (:index-fn model)]
+     (index-fn spec)
+     (do
+       (log/warn (str "get-lexemes: no index found: using entire lexicon."))
+       (flatten (vals
+                 (or (:lexicon (:generate model)) (:lexicon model))))))
+   (filter #(or (= false (u/get-in % [:exception] false))
+                (not (= :verb (u/get-in % [:synsem :cat])))))
+   (map #(unify % spec))
+   (filter #(not (= :fail %)))
+   (map #(u/assoc-in! % [::done?] true))))
+
+(defn assoc-each-default [tree children f]
+  (if (not (empty? children))
+    (lazy-cat
+     (let [child (first children)
+           tree-with-child (u/assoc-in tree f child)]
+       (-> tree-with-child
+           (u/assoc-in! 
+            (concat (butlast f) [::done?])
+            true)
+           (u/dissoc-paths (if truncate? [f] []))
+           ((or (:default-fn model) (fn [x] [x])))))
+     (assoc-each-default tree (rest children) f))))
+
+(defn assoc-children [tree children f]
+  (if (not (empty? children))
+    (let [child (first children)
+          default-fn (or (:default-fn model)
+                         (fn [x] [x]))]
+      (lazy-cat
+       (if (= true (u/get-in child [::done?]))
+         (assoc-each-default tree (default-fn child) f)
+         [(u/assoc-in tree f child)])
+       (assoc-children tree (rest children) f)))))
+

(def ^:dynamic println? false)
(def ^:dynamic model)

(declare gen)
(declare get-lexemes)
(declare grow)

   list of expressions that match the given _spec_."
  [spec]
  (grow (parent-with-head spec 0)))

(defn grow
  "recursively generate trees given 
