module CoercionExpr.SimCastUp where
open import Data.Nat
open import Data.Unit using (⊤; tt)
open import Data.Bool using (true; false) renaming (Bool to 𝔹)
open import Data.List hiding ([_])
open import Data.Product renaming (_,_ to ⟨_,_⟩)
open import Data.Sum using (_⊎_)
open import Data.Maybe
open import Relation.Nullary using (¬_; Dec; yes; no)
open import Relation.Binary.PropositionalEquality using (_≡_; refl)
open import Function using (case_of_)
open import Common.Utils
open import Common.SecurityLabels
open import Common.BlameLabels
open import CoercionExpr.CoercionExpr
open import CoercionExpr.Precision
open import CoercionExpr.CatchUp
sim-cast-↑-proj : ∀ {g g′} {p} {c̅₁ : CExpr g ⇒ ⋆} {c̅′ : CExpr g′ ⇒ l low}
→ ⊢ c̅₁ ⊑ c̅′ ⨾ low !
→ CVal c̅′
→ ∃[ c̅₂ ] (c̅₁ ⨾ high ?? p —↠ c̅₂) × (⊢ c̅₂ ⊑ c̅′ ⨾ ↑)
sim-cast-↑-proj {p = p} {c̅₁ = c̅₁} {c̅′ = id (l low)} c̅₁⊑c̅′⨾! id
with catchup c̅₁ _ (inj id) c̅₁⊑c̅′⨾!
... | ⟨ id ⋆ , id , c̅₁↠id , ⊑-castr id⊑c̅₂′ ⋆⊑ ⋆⊑ ⟩ =
⟨ id ⋆ ⨾ high ?? p , plug-cong c̅₁↠id , ⊑-cast id⊑c̅₂′ ⋆⊑ l⊑l ⟩
... | ⟨ c̅ₙ ⨾ low ! , inj v , c̅₁↠c̅ₙ⨾! , ⊑-castr (⊑-castl c̅ₙ⊑id l⊑l ⋆⊑) ⋆⊑ ⋆⊑ ⟩ =
⟨ c̅ₙ ⨾ ↑ , ↠-trans (plug-cong c̅₁↠c̅ₙ⨾!) (_ —→⟨ ?-↑ v ⟩ _ ∎) , ⊑-cast c̅ₙ⊑id l⊑l l⊑l ⟩
... | ⟨ c̅ₙ ⨾ low ! , inj v , c̅₁↠c̅ₙ⨾! , ⊑-cast c̅ₙ⊑id l⊑l ⋆⊑ ⟩ =
⟨ c̅ₙ ⨾ ↑ , ↠-trans (plug-cong c̅₁↠c̅ₙ⨾!) (_ —→⟨ ?-↑ v ⟩ _ ∎) , ⊑-cast c̅ₙ⊑id l⊑l l⊑l ⟩
sim-cast-↑-proj {p = p} {c̅₁ = c̅₁} {c̅′ = id ⋆ ⨾ low ?? p′} c̅₁⊑c̅′⨾! id⨾?
with catchup c̅₁ _ (inj id⨾?) c̅₁⊑c̅′⨾!
... | ⟨ id ⋆ , id , c̅₁↠id , ⊑-castr id⊑id⨾? ⋆⊑ ⋆⊑ ⟩ =
⟨ id ⋆ ⨾ high ?? p , plug-cong c̅₁↠id , ⊑-cast id⊑id⨾? ⋆⊑ l⊑l ⟩
... | ⟨ c̅ₙ ⨾ low ! , inj v , c̅₁↠c̅ₙ⨾! , ⊑-castr (⊑-castl x l⊑l ⋆⊑) ⋆⊑ ⋆⊑ ⟩ =
⟨ c̅ₙ ⨾ ↑ , ↠-trans (plug-cong c̅₁↠c̅ₙ⨾!) (_ —→⟨ ?-↑ v ⟩ _ ∎) , ⊑-cast x l⊑l l⊑l ⟩
... | ⟨ c̅ₙ ⨾ low ! , inj v , c̅₁↠c̅ₙ⨾! , ⊑-castr (⊑-castr (⊑-castl _ () _) _ _) ⋆⊑ ⋆⊑ ⟩
... | ⟨ c̅ₙ ⨾ low ! , inj v , c̅₁↠c̅ₙ⨾! , ⊑-cast x l⊑l ⋆⊑ ⟩ =
⟨ c̅ₙ ⨾ ↑ , ↠-trans (plug-cong c̅₁↠c̅ₙ⨾!) (_ —→⟨ ?-↑ v ⟩ _ ∎) , ⊑-cast x l⊑l l⊑l ⟩
... | ⟨ c̅ₙ ⨾ high ! , inj v , c̅₁↠c̅ₙ⨾! , ⊑-castr (⊑-castr (⊑-castl _ () _) ⋆⊑ ⋆⊑) ⋆⊑ ⋆⊑ ⟩
sim-cast-↑ : ∀ {g₁ g₂ g₃ g′}
{c̅₁ : CExpr g₁ ⇒ g₂} {c̅′ : CExpr g′ ⇒ l low}
{c : ⊢ g₂ ⇒ g₃}
→ ⊢ c̅₁ ⊑ c̅′ ⨾ low !
→ g₂ ⊑ₗ ⋆ → g₃ ⊑ₗ l high
→ CVal c̅′
→ ∃[ c̅₂ ] (c̅₁ ⨾ c —↠ c̅₂) × (⊢ c̅₂ ⊑ c̅′ ⨾ ↑)
sim-cast-↑ {c̅₁ = c̅₁} {c = id ⋆} c̅₁⊑c̅₁′ ⋆⊑ ⋆⊑ v′
with catchup c̅₁ _ (inj v′) c̅₁⊑c̅₁′
... | ⟨ c̅ₙ , v , c̅₁↠c̅ₙ , c̅ₙ⊑c̅₁′ ⟩ =
⟨ c̅ₙ , ↠-trans (plug-cong c̅₁↠c̅ₙ) (_ —→⟨ id v ⟩ _ ∎) ,
⊑-castr (prec-inj-left _ _ v v′ c̅ₙ⊑c̅₁′) ⋆⊑ ⋆⊑ ⟩
sim-cast-↑ {c̅₁ = c̅₁} {c = high ?? p} c̅₁⊑c̅₁′ ⋆⊑ l⊑l v′ = sim-cast-↑-proj c̅₁⊑c̅₁′ v′