1
2
3
4
5 package types2
6
7
8
9
10
11
12
13 type term struct {
14 tilde bool
15 typ Type
16 }
17
18 func (x *term) String() string {
19 switch {
20 case x == nil:
21 return "β
"
22 case x.typ == nil:
23 return "π€"
24 case x.tilde:
25 return "~" + x.typ.String()
26 default:
27 return x.typ.String()
28 }
29 }
30
31
32 func (x *term) equal(y *term) bool {
33
34 switch {
35 case x == nil || y == nil:
36 return x == y
37 case x.typ == nil || y.typ == nil:
38 return x.typ == y.typ
39 }
40
41
42 return x.tilde == y.tilde && Identical(x.typ, y.typ)
43 }
44
45
46 func (x *term) union(y *term) (_, _ *term) {
47
48 switch {
49 case x == nil && y == nil:
50 return nil, nil
51 case x == nil:
52 return y, nil
53 case y == nil:
54 return x, nil
55 case x.typ == nil:
56 return x, nil
57 case y.typ == nil:
58 return y, nil
59 }
60
61
62 if x.disjoint(y) {
63 return x, y
64 }
65
66
67
68
69
70
71 if x.tilde || !y.tilde {
72 return x, nil
73 }
74 return y, nil
75 }
76
77
78 func (x *term) intersect(y *term) *term {
79
80 switch {
81 case x == nil || y == nil:
82 return nil
83 case x.typ == nil:
84 return y
85 case y.typ == nil:
86 return x
87 }
88
89
90 if x.disjoint(y) {
91 return nil
92 }
93
94
95
96
97
98
99 if !x.tilde || y.tilde {
100 return x
101 }
102 return y
103 }
104
105
106 func (x *term) includes(t Type) bool {
107
108 switch {
109 case x == nil:
110 return false
111 case x.typ == nil:
112 return true
113 }
114
115
116 u := t
117 if x.tilde {
118 u = under(u)
119 }
120 return Identical(x.typ, u)
121 }
122
123
124 func (x *term) subsetOf(y *term) bool {
125
126 switch {
127 case x == nil:
128 return true
129 case y == nil:
130 return false
131 case y.typ == nil:
132 return true
133 case x.typ == nil:
134 return false
135 }
136
137
138 if x.disjoint(y) {
139 return false
140 }
141
142
143
144
145
146
147 return !x.tilde || y.tilde
148 }
149
150
151
152 func (x *term) disjoint(y *term) bool {
153 if debug && (x.typ == nil || y.typ == nil) {
154 panic("invalid argument(s)")
155 }
156 ux := x.typ
157 if y.tilde {
158 ux = under(ux)
159 }
160 uy := y.typ
161 if x.tilde {
162 uy = under(uy)
163 }
164 return !Identical(ux, uy)
165 }
166
View as plain text