-
Notifications
You must be signed in to change notification settings - Fork 0
/
DeBruijn.ts
137 lines (119 loc) · 3.63 KB
/
DeBruijn.ts
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
type CountTo<N extends number, R extends number[] = []> = N extends R["length"]
? R
: CountTo<N, [0, ...R]>;
type Inc<N extends number[]> = [0, ...N];
type Dec<N extends number[]> = N extends [infer _, ...infer Rest]
? Rest
: never;
type Sum<N extends number[], M extends number[]> = [...N, ...M];
type IfLess<A, B, True, False> = B extends []
? False
: A extends []
? True
: A extends [infer _, ...infer RA]
? B extends [infer _, ...infer RB]
? IfLess<RA, RB, True, False>
: never
: never;
type IfEq<A, B, True, False> = A extends []
? B extends []
? True
: False
: B extends []
? False
: A extends [infer _, ...infer RA]
? B extends [infer _, ...infer RB]
? IfEq<RA, RB, True, False>
: never
: never;
type AsDec<N extends number[]> = N["length"];
type TD<Term> = Term extends number
? CountTo<Term>
: Term extends [infer Inner]
? { inner: TD<Inner> }
: Term extends [infer Left, infer Right]
? { left: TD<Left>; right: TD<Right> }
: never;
type UnTD<Term> = Term extends { inner: infer Inner }
? [UnTD<Inner>]
: Term extends { left: infer Left; right: infer Right }
? [UnTD<Left>, UnTD<Right>]
: Term extends number[]
? AsDec<Term>
: never;
/*
shift d c (V k) = if k < c then V k else V (k + d)
shift d c (L t1) = L (shift d (c + 1) t1)
shift d c (App t1 t2) = App (shift d c t1) (shift d c t2)
*/
type Shift<
D extends number[] | -1,
C extends number[],
Term
> = Term extends number[]
? IfLess<Term, C, Term, D extends number[] ? Sum<Term, D> : Dec<Term>>
: Term extends { inner: infer Inner }
? { inner: Shift<D, Inc<C>, Inner> }
: Term extends { left: infer Left; right: infer Right }
? { left: Shift<D, C, Left>; right: Shift<D, C, Right> }
: never;
/*
sub j s (V k) = if k == j then s else V k
sub j s (L t1) = L (sub (j + 1) (shift 1 0 s) t1)
sub j s (App t1 t2) = App (sub j s t1) (sub j s t2)
*/
type Subst<J extends number[], S, Term> = Term extends number[]
? IfEq<Term, J, S, Term>
: Term extends { inner: infer Inner }
? { inner: Subst<Inc<J>, Shift<CountTo<1>, CountTo<0>, S>, Inner> }
: Term extends { left: infer Left; right: infer Right }
? { left: Subst<J, S, Left>; right: Subst<J, S, Right> }
: never;
/*
normal (V _) = True
normal (L t) = normal t
normal (App (L _) _) = False
normal (App t1 t2) = normal t1 && normal t2
*/
type IfNormal<Term, True, False> = Term extends number[]
? True
: Term extends { inner: infer Inner }
? IfNormal<Inner, True, False>
: Term extends { left: { inner: infer _ }; right: infer _ }
? False
: Term extends { left: infer Left; right: infer Right }
? IfNormal<Left, IfNormal<Right, True, False>, False>
: never;
/*
beta (App (L t12) v2) = Just $ shift (-1) 0 (sub 0 (shift 1 0 v2) t12)
beta (App t1 t2) | normal t1 = App t1 <$> beta t2
beta (App t1 t2) = App <$> beta t1 <*> pure t2
beta (L t1) = L <$> beta t1
beta _ = Nothing
*/
type Beta<Term> = Term extends { left: { inner: infer T12 }; right: infer V2 }
? Shift<
-1,
CountTo<0>,
Subst<CountTo<0>, Shift<CountTo<1>, CountTo<0>, V2>, T12>
>
: Term extends { inner: infer Inner }
? { inner: Beta<Inner> }
: Term extends { left: infer Left; right: infer Right }
? IfNormal<
Left,
{ left: Left; right: Beta<Right> },
{ left: Beta<Left>; right: Right }
>
: never;
type FullBeta<Term> = IfNormal<Term, true, false> extends true
? Term
: FullBeta<Beta<Term>>;
type LId = [0];
type LTrue = [[1]];
type LFalse = [[0]];
type LNot = [[[[[2, 0], 1]]]];
type LAnd = [[[[[[3, [[2, 1], 0]], 0]]]]];
type LOr = [[[[[[3, 1], [[2, 1], 0]]]]]];
type Test = [[LAnd, LFalse], LFalse];
type Result = UnTD<FullBeta<TD<Test>>>;