{-# OPTIONS --safe --sized-types #-}
open import Generic.Syntax
module Generic.Semantics.Elaboration.LetCounter {I : Set} {d : Desc I} where
import Level as L
open import Size
open import Agda.Builtin.Equality
open import Agda.Builtin.Bool
open import Data.Product
import Data.Product.Categorical.Right as PC
open import Data.List.Base using (List; []; _∷_)
open import Data.List.Relation.Unary.All as All using (All; _∷_)
open import Data.List.Relation.Unary.All.Properties renaming (++⁻ʳ to drop)
open import Function
open import Relation.Unary
open import Data.Var
open import Data.Var.Varlike
open import Data.Environment using (Kripke; th^Var; ε; _∙_; identity; weaken; extract)
open import Generic.Syntax.LetCounter
open import Generic.Syntax.LetBinder
open import Generic.Semantics
open import Generic.Semantics.Syntactic
private
variable
Γ Δ : List I
σ : I
module PCR {Γ : List I} = PC L.zero (rawMonoid Γ)
instance _ = PCR.applicative
Counted : I ─Scoped → I ─Scoped
Counted T i Γ = T i Γ × Count Γ
reify^Count : ∀ Δ σ → Kripke Var (Counted (Tm (d `+ CLet) ∞)) Δ σ Γ →
Counted (Scope (Tm (d `+ CLet) ∞) Δ) σ Γ
reify^Count Δ σ kr = let (scp , c) = reify vl^Var Δ σ kr in scp , drop Δ c
clet : ⟦ Let ⟧ (Kripke Var (Counted (Tm (d `+ CLet) ∞))) σ Γ →
Counted (⟦ CLet ⟧ (Scope (Tm (d `+ CLet) ∞))) σ Γ
clet (στ , (e , ce) , body , eq) = case body weaken (ε ∙ z) of λ where
(t , cx ∷ ct) → (cx , στ , e , t , eq) , merge (control cx ce) ct
Annotate : Semantics (d `+ Let) Var (Counted (Tm (d `+ CLet) ∞))
Semantics.th^𝓥 Annotate = th^Var
Semantics.var Annotate = λ v → `var v , fromVar v
Semantics.alg Annotate = λ where
(true , t) → let (t' , c) = mapA d reify^Count t in `con (true , t') , c
(false , et) → let (et' , c) = clet et in `con (false , et') , c
annotate : ∀[ Tm (d `+ Let) ∞ σ ⇒ Tm (d `+ CLet) ∞ σ ]
annotate t = let (t' , _) = Semantics.semantics Annotate identity t in t'
Inline : Semantics (d `+ CLet) (Tm (d `+ Let) ∞) (Tm (d `+ Let) ∞)
Semantics.th^𝓥 Inline = th^Tm
Semantics.var Inline = id
Semantics.alg Inline = λ where
(true , t) → `con (true , fmap d (reify vl^Tm) t)
(false , many , στ , e , b , eq) → `con (false , στ , e , b weaken (ε ∙ `var z) , eq)
(false , _ , στ , e , b , refl) → extract b (ε ∙ e)
inline : Tm (d `+ CLet) ∞ σ Γ → Tm (d `+ Let) ∞ σ Γ
inline = Semantics.semantics Inline id^Tm
inline-affine : Tm (d `+ Let) ∞ σ Γ → Tm (d `+ Let) ∞ σ Γ
inline-affine = inline ∘′ annotate