2016-08-31 6 views
2

QuickCheckを使用して、関数が終了することを確認する関数をテストしたい(無限再帰や例外のスローなどはしない)。これは私が現時点で行っていることです:QuickCheckを使用して関数が終了するかどうかをテストするにはどうすればよいですか?

f :: Int -> Int -> Int 

prop_fTerminates :: Int -> Int -> Bool -- say 
prop_fTerminates x y = f x y `seq` True 

より良い(表現力豊かで慣用的な)方法がありますか?

答えて

4

を使用することができます私はおそらく、私はちょうどその出力の他の特性を試験したい、気にしないでしょう。

どのような方法でf x yの出力を調べているプロパティは、あなたのprop_fTerminatesとしてチェック少なくともとして多くの終了を行うとしているので、なぜ無駄時間は、そのチェックにまで倍増?

何らかの理由で「fx y terminates」だけがfについてテストできる唯一のプロパティである場合は、あなたが得意とするものは妥当と思われます。

+2

はい、問題は、実際にはモンテカルロ計算の結果である、 'f'の出力については妥当な不変量を表現できないということです。 –

7

これはhalting problemです。関数が終了するかどうかを知らせるアルゴリズムはありません。

特に、は、長時間待つことを喜んで肯定的な結果を得ることができます(つまり、関数が終了すると、この命題はあなたに伝えられます)。しかし、ちょうど待つことによって、あなたはの違いを知ることができませんこの関数はまだ終了していません

のようなチェックを実装することができます。この機能は、必要に応じて時間Tで終了します。


編集書かれたよう、あなたの関数は、必要なものを行いません。理由はseqだけweak head normal formと評価されていることである

> let f = 1:f 
> f `seq` True 
True 

考えてみましょう。代わりに、あなたは深く、データ構造を評価deepseq

> import Control.DeepSeq (deepseq) 
> f `deepseq` True 
* never returns * 
+3

私は、関数が終了する(つまり停止問題です)_prove_したくないので、無限再帰につながる実装を間違えないようにしたいと思います。私は、私の意図をはっきりと表現する方法でテストを書きたいと思っています。 –

+0

私の編集を見てください。これは 'seq'がなぜここで適切でないのかを説明しています。 –

+1

さて、 'f'は' Int'を返すのでWHNFとNFは同じですか?しかし、一般的なケースではあなたは間違いなく正しいです。 –

関連する問題