#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)
xa2: xa3 + 2
xa3: 6 & xa1-2
xa4: xa2 + 2

xb1: (xb2 & 8) | (xb4 & 9)
xb2: xb3 + 2
xb3: (6 & (xb1 - 2)) | (xb4 & 9)
xb4: xb2 + 2

// 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
xc2: xc3 + 2
xc3: 6 & xc1-2
xc4: xc2 + 1
xc5: xc2 + 2

// The below is resolved by setting xd1 explicitly.
xd1: xd2 & 8 | xd4 & 9 | xd5 & 9
xd2: xd3 + 2
xd3: 6 & xd1-2
xd4: xd2 + 1
xd5: xd2 + 2
xd1: 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
xe3: 6 & xe1-2
xe4: xe2 + 1
xe5: xe2 + 2
xe1: 9

xf1: xf2 & 8 | xf4 & 9
xf2: xf3 + 2
xf3: 6 & xf1-2 | xf4 & 9
xf4: xf2 + 2

z1: z2+1 | z3+5 // +3 for fun
z2: z3 + 2
z3: z1 - 3
z3: 8
-- out/def --
// 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: 8
xa2: 8
xa4: 10
xa3: 6

// The second disjunct in xb4 can be eliminated as both disjuncts
// of xb3 result in an incompatible sum when substituted.
xb1: 8
xb2: 8
xb4: 10
xb3: 6

// 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
xc2: xc3 + 2
xc4: xc2 + 1
xc5: xc2 + 2
xc3: 6 & xc1-2

// The above is resolved by setting xd1 explicitly.
xd1: 8
xd2: 8
xd4: 9
xd5: 10
xd3: 6

// The above is resolved by setting xd1 explicitly to the wrong
// value, resulting in an error.
xe1: _|_ // conflicting values 6 and 7
xe2: _|_ // conflicting values 6 and 7
xe4: _|_ // conflicting values 6 and 7
xe5: _|_ // conflicting values 6 and 7
xe3: _|_ // conflicting values 6 and 7

// Only one solution.
xf1: 8
xf2: 8
xf4: 10
xf3: 6
z1:  z2+1 | z3+5
z2:  z3 + 2
z3:  z1-3 & 8
-- out/legacy-debug --
<0>{xa1: 8, xa2: 8, xa4: 10, xa3: 6, xb1: 8, xb2: 8, xb4: 10, xb3: 6, xc1: ((<1>.xc2 & 8) | (<1>.xc4 & 9) | (<1>.xc5 & 9)), xc2: (<1>.xc3 + 2), xc4: (<1>.xc2 + 1), xc5: (<1>.xc2 + 2), xc3: (6 & (<1>.xc1 - 2)), xd1: 8, xd2: 8, xd4: 9, xd5: 10, xd3: 6, xe1: _|_((6 & 7):conflicting values 6 and 7), xe2: _|_((6 & 7):conflicting values 6 and 7), xe4: _|_((6 & 7):conflicting values 6 and 7), xe5: _|_((6 & 7):conflicting values 6 and 7), xe3: _|_((6 & 7):conflicting values 6 and 7), xf1: 8, xf2: 8, xf4: 10, xf3: 6, z1: ((<1>.z2 + 1) | (<1>.z3 + 5)), z2: (<1>.z3 + 2), z3: ((<1>.z1 - 3) & 8)}
-- out/compile --
--- in.cue
{
  xa1: ((〈0;xa2〉 & 8)|(〈0;xa4〉 & 9))
  xa2: (〈0;xa3〉 + 2)
  xa3: (6 & (〈0;xa1〉 - 2))
  xa4: (〈0;xa2〉 + 2)
  xb1: ((〈0;xb2〉 & 8)|(〈0;xb4〉 & 9))
  xb2: (〈0;xb3〉 + 2)
  xb3: ((6 & (〈0;xb1〉 - 2))|(〈0;xb4〉 & 9))
  xb4: (〈0;xb2〉 + 2)
  xc1: ((〈0;xc2〉 & 8)|(〈0;xc4〉 & 9)|(〈0;xc5〉 & 9))
  xc2: (〈0;xc3〉 + 2)
  xc3: (6 & (〈0;xc1〉 - 2))
  xc4: (〈0;xc2〉 + 1)
  xc5: (〈0;xc2〉 + 2)
  xd1: ((〈0;xd2〉 & 8)|(〈0;xd4〉 & 9)|(〈0;xd5〉 & 9))
  xd2: (〈0;xd3〉 + 2)
  xd3: (6 & (〈0;xd1〉 - 2))
  xd4: (〈0;xd2〉 + 1)
  xd5: (〈0;xd2〉 + 2)
  xd1: 8
  xe1: ((〈0;xe2〉 & 8)|(〈0;xe4〉 & 9)|(〈0;xe5〉 & 9))
  xe2: (〈0;xe3〉 + 2)
  xe3: (6 & (〈0;xe1〉 - 2))
  xe4: (〈0;xe2〉 + 1)
  xe5: (〈0;xe2〉 + 2)
  xe1: 9
  xf1: ((〈0;xf2〉 & 8)|(〈0;xf4〉 & 9))
  xf2: (〈0;xf3〉 + 2)
  xf3: ((6 & (〈0;xf1〉 - 2))|(〈0;xf4〉 & 9))
  xf4: (〈0;xf2〉 + 2)
  z1: ((〈0;z2〉 + 1)|(〈0;z3〉 + 5))
  z2: (〈0;z3〉 + 2)
  z3: (〈0;z1〉 - 3)
  z3: 8
}
-- out/eval/stats --
Leaks:  0
Freed:  52
Reused: 44
Allocs: 8
Retain: 24

