Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- (defn- type-matcher-1
- "Returns a matcher for elements Foo, !Foo, Foo!, !Foo!."
- [g c]
- (fn [x]
- (let [[neg qname exact] (split-name (name c))
- type (resolve-aec g qname)]
- (xor (not (empty? neg))
- (if (not (empty? exact))
- (= type (m1class x))
- (instance? type x))))))
- (defn- type-matcher
- "Returns a matcher for either nil, !Foo!, or [Foo Bar! !Baz]."
- [g cls]
- (cond
- (nil? cls) identity
- (qname? cls) (type-matcher-1 g cls)
- (coll? cls) (let [t-matchers (map #(type-matcher-1 g %) cls)]
- (fn [arg]
- ;; TODO: support of arbitrary logical op
- (reduce #(or %1 %2)
- ((apply juxt t-matchers)
- arg))))
- :else (RuntimeException. "Don't know how to create a type matcher for" cls)))
- (defn- direction-matcher
- [dir]
- (cond
- (or (nil? dir) (= dir EdgeDirection/INOUT)) identity
- (= dir EdgeDirection/OUT) (fn [i] (normal-edge? i))
- (= dir EdgeDirection/IN) (fn [i] (not (normal-edge? i)))
- :else (throw (RuntimeException. "Unknown direction " dir))))
- (defn first-inc
- "Returns the first incidence in iseq of v.
- May be restricted by cls and dir."
- ([^Vertex v]
- (first-inc v nil nil))
- ([^Vertex v cls]
- (first-inc v cls nil))
- ([^Vertex v cls dir]
- (let [tm (type-matcher v cls)
- dm (direction-matcher dir)]
- (loop [i (.getFirstIncidence v)]
- (if (or (nil? i) (and (dm i) (tm i)))
- i
- (recur (.getNextIncidence i)))))))
- (defn next-inc
- "Returns the incidence following e in the current vertex's iseq.
- May be restricted by cls and dir."
- ([^Edge e]
- (next-inc e nil nil))
- ([^Edge e cls]
- (next-inc e cls nil))
- ([^Edge e cls dir]
- (let [tm (type-matcher e cls)
- dm (direction-matcher dir)]
- (loop [i (.getNextIncidence e)]
- (if (or (nil? i) (and (dm i) (tm i)))
- i
- (recur (.getNextIncidence i)))))))
- (defmulti iseq
- "Returns a lazy sequence of v's incidences."
- (fn [c & _ ] (class c)))
- (defmethod iseq Vertex
- ([v]
- (iseq v nil nil))
- ([v cls]
- (iseq v cls nil))
- ([v cls dir]
- (let [f (first-inc v cls dir)]
- (if f
- (lazy-cat (iseq f cls dir))
- []))))
- (defmethod iseq Edge
- ([e]
- (iseq e nil nil))
- ([e cls]
- (iseq e cls nil))
- ([e cls dir]
- (let [n (next-inc e cls dir)]
- (lazy-cat [e] (and n (iseq n cls dir))))))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement