|
| 1 | +module Generic.Semantics.Elaboration.LetCounter where |
| 2 | + |
| 3 | +import Level as L |
| 4 | +open import Size |
| 5 | +open import Agda.Builtin.Equality |
| 6 | +open import Agda.Builtin.Bool |
| 7 | +open import Data.Product |
| 8 | +import Data.Product.Categorical.Right as PC |
| 9 | +open import Data.List.Base |
| 10 | +open import Data.List.Relation.Unary.All as All |
| 11 | +open import Data.List.Relation.Unary.All.Properties |
| 12 | +open import Function |
| 13 | + |
| 14 | +open import var |
| 15 | +open import varlike |
| 16 | +open import indexed |
| 17 | +open import environment using (Kripke; th^Var; ε; _∙_; extend) |
| 18 | +open import Generic.Syntax |
| 19 | +import Generic.Syntax.LetCounter as LetCounter |
| 20 | +open LetCounter hiding (Let) |
| 21 | +import Generic.Syntax.LetBinder as LetBinder |
| 22 | +open import Generic.Semantics |
| 23 | +open import Generic.Semantics.Syntactic |
| 24 | + |
| 25 | +module _ {I : Set} {d : Desc I} where |
| 26 | + |
| 27 | + module PCR {Γ : List I} = PC L.zero (rawMonoid Γ) |
| 28 | + |
| 29 | + Counted : I ─Scoped → I ─Scoped |
| 30 | + Counted T i Γ = T i Γ × Count Γ |
| 31 | + |
| 32 | + count : ∀ {σ Γ} e → ⟦ e ⟧ (Kripke Var (Counted (Tm (d `+ LetCounter.Let) ∞))) σ Γ → |
| 33 | + Counted (⟦ e ⟧ (Scope (Tm (d `+ LetCounter.Let) ∞))) σ Γ |
| 34 | + count (`σ A e) (a , t) = map₁ (a ,_) (count (e a) t) |
| 35 | + count (`X Δ j e) (kr , t) = |
| 36 | + let (r , cr) = reify vl^Var Δ j kr |
| 37 | + (u , cu) = count e t |
| 38 | + in (r , u) , merge (++⁻ʳ Δ cr) cu |
| 39 | + count (`∎ eq) t = t , zeros |
| 40 | + |
| 41 | + LetCount : Sem (d `+ LetBinder.Let) Var (Counted (Tm (d `+ LetCounter.Let) ∞)) |
| 42 | + Sem.th^𝓥 LetCount = th^Var |
| 43 | + Sem.var LetCount = λ v → `var v , fromVar v |
| 44 | + Sem.alg LetCount = λ where |
| 45 | + (true , t) → map₁ (`con ∘′ (true ,_)) (count d t) |
| 46 | + (false , στ , (e , ce) , tct , refl) → |
| 47 | + let (t , ct) = tct extend (ε ∙ z) |
| 48 | + e-usage = All.head ct |
| 49 | + in `con (false , e-usage , στ , e , t , refl) |
| 50 | + , -- if e (the let-bound expression) is not used in t (the body of the let) |
| 51 | + -- we can ignore its contribution to the count: |
| 52 | + (case e-usage of λ where |
| 53 | + zero → All.tail ct |
| 54 | + _ → merge ce (All.tail ct)) |
| 55 | + |
| 56 | + annotate : ∀ {σ Γ} → Tm (d `+ LetBinder.Let) ∞ σ Γ → Tm (d `+ LetCounter.Let) ∞ σ Γ |
| 57 | + annotate = proj₁ ∘′ Sem.sem LetCount (base vl^Var) |
| 58 | + |
| 59 | + Inline : Sem (d `+ LetCounter.Let) (Tm (d `+ LetBinder.Let) ∞) |
| 60 | + (Tm (d `+ LetBinder.Let) ∞) |
| 61 | + Sem.th^𝓥 Inline = th^Tm |
| 62 | + Sem.var Inline = id |
| 63 | + Sem.alg Inline = λ where |
| 64 | + (true , t) → `con (true , fmap d (reify vl^Tm) t) |
| 65 | + (false , many , στ , e , b , eq) → `con (false , στ , e , b extend (ε ∙ `var z) , eq) |
| 66 | + (false , _ , στ , e , b , refl) → b (base vl^Var) (ε ∙ e) |
| 67 | + |
| 68 | + inline : ∀ {σ Γ} → Tm (d `+ LetCounter.Let) ∞ σ Γ → Tm (d `+ LetBinder.Let) ∞ σ Γ |
| 69 | + inline = Sem.sem Inline (base vl^Tm) |
| 70 | + |
| 71 | + inline-affine : ∀ {σ Γ} → Tm (d `+ LetBinder.Let) ∞ σ Γ → Tm (d `+ LetBinder.Let) ∞ σ Γ |
| 72 | + inline-affine = inline ∘′ annotate |
0 commit comments