------------------------------------------------------------------------
-- A resource aware heap semantics. The reduction relations.
------------------------------------------------------------------------

open import Graded.Modality
open import Graded.Usage.Restrictions
open import Definition.Typed.Variant
open import Graded.Usage.Restrictions.Natrec

module Graded.Heap.Reduction
  {a} {M : Set a}
  {𝕄 : Modality M}
  (type-variant : Type-variant)
  (UR : Usage-restrictions 𝕄)
  (open Usage-restrictions UR)
  (factoring-nr :
     has-nr : Nr-available  
    Is-factoring-nr M (Natrec-mode-Has-nr 𝕄 has-nr))
  where

open import Tools.Empty
open import Tools.Fin
open import Tools.Nat
open import Tools.Product
open import Tools.Relation

open import Definition.Untyped M
open import Graded.Heap.Untyped type-variant UR factoring-nr

open Type-variant type-variant
open Modality 𝕄

private variable
  m m′ n n′ k  : Nat
  H H′ : Heap _ _
  ρ ρ′ : Wk _ _
  t t′ u v w z s A B t₁ t₂ : Term _
  x : Fin _
  S S′ : Stack _
  p p′ q q′ r : M
  str : Strength
  l : Universe-level
  s₁ s₂ s₃ : State _ _ _

-- The abstract machine has three different semantics.
-- 1. A call-by-name semantics with resource tracking that reduces terms
--    to WHNF. Denoted by _⇾_.
-- 2. A call-by-name semantics without resource tracking that reduces
--    terms to WHNF. Denoted by _⇢_.
-- 3. A call-by-name semantics with resource tracking that fully
--    evaluates natural numbers to numerals (but that otherwise reduces
--    terms to WHNF). Denoted by _↠_.
--
-- These are defined using a few additional reduction relations.

------------------------------------------------------------------------
-- The preliminary reduction relations.

-- The relation _⇒ₑ_ describes evaluation of states with an eliminator
-- in head position.

infix 28 _⇒ₑ_

data _⇒ₑ_ {k m n} : State k m n  State k m n  Set a where
  appₕ :  H , t ∘⟨ p  u , ρ , S  ⇒ₑ  H , t , ρ , ∘ₑ p u ρ  S 
  fstₕ :  H , fst p t , ρ , S  ⇒ₑ  H , t , ρ , fstₑ p  S 
  sndₕ :  H , snd p t , ρ , S  ⇒ₑ  H , t , ρ , sndₑ p  S 
  prodrecₕ :  H , prodrec r p q A t u , ρ , S  ⇒ₑ
              H , t , ρ , prodrecₑ r p q A u ρ  S 
  natrecₕ :  H , natrec p q r A z s t , ρ , S  ⇒ₑ
             H , t , ρ , natrecₑ p q r A z s ρ  S 
  unitrecₕ : ¬ Unitʷ-η 
              H , unitrec l p q A t u , ρ , S  ⇒ₑ
              H , t , ρ , unitrecₑ l p q A u ρ  S 
  emptyrecₕ :  H , emptyrec p A t , ρ , S  ⇒ₑ
               H , t , ρ , emptyrecₑ p A ρ  S 
  Jₕ :  H , J p q A t B u v w , ρ , S  ⇒ₑ
        H , w , ρ , Jₑ p q A t B u v ρ  S 
  Kₕ :  H , K p A t B u v , ρ , S  ⇒ₑ
        H , v , ρ , Kₑ p A t B u ρ  S 
  []-congₕ :  H , []-cong str A t u v , ρ , S  ⇒ₑ
              H , v , ρ , []-congₑ str A t u ρ  S 

-- The relation _⇾ₑ_ describes evaluation of states with an eliminator
-- or a variable in head position with resource tracking.

infix 28 _⇾ₑ_
infix 30 ⇒ₑ_

data _⇾ₑ_ {k m n} : State k m n  State k m n′  Set a where
  var :  S ∣≡ p 
        H  wkVar ρ x ↦[ p ] (t , ρ′)  H′ 
         H , var x , ρ , S  ⇾ₑ  H′ , t , ρ′ , S 
  ⇒ₑ_ : s₁ ⇒ₑ s₂  s₁ ⇾ₑ s₂

-- Reflexive, transistive closure of _⇾ₑ_.

infix 28 _⇾ₑ*_
infixr 29 _⇨_

data _⇾ₑ*_ (s : State k m n) : (s′ : State k m n′)  Set a where
  id : s ⇾ₑ* s
  _⇨_ :  {n″} {s′ : State k m n′} {s″ : State k m n″}
       s ⇾ₑ s′  s′ ⇾ₑ* s″  s ⇾ₑ* s″

-- The relation _⇢ₑ_ describes evaluation of states with an eliminator
-- or a variable in head position without resource tracking.

infix 28 _⇢ₑ_

data _⇢ₑ_ {k m n} : State k m n  State k m n′  Set a where
  var : H  wkVar ρ x  (t , ρ′) 
         H , var x , ρ , S  ⇢ₑ  H , t , ρ′ , S 
  ⇒ₑ_ : s₁ ⇒ₑ s₂  s₁ ⇢ₑ s₂

-- Reflexive, transistive closure of _⇢ₑ*_

infix 28 _⇢ₑ*_

data _⇢ₑ*_ (s : State k m n) : (s′ : State k m n′)  Set a where
  id : s ⇢ₑ* s
  _⇨_ :  {n″} {s′ : State k m n′} {s″ : State k m n″}
       s ⇢ₑ s′  s′ ⇢ₑ* s″  s ⇢ₑ* s″

-- The relation _⇒ᵥ_ evaluates states with values in head position and a
-- matching continuation on the top of the stack.

