私は、次のセクション4に示すように、並列プリエンプティブスケジューリングを使用してIMP言語の機能セマンティクスをコーディングしようとしています。paper。Agdaのコイン導出を理解するのに苦労します
私はAgda 2.5.2と標準ライブラリ0.13を使用しています。また、コード全体は、gistで利用可能です。
まず、問題の言語の構文を誘導型と定義しました。
data Exp (n : ℕ) : Set where
$_ : ℕ → Exp n
Var : Fin n → Exp n
_⊕_ : Exp n → Exp n → Exp n
data Stmt (n : ℕ) : Set where
skip : Stmt n
_≔_ : Fin n → Exp n → Stmt n
_▷_ : Stmt n → Stmt n → Stmt n
iif_then_else_ : Exp n → Stmt n → Stmt n → Stmt n
while_do_ : Exp n → Stmt n → Stmt n
_∥_ : Stmt n → Stmt n → Stmt n
atomic : Stmt n → Stmt n
await_do_ : Exp n → Stmt n → Stmt n
状態は単なる自然数のベクトルであり、式の意味は単純です。
σ_ : ℕ → Set
σ n = Vec ℕ n
⟦_,_⟧ : ∀ {n} → Exp n → σ n → ℕ
⟦ $ n , s ⟧ = n
⟦ Var v , s ⟧ = lookup v s
⟦ e ⊕ e' , s ⟧ = ⟦ e , s ⟧ + ⟦ e' , s ⟧
次に、ある種の遅延計算である再開のタイプを定義しました。
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
次に、1を次のように、私は、これまでのところは良い文
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
のシーケンシャルおよび並列実行を定義します。次に、文章評価関数を、再開時に閉じる(中断した計算を実行する)操作で相互に定義する必要があります。私はδ (♯ close (eval s st))
が終了チェックが両方eval
とclose
機能にいくつかの点で失敗したと言ってatomic
コンストラクタのeval
式の穴を埋めるためにしようとすると
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の全体チェッカーが文句を言います。この問題について
私の質問は以下のとおりです。
1)なぜAgdaの終了は、これらの定義について不満をチェックしていますか?構造的に小さい文の上に が実行されているので、δ (♯ close (eval s st))
というコールは正常です。
2)Current Agda's language documentationは、この種類の音楽表記をベースにした共誘導はAgdaの「旧式」共導出であると言います。それは のコインシデンスレコードと共用体の使用を推奨しています。私は周りを見回しましたが、ストリームと遅延モナド以外のパターンの例は見つけられませんでした。私の質問:コインシデンス・レコードとコパタンを使って再開を表現することは可能でしょうか?
WRT 1: 'δ(♯近い(evalのS ST))でのevalが'構造的に少ない引数で呼び出されている間、近くにはもevalの上の呼び出し、その結果、未知の大きさの引数があります。したがって、誘導を使用して評価の終了を証明することはできません。 –