Ich versuche, eine funktionale Semantik für IMP Sprache mit parallelen präventiven Planung wie in Abschnitt 4 der folgenden paper vorgestellt.Problem zu verstehen, Agda Coinduction
Ich benutze Agda 2.5.2 und Standard-Bibliothek 0.13. Der gesamte Code ist auch unter folgender Nummer verfügbar: gist.
Zuerst habe ich die Syntax der betreffenden Sprache als induktive Typen definiert.
Der Zustand ist nur ein Vektor der natürlichen Zahlen und Ausdruck Semantik ist einfach.
σ_ : ℕ → Set
σ n = Vec ℕ n
⟦_,_⟧ : ∀ {n} → Exp n → σ n → ℕ
⟦ $ n , s ⟧ = n
⟦ Var v , s ⟧ = lookup v s
⟦ e ⊕ e' , s ⟧ = ⟦ e , s ⟧ + ⟦ e' , s ⟧
Dann habe ich die Art der Wiederaufnahmen definiert, die eine Art von verzögerten Berechnungen sind.
data Res (n : ℕ) : Set where
ret : (st : σ n) → Res n
δ : (r : ∞ (Res n)) → Res n
_∨_ : (l r : ∞ (Res n)) → Res n
yield : (s : Stmt n)(st : σ n) → Res n
Als nächstes folgt 1 definiere ich sequentielle und parallele Ausführung von Anweisungen
evalSeq : ∀ {n} → Stmt n → Res n → Res n
evalSeq s (ret st) = yield s st
evalSeq s (δ r) = δ (♯ (evalSeq s (♭ r)))
evalSeq s (l ∨ r) = ♯ evalSeq s (♭ l) ∨ ♯ evalSeq s (♭ r)
evalSeq s (yield s' st) = yield (s ▷ s') st
evalParL : ∀ {n} → Stmt n → Res n → Res n
evalParL s (ret st) = yield s st
evalParL s (δ r) = δ (♯ evalParL s (♭ r))
evalParL s (l ∨ r) = ♯ evalParL s (♭ l) ∨ ♯ evalParL s (♭ r)
evalParL s (yield s' st) = yield (s ∥ s') st
evalParR : ∀ {n} → Stmt n → Res n → Res n
evalParR s (ret st) = yield s st
evalParR s (δ r) = δ (♯ evalParR s (♭ r))
evalParR s (l ∨ r) = ♯ evalParR s (♭ l) ∨ ♯ evalParR s (♭ r)
evalParR s (yield s' st) = yield (s' ∥ s) st
So weit, so gut. Als nächstes muss ich die Anweisungsbewertungsfunktion wechselseitig definieren mit einer Operation zum Schließen (Ausführen von suspendierten Berechnungen) in einer Wiederaufnahme.
mutual
close : ∀ {n} → Res n → Res n
close (ret st) = ret st
close (δ r) = δ (♯ close (♭ r))
close (l ∨ r) = ♯ close (♭ l) ∨ ♯ close (♭ r)
close (yield s st) = δ (♯ eval s st)
eval : ∀ {n} → Stmt n → σ n → Res n
eval skip st = ret st
eval (x ≔ e) st = δ (♯ (ret (st [ x ]≔ ⟦ e , st ⟧)))
eval (s ▷ s') st = evalSeq s (eval s' st)
eval (iif e then s else s') st with ⟦ e , st ⟧
...| zero = δ (♯ yield s' st)
...| suc n = δ (♯ yield s st)
eval (while e do s) st with ⟦ e , st ⟧
...| zero = δ (♯ ret st)
...| suc n = δ (♯ yield (s ▷ while e do s) st)
eval (s ∥ s') st = (♯ evalParR s' (eval s st)) ∨ (♯ evalParL s (eval s' st))
eval (atomic s) st = {!!} -- δ (♯ close (eval s st))
eval (await e do s) st = {!!}
Agda der Gesamtheit checker beschwert, wenn ich versuche für atomic
Konstruktor das Loch in eval
Gleichung zu füllen mit δ (♯ close (eval s st))
sagen, dass die Abschlussprüfung für mehrere Punkte nicht in beiden eval
und close
Funktion.
Meine Fragen zu diesem Problem sind:
1) Warum ist Agda Kündigung über diese Definitionen Überprüfung beschweren? Es scheint mir, dass der Anruf δ (♯ close (eval s st))
in Ordnung ist, da es auf eine strukturell kleinere Aussage gemacht wird.
2) Current Agda's language documentation sagt, dass diese Art Musiknotation basierte Coinduction ist die "alten Weg" Coinduction in Agda. Es empfiehlt die Verwendung von coinductive records und copatterns. Ich habe mich umgesehen, aber ich konnte keine Beispiele für Copatterns jenseits von Streams und der Verzögerungs-Monade finden. Meine Frage: Ist es möglich, Wiederaufnahmen mit Koinduktiven Akten und Copattern darzustellen?
WRT 1: während eval in 'δ (♯ schließen (eval s st))' mit einem strukturell kleineren Argumente genannt wird, auch in der Nähe eval auf Anrufe das Ergebnis mit Argumenten unbekannter Größe. Eine Beendigung des Evals kann also nicht durch Induktion nachgewiesen werden. –