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

欢迎!请查看关于页面以了解更多关于此如何运作的信息。

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 投票

评论者:maiej.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 text: 这里)。

0 投票

评论者:maiej.jaskowski

显然我需要更多的提示,因为我(顺便提一下,使用gen/bing)能生成的所有都是一对:(图 随机路径列表)

只要算法按预期工作,这很有用。然而,一旦它失败,就很难找出哪个随机路径导致了失败。

0 投票

评论者:reiddraper

你能展示你是如何编写具有嵌套属性的测试的吗?然后或许我可以帮助你重写以使用 {{bind}} 代替?

0 投票

评论者:maiej.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生成一个阶乘矩阵,例如:(链接:[0 1) (链接:4 0)]
gen-permutations生成提供的向量的排列

0 投票

评论者:reiddraper

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

0 投票

评论者:maiej.jaskowski

好吧,但现在我只能写下这样的话

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

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

`

这将指向一个矩阵和长度为500的路径向量,其中一个路径是反例。如果我能得到矩阵和一个单个的反例会更好。

0 投票

评论者:reiddraper

我还不确定如何使用嵌套属性来表示这个样子。您能否按照您希望的嵌套属性的方式编写代码?这至少将涉及两个forall。

0 投票

评论者:maiej.jaskowski

当然可以!

我喜欢写这样的

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

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

`

0 投票

评论者:maiej.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))
`

...