...
Source file
src/go/types/termlist.go
1
2
3
4
5
6
7 package types
8
9 import "strings"
10
11
12
13
14
15
16 type termlist []*term
17
18
19
20 var allTermlist = termlist{new(term)}
21
22
23 const termSep = " | "
24
25
26 func (xl termlist) String() string {
27 if len(xl) == 0 {
28 return "∅"
29 }
30 var buf strings.Builder
31 for i, x := range xl {
32 if i > 0 {
33 buf.WriteString(termSep)
34 }
35 buf.WriteString(x.String())
36 }
37 return buf.String()
38 }
39
40
41 func (xl termlist) isEmpty() bool {
42
43
44
45 for _, x := range xl {
46 if x != nil {
47 return false
48 }
49 }
50 return true
51 }
52
53
54 func (xl termlist) isAll() bool {
55
56
57
58 for _, x := range xl {
59 if x != nil && x.typ == nil {
60 return true
61 }
62 }
63 return false
64 }
65
66
67 func (xl termlist) norm() termlist {
68
69
70 used := make([]bool, len(xl))
71 var rl termlist
72 for i, xi := range xl {
73 if xi == nil || used[i] {
74 continue
75 }
76 for j := i + 1; j < len(xl); j++ {
77 xj := xl[j]
78 if xj == nil || used[j] {
79 continue
80 }
81 if u1, u2 := xi.union(xj); u2 == nil {
82
83
84
85
86
87
88 if u1.typ == nil {
89 return allTermlist
90 }
91 xi = u1
92 used[j] = true
93 }
94 }
95 rl = append(rl, xi)
96 }
97 return rl
98 }
99
100
101 func (xl termlist) union(yl termlist) termlist {
102 return append(xl, yl...).norm()
103 }
104
105
106 func (xl termlist) intersect(yl termlist) termlist {
107 if xl.isEmpty() || yl.isEmpty() {
108 return nil
109 }
110
111
112
113 var rl termlist
114 for _, x := range xl {
115 for _, y := range yl {
116 if r := x.intersect(y); r != nil {
117 rl = append(rl, r)
118 }
119 }
120 }
121 return rl.norm()
122 }
123
124
125 func (xl termlist) equal(yl termlist) bool {
126
127 return xl.subsetOf(yl) && yl.subsetOf(xl)
128 }
129
130
131 func (xl termlist) includes(t Type) bool {
132 for _, x := range xl {
133 if x.includes(t) {
134 return true
135 }
136 }
137 return false
138 }
139
140
141 func (xl termlist) supersetOf(y *term) bool {
142 for _, x := range xl {
143 if y.subsetOf(x) {
144 return true
145 }
146 }
147 return false
148 }
149
150
151 func (xl termlist) subsetOf(yl termlist) bool {
152 if yl.isEmpty() {
153 return xl.isEmpty()
154 }
155
156
157 for _, x := range xl {
158 if !yl.supersetOf(x) {
159 return false
160 }
161 }
162 return true
163 }
164
View as plain text