#name: resolved self-reference cycles with disjunction
#evalPartial

// TODO(cycle)
//
// Some of these examples used to work, but the changes corresponding to this
// addition, it ceased to do so. Fixing these cycle issues seemed more
// important than keeping this esoteric case working, which was already broken
// in the last release anyway.
//
// Reproducer of underlying problem. Still works, but triggers unexpected
// condition.
//
// xb1: xb2
// xb2: xb3
// xb3: xb2 + 0
-- in.cue --
// The second disjunct in xa1 is not resolvable and can be
// eliminated:
//   xa4 & 9
//   (xa2 + 2) & 9
//   ((xa3 + 2) + 2) & 9
//   (((6 & xa1-2) + 2) + 2) & 9
//   ((6 + 2) + 2) & 9 // 6 == xa1-2
//   10 & 9 => _|_
// The remaining values resolve.
xa1: (xa2 & 8) | (xa4 & 9) @test(eq, 8)
xa2: xa3 + 2               @test(eq, 8)
xa3: 6 & xa1-2             @test(eq, 6)
xa4: xa2 + 2               @test(eq, 10)

// TODO(inline): make positions work here.
xb1: (xb2 & 8) | (xb4 & 9)       @test(err, code=cycle,
	suberr=(code=cycle, path=xb2, contains="unresolved disjunction: %v", args=[xb3]),
	suberr=(code=cycle, path=xb3, contains="%d errors in empty disjunction:", args=[3]),
	suberr=(code=cycle, path=xb3, contains="unresolved disjunction: %v", args=[xb1]),
	suberr=(code=cycle, path=xb3, contains="cycle with field: %v", args=[xb2]))
xb2: xb3 + 2                     @test(err, code=cycle,
	suberr=(code=cycle, contains="unresolved disjunction: %v", args=[xb3]),
	suberr=(code=cycle, path=xb3, contains="cycle with field: %v", args=[xb2]))
xb3: (6 & (xb1 - 2)) | (xb4 & 9) @test(err, code=cycle,
	suberr=(code=cycle, path=xb2, contains="unresolved disjunction: %v", args=[xb3]),
	suberr=(code=cycle, contains="unresolved disjunction: %v", args=[xb1]),
	suberr=(code=cycle, contains="cycle with field: %v", args=[xb2]))
xb4: xb2 + 2                     @test(err, code=cycle,
	suberr=(code=cycle, path=xb2, contains="unresolved disjunction: %v", args=[xb3]),
	suberr=(code=cycle, path=xb3, contains="cycle with field: %v", args=[xb2]))

// Another variant with more disjunctions. xc1 remains with two
// possibilities. Technically, only the first value is valid.
// However, to fully determine that, all options of the remaining
// disjunction will have to be evaluated algebraically, which is
// not done.
xc1: xc2 & 8 | xc4 & 9 | xc5 & 9 @test(eq, 8|9)
xc2: xc3 + 2                     @test(eq, 8)
xc3: 6 & xc1-2                   @test(err, code=incomplete,
	contains="unresolved disjunction %v (type %s)", args=[8 | 9, int], pos=[0:10])
xc4: xc2 + 1                     @test(eq, 9)
xc5: xc2 + 2                     @test(eq, 10)

// The below is resolved by setting xd1 explicitly.
xd1: xd2 & 8 | xd4 & 9 | xd5 & 9  // 8 see below
xd2: xd3 + 2    @test(eq, 8)
xd3: 6 & xd1-2  @test(eq, 6)
xd4: xd2 + 1    @test(eq, 9)
xd5: xd2 + 2    @test(eq, 10)
xd1: 8          @test(eq, 8)

// The below is resolved by setting xd1 explicitly to the wrong
// value, resulting in an error.
xe1: xe2 & 8 | xe4 & 9 | xe5 & 9
xe2: xe3 + 2    @test(eq, 8)
xe3: 6 & xe1-2  @test(err, code=eval, pos=[0:6, 0:10])
xe4: xe2 + 1    @test(eq, 9)
xe5: xe2 + 2    @test(eq, 10)
xe1: 9          @test(eq, 9)

xf1: xf2 & 8 | xf4 & 9    @test(err, code=cycle, pos=[])
xf2: xf3 + 2              @test(err, code=cycle, pos=[0:6])
xf3: 6 & xf1-2 | xf4 & 9  @test(err, code=cycle, pos=[-1:6])
xf4: xf2 + 2              @test(err, code=cycle, pos=[-2:6])

z1: z2+1 | z3+5 @test(eq, 11|13) // +3 for fun
z2: z3 + 2      @test(eq, 10)
z3: z1 - 3
z3: 8           @test(err, code=incomplete,
	contains="unresolved disjunction %v (type %s)", args=[11 | 13, int], pos=[-1:5])
-- out/errors.txt --
[cycle] xb1: 4 errors in empty disjunction:
xb2: unresolved disjunction: xb3:
    ./in.cue:21:6
xb3: 3 errors in empty disjunction::
    ./in.cue:21:6
xb3: unresolved disjunction: xb1:
    ./in.cue:24:12
xb3: cycle with field: xb2:
    ./in.cue:28:6
[cycle] xb2: unresolved disjunction: xb3:
    ./in.cue:21:6
xb3: cycle with field: xb2:
    ./in.cue:28:6
[cycle] xb2: unresolved disjunction: xb3:
    ./in.cue:21:6
xb3: 3 errors in empty disjunction::
    ./in.cue:21:6
xb3: unresolved disjunction: xb1:
    ./in.cue:24:12
xb3: cycle with field: xb2:
    ./in.cue:28:6
[cycle] xb2: unresolved disjunction: xb3:
    ./in.cue:21:6
xb3: cycle with field: xb2:
    ./in.cue:28:6
[incomplete] xc3: unresolved disjunction 8 | 9 (type int):
    ./in.cue:39:10
[eval] xe3: conflicting values 7 and 6:
    ./in.cue:56:6
    ./in.cue:56:10
[cycle] xf1: 4 errors in empty disjunction:
xf2: unresolved disjunction: xf3:
    ./in.cue:62:6
xf3: 3 errors in empty disjunction::
    ./in.cue:62:6
xf3: unresolved disjunction: xf1:
    ./in.cue:63:10
xf3: cycle with field: xf2:
    ./in.cue:64:6
[cycle] xf2: unresolved disjunction: xf3:
    ./in.cue:62:6
xf3: cycle with field: xf2:
    ./in.cue:64:6
[cycle] xf2: unresolved disjunction: xf3:
    ./in.cue:62:6
xf3: 3 errors in empty disjunction::
    ./in.cue:62:6
xf3: unresolved disjunction: xf1:
    ./in.cue:63:10
xf3: cycle with field: xf2:
    ./in.cue:64:6
[cycle] xf2: unresolved disjunction: xf3:
    ./in.cue:62:6
xf3: cycle with field: xf2:
    ./in.cue:64:6
[incomplete] z3: unresolved disjunction 11 | 13 (type int):
    ./in.cue:68:5
-- out/todo.txt --
xb* and xf* cycles: v2 evaluator reports incomplete errors for the unresolved
disjunction, while v3 correctly identifies and reports cycle errors.
-- out/eval/stats --
Leaks:  3
Freed:  49
Reused: 16
Allocs: 36
Retain: 0

Unifications: 31
Conjuncts:    95
Disjuncts:    21

NumCloseIDs: 17
