packages feed

MiniAgda-0.2022.3.11: test/succeed/MeasuredHerSubst1.ma

-- 2010-07-27 Implementation of JFP-paper
-- Implementing a Normalizer Using Heterogeneous Sized Types
-- Version with subst/simsubst/normApp mutual

-- 2012-01-22 parameters gone from constructors

data Maybe (A : Set) : Set
{ nothing : Maybe A
; just    : A -> Maybe A
}

let just_ : [A : Set] -> A -> Maybe A = \ A a -> just a

fun mapMaybe : [A, B : Set] -> (A -> B) -> Maybe A -> Maybe B
{ mapMaybe A B f (nothing) = nothing
; mapMaybe A B f (just a)  = just (f a)
}

sized data Ty : Size -> Set
{ base : [i : Size] -> Ty $i
; arr  : [i : Size] -> Ty i -> Ty i -> Ty $i
}

sized data Tm (A : Set) : Size -> Set
{ var  : [i : Size] -> A -> Tm A $i
; app  : [i : Size] -> Tm A i -> Tm A i -> Tm A $i
; abs  : [i : Size] -> Ty # -> Tm (Maybe A) i -> Tm A $i
}

fun mapTm : [A, B : Set] -> [i : Size] -> |i| -> (A -> B) -> Tm A i -> Tm B i
{ mapTm A B i f (var (i > j) x)   = var j (f x)
; mapTm A B i f (app (i > j) r s) = app j (mapTm A B j f r) (mapTm A B j f s)
; mapTm A B i f (abs (i > j) a r) =
    abs j a (mapTm (Maybe A) (Maybe B) j (mapMaybe A B f) r)
}

let shiftTm : [A : Set] -> [i : Size] -> Tm A i -> Tm (Maybe A) i
  = \ A i t -> mapTm A (Maybe A) i (just_ A) t

-- result of substitution is carrying a type or not
data Res (A : Set) +(i : Size) : Set
{ ne : Tm A # -> Res A i
; nf : Tm A # -> Ty i -> Res A i
}

fun tm : [A : Set] -> [i : Size] -> Res A i -> Tm A #
{ tm A i (ne t)   = t
; tm A i (nf t a) = t
}

fun shiftRes : [A : Set] -> [i : Size] -> Res A i -> Res (Maybe A) i
{ shiftRes A i (ne t)   = ne (shiftTm A # t)
; shiftRes A i (nf t a) = nf (shiftTm A # t) a
}

-- construct results without type information
let varRes : [A : Set] -> [i : Size] -> A -> Res A i
  = \ A i x -> ne (var # x)

let absRes : [A : Set] -> [i : Size] -> Ty # -> Res (Maybe A) # -> Res A i
  = \ A i a r -> ne (abs # a (tm (Maybe A) # r))

let appRes : [A : Set] -> [i : Size] -> Res A # -> Res A # -> Res A i
  = \ A i t u -> ne (app # (tm A # t) (tm A # u))

-- environments (in paper: Val)

let Env : Set -> Set -> Size -> Set
  = \ A B i -> A -> Res B i

fun sg : [A : Set] -> [i : Size] -> Tm A # -> Ty i -> Env (Maybe A) A i
{ sg A i s a (nothing) = nf s a
; sg A i s a (just y)  = varRes A i y
}

fun lift : [A, B : Set] -> [i : Size] -> Env A B i -> Env (Maybe A) (Maybe B) i
{ lift A B i rho (nothing) = varRes (Maybe B) i (nothing)
; lift A B i rho (just x)  = shiftRes B i (rho x)
}

-- hereditary substitution

mutual {

fun subst : [i : Size] -> |i,$$0,#| -> Ty i ->
            [A : Set] -> Tm A # -> Tm (Maybe A) # -> Tm A #
{ subst i a A s t = tm A i (simsubst i # (Maybe A) A t (sg A i s a))
}

fun simsubst : [i, j : Size] -> |i,$0,j| ->
               [A, B : Set] -> Tm A j -> Env A B i -> Res B i
{ simsubst i j A B (var (j > j') x) rho = rho x
; simsubst i j A B (abs (j > j') b t) rho =
    absRes B i b (simsubst i j' (Maybe A) (Maybe B) t (lift A B i rho))
; simsubst i j A B (app (j > j') t u) rho =
    let t' : Res B i = simsubst i j' A B t rho in
    let u' : Res B i = simsubst i j' A B u rho in
      normApp i B t' u'
}

fun normApp : [i : Size] -> |i,0,#| ->
              [B : Set] -> Res B i -> Res B i -> Res B i
{ normApp i B (nf (abs .# b' r') (arr (i > i') b c)) u' =
    nf (subst i' b B (tm B i u') r') c
; normApp i B t' u' = appRes B i t' u'
}

}