Unifications: 31
Conjuncts:    128
Disjuncts:    60
-- out/evalalpha --
Errors:
xe3: conflicting values 7 and 6:
    ./in.cue:43:6
    ./in.cue:43:10

Result:
(_|_){
  // [eval]
  xa1: (int){ 8 }
  xa2: (int){ 8 }
  xa3: (int){ 6 }
  xa4: (int){ 10 }
  xb1: (_|_){
    // [cycle] xb1: 4 errors in empty disjunction:
    // xb2: unresolved disjunction: xb3:
    //     ./in.cue:16:6
    // xb3: 3 errors in empty disjunction::
    //     ./in.cue:16:6
    // xb3: unresolved disjunction: xb1:
    //     ./in.cue:17:12
    // xb3: cycle with field: xb2:
    //     ./in.cue:18:6
  }
  xb2: (_|_){
    // [cycle] xb2: unresolved disjunction: xb3:
    //     ./in.cue:16:6
    // xb3: cycle with field: xb2:
    //     ./in.cue:18:6
  }
  xb3: (_|_){
    // [cycle] xb2: unresolved disjunction: xb3:
    //     ./in.cue:16:6
    // xb3: 3 errors in empty disjunction::
    //     ./in.cue:16:6
    // xb3: unresolved disjunction: xb1:
    //     ./in.cue:17:12
    // xb3: cycle with field: xb2:
    //     ./in.cue:18:6
  }
  xb4: (_|_){
    // [cycle] xb2: unresolved disjunction: xb3:
    //     ./in.cue:16:6
    // xb3: cycle with field: xb2:
    //     ./in.cue:18:6
  }
  xc1: (int){ |((int){ 8 }, (int){ 9 }) }
  xc2: (int){ 8 }
  xc3: (_|_){
    // [incomplete] xc3: unresolved disjunction 8 | 9 (type int):
    //     ./in.cue:27:10
  }
  xc4: (int){ 9 }
  xc5: (int){ 10 }
  xd1: (int){ 8 }
  xd2: (int){ 8 }
  xd3: (int){ 6 }
  xd4: (int){ 9 }
  xd5: (int){ 10 }
  xe1: (int){ 9 }
  xe2: (int){ 8 }
  xe3: (_|_){
    // [eval] xe3: conflicting values 7 and 6:
    //     ./in.cue:43:6
    //     ./in.cue:43:10
  }
  xe4: (int){ 9 }
  xe5: (int){ 10 }
  xf1: (_|_){
    // [cycle] xf1: 4 errors in empty disjunction:
    // xf2: unresolved disjunction: xf3:
    //     ./in.cue:49:6
    // xf3: 3 errors in empty disjunction::
    //     ./in.cue:49:6
    // xf3: unresolved disjunction: xf1:
    //     ./in.cue:50:10
    // xf3: cycle with field: xf2:
    //     ./in.cue:51:6
  }
  xf2: (_|_){
    // [cycle] xf2: unresolved disjunction: xf3:
    //     ./in.cue:49:6
    // xf3: cycle with field: xf2:
    //     ./in.cue:51:6
  }
  xf3: (_|_){
    // [cycle] xf2: unresolved disjunction: xf3:
    //     ./in.cue:49:6
    // xf3: 3 errors in empty disjunction::
    //     ./in.cue:49:6
    // xf3: unresolved disjunction: xf1:
    //     ./in.cue:50:10
    // xf3: cycle with field: xf2:
    //     ./in.cue:51:6
  }
  xf4: (_|_){
    // [cycle] xf2: unresolved disjunction: xf3:
    //     ./in.cue:49:6
    // xf3: cycle with field: xf2:
    //     ./in.cue:51:6
  }
  z1: (int){ |((int){ 11 }, (int){ 13 }) }
  z2: (int){ 10 }
  z3: (_|_){
    // [incomplete] z3: unresolved disjunction 11 | 13 (type int):
    //     ./in.cue:55:5
  }
}
-- diff/-out/evalalpha<==>+out/eval --
diff old new
--- old
+++ new
@@ -11,20 +11,37 @@
   xa3: (int){ 6 }
   xa4: (int){ 10 }
   xb1: (_|_){
-    // [incomplete] xb1: 2 errors in empty disjunction:
-    // xb1: unresolved disjunction 6 | 9 (type int):
-    //     ./in.cue:16:6
-    // xb2: unresolved disjunction 6 | 9 (type int):
-    //     ./in.cue:16:6
+    // [cycle] xb1: 4 errors in empty disjunction:
+    // xb2: unresolved disjunction: xb3:
+    //     ./in.cue:16:6
+    // xb3: 3 errors in empty disjunction::
+    //     ./in.cue:16:6
+    // xb3: unresolved disjunction: xb1:
+    //     ./in.cue:17:12
+    // xb3: cycle with field: xb2:
+    //     ./in.cue:18:6
   }
   xb2: (_|_){
-    // [incomplete] xb2: unresolved disjunction 6 | 9 (type int):
-    //     ./in.cue:16:6
-  }
-  xb3: (int){ |((int){ 6 }, (int){ 9 }) }
+    // [cycle] xb2: unresolved disjunction: xb3:
+    //     ./in.cue:16:6
+    // xb3: cycle with field: xb2:
+    //     ./in.cue:18:6
+  }
+  xb3: (_|_){
+    // [cycle] xb2: unresolved disjunction: xb3:
+    //     ./in.cue:16:6
+    // xb3: 3 errors in empty disjunction::
+    //     ./in.cue:16:6
+    // xb3: unresolved disjunction: xb1:
+    //     ./in.cue:17:12
+    // xb3: cycle with field: xb2:
+    //     ./in.cue:18:6
+  }
   xb4: (_|_){
-    // [incomplete] xb2: unresolved disjunction 6 | 9 (type int):
-    //     ./in.cue:16:6
+    // [cycle] xb2: unresolved disjunction: xb3:
+    //     ./in.cue:16:6
+    // xb3: cycle with field: xb2:
+    //     ./in.cue:18:6
   }
   xc1: (int){ |((int){ 8 }, (int){ 9 }) }
   xc2: (int){ 8 }
