1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package subsume
16
17 import (
18 "bytes"
19
20 "cuelang.org/go/cue/errors"
21 "cuelang.org/go/internal/core/adt"
22 )
23
24 func (s *subsumer) values(a, b adt.Value) (result bool) {
25 defer func() {
26 if !result && s.gt == nil && s.lt == nil {
27 s.gt = a
28 s.lt = b
29 }
30 }()
31
32 if a == b {
33 return true
34 }
35
36 if s.Defaults {
37 b = adt.Default(b)
38 }
39
40 switch b := b.(type) {
41 case *adt.Bottom:
42
43
44 return !b.IsIncomplete()
45
46 case *adt.Vertex:
47 if a, ok := a.(*adt.Vertex); ok {
48 return s.vertices(a, b)
49 }
50 if v, ok := b.BaseValue.(adt.Value); ok {
51
52 return s.values(a, v)
53 }
54
55
56 case *adt.Conjunction:
57 if _, ok := a.(*adt.Conjunction); ok {
58 break
59 }
60 for _, y := range b.Values {
61 if s.values(a, y) {
62 return true
63 }
64 }
65 return false
66
67 case *adt.Disjunction:
68 if _, ok := a.(*adt.Disjunction); ok {
69 break
70 }
71
72 for _, y := range b.Values {
73 if !s.values(a, y) {
74 return false
75 }
76 }
77 return true
78
79 case *adt.NodeLink:
80
81
82
83 return deref(a) == deref(b)
84 }
85
86 switch x := a.(type) {
87 case *adt.Top:
88 return true
89
90 case *adt.Bottom:
91
92 return false
93
94 case *adt.BasicType:
95 k := b.Kind()
96 return x.K&k == k
97
98 case *adt.BoundValue:
99 return s.bound(x, b)
100
101 case *adt.Builtin:
102 return x == b
103
104 case *adt.BuiltinValidator:
105 if y := s.ctx.Validate(x, b); y != nil {
106 s.errs = errors.Append(s.errs, y.Err)
107 return false
108 }
109 return true
110
111 case *adt.Null:
112 return b.Kind() == adt.NullKind
113
114 case *adt.Bool:
115 y, ok := b.(*adt.Bool)
116 return ok && x.B == y.B
117
118 case *adt.Num:
119 y, ok := b.(*adt.Num)
120 return ok && x.K&y.K == y.K && test(s.ctx, x, adt.EqualOp, x, y)
121
122 case *adt.String:
123 y, ok := b.(*adt.String)
124 return ok && x.Str == y.Str
125
126 case *adt.Bytes:
127 y, ok := b.(*adt.Bytes)
128 return ok && bytes.Equal(x.B, y.B)
129
130 case *adt.Vertex:
131 y, ok := b.(*adt.Vertex)
132 if ok {
133 return s.vertices(x, y)
134 }
135
136
137 if v, _ := x.BaseValue.(adt.Value); v != nil {
138 return s.values(v, b)
139 }
140 return false
141
142 case *adt.Conjunction:
143 if y, ok := b.(*adt.Conjunction); ok {
144
145
146
147
148
149
150 outerC:
151 for _, a := range x.Values {
152 for _, b := range y.Values {
153 if s.values(a, b) {
154 continue outerC
155 }
156 }
157
158 return false
159 }
160 return true
161 }
162 subsumed := true
163 for _, a := range x.Values {
164 subsumed = subsumed && s.values(a, b)
165 }
166 return subsumed
167
168 case *adt.Disjunction:
169
170 if s.LeftDefault {
171 a = adt.Default(a)
172 var ok bool
173 x, ok = a.(*adt.Disjunction)
174 if !ok {
175 return s.values(a, b)
176 }
177 }
178
179
180
181
182
183
184
185 if y, ok := b.(*adt.Disjunction); ok {
186
187 outerD:
188 for i, b := range y.Values {
189 bDefault := i < y.NumDefaults
190
191 for j, a := range x.Values {
192 aDefault := j < x.NumDefaults
193 if (aDefault || !bDefault) && s.values(a, b) {
194 continue outerD
195 }
196 }
197 return false
198 }
199 return true
200 }
201
202 for _, a := range x.Values {
203 if s.values(a, b) {
204 return true
205 }
206 }
207
208 return false
209
210 case *adt.NodeLink:
211 return deref(x) == deref(b)
212 }
213 return false
214 }
215
216 func deref(v adt.Expr) *adt.Vertex {
217 switch x := v.(type) {
218 case *adt.Vertex:
219 return x
220 case *adt.NodeLink:
221 return x.Node
222 }
223 return nil
224 }
225
226 func (s *subsumer) bound(x *adt.BoundValue, v adt.Value) bool {
227 ctx := s.ctx
228 if isBottom(v) {
229 return true
230 }
231
232 switch y := v.(type) {
233 case *adt.BoundValue:
234 if !adt.IsConcrete(y.Value) {
235 return false
236 }
237
238 kx := x.Kind()
239 ky := y.Kind()
240 if (kx&ky)&^kx != 0 {
241 return false
242 }
243
244
245
246
247
248
249
250
251
252
253
254
255 xv := x.Value
256 yv := y.Value
257 switch x.Op {
258 case adt.GreaterThanOp:
259 if y.Op == adt.GreaterEqualOp {
260 return test(ctx, x, adt.LessThanOp, xv, yv)
261 }
262 fallthrough
263 case adt.GreaterEqualOp:
264 if y.Op == adt.GreaterThanOp || y.Op == adt.GreaterEqualOp {
265 return test(ctx, x, adt.LessEqualOp, xv, yv)
266 }
267 case adt.LessThanOp:
268 if y.Op == adt.LessEqualOp {
269 return test(ctx, x, adt.GreaterThanOp, xv, yv)
270 }
271 fallthrough
272 case adt.LessEqualOp:
273 if y.Op == adt.LessThanOp || y.Op == adt.LessEqualOp {
274 return test(ctx, x, adt.GreaterEqualOp, xv, yv)
275 }
276 case adt.NotEqualOp:
277 switch y.Op {
278 case adt.NotEqualOp:
279 return test(ctx, x, adt.EqualOp, xv, yv)
280 case adt.GreaterEqualOp:
281 return test(ctx, x, adt.LessThanOp, xv, yv)
282 case adt.GreaterThanOp:
283 return test(ctx, x, adt.LessEqualOp, xv, yv)
284 case adt.LessThanOp:
285 return test(ctx, x, adt.GreaterEqualOp, xv, yv)
286 case adt.LessEqualOp:
287 return test(ctx, x, adt.GreaterThanOp, xv, yv)
288 }
289
290 case adt.MatchOp, adt.NotMatchOp:
291
292 if y.Op == x.Op {
293 return test(ctx, x, adt.EqualOp, xv, yv)
294 }
295
296 default:
297
298 panic("cue: undefined bound mode")
299 }
300
301 case *adt.Num, *adt.String, *adt.Bool:
302 return test(ctx, x, x.Op, y, x.Value)
303 }
304 return false
305 }
306
307 func test(ctx *adt.OpContext, src adt.Node, op adt.Op, gt, lt adt.Value) bool {
308 x := adt.BinOp(ctx, op, gt, lt)
309 b, ok := x.(*adt.Bool)
310 return ok && b.B
311 }
312
View as plain text