module Memory.HeapContext where

open import Data.Nat
open import Data.List
open import Data.Maybe
open import Data.Product using (_×_; ; ∃-syntax) renaming (_,_ to ⟨_,_⟩)
open import Relation.Nullary using (¬_; Dec; yes; no)
open import Relation.Nullary.Negation using (contradiction)
open import Relation.Binary.PropositionalEquality using (_≡_; refl)

open import Common.Utils
open import Common.Types
open import Memory.Addr public

HalfHeapContext = List (RawAddr × RawType)
HeapContext     = HalfHeapContext × HalfHeapContext

lookup-Σ : HeapContext  Addr  Maybe RawType
lookup-Σ  Σᴸ , Σᴴ  (a⟦ low   n) = find _≟_ Σᴸ n
lookup-Σ  Σᴸ , Σᴴ  (a⟦ high  n) = find _≟_ Σᴴ n


infix 4 _⊇_

_⊇_ :  (Σ′ Σ : HeapContext)  Set
Σ′  Σ =  a {T}  lookup-Σ Σ a  just T  lookup-Σ Σ′ a  just T

⊇-refl :  Σ  Σ  Σ
⊇-refl Σ a eq = eq

⊇-trans :  {Σ₁ Σ₂ Σ₃}  Σ₁  Σ₂  Σ₂  Σ₃  Σ₁  Σ₃
⊇-trans Σ₁⊇Σ₂ Σ₂⊇Σ₃ a eq = Σ₁⊇Σ₂ a (Σ₂⊇Σ₃ a eq)

cons-Σ : Addr  RawType  HeapContext  HeapContext
cons-Σ (a⟦ low  n) T  Σᴸ , Σᴴ  =   n , T   Σᴸ , Σᴴ 
cons-Σ (a⟦ high  n) T  Σᴸ , Σᴴ  =  Σᴸ ,  n , T   Σᴴ 

lookup-Σ-cons :  a {T} Σ
   lookup-Σ (cons-Σ a T Σ) a  just T
lookup-Σ-cons (a⟦ high  n)  Σᴸ , Σᴴ  with n  n
... | yes refl = refl
... | no  n≢n  = contradiction refl n≢n
lookup-Σ-cons (a⟦ low  n)  Σᴸ , Σᴴ  with n  n
... | yes refl = refl
... | no  n≢n  = contradiction refl n≢n