@@ -49,20 +66,37 @@
   xe4: (int){ 9 }
   xe5: (int){ 10 }
   xf1: (_|_){
-    // [incomplete] xf1: 2 errors in empty disjunction:
-    // xf1: unresolved disjunction 6 | 9 (type int):
-    //     ./in.cue:49:6
-    // xf2: unresolved disjunction 6 | 9 (type int):
-    //     ./in.cue:49:6
+    // [cycle] xf1: 4 errors in empty disjunction:
+    // xf2: unresolved disjunction: xf3:
+    //     ./in.cue:49:6
+    // xf3: 3 errors in empty disjunction::
+    //     ./in.cue:49:6
+    // xf3: unresolved disjunction: xf1:
+    //     ./in.cue:50:10
+    // xf3: cycle with field: xf2:
+    //     ./in.cue:51:6
   }
   xf2: (_|_){
-    // [incomplete] xf2: unresolved disjunction 6 | 9 (type int):
-    //     ./in.cue:49:6
-  }
-  xf3: (int){ |((int){ 6 }, (int){ 9 }) }
+    // [cycle] xf2: unresolved disjunction: xf3:
+    //     ./in.cue:49:6
+    // xf3: cycle with field: xf2:
+    //     ./in.cue:51:6
+  }
+  xf3: (_|_){
+    // [cycle] xf2: unresolved disjunction: xf3:
+    //     ./in.cue:49:6
+    // xf3: 3 errors in empty disjunction::
+    //     ./in.cue:49:6
+    // xf3: unresolved disjunction: xf1:
+    //     ./in.cue:50:10
+    // xf3: cycle with field: xf2:
+    //     ./in.cue:51:6
+  }
   xf4: (_|_){
-    // [incomplete] xf2: unresolved disjunction 6 | 9 (type int):
-    //     ./in.cue:49:6
+    // [cycle] xf2: unresolved disjunction: xf3:
+    //     ./in.cue:49:6
+    // xf3: cycle with field: xf2:
+    //     ./in.cue:51:6
   }
   z1: (int){ |((int){ 11 }, (int){ 13 }) }
   z2: (int){ 10 }
