自动且确定地测试关联性,交换性等功能

The*_*kle 7 haskell halting-problem associativity higher-order-functions commutativity

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

类似的问题,但对于其他属性,如交换性.

如果这是不可能的,有没有办法用任何语言自动化它?如果有我感兴趣的Agda,Coq或Prolog解决方案.

我可以设想一个强力解决方案,它检查每个可能的参数组合,永远不会终止.但在这种情况下,"永不终止"是一种不受欢迎的财产.

Jan*_*Jan 9

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

quickCheck $ \(x, y, z) -> f x (f y z) == f (f x y) z
quickCheck $ \(x, y) -> f x y == f y x
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

这是在IO为快速检查随机选择测试用例.


ony*_*ony 3

我猜 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
Run Code Online (Sandbox Code Playgroud)

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