Clojure 2024 年状态调查中分享你的想法!

欢迎!请参阅关于页面获取更多关于这个工作方式的信息。

0
提问于 test.check

包括支持添加嵌套属性的功能将会很有用。以下是一个如何实现这一功能的示例

`
(defn exists?
[e coll]
(some #{e} coll))

(defn remove-elem
[e coll]
(remove #{e} coll))

;; 这个测试应该失败,并且展示了嵌套属性
(quick-check (for-all [v (gen/vector gen/int)]

           (for-all [e (elements v)]
             #(exists? e (remove-elem e v)))))

`

这个要求是支持重构属性,这是目前未实现的。

(link: https://github.com/reiddraper/simple-check/issues/10 text: 原始问题 - GitHub #10)

12 答案

0

评论来自:maciej.jaskowski

这个问题的状态是?
以下情况我们非常需要这个功能:我想验证我的路径查找算法能否在给定图 G 中找到最优解,所以我生成图和大量随机路径,检查所有随机路径都比算法找到的路径“不优”。

如果有一个嵌套的 for-all 将会使事情更加简单。有没有其他方法可以做到这一点?

0

评论来自:reiddraper

很抱歉未能及时更新此处。嵌套属性在我这边还是处于一些“犹豫”时间。好消息是它相当方便,你可以使用 {{clojure.test.check.generators/bind}} 实现完全相同的效应。您可以在这里看到 {{bind}} 的一个使用示例(链接:https://github.com/clojure/test.check/blob/v0.5.8/doc/generator-examples.md#a-vector-and-a-random-element-from-it 文本:这里)。

0

评论来自:maciej.jaskowski

显然我需要更多的提示,因为我(顺便提及,使用gen/bing)所能生成的只有这样的对子:(graph list-of-random-paths)

只要算法按预期工作,这就有助于。然而,一旦失败,要找出是哪个random-paths导致的就无法轻易做到了。

0

评论来自:reiddraper

你能展示你是如何编写使用嵌套属性的测试的吗?然后我可以帮你重写它,使用{{bind}}吗?

0

评论来自:maciej.jaskowski

太好了(图片:谢谢)

请找到下面最重要的部分。

`
(defn gen-matrix-and-paths [size]

(gen/bind
  (gen-matrix gen/s-pos-int size)
  (fn [matrix]
    (let [ nodes (into [] (range (count matrix)))
           gen-perms (gen-permutations nodes)
           perms (distinct (gen/sample gen-perms 500)) ]
      (gen/tuple 
        (gen/return matrix) 
        (gen/return perms))))))

`

gen-matrix生成一个包含关联的平方矩阵,例如:(link: [0 1) (link: 4 0)]
gen-permutations对提供的向量生成一个排列

0

评论来自:reiddraper

我感到困惑,你遇到什么问题?你粘贴的代码使用了{{bind}},而不是嵌套属性。

0

评论来自:maciej.jaskowski

好,但现在我只能写成如下这样

`
(prop/for-all [data (gen-matrix-and-paths 6)]
(let [ [matrix random-paths] data ]

 (not-worse-then-others? tsp matrix random-paths))))

`

如果我的'tsp'算法工作不正确,将会指向矩阵和长度为500的路径向量中的一个作为反例。如果能直接得到矩阵和单个反例会更好。

0

评论来自:reiddraper

我还不清楚嵌套属性会是怎样的样子。你能按照你希望的样子,将代码编写为嵌套属性吗?这将涉及至少两个for-all。

0

评论来自:maciej.jaskowski

当然可以!

我想要编写一些类似的东西

`
(prop/for-all [matrix (gen-matrix 6)]
(prop/for-all [random-path (gen-random-path matrix)]

(<= (cost (tsp matrix)) (cost random-path))))

`

0

评论来自:maciej.jaskowski

ping!

0

评论来自:reiddraper

好的,让我们将其转换成使用{{gen/bind}}。就像嵌套属性一样,{{bind}}允许你创建依赖于另一个生成器的生成器。例如,你的{{gen-random-path}}依赖于先前生成的{{matrix}}变量。所以让我们写一个同时返回{{matrix}}和{{random-path}}的生成器。

`
(def matrix-and-path
"返回一个[matrix random-path]的双元组"
(gen/bind (gen-matrix 6)

        (fn [matrix]
           (gen/tuple (gen/return matrix) (gen-random-path matrix)))))

(prop/for-all [[matrix random-path] matrix-and-path]
(<= (cost (tsp matrix)) (cost random-path))
`

0
参考:https://clojure.atlassian.net/browse/TCHECK-7 (由hypirion报告)
...