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