infix 28 _⇒ᵥ_

data _⇒ᵥ_ {k m n} : State k m n  State k m′ n′  Set a where
  lamₕ :  S ∣≡ q
         H , lam p t , ρ , ∘ₑ p u ρ′  S  ⇒ᵥ
          H  (q · p , u , ρ′) , t , lift ρ , wk1ˢ S 
  prodˢₕ₁ :  H , prodˢ p t₁ t₂ , ρ , fstₑ p  S  ⇒ᵥ
             H , t₁           , ρ , S          
  prodˢₕ₂ :  H , prodˢ p t₁ t₂ , ρ , sndₑ p  S 
          ⇒ᵥ  H , t₂           , ρ , S          
  prodʷₕ :  S ∣≡ q′
           H , prodʷ p t₁ t₂ , ρ , prodrecₑ r p q A u ρ′  S  ⇒ᵥ
            H  (q′ · r · p , t₁ , ρ)  (q′ · r , t₂ , step ρ)
              , u             , liftn ρ′ 2 , wk2ˢ S 
  zeroₕ :  H , zero , ρ  , natrecₑ p q r A z s ρ′  S  ⇒ᵥ
           H , z    , ρ′ , S                          

  sucₕ : -- p′ is the multiplicity of the natrec continuation
         -- on top of the stack and q′ is the multiplicity of
         -- the rest of the stack.
          S ∣≡ q′  ∣natrec p , r ∣≡ p′ 
          H , suc t , ρ , natrecₑ p q r A z s ρ′  S  ⇒ᵥ
          H  (q′ · p′ , t , ρ)
              (q′ · r , natrec p q r (wk (lift (step id)) A) (wk1 z)
                              (wk (liftn (step id) 2) s) (var x0)
                          , lift ρ′)
             , s , liftn ρ′ 2 , wk2ˢ S 
  starʷₕ :   H , starʷ l , ρ  , unitrecₑ l p q A u ρ′  S  ⇒ᵥ
             H , u       , ρ′ ,                         S 
  unitrec-ηₕ : Unitʷ-η 
                H , unitrec l p q A t u , ρ , S  ⇒ᵥ
                H ,                   u , ρ , S 
  rflₕⱼ :  H , rfl , ρ  , Jₑ p q A t B u v ρ′  S  ⇒ᵥ
           H , u   , ρ′ , S 
  rflₕₖ :  H , rfl , ρ ,  Kₑ p A t B u ρ′  S  ⇒ᵥ  H , u , ρ′ , S 
  rflₕₑ :  H , rfl , ρ  , []-congₑ str A t u ρ′  S  ⇒ᵥ
           H , rfl , ρ′ , S 

-- The relation _⇒ₙ_ allows evaluation under the successor constructor
-- in order to fully evaluate terms to numerals.

infix 28 _⇒ₙ_

data _⇒ₙ_ {k m n} : State k m n  State k m n  Set a where
  sucₕ : ¬ Numeral t 
          H , suc t , ρ , sucₛ   ⇒ₙ  H , t , ρ , sucₑ  sucₛ  
  numₕ : Numeral t 
          H , t , ρ , sucₑ  S  ⇒ₙ  H , suc t , ρ , S 

------------------------------------------------------------------------
-- The main reduction relations.

infix 30 ⇾ₑ_
infix 30 ⇒ᵥ_
infix 30 ⇒ₙ_
infix 30 ⇢ₑ_

-- Evaluation to WHNF with resource tracking.

data _⇾_ (s₁ : State k m n) : State k m′ n′  Set a where
  ⇾ₑ_ : s₁ ⇾ₑ s₂  s₁  s₂
  ⇒ᵥ_ : s₁ ⇒ᵥ s₂  s₁  s₂

-- Evaluation of natural numbers to numerals with resource tracking.

data _↠_ (s₁ : State k m n) : State k m′ n′  Set a where
  ⇾ₑ_ : s₁ ⇾ₑ s₂  s₁  s₂
  ⇒ᵥ_ : s₁ ⇒ᵥ s₂  s₁  s₂
  ⇒ₙ_ : s₁ ⇒ₙ s₂  s₁  s₂

pattern ⇾ₑ′ d = ⇾ₑ (⇒ₑ d)

-- Evaluation to WHNF without resource tracking.

data _⇢_ (s₁ : State k m n) : State k m′ n′  Set a where
  ⇢ₑ_ : s₁ ⇢ₑ s₂  s₁  s₂
  ⇒ᵥ_ : s₁ ⇒ᵥ s₂  s₁  s₂

infix 28 _⇾*_
infix 28 _↠*_
infix 28 _⇢*_

-- Reflexive, transitive closure of _⇾_.

data _⇾*_ (s₁ : State k m n) : State k m′ n′  Set a where
  id  : s₁ ⇾* s₁
  _⇨_ : s₁  s₂  s₂ ⇾* s₃  s₁ ⇾* s₃

-- Reflexive, transitive closure of _↠_.

data _↠*_ (s₁ : State k m n) : State k m′ n′  Set a where
  id  : s₁ ↠* s₁
  _⇨_ : s₁  s₂  s₂ ↠* s₃  s₁ ↠* s₃

-- Reflexive, transitive closure of _⇢_.

data _⇢*_ (s₁ : State k m n) : State k m′ n′  Set a where
  id  : s₁ ⇢* s₁
  _⇨_ : s₁  s₂  s₂ ⇢* s₃  s₁ ⇢* s₃

Final : State k m n  Set a
Final s =  {m n} {s′ : State _ m n}  s  s′  

_⇘_ : State k m n  State k m′ n′  Set a
s  s′ = s ⇾* s′ × Final s′