```------------------------------------------------------------------------
-- Big-step semantics
------------------------------------------------------------------------

module Semantics.BigStep where

open import Syntax
open import Semantics

open import Data.Nat
open import Data.Product

infix 3 _⇓[_]_ _⇓[_] _↡[_] _↯[_] _⇑[_] _∶_⇑[_]

-- x ⇓[ i ] v means that x _can_ terminate with the value (or
-- exception) v.

mutual

private
_∶_⇓[_]_ : ∀ t → Expr t → Status → Value → Set
_ ∶ e ⇓[ i ] v = e ⇓[ i ] v

data _⇓[_]_ : ∀ {t} → Expr t → Status → Value → Set where
Val     : ∀ {t v i}                                                   → t ∶ ⌜ v ⌝     ⇓[ i ] v
Loop    : ∀ {x v i}       ( ⇓ : x >> loop x ⇓[ i ] v)                 →     loop x    ⇓[ i ] v
Add₁    : ∀ {t x y m n i} (x↡ : x ⇓[ i ] nat m) (y↡ : y ⇓[ i ] nat n) → t ∶ x ⊕ y     ⇓[ i ] nat (m + n)
Add₂    : ∀ {t x y i}     (x↯ : x ⇓[ i ] throw)                       → t ∶ x ⊕ y     ⇓[ i ] throw
Add₃    : ∀ {t x y m i}   (x↡ : x ⇓[ i ] nat m) (y↯ : y ⇓[ i ] throw) → t ∶ x ⊕ y     ⇓[ i ] throw
Seqn₁   : ∀ {t x y m v i} (x↡ : x ⇓[ i ] nat m) (y⇓ : y ⇓[ i ] v)     → t ∶ x >> y    ⇓[ i ] v
Seqn₂   : ∀ {t x y i}     (x↯ : x ⇓[ i ] throw)                       → t ∶ x >> y    ⇓[ i ] throw
Catch₁  : ∀ {t x y m i}   (x↡ : x ⇓[ i ] nat m)                       → t ∶ x catch y ⇓[ i ] nat m
Catch₂  : ∀ {t x y v i}   (x↯ : x ⇓[ i ] throw) (y⇓ : y ⇓[ B ] v)     → t ∶ x catch y ⇓[ i ] v
Block   : ∀ {t x v i}     (x⇓ : x ⇓[ B ] v)                           → t ∶ block x   ⇓[ i ] v
Unblock : ∀ {t x v i}     (x⇓ : x ⇓[ U ] v)                           → t ∶ unblock x ⇓[ i ] v
Int     : ∀ {t x}                                                     → t ∶ x         ⇓[ U ] throw

-- Short-hand notation.

_⇓[_] : ∀ {t} → Expr t → Status → Set
x ⇓[ i ] = ∃ λ v → x ⇓[ i ] v

_↡[_] : ∀ {t} → Expr t → Status → Set
x ↡[ i ] = ∃ λ n → x ⇓[ i ] nat n

_↯[_] : ∀ {t} → Expr t → Status → Set
x ↯[ i ] = x ⇓[ i ] throw

-- x ⇑[ i ] means that x _can_ fail to terminate.

mutual

private
_∶_⇑[_] : ∀ t → Expr t → Status → Set
t ∶ e₁ ⇑[ i ] = e₁ ⇑[ i ]

codata _⇑[_] : ∀ {t} → Expr t → Status → Set where
Loop    : ∀ {x i}     ( ⇑ : x >> loop x ⇑[ i ])       →     loop x    ⇑[ i ]
Add₁    : ∀ {t x y i} (x⇑ : x ⇑[ i ])                 → t ∶ x ⊕     y ⇑[ i ]
Add₂    : ∀ {t x y i} (x↡ : x ↡[ i ]) (y⇑ : y ⇑[ i ]) → t ∶ x ⊕     y ⇑[ i ]
Seqn₁   : ∀ {t x y i} (x⇑ : x ⇑[ i ])                 → t ∶ x >>    y ⇑[ i ]
Seqn₂   : ∀ {t x y i} (x↡ : x ↡[ i ]) (y⇑ : y ⇑[ i ]) → t ∶ x >>    y ⇑[ i ]
Catch₁  : ∀ {t x y i} (x⇑ : x ⇑[ i ])                 → t ∶ x catch y ⇑[ i ]
Catch₂  : ∀ {t x y i} (x↯ : x ↯[ i ]) (y⇑ : y ⇑[ B ]) → t ∶ x catch y ⇑[ i ]
Block   : ∀ {t x i}   (x⇑ : x ⇑[ B ])                 → t ∶ block   x ⇑[ i ]
Unblock : ∀ {t x i}   (x⇑ : x ⇑[ U ])                 → t ∶ unblock x ⇑[ i ]

-- The semantics.

BigStep : Sem
BigStep = record
{ _⇓[_]_ = _⇓[_]_
; _⇑[_]  = _⇑[_]
}
```