           res (f/add-vertex!
                g {:val (delay nil)
                   ::f/collect-fn (aggregate-select g)
-                  ::f/score-collect-fn score-aggregate-select})]
+                  ::f/score-collect-fn (score-collect-min-signal-vals 3)})]
       (f/add-edge! g subj acc signal-select [0 s])
       (f/add-edge! g pred acc signal-select [1 p])
       (f/add-edge! g obj  acc signal-select [2 o])

       ;;(info :coll-select val incoming)
       val))))

(defn score-aggregate-select
  [vertex]
  (if (> 3 (count (vals (peek (::f/uncollected @(:state vertex)))))) 0 1))

(defn aggregate-select
  [g]

    (f/add-edge! g src v f/signal-forward nil)
    v))

(defn qvar?
  "Returns true, if x is a qvar (a symbol prefixed with '?')"
  [x] (and (symbol? x) (= \? (.charAt ^String (name x) 0))))

(defn bind-translator
  [vs? vp? vo? s p o]
  (if vs?
    (if vp?
      (if vo?
        (fn [r] {s (r 0) p (r 1) o (r 2)})
        (fn [r] {s (r 0) p (r 1)}))
      (if vo?
        (fn [r] {s (r 0) o (r 2)})
        (fn [r] {s (r 0)})))
    (if vp?
      (if vo?
        (fn [r] {p (r 1) o (r 2)})
        (fn [r] {p (r 1)}))
      (if vo?
        (fn [r] {o (r 2)})
        (fn [_] {})))))

(defn pattern-translator
  [vs? vp? vo? [s p o]]
  (if (qvar? vs? s)
    (if (qvar? vp? p)
      (if (qvar? vo? o)
        (fn [p] [nil nil nil])
        (fn [p] [nil nil (p 2)]))
      (if (qvar? vo? o)
        (fn [p] [nil (p 1) nil])
        (fn [p] (assoc p 0 nil))))
    (if (qvar? vp? p)
      (if (qvar? vo? o)
        (fn [p] [(p 0) nil nil])
        (fn [p] (assoc p 1 nil)))
      (if (qvar? vo? o)
        (fn [p] (assoc p 2 nil))
        identity))))

(defn triple-verifier
  [ts tp to vars varp varo]
  (cond
    (and vars varp varo) (cond
                           (= ts tp to) (fn [r] (= (r 0) (r 1) (r 2)))
                           (= ts tp) (fn [r] (and (= (r 0) (r 1)) (not= (r 0) (r 2))))
                           (= ts to) (fn [r] (and (= (r 0) (r 2)) (not= (r 0) (r 1))))
                           (= tp to) (fn [r] (and (= (r 1) (r 2)) (not= (r 0) (r 1))))
                           :else (constantly true))
    (and vars varp)      (if (= ts tp)
                           (fn [r] (= (r 0) (r 1)))
                           (fn [r] (not= (r 0) (r 1))))
    (and vars varo)      (if (= ts to)
                           (fn [r] (= (r 0) (r 2)))
                           (fn [r] (not= (r 0) (r 2))))
    (and varp varo)      (if (= tp to)
                           (fn [r] (= (r 1) (r 2)))
                           (fn [r] (not= (r 1) (r 2))))
    :else                (constantly true)))

(defn param-query
  [g id [s p o]]
  (let [vs?        (qvar? s), vp? (qvar? p), vo? (qvar? o)
        vmap       (bind-translator vs? vp? vo? s p o)
        verify     (triple-verifier s p o vs? vp? vo?)
        collect-fn (f/simple-collect
                    (fn [_ incoming]
                      (delay
                       (when-let [res (peek incoming)]
                         (into #{}
                               (comp (map #(if (verify %) (vmap %)))
                                     (filter identity))
                               @res)))))
        q-pattern  [(if vs? nil s) (if vp? nil p) (if vo? nil o)]
        q-spec     (add-query! g id q-pattern)
        r-vertex   (f/add-vertex! g {:val (delay nil) ::f/collect-fn collect-fn})]
    (f/add-edge! g (:result q-spec) r-vertex f/signal-forward nil)
    (assoc q-spec :qvar-result r-vertex)))

(defn add-join-query
  [g pat-a pat-b]
  (let [qa  (param-query g (keyword (gensym)) pat-a)
        qb  (param-query g (keyword (gensym)) pat-b)
        jfn (fn [vertex]
              (let [state (:state vertex)
                    a @(get-in @state [::f/signal-map (:id (:qvar-result qa))])
                    b @(get-in @state [::f/signal-map (:id (:qvar-result qb))])]
                (info :join-sets a b)
                (swap! state assoc :val (set/join a b))))
        jv  (f/add-vertex!
             g {:val (delay nil)
                ::f/collect-fn jfn
                ::f/score-collect-fn #(if (== (count (::f/signal-map @(:state %))) 2) 1 0)})]
    (f/add-edge! g (:qvar-result qa) jv f/signal-forward nil)
    (f/add-edge! g (:qvar-result qb) jv f/signal-forward nil)
    {:a qa :b qb :join jv}))

(defn start
  []
  (let [g (triple-graph (f/compute-graph))
        toxi (:result (add-query! g :toxi ['toxi nil nil]))
        types (:result (add-query! g :types [nil 'type nil]))
        projects (:result (add-query! g :projects [nil 'type 'project]))
        knows (:result (add-query! g :projects [nil 'knows nil]))
        all (:result (add-query! g :all [nil nil nil]))
        num-projects (add-counter! g projects)
        num-types (add-counter! g types)
        inf1 (add-rule! g :knows [nil 'knows nil] (fn [[s p o]] [[s 'type 'person] [o 'type 'person] [o 'knows s]]))
        pq (:qvar-result (param-query g :pq '[?s knows ?o]))
        jq (:join (add-join-query g '[?p author ?prj] '[?prj type project]))
        ctx (f/async-context {:graph g :processor f/eager-vertex-processor :timeout nil})]
    (f/execute! ctx)
    (mapv
