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