-- out/eval --
Errors:
xe3: conflicting values 7 and 6:
    ./in.cue:43:6
    ./in.cue:43:10

Result:
(_|_){
  // [eval]
  xa1: (int){ 8 }
  xa2: (int){ 8 }
  xa3: (int){ 6 }
  xa4: (int){ 10 }
  xb1: (_|_){
    // [incomplete] xb1: 2 errors in empty disjunction:
    // xb1: unresolved disjunction 6 | 9 (type int):
    //     ./in.cue:16:6
    // xb2: unresolved disjunction 6 | 9 (type int):
    //     ./in.cue:16:6
  }
  xb2: (_|_){
    // [incomplete] xb2: unresolved disjunction 6 | 9 (type int):
    //     ./in.cue:16:6
  }
  xb3: (int){ |((int){ 6 }, (int){ 9 }) }
  xb4: (_|_){
    // [incomplete] xb2: unresolved disjunction 6 | 9 (type int):
    //     ./in.cue:16:6
  }
  xc1: (int){ |((int){ 8 }, (int){ 9 }) }
  xc2: (int){ 8 }
  xc3: (_|_){
    // [incomplete] xc3: unresolved disjunction 8 | 9 (type int):
    //     ./in.cue:27:10
  }
  xc4: (int){ 9 }
  xc5: (int){ 10 }
  xd1: (int){ 8 }
  xd2: (int){ 8 }
  xd3: (int){ 6 }
  xd4: (int){ 9 }
  xd5: (int){ 10 }
  xe1: (int){ 9 }
  xe2: (int){ 8 }
  xe3: (_|_){
    // [eval] xe3: conflicting values 7 and 6:
    //     ./in.cue:43:6
    //     ./in.cue:43:10
  }
  xe4: (int){ 9 }
  xe5: (int){ 10 }
  xf1: (_|_){
    // [incomplete] xf1: 2 errors in empty disjunction:
    // xf1: unresolved disjunction 6 | 9 (type int):
    //     ./in.cue:49:6
    // xf2: unresolved disjunction 6 | 9 (type int):
    //     ./in.cue:49:6
  }
  xf2: (_|_){
    // [incomplete] xf2: unresolved disjunction 6 | 9 (type int):
    //     ./in.cue:49:6
  }
  xf3: (int){ |((int){ 6 }, (int){ 9 }) }
  xf4: (_|_){
    // [incomplete] xf2: unresolved disjunction 6 | 9 (type int):
    //     ./in.cue:49:6
  }
  z1: (int){ |((int){ 11 }, (int){ 13 }) }
  z2: (int){ 10 }
  z3: (_|_){
    // [incomplete] z3: unresolved disjunction 11 | 13 (type int):
    //     ./in.cue:55:5
  }
}
