   (raw-pattern [_])
   (result-vertex [_]))
 
-(defn signal-triple
+(defn- sole-user?
+  [src user]
+  (let [n (f/neighbors src)]
+    (and (== 1 (count n)) (= user (first n)))))
+
+(defn- random-id
+  [] (keyword (gensym)))
+
+(defn- signal-triple
   [vertex op] [op (:id vertex) @vertex])
 
-(defn collect-index
+(defn- collect-index
   [spo]
   (f/collect-pure
    (fn [val incoming]

          :- (do (debug :remove-triple t)
                 (remove-triple! g t))
          (warn "invalid inference:" inf)))
      (swap! (:value vertex) set/union in (set inferred)))))

(defrecord TripleInferenceRule
    [id query patterns production inf]
  f/IGraphComponent
  (add-to-graph!
    [_ g]
    (let [q   (apply add-query-join! g patterns)
          inf (f/add-vertex!
               g #{} {::f/collect-fn (collect-inference g production)})]
      (f/add-edge! g (result-vertex q) inf f/signal-forward nil)
      (assoc _ :query q :inf inf))))

(defn add-rule!
  [g id query production]
  (f/add-to-graph!
   (map->TripleInferenceRule
    {:id id :patterns query :production production})
   g))

(defn- index-vertex
  [g spo]

  (f/remove-watch! graph :add-vertex watch-id)
  (f/remove-watch! graph :remove-vertex watch-id)
  (close! chan))

(def inference-rules
  {:symmetric  ['[[?a ?prop ?b] [?prop type symmetric-prop]]
                (fn [{:syms [?a ?prop ?b]}] [[:+ [?b ?prop ?a]]])]
   :domain     ['[[?a ?prop nil] [?prop domain ?d]]
                (fn [{:syms [?a ?prop ?d]}] [[:+ [?a 'type ?d]]])]
   :range      ['[[nil ?prop ?a] [?prop range ?r]]
                (fn [{:syms [?a ?prop ?r]}] [[:+ [?a 'type ?r]]])]
   :transitive ['[[?a ?prop ?b] [?b ?prop ?c] [?prop type transitive-prop]]
                (fn [{:syms [?a ?prop ?c]}] [[:+ [?a ?prop ?c]]])]
   :sub-prop   ['[[?a ?prop ?b] [?prop sub-prop-of ?super]]
                (fn [{:syms [?a ?super ?b]}] [[:+ [?a ?super ?b]]])]
   :modified   ['[[?a modified ?t1] [?a modified ?t2]]
                (fn [{:syms [?a ?t1 ?t2]}] (if (not= ?t1 ?t2) [[:- [?a 'modified (min ?t1 ?t2)]]]))]})

(defn make-test-graph
  []
