Hi Gary
I have tried your suggestion but I fear there is a deeper problem.
Thanks
Cliff
On Monday, 8 December 2014 12:03:47 UTC+2, Gary Verhaegen wrote:
>
> I haven't touched test.check yet, si this might be completely off the
> mark, but based on my limited understanding, here's what I think happens.
>
> for-all probably removes one level of nesting from your generator, which
> means that bindings is bound to a seq with one element, which is a map.
> Then, keys in the (let [ks (into #{} (keys bindings))]... Form turns its
> argument into a seq, which is easy as it is already one, and then tries to
> map the key function on the result. The key function expects a Map.Entry,
> but here the elements of the seq are (or actually is, as there is only one)
> maps, so it blows up. Easiest way to test (I'm on my phone, emse I'd have
> done it) this hypothesis would be to turn the into for into (into #{} (keys
> (first bindings))).
>
> Once confirmed, I would suggest getting ris of that extra level of nesting
> earlier, for example inside your ->maps fn (mapcat identity should do the
> trick).
>
> On Monday, 8 December 2014, cig <[email protected] <javascript:>>
> 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 [email protected]
>> Note that posts from new members are moderated - please be patient with
>> your first post.
>> To unsubscribe from this group, send email to
>> [email protected]
>> 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 [email protected].
>> For more options, visit https://groups.google.com/d/optout.
>>
>
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
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 [email protected].
For more options, visit https://groups.google.com/d/optout.