Ich möchte eine find
Funktion für Streams von Größe-gebundenen Typen, die analog zu den Suchfunktionen für Lists und Vects ist.Totalität und Suche nach Elementen in Streams
total
find : MaxBound a => (a -> Bool) -> Stream a -> Maybe a
Die Herausforderung ist es, es zu machen:
- insgesamt sein
- verbrauchen nicht mehr als
konstantlog_2 N Raum, wobei N die Anzahl der Bits ist erforderlich, um die größtea
zu kodieren. - nicht länger als eine Minute bei der Kompilierung
- zu überprüfen, keine Laufzeit Kosten auferlegen
Allgemeinen insgesamt finden Implementierung für Streams klingt absurd. Streams sind unendlich und ein Prädikat von const False
würde die Suche für immer weitergehen lassen. Eine gute Möglichkeit, diesen allgemeinen Fall zu behandeln, ist die Technik des unendlichen Treibstoffs.
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
, die gut für meinen Anwendungsfall funktioniert, aber ich frage mich, ob in bestimmten spezialisierten Fällen die Gesamtheit Prüfung ohne forever
mit überzeugt sein könnte. Ansonsten kann jemand ein langweiliges Leben lang warten, bis find forever ?predicateWhichHappensToAlwaysReturnFalse (iterate S Z)
fertig ist.
Betrachten Sie den speziellen Fall, in dem a
Bits32
ist.
find32 : (Bits32 -> Bool) -> Stream Bits32 -> Maybe Bits32
find32 f (value :: xs) = if f value then Just value else find32 f xs
Zwei Probleme: es ist nicht total ist, und es kann möglicherweise nicht Nothing
selbst zurückkehren, obwohl es eine endliche Anzahl von Bits32
Einwohnern ist zu versuchen. Vielleicht könnte ich take (pow 2 32)
verwenden, um eine Liste zu erstellen und dann Lists Suche zu verwenden ... uh, warte ... die Liste würde nur GBs Speicherplatz belegen.
Im Prinzip scheint es nicht so schwierig zu sein. Es gibt endlich viele Einwohner, die man ausprobieren kann, und ein moderner Computer kann alle 32-Bit-Permutationen in Sekunden durchlaufen. Gibt es eine Möglichkeit, die Vollständigkeitsprüfung überprüfen zu lassen the (Stream Bits32) $ iterate (+1) 0
schließlich zurück zu 0
und sobald es behauptet, dass alle Elemente ausprobiert worden sind, seit (+1)
ist rein?
Hier ist ein Anfang, obwohl ich nicht sicher bin, wie man die Löcher füllt und find
genug spezialisiert, um es total zu machen. Vielleicht würde eine Schnittstelle helfen?
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}
Gibt es eine Möglichkeit, die Gesamtheit checker zu sagen, unendlich Kraftstoff zu verwenden, um eine Suche über einen bestimmten Strom Verifizieren ist insgesamt?
Können 'isCyclic' und' find' implementiert werden, ohne sich auf lineare '' Nat's zu verlassen? Ich war nicht einmal geduldig genug, um 'all16bits' auf meiner Maschine zu beenden, und ich nehme an,' Nat' ist der Schuldige. Ein nicht optimiertes C-Programm, das über alle "unsigned int" iteriert, dauert etwas mehr als 10 Sekunden auf meinem Rechner, und ich strebe eine vergleichbare Leistung mit konstantem Speicherplatzverbrauch an. –
Sie haben Recht, es ist ein langjähriges Problem. Binärzahlen können die Schmerzen lindern. Es gibt ein Projekt auf github, das darauf abzielt, Coqs Binärzahlen nach Idris zu portieren. –
Sind diese Binärzahlen eine nicht optimierte induktive Definition? Ich stelle mir vor, dass das helfen würde, aber kann es mit optimierten, unsignierten Ints mit beliebiger Genauigkeit gemacht werden? (Zugegebenermaßen würde jede Lösung $ \ log_2 n $ anstelle von konstantem Speicherplatz verbrauchen.) –