ListsとVectのfind関数に類似した、サイズに制限されたStreamsのストリームに対して、find
関数が必要です。Streamsの要素の完全性と検索
total
find : MaxBound a => (a -> Bool) -> Stream a -> Maybe a
課題は、それを作ることである。
- は
- Nが最大
a
を符号化するために必要なビット数であるせいぜい定数log_2 Nスペースを消費しない合計です。 - 何のランタイムコスト
を課していないコンパイル時
const False
の場合、検索は永遠に続行されます。この一般的なケースを処理するうまい方法は、無限の燃料技術です。私のユースケースに適していますが、特定の特殊なケースでは全体のチェッカーがforever
を使用せずに納得することができれば、私は疑問に思う data Fuel = Dry | More (Lazy Fuel)
partial
forever : Fuel
forever = More forever
total
find : Fuel -> (a -> Bool) -> Stream a -> Maybe a
find Dry _ _ = Nothing
find (More fuel) f (value :: xs) = if f value
then Just value
else find fuel f xs
。そうしないと、誰かがfind forever ?predicateWhichHappensToAlwaysReturnFalse (iterate S Z)
の終了を待つ退屈な生活に苦しむかもしれません。
a
がBits32
の特殊なケースを考えてみましょう。
find32 : (Bits32 -> Bool) -> Stream Bits32 -> Maybe Bits32
find32 f (value :: xs) = if f value then Just value else find32 f xs
2つの問題:それは、合計ではありませんし、しようとするBits32
住民の有限数があるのにもかかわらず、それはおそらくNothing
を返すことができません。たぶん私はtake (pow 2 32)
を使用してリストを作成し、次にリストの検索を使用することができます。ああ、待つ...リストだけでGBのスペースを占有します。
原則として、これは難しいはずのようではありません。非常に多くの住民が試してみることができ、現代のコンピュータはすべての32ビットパーミュテーションを数秒で繰り返すことができます。 the (Stream Bits32) $ iterate (+1) 0
が最終的には0
に戻ってくることを確認する方法がありますか?(+1)
は純粋なので、すべての要素が試されたことを一度アサートしますか?
私は穴を埋める方法がわかりませんが、それを合計するには十分にfind
を特化していますが、ここは始まりです。おそらくインタフェースが助けになるだろうか?
total
IsCyclic : (init : a) -> (succ : a -> a) -> Type
data FinStream : Type -> Type where
MkFinStream : (init : a) ->
(succ : a -> a) ->
{prf : IsCyclic init succ} ->
FinStream a
partial
find : Eq a => (a -> Bool) -> FinStream a -> Maybe a
find pred (MkFinStream {prf} init succ) = if pred init
then Just init
else find' (succ init)
where
partial
find' : a -> Maybe a
find' x = if x == init
then Nothing
else
if pred x
then Just x
else find' (succ x)
total
all32bits : FinStream Bits32
all32bits = MkFinStream 0 (+1) {prf=?prf}
合計で特定のストリーム上で検索を検証する無限の燃料を使用するように全体チェッカーを伝える方法はありますか?
'isCyclic'と' find'は線形スペース 'Nat'sに依存することなく実装できますか?私は私のマシンで 'all16bits'が終了するのに十分なほどの辛抱強さではなかったし、' Nat'が原因だと思う。すべての 'unsigned int'を反復する最適化されていないCプログラムは、私のマシンでは10秒を少し時間がかかり、一定のスペース消費量で同等の性能を目指しています。 –
あなたは正しい、それは長年の問題です。二進数は痛みを緩和することができる。 githubには、Coqのバイナリ番号をIdrisに移植することを目的としたプロジェクトがあります –
これらの2進数は最適化されていない帰納的定義ですか?私はそれが助けになると思いますが、それは最適化された任意精度の符号なし整数を使って行うことができますか? (確かにどちらのソリューションでも一定のスペースではなく$ \ log_2 n $が消費されます) –