Generieren von Laufzeitproofs mit Typprädikaten in Idris

8

Ich verwende diesen Typ, um über Strings zu argumentieren, auf denen Decidable Parsing ausgeführt werden kann:

%Vor%

Zum Beispiel definieren Sie die Ziffern [0-9] wie folgt:

%Vor%

Dann können wir folgende Funktionen haben:

%Vor%

Diese s2n -Funktion funktioniert jetzt gut zur Kompilierzeit, aber das ist an sich nicht sehr nützlich. Um es zur Laufzeit zu verwenden, müssen wir den Beweis Every Digit (unpack s) erstellen, bevor wir die Funktion verwenden können.

Also ich denke ich möchte jetzt so etwas wie diese Funktion schreiben:

%Vor%

Das oder wir wollen entweder einen Beweis der Mitgliedschaft oder einen Nachweis der Nicht-Mitgliedschaft zurückgeben, aber ich bin mir nicht ganz sicher, wie ich eines dieser Dinge allgemein machen soll. Also habe ich versucht, die Maybe Version nur für Charaktere zu machen:

%Vor%

Aber dann bekomme ich diesen Unifikationsfehler:

%Vor%

Aber p ist vom Typ Char -> Type . Ich bin mir nicht sicher, was diesen Unifikationsfehler verursacht, aber denke, dass das Problem mit zusammenhängen könnte meine vorherige Frage .

Ist das eine vernünftige Herangehensweise an das, was ich versuche? Ich habe das Gefühl, dass es im Moment ein wenig zu viel Arbeit ist und allgemeinere Versionen dieser Funktionen möglich sein sollten. Es wäre schön, wenn das auto Schlüsselwort zum Schreiben einer Funktion verwendet werden könnte, gibt es eine Maybe proof oder eine Either proof proofThatItIsNot , ähnlich wie die DecEq Klasse funktioniert.

    
Vic Smith 23.11.2014, 23:12
quelle

1 Antwort

8

Die Fehlermeldung ist korrekt: Sie haben einen Wert vom Typ Type angegeben, aber Sie benötigen einen Wert vom Typ p '0' . Sie haben auch Recht, dass p vom Typ Char -> Type ist und daher p '0' vom Typ Type ist. % Co_de% hat jedoch nicht den Typ p '0' .

Vielleicht wäre das Problem einfacher mit einfacheren Typen zu sehen: p '0' hat den Typ 3 und Int hat den Typ Int , aber Type hat nicht den Typ Int .

Nun, wie beheben wir das Problem? Nun, Int ist ein Prädikat, was bedeutet, dass es Typen konstruiert, deren Bewohner Beweise für dieses Prädikat sind. Also wäre der Wert des Typs p , den wir bereitstellen müssen, ein Beweis, in diesem Fall ein Beweis dafür, dass p '0' eine Ziffer ist. '0' ist ein solcher Beweis. Aber in der Signatur von Zero spricht die Variable every nicht von Ziffern: Es ist ein abstraktes Prädikat, über das wir nichts wissen. Aus diesem Grund gibt es keine Werte, die wir anstelle von p verwenden könnten. Wir müssen stattdessen den Typ von p '0' ändern.

Eine Möglichkeit wäre, eine speziellere Version von every zu schreiben, die nur für das bestimmte Prädikat every funktioniert, anstatt für eine beliebige Digit :

zu arbeiten %Vor%

Anstatt den Wert p an einer Stelle falsch zu verwenden, die einen Wert vom Typ p '0' benötigt, habe ich den Wert p '0' an einer Stelle verwendet, die jetzt einen Wert vom Typ Zero benötigt.

Eine andere Möglichkeit bestünde darin, Digit '0' so zu ändern, dass zusätzlich zu dem Prädikat every , das für jeden p einen Proof-Typ gibt, auch eine Proof-Funktion Char erhalten würde, die das entsprechende ergibt Beweiswert für jedes mkPrf , wenn möglich.

%Vor%

Ich habe keinen Mustervergleich mehr auf der Seite Char , stattdessen frage ich Char , um mkPrf zu untersuchen. Ich mustere dann das Ergebnis, um zu sehen, ob es einen Beweis gefunden hat. Es ist die Implementierung von Char , die Muster-Übereinstimmungen in mkPrf .

%Vor%

In der Implementierung von Char konstruieren wir wieder einen Beweis für den konkreten Typ mkPrf anstelle des abstrakten Typs Digit '0' , also ist p '0' ein akzeptabler Beweis.

    
gelisam 25.11.2014, 02:57
quelle