module Dyn.Noninterference where

open import Data.Empty using (βŠ₯; βŠ₯-elim)
open import Data.Bool using (true; false) renaming (Bool to 𝔹)
open import Data.Sum using (_⊎_; inj₁; injβ‚‚)
open import Data.Product using (_Γ—_; βˆƒ; βˆƒ-syntax; Ξ£; Ξ£-syntax) renaming (_,_ to ⟨_,_⟩)
open import Data.List hiding ([_])
open import Relation.Nullary using (Β¬_; Dec; yes; no)
open import Relation.Nullary.Negation using (contradiction)
open import Relation.Binary.PropositionalEquality using (_≑_; _β‰’_; refl; trans; subst; cong; sym)
open import Function using (case_of_)

open import Common.Utils
open import Common.SecurityLabels
open import Common.Types using (Base; Bool; rep)
open import Dyn.Syntax
open import Dyn.Values
open import Dyn.Erasure
open import Dyn.BigStep
open import Dyn.BigStepErased
open import Dyn.BigStepSimulation
open import Dyn.BigStepErasedDeterministic
open import Dyn.HeapSecure using (βˆ…-sec)


noninterference : βˆ€ {μ₁ ΞΌβ‚‚ M} {b₁ bβ‚‚ b₃ bβ‚„ : rep Bool}
  β†’ βˆ… ∣ low ⊒ M [ $ b₁ of high ] ⇓ $ b₃ of low ∣ μ₁
  β†’ βˆ… ∣ low ⊒ M [ $ bβ‚‚ of high ] ⇓ $ bβ‚„ of low ∣ ΞΌβ‚‚
    ---------------------------------------------
  β†’ b₃ ≑ bβ‚„
noninterference {M = M} {b₁} {bβ‚‚} {b₃} {bβ‚„} M[b₁]⇓b₃ M[bβ‚‚]⇓bβ‚„ =
  let Ο΅M[●]⇓ϡb₃ = subst (Ξ» β–‘ β†’ _ ∣ _ ⊒ β–‘ ⇓ₑ _ ∣ _) (substitution-erase M ($ b₁ of high))
                          (sim βˆ…-sec M[b₁]⇓b₃)
      Ο΅M[●]⇓ϡbβ‚„ = subst (Ξ» β–‘ β†’ _ ∣ _ ⊒ β–‘ ⇓ₑ _ ∣ _) (substitution-erase M ($ bβ‚‚ of high))
                          (sim βˆ…-sec M[bβ‚‚]⇓bβ‚„) in
      case ⇓ₑ-deterministic Ο΅M[●]⇓ϡb₃ Ο΅M[●]⇓ϡbβ‚„ of Ξ» where
      ⟨ refl , _ ⟩ β†’ refl