------------------------------------------------------------------------ -- The "bar theorem" ------------------------------------------------------------------------ module Semantics.BigStep.CompilerCorrectness.BarTheorem where open import Syntax open import Semantics.BigStep open import VirtualMachine import CompilerCorrectness as CC; open CC BigStep import Bar; open Bar _⟶_ open import Data.List hiding (_∈_) open import Data.Product open import Data.Function using (_∘_) open import Relation.Unary hiding (U) open import Relation.Binary.PropositionalEquality -- A generalisation of CompilerCorrectness.Matches. data Matches⁺ (ops : Code) (s : Stack) {t : _} (e : Expr t) (i : Status) : Pred State where returns : ∀ {n} (↡ : e ⇓[ i ] nat n) → Matches⁺ ops s e i ⟨ ops , i , nat n ∷ s ⟩ throws : (↯ : e ⇓[ i ] throw) → Matches⁺ ops s e i ⟪ i , s ⟫ -- Matches⁺ is actually a generalisation. Matches⁺⇒Matches : ∀ {t} {e : Expr t} {i} → Matches⁺ [] [] e i ⊆ λ s → e ⇓[ i ]Matches s Matches⁺⇒Matches ._ (returns ↡) = returns ↡ Matches⁺⇒Matches ._ (throws ↯) = throws ↯ -- Some abbreviations, used in the proof of the bar theorem. _∋◁∞_ : Pred State → Pred State → Set1 P ∋◁∞ Q = ∀ {y} → y ∈ P → y ◁∞″ Q _⟶◁∞_ : State → Pred State → Set1 _⟶◁∞_ x = _∋◁∞_ (_⟶_ x) -- The bar theorem. bar-thm : ∀ {t} (e : Expr t) {ops i s} → ⟨ comp e ops , i , s ⟩ ◁∞″ Matches⁺ ops s e i bar-thm {t = t} ⌜ nat n ⌝ = ↓ later (, push) helper₁ where helper₁ : ∀ {ops i s} → ⟨ push n ∷ ops , i , s ⟩ ⟶◁∞ Matches⁺ ops s {t} ⌜ nat n ⌝ i helper₁ push = ↓ now (returns Val) helper₁ interrupt = ↓ now (throws Int) bar-thm {t = t} ⌜ throw ⌝ = ↓ later (, throw) helper₁ where helper₁ : ∀ {ops i s} → ⟨ throw ∷ ops , i , s ⟩ ⟶◁∞ Matches⁺ ops s {t} ⌜ throw ⌝ i helper₁ throw = ↓ now (throws Val) helper₁ interrupt = ↓ now (throws Int) bar-thm (x ⊕ y) = ◁∞′-trans (bar-thm x) helper₁ where helper₆ : ∀ {ops m s} → ⟪ U , nat m ∷ s ⟫ ⟶◁∞ Matches⁺ ops s (x ⊕ y) U helper₆ nat = ↓ now (throws Int) helper₅ : ∀ {ops m n s} → ⟪ U , nat n ∷ nat m ∷ s ⟫ ⟶◁∞ Matches⁺ ops s (x ⊕ y) U helper₅ nat = ↓ later (, nat) helper₆ helper₄ : ∀ {ops i m s} → x ⇓[ i ] nat m → y ↯[ i ] → ⟪ i , nat m ∷ s ⟫ ⟶◁∞ Matches⁺ ops s (x ⊕ y) i helper₄ x↡ y↯ nat = ↓ now (throws (Add₃ x↡ y↯)) helper₃ : ∀ {ops i n m s} → x ⇓[ i ] nat m → y ⇓[ i ] nat n → ⟨ add ∷ ops , i , nat n ∷ nat m ∷ s ⟩ ⟶◁∞ Matches⁺ ops s (x ⊕ y) i helper₃ x↡ y↡ add = ↓ now (returns (Add₁ x↡ y↡)) helper₃ _ _ interrupt = ↓ later (, nat) helper₅ helper₂ : ∀ {ops i m s} → x ⇓[ i ] nat m → Matches⁺ (add ∷ ops) (nat m ∷ s) y i ∋◁∞ Matches⁺ ops s (x ⊕ y) i helper₂ x↡ (returns y↡) = ↓ later (, add) (helper₃ x↡ y↡) helper₂ x↡ (throws y↯) = ↓ later (, nat) (helper₄ x↡ y↯) helper₁ : ∀ {ops i s} → Matches⁺ (comp y (add ∷ ops)) s x i ∋◁∞ Matches⁺ ops s (x ⊕ y) i helper₁ (throws x↯) = ↓ now (throws (Add₂ x↯)) helper₁ (returns x↡) = ◁∞′-trans (bar-thm y) (helper₂ x↡) bar-thm (x >> y) = ◁∞′-trans (bar-thm x) helper₁ where helper₄ : ∀ {ops m s} → ⟪ U , nat m ∷ s ⟫ ⟶◁∞ Matches⁺ ops s (x >> y) U helper₄ nat = ↓ now (throws Int) helper₃ : ∀ {ops i m s} → x ⇓[ i ] nat m → Matches⁺ ops s y i ∋◁∞ Matches⁺ ops s (x >> y) i helper₃ x↡ (returns y↡) = ↓ now (returns (Seqn₁ x↡ y↡)) helper₃ x↡ (throws y↯) = ↓ now (throws (Seqn₁ x↡ y↯)) helper₂ : ∀ {ops i m s} → x ⇓[ i ] nat m → ⟨ pop ∷ comp y ops , i , nat m ∷ s ⟩ ⟶◁∞ Matches⁺ ops s (x >> y) i helper₂ x↡ pop = ◁∞′-trans (bar-thm y) (helper₃ x↡) helper₂ _ interrupt = ↓ later (, nat) helper₄ helper₁ : ∀ {ops i s} → Matches⁺ (pop ∷ comp y ops) s x i ∋◁∞ Matches⁺ ops s (x >> y) i helper₁ (throws x↯) = ↓ now (throws (Seqn₂ x↯)) helper₁ (returns x↡) = ↓ later (, pop) (helper₂ x↡) bar-thm (x catch y) = ↓ later (, mark) helper₁ where helper₉ : ∀ {ops i s} → x ↯[ i ] → y ↯[ B ] → ⟪ B , int i ∷ s ⟫ ⟶◁∞ Matches⁺ ops s (x catch y) i helper₉ x↯ y↯ int = ↓ now (throws (Catch₂ x↯ y↯)) helper₈ : ∀ {ops i n s} → x ↯[ i ] → y ⇓[ B ] nat n → ⟨ reset ∷ ops , B , nat n ∷ int i ∷ s ⟩ ⟶◁∞ Matches⁺ ops s (x catch y) i helper₈ x↯ y↡ reset = ↓ now (returns (Catch₂ x↯ y↡)) helper₇ : ∀ {ops i s} → x ↯[ i ] → Matches⁺ (reset ∷ ops) (int i ∷ s) y B ∋◁∞ Matches⁺ ops s (x catch y) i helper₇ x↯ (returns y↡) = ↓ later (, reset) (helper₈ x↯ y↡) helper₇ x↯ (throws y↯) = ↓ later (, int) (helper₉ x↯ y↯) helper₆ : ∀ {ops i s} → x ↯[ i ] → ⟪ i , han (comp y (reset ∷ ops)) ∷ s ⟫ ⟶◁∞ Matches⁺ ops s (x catch y) i helper₆ x↯ han = ◁∞′-trans (bar-thm y) (helper₇ x↯) helper₅ : ∀ {ops i s} → x ↯[ i ] → ⟪ i , han (comp y (reset ∷ ops)) ∷ s ⟫ ◁∞″ Matches⁺ ops s (x catch y) i helper₅ x↯ = ↓ later (, han) (helper₆ x↯) helper₄ : ∀ {ops m s} → ⟪ U , nat m ∷ han (comp y (reset ∷ ops)) ∷ s ⟫ ⟶◁∞ Matches⁺ ops s (x catch y) U helper₄ nat = helper₅ Int helper₃ : ∀ {ops i m s} → x ⇓[ i ] nat m → ⟨ unmark ∷ ops , i , nat m ∷ han (comp y (reset ∷ ops)) ∷ s ⟩ ⟶◁∞ Matches⁺ ops s (x catch y) i helper₃ x↡ unmark = ↓ now (returns (Catch₁ x↡)) helper₃ _ interrupt = ↓ later (, nat) helper₄ helper₂ : ∀ {ops i s} → Matches⁺ (unmark ∷ ops) (han (comp y (reset ∷ ops)) ∷ s) x i ∋◁∞ Matches⁺ ops s (x catch y) i helper₂ (returns x↡) = ↓ later (, unmark) (helper₃ x↡) helper₂ (throws x↯) = helper₅ x↯ helper₁ : ∀ {ops i s} → ⟨ mark (comp y (reset ∷ ops)) ∷ comp x (unmark ∷ ops) , i , s ⟩ ⟶◁∞ Matches⁺ ops s (x catch y) i helper₁ mark = ◁∞′-trans (bar-thm x) helper₂ helper₁ interrupt = ↓ now (throws Int) bar-thm (block x) = ↓ later (, set) helper₁ where helper₄ : ∀ {ops i s} → x ↯[ B ] → ⟪ B , int i ∷ s ⟫ ⟶◁∞ Matches⁺ ops s (block x) i helper₄ x↯ int = ↓ now (throws (Block x↯)) helper₃ : ∀ {ops i m s} → x ⇓[ B ] nat m → ⟨ reset ∷ ops , B , nat m ∷ int i ∷ s ⟩ ⟶◁∞ Matches⁺ ops s (block x) i helper₃ x↡ reset = ↓ now (returns (Block x↡)) helper₂ : ∀ {ops i s} → Matches⁺ (reset ∷ ops) (int i ∷ s) x B ∋◁∞ Matches⁺ ops s (block x) i helper₂ (returns x↡) = ↓ later (, reset) (helper₃ x↡) helper₂ (throws x↯) = ↓ later (, int) (helper₄ x↯) helper₁ : ∀ {ops i s} → ⟨ set B ∷ comp x (reset ∷ ops) , i , s ⟩ ⟶◁∞ Matches⁺ ops s (block x) i helper₁ set = ◁∞′-trans (bar-thm x) helper₂ helper₁ interrupt = ↓ now (throws Int) bar-thm (unblock x) = ↓ later (, set) helper₁ where helper₆ : ∀ {ops i s} → x ↯[ U ] → ⟪ U , int i ∷ s ⟫ ⟶◁∞ Matches⁺ ops s (unblock x) i helper₆ x↯ int = ↓ now (throws (Unblock x↯)) helper₅ : ∀ {ops i s} → x ↯[ U ] → ⟪ U , int i ∷ s ⟫ ◁∞″ (Matches⁺ ops s (unblock x) i) helper₅ x↯ = ↓ later (, int) (helper₆ x↯) helper₄ : ∀ {ops i m s} → ⟪ U , nat m ∷ int i ∷ s ⟫ ⟶◁∞ Matches⁺ ops s (unblock x) i helper₄ nat = helper₅ Int helper₃ : ∀ {ops i m s} → x ⇓[ U ] nat m → ⟨ reset ∷ ops , U , nat m ∷ int i ∷ s ⟩ ⟶◁∞ Matches⁺ ops s (unblock x) i helper₃ x↡ reset = ↓ now (returns (Unblock x↡)) helper₃ _ interrupt = ↓ later (, nat) helper₄ helper₂ : ∀ {ops i s} → Matches⁺ (reset ∷ ops) (int i ∷ s) x U ∋◁∞ Matches⁺ ops s (unblock x) i helper₂ (returns x↡) = ↓ later (, reset) (helper₃ x↡) helper₂ (throws x↯) = helper₅ x↯ helper₁ : ∀ {ops i s} → ⟨ set U ∷ comp x (reset ∷ ops) , i , s ⟩ ⟶◁∞ Matches⁺ ops s (unblock x) i helper₁ set = ◁∞′-trans (bar-thm x) helper₂ helper₁ interrupt = ↓ now (throws Int) bar-thm (loop x) = ↓ later (, loop) helper₁ where helper₄ : ∀ {ops m s} → ⟪ U , nat m ∷ s ⟫ ⟶◁∞ Matches⁺ ops s (loop x) U helper₄ nat = ↓ now (throws Int) helper₃ : ∀ {ops i m s} → x ⇓[ i ] nat m → ⟨ pop ∷ loop x ∷ ops , i , nat m ∷ s ⟩ ⟶◁∞ Matches⁺ ops s (loop x) i helper₃ x↡ pop ~ bar-thm (loop x) helper₃ _ interrupt = ↓ later (, nat) helper₄ helper₂ : ∀ {ops i s} → Matches⁺ (pop ∷ loop x ∷ ops) s x i ∋◁∞ Matches⁺ ops s (loop x) i helper₂ (throws x↯) = ↓ now (throws (Loop (Seqn₂ x↯))) helper₂ (returns x↡) = ↓ later (, pop) (helper₃ x↡) helper₁ : ∀ {ops i s} → ⟨ loop x ∷ ops , i , s ⟩ ⟶◁∞ Matches⁺ ops s (loop x) i helper₁ loop = ◁∞′-trans (bar-thm x) helper₂ helper₁ interrupt = ↓ now (throws Int) bar-theorem : ∀ {t} (e : Expr t) {ops i s} → ⟨ comp e ops , i , s ⟩ ◁∞ Matches⁺ ops s e i bar-theorem e = ∞″→∞ (bar-thm e)