J'essaie de coder une sémantique fonctionnelle pour le langage IMP avec une planification préemptive parallèle comme présenté dans la section 4 du paper suivant. J'utilise Agda 2.5.2 et la bibliothèque standard 0.13. En outre, le code entier est disponible à l'adresse suivante gist. En premier lieu, j'ai défini la syntaxe du langage en question comme des types inductifs. L'état est juste un vecteur de nombres naturels et la sémantique d'expression est directe. Ensuite, j'ai défini le type de reprises, qui sont une sorte de calculs retardés.Problème de compréhension de la Coinduction d'Agda
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
Ensuite, suivant 1, je définir l'exécution séquentielle et parallèle des états
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
Jusqu'à présent, si bon. Ensuite, j'ai besoin de définir la fonction d'évaluation d'une instruction avec une opération de fermeture (exécution de calculs suspendus) dans une reprise.
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 = {!!}
le vérificateur de la totalité de Agda se plaint lorsque je tente de combler le trou dans eval
équation pour atomic
constructeur avec δ (♯ close (eval s st))
en disant que la vérification de terminaison échoue pour plusieurs points dans les deux fonctions eval
et close
.
Mes questions sur ce problème sont:
1) Pourquoi la fin Agda vérifier se plaindre de ces définitions? Il me semble que l'appel δ (♯ close (eval s st))
est bien car il est fait sur une déclaration structurellement plus petit. 2) Current Agda's language documentation 2) Current Agda's language documentation dit que cette sorte de coinduction basée sur la notation musicale est la coinduction "à l'ancienne" dans Agda. Il recommande l'utilisation des enregistrements coindatifs et des copatterns. J'ai regardé autour de moi mais je ne pouvais pas trouver des exemples de personnages au-delà des flux et de la monade de retard. Ma question: est-il possible de représenter des reprises en utilisant des enregistrements coinductifs et des copatterns?
WRT 1: alors que eval dans 'δ (♯ proche (eval s st))' est appelée avec un argument structurellement plus petit, à proximité appelle également eval sur le résultat, avec des arguments de taille inconnue. Donc, la fin d'eval ne peut pas être prouvée en utilisant l'induction. –