【问题标题】:Automatically and deterministicly testing a function for associativity, commutativity etc自动和确定性地测试一个函数的关联性、交换性等
【发布时间】:2012-01-28 23:16:57
【问题描述】:

是否可以构造一个高阶函数isAssociative,它接受另一个具有两个参数的函数并确定该函数是否是关联的?

类似的问题,但也适用于其他属性,例如交换性。

如果这是不可能的,有什么方法可以用任何语言自动化它吗?如果有我感兴趣的 Agda、Coq 或 Prolog 解决方案。

我可以设想一个蛮力解决方案,它检查所有可能的参数组合并且永不终止。但在这种情况下,“永不终止”是一个不受欢迎的属性。

【问题讨论】:

标签: haskell higher-order-functions halting-problem associativity commutativity


【解决方案1】:

我猜 Haskell 不太适合这样的事情。通常你做完全相反的检查。您声明您的对象具有某些属性,因此可以以某种特殊方式使用(请参阅Data.Foldable)。有时您可能想宣传您的系统:

import Control.Parallel
import Data.Monoid

pmconcat :: Monoid a => [a] -> a
pmconcat [x] = x
pmconcat xs = pmconcat (pairs xs) where
    pairs [] = []
    pairs [x] = [x]
    pairs (x0 : x1 : xs') = y `par` (y : ys) where
        y = x0 `mappend` x1
        ys = pairs xs'

data SomeType

associativeSlowFold = undefined :: SomeType -> SomeType -> SomeType

data SlowFold = SlowFoldId
              | SlowFold { getSlowFold :: SomeType }

instance Monoid SlowFold where
    mempty = SlowFoldId
    SlowFoldId `mappend` x = x
    x `mappend` SlowFoldId = x
    x0 `mappend` x1 = SlowFold y where
        y = (getSlowFold x0) `associativeSlowFold` (getSlowFold x1)
    mconcat = pmconcat

如果您真的想要证明系统,您可能还想看看您提到的那些证明助手。 Prolog - 是逻辑语言,我认为它也不太适合。但它可能用于编写一些简单的助手。 IE。应用关联性规则,并看到在较低级别不可能推导出相等性。

【讨论】:

    【解决方案2】:

    我想到的第一个解决方案是使用QuickCheck

    quickCheck $ \(x, y, z) -> f x (f y z) == f (f x y) z
    quickCheck $ \(x, y) -> f x y == f y x
    

    f 是我们正在测试的函数。它既不能证明结合性也不能证明交换性;这只是编写您一直在考虑的蛮力解决方案的最简单方法。 QuickCheck 的优势在于它能够选择测试的参数,这些参数有望成为测试代码的极端案例。

    您要求的isAssociative 可以定义为

    isAssociative
      :: (Arbitrary t, Show t, Eq t) => (t -> t -> t) -> IO ()
    isAssociative f = quickCheck $ \(x, y, z) -> f x (f y z) == f (f x y) z
    

    它在IO 中,因为 QuickCheck 随机选择测试用例。

    【讨论】:

    • 我不想启发式地“测试”它,我想确定性地“证明”它。这意味着没有随机测试。不过,我赞成向我介绍一个很棒的功能。该功能听起来像是单元测试的天赐之物。
    猜你喜欢
    • 2012-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-23
    • 1970-01-01
    • 2014-03-22
    • 1970-01-01
    • 2018-05-12
    相关资源
    最近更新 更多