Nico, what is the correct way to turn my function which generates the graph (using core.logic) into a generator?
On Monday, 8 December 2014 09:04:14 UTC+2, cliff wrote: > > Hi > > I would like to test a function which recursively traverses the nodes in a > graph and collects them. For example, > > (def graph {1 [2 3 4] > 2 [5 6 7] > 6 [8 9] > 10 [11 12 13]} > > my function is given a starting point say, 1 and should then traverse each > node which is reachable and return the set. In this case the result should > be: > #{3, 4, 5, 7, 8, 9} > > note: it does not return any elements reachable by 10. > > I would like to test this using test.check, but I would like to generate > test data which will exercise the traversal of the graph. > > I found a similar thread here: > https://groups.google.com/forum/#!topic/clojure/YWeT8BFc8k4 > > But, I don't think the proposed solution would suit this use case. So, I > tried generating a graph with relations using core.logic > > (defn ->maps >> >> "take the output of run* and convert it into sequence of maps" >> [q] >> (let [r (->> q >> (partition 2) >> (map (fn [[k v]] {k (apply vector v)})) >> (apply merge))] >> r )) >> (defn gen-hierarchy >> "generate a related hierarchy" >> [size] >> (let [vars1 (->> (repeatedly 7 lvar) (into [])) >> vars2 (->> (repeatedly 7 lvar) (into [])) >> vars3 (->> (repeatedly 7 lvar) (into []))] >> (->> >> (run size [q] >> (fresh [?k1 ?k2 ?k3 ?v1 ?v2 ?v3 ?a] >> (fd/distinct vars1) >> (everyg #(fd/in % (fd/interval 1 9)) vars1) >> (fd/in ?k1 (fd/interval 1 9)) >> (rembero ?k1 vars1 ?v1) >> (membero ?k2 ?v1) >> (fd/distinct vars2) >> (everyg #(fd/in % (fd/interval 1 9)) vars2) >> (rembero ?k2 vars2 ?v2) >> (membero ?k3 ?v2) >> (fd/distinct vars3) >> (everyg #(fd/in % (fd/interval 1 9)) vars3) >> (rembero ?k3 vars3 ?v3) >> (appendo [?k1 ?v1] [?k2 ?v2] ?a) >> (appendo ?a [?k3 ?v3] q))) >> (map ->maps)))) >> >> > Hooking this into test.check. I tried the following: > > (defn gen-port-hierarchy [] >> (gen/sized (fn [size] >> (gen/fmap #(gen-hierarchy %) (gen/return size))))) >> (gen/sample (gen/not-empty (gen-port-hierarchy)) 1) > > > Which does produce more or less what I'm after: > > (({6 [2 3 4 5 7 1], 3 [6 7 1 2 4 5], 1 [3 2 4 5 6 7]}) > ({5 [1 2 3 4 6 7], 7 [5 3 4 6 1 2], 1 [7 2 3 4 5 6]})) > > However, when I try use this in a spec: > > (prop/for-all [bindings (gen/not-empty (gen-port-hierarchy))] > > (let [ ks (into #{} (keys bindings))] ...) > > > I seem to be getting back a LazySeq which then leads to a > ClassCastException: > > java.lang.ClassCastException: clojure.lang.PersistentArrayMap cannot be > cast to java.util.Map$Entry > > Am I on the completely wrong path here? > Or have I incorrectly hooked this generator up with test.check? > > Any help would be very appreciated. > > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.