summaryrefslogtreecommitdiff
path: root/src/Example.idr
blob: ed7d891d61fb524f4d736dfe43f370863e5061a5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
module Example

import Data.Singleton
import SOAS

infixr 3 -:>

-- Writing the descriptions directly is fine
-- but deriving their functoriality and strength is annoying
-- and not needed with enough metaprogramming

%hide Syntax.PreorderReasoning.prefix.(|~)
%hide Syntax.PreorderReasoning.Generic.prefix.(|~)

data TypeSTLC = B | (-:>) TypeSTLC TypeSTLC

data OpSTLC : TypeSTLC -> (TypeSTLC .Ctx, TypeSTLC).Ctx -> Type where
  App : OpSTLC ty2 [<"f" :- ([<], ty1 -:> ty2), "x" :- ([<], ty1)]
  Lam : OpSTLC (ty1 -:> ty2) [<"body" :- ([<"x" :- ty1], ty2)]

STLC : TypeSTLC .Signature
STLC = MkSig OpSTLC $ \case
  App => [<Z, Z]
  Lam => [<S Z]

Ex1 : STLC .Term Var (B -:> (B -:> B) -:> B) [<]
Ex1 =
  Alg $ Op Lam [<Bind [<"x"] $
  Alg $ Op Lam [<Bind [<"f"] $
    Alg $ Op App [<[] (Var (%% "f")), [] (Var (%% "x"))]]]

beta :
  {0 body : STLC .Term Var ty2 (ctx :< (x :- ty1))} ->
  Singleton (Alg $ Op App [<[] (Alg $ Op Lam [<Bind [<x] body]), [] t]) ->
  STLC .Term Var ty2 ctx
beta (Val $ Alg $ Op App [<Bind [<] $ Alg $ Op Lam [<Bind [<x] body], Bind [<] t]) =
  (STLC .Term Var).sub body t

eta : STLC .Term Var (ty1 -:> ty2) ctx -> STLC .Term Var (ty1 -:> ty2) ctx
eta t =
  Alg $ Op Lam [<Bind [<"x"] $
    Alg $ Op App [<[] ((STLC .Term Var).wkn t), [] (Var $ %% "x")]]

Ex2 : STLC .Term Var (B -:> B) [<]
Ex2 =
  Alg $ Op App
    [<[] (Alg $ Op Lam [<Bind [<"f"] $
          Alg $ Op Lam [<Bind [<"x"] $
          Alg $ Op App [<[] (Var $ (%% "f") {pos = There Here}), [] (Var $ %% "x")]]])
    , [] (Alg $ Op Lam [<Bind [<"x"] $ Var $ %% "x"])]

Ex3 : STLC .Term Var (B -:> B) [<]
Ex3 = eta $ beta $ Val Ex2