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