TODO: a bound value resolving to a disjunction should probably
be an error. In this case #Size.amx should resolve.

-- in.cue --
// Range disjunction without cycle (checks only one-way).
#Size: {
	res: uint | *0
	min: >res | *(1 + res)
	max: >min | *min
}

s0: #Size & {res: 1}
// This discards the default for max. This is correct, but unfortunate.
// TODO: is there a tweak to the default mechanism possible that would fix that?
//       Tread very carefully, though! Perhaps we could have a builtin that
//       discards any default, so that we can at least manually override this
//       behavior.
s1: #Size & {min: 5}
s2: #Size & {max: 5}
s3: #Size & {
	min: 5
	max: 10
}
es3: #Size & {
	min: 10
	max: 5
}

// Disjunctions with cycles
// TODO: improve error message here. Logic is correct, though.
#nonEmptyRange: {
	min: *1 | int
	min: <max
	max: >min
}
r1: #nonEmptyRange & {
	min: 3
}
r2: #nonEmptyRange & {
	max: 5
}
r3: #nonEmptyRange & {
	min: 3
	max: 6
}

er3: #nonEmptyRange & {
	min: 5
	max: 5
}
-- out/eval/stats --
Leaks:  0
Freed:  98
Reused: 91
Allocs: 7
Retain: 12

Unifications: 40
Conjuncts:    150
Disjuncts:    101
-- out/evalalpha --
Errors:
er3.min: 2 errors in empty disjunction:
er3.min: conflicting values 1 and 5:
    ./in.cue:28:8
    ./in.cue:44:7
es3.max: 2 errors in empty disjunction:
es3.max: 4 errors in empty disjunction:
es3.max: conflicting values 1 and 5:
    ./in.cue:4:16
    ./in.cue:22:7
es3.max: conflicting values 10 and 5:
    ./in.cue:21:7
    ./in.cue:22:7
es3.max: invalid value 5 (out of bound >10):
    ./in.cue:5:7
    ./in.cue:22:7
er3.min: invalid value 5 (out of bound <5):
    ./in.cue:29:7
    ./in.cue:44:7

Result:
(_|_){
  // [eval]
  #Size: (#struct){
    res: (int){ |(*(int){ 0 }, (int){ &(>=0, int) }) }
    min: (number){ |(*(int){ 1 }, (number){ >0 }) }
    max: (number){ |(*(int){ 1 }, (number){ >0 }, (number){ >1 }) }
  }
  s0: (#struct){
    res: (int){ 1 }
    min: (number){ |(*(int){ 2 }, (number){ >1 }) }
    max: (number){ |(*(int){ 2 }, (number){ >1 }, (number){ >2 }) }
  }
  s1: (#struct){
    min: (int){ 5 }
    res: (int){ |(*(int){ 0 }, (int){ &(>=0, int) }) }
    max: (number){ |(*(int){ 5 }, (number){ >5 }) }
  }
  s2: (#struct){
    max: (int){ 5 }
    res: (int){ |(*(int){ 0 }, (int){ &(>=0, int) }) }
    min: (number){ |(*(int){ 1 }, (number){ >0 }) }
  }
  s3: (#struct){
    min: (int){ 5 }
    max: (int){ 10 }
    res: (int){ |(*(int){ 0 }, (int){ &(>=0, int) }) }
  }
  es3: (_|_){
    // [eval]
    min: (int){ 10 }
    max: (_|_){
      // [eval] es3.max: 2 errors in empty disjunction:
      // es3.max: 4 errors in empty disjunction:
      // es3.max: conflicting values 1 and 5:
      //     ./in.cue:4:16
      //     ./in.cue:22:7
      // es3.max: conflicting values 10 and 5:
      //     ./in.cue:21:7
      //     ./in.cue:22:7
      // es3.max: invalid value 5 (out of bound >10):
      //     ./in.cue:5:7
      //     ./in.cue:22:7
    }
    res: (int){ |(*(int){ 0 }, (int){ &(>=0, int) }) }
  }
  #nonEmptyRange: (#struct){
    min: (_|_){
      // [cycle] #nonEmptyRange.min: cycle with field: max:
      //     ./in.cue:29:8
      // #nonEmptyRange.max: cycle with field: min:
      //     ./in.cue:30:8
    }
    max: (_|_){
      // [cycle] #nonEmptyRange.min: cycle with field: max:
      //     ./in.cue:29:8
      // #nonEmptyRange.max: cycle with field: min:
      //     ./in.cue:30:8
    }
  }
  r1: (#struct){
    min: (int){ 3 }
    max: (number){ >3 }
  }
  r2: (#struct){
    max: (int){ 5 }
    min: (int){ |(*(int){ 1 }, (int){ &(<5, int) }) }
  }
  r3: (#struct){
    min: (int){ 3 }
    max: (int){ 6 }
  }
  er3: (_|_){
    // [eval]
    min: (_|_){
      // [eval] er3.min: 2 errors in empty disjunction:
      // er3.min: conflicting values 1 and 5:
      //     ./in.cue:28:8
      //     ./in.cue:44:7
      // er3.min: invalid value 5 (out of bound <5):
      //     ./in.cue:29:7
      //     ./in.cue:44:7
    }
    max: (_|_){
      // [eval] er3.min: 2 errors in empty disjunction:
      // er3.min: conflicting values 1 and 5:
      //     ./in.cue:28:8
      //     ./in.cue:44:7
      // er3.min: invalid value 5 (out of bound <5):
      //     ./in.cue:29:7
      //     ./in.cue:44:7
    }
  }
}
-- diff/-out/evalalpha<==>+out/eval --
diff old new
--- old
+++ new
@@ -2,17 +2,13 @@
 er3.min: 2 errors in empty disjunction:
 er3.min: conflicting values 1 and 5:
     ./in.cue:28:8
-    ./in.cue:43:6
-    ./in.cue:44:7
-es3.max: 3 errors in empty disjunction:
+    ./in.cue:44:7
+es3.max: 2 errors in empty disjunction:
+es3.max: 4 errors in empty disjunction:
 es3.max: conflicting values 1 and 5:
     ./in.cue:4:16
-    ./in.cue:5:15
-    ./in.cue:20:6
     ./in.cue:22:7
 es3.max: conflicting values 10 and 5:
-    ./in.cue:5:15
-    ./in.cue:20:6
     ./in.cue:21:7
     ./in.cue:22:7
 es3.max: invalid value 5 (out of bound >10):
@@ -36,34 +32,30 @@
     max: (number){ |(*(int){ 2 }, (number){ >1 }, (number){ >2 }) }
   }
   s1: (#struct){
-    res: (int){ |(*(int){ 0 }, (int){ &(>=0, int) }) }
-    min: (int){ 5 }
+    min: (int){ 5 }
+    res: (int){ |(*(int){ 0 }, (int){ &(>=0, int) }) }
     max: (number){ |(*(int){ 5 }, (number){ >5 }) }
   }
   s2: (#struct){
-    res: (int){ |(*(int){ 0 }, (int){ &(>=0, int) }) }
-    min: (number){ |(*(int){ 1 }, (number){ >0 }) }
-    max: (int){ 5 }
+    max: (int){ 5 }
+    res: (int){ |(*(int){ 0 }, (int){ &(>=0, int) }) }
+    min: (number){ |(*(int){ 1 }, (number){ >0 }) }
   }
   s3: (#struct){
-    res: (int){ |(*(int){ 0 }, (int){ &(>=0, int) }) }
     min: (int){ 5 }
     max: (int){ 10 }
+    res: (int){ |(*(int){ 0 }, (int){ &(>=0, int) }) }
   }
   es3: (_|_){
     // [eval]
-    res: (int){ |(*(int){ 0 }, (int){ &(>=0, int) }) }
     min: (int){ 10 }
     max: (_|_){
-      // [eval] es3.max: 3 errors in empty disjunction:
+      // [eval] es3.max: 2 errors in empty disjunction:
+      // es3.max: 4 errors in empty disjunction:
       // es3.max: conflicting values 1 and 5:
       //     ./in.cue:4:16
-      //     ./in.cue:5:15
-      //     ./in.cue:20:6
       //     ./in.cue:22:7
       // es3.max: conflicting values 10 and 5:
-      //     ./in.cue:5:15
-      //     ./in.cue:20:6
       //     ./in.cue:21:7
       //     ./in.cue:22:7
       // es3.max: invalid value 5 (out of bound >10):
@@ -70,12 +62,21 @@
       //     ./in.cue:5:7
       //     ./in.cue:22:7
     }
+    res: (int){ |(*(int){ 0 }, (int){ &(>=0, int) }) }
   }
   #nonEmptyRange: (#struct){
     min: (_|_){
-      // [cycle] cycle error
-    }
-    max: (number){ >1 }
+      // [cycle] #nonEmptyRange.min: cycle with field: max:
+      //     ./in.cue:29:8
+      // #nonEmptyRange.max: cycle with field: min:
+      //     ./in.cue:30:8
+    }
+    max: (_|_){
+      // [cycle] #nonEmptyRange.min: cycle with field: max:
+      //     ./in.cue:29:8
+      // #nonEmptyRange.max: cycle with field: min:
+      //     ./in.cue:30:8
+    }
   }
   r1: (#struct){
     min: (int){ 3 }
@@ -82,8 +83,8 @@
     max: (number){ >3 }
   }
   r2: (#struct){
+    max: (int){ 5 }
     min: (int){ |(*(int){ 1 }, (int){ &(<5, int) }) }
-    max: (int){ 5 }
   }
   r3: (#struct){
     min: (int){ 3 }
@@ -95,17 +96,15 @@
       // [eval] er3.min: 2 errors in empty disjunction:
       // er3.min: conflicting values 1 and 5:
       //     ./in.cue:28:8
-      //     ./in.cue:43:6
-      //     ./in.cue:44:7
-      // er3.min: invalid value 5 (out of bound <5):
-      //     ./in.cue:29:7
-      //     ./in.cue:44:7
-    }
-    max: (_|_){
-      // [eval] er3.min: 2 errors in empty disjunction:
-      // er3.min: conflicting values 1 and 5:
-      //     ./in.cue:28:8
-      //     ./in.cue:43:6
+      //     ./in.cue:44:7
+      // er3.min: invalid value 5 (out of bound <5):
+      //     ./in.cue:29:7
+      //     ./in.cue:44:7
+    }
+    max: (_|_){
+      // [eval] er3.min: 2 errors in empty disjunction:
+      // er3.min: conflicting values 1 and 5:
+      //     ./in.cue:28:8
       //     ./in.cue:44:7
       // er3.min: invalid value 5 (out of bound <5):
       //     ./in.cue:29:7
-- diff/todo/p2 --
#nonEmptyRange: missing disjunction error, or at least missing validation.
At least this seems more correct than the old evaluator. It is an
incomplete error at best.
-- diff/explanation --
s1.max: the changes in default behavior as are shown here are according to spec,
as is described in disjunctions/specdeviation.txtar. These changes may pose too
much of a problem for the transition to the new evaluator, though.
TODO: consider reintroducing bugs.
-- diff/todo/p3 --
Reordering.
Missing empty disjunction message.
Missing error positions.
-- out/eval --
Errors:
er3.min: 2 errors in empty disjunction:
er3.min: conflicting values 1 and 5:
    ./in.cue:28:8
    ./in.cue:43:6
    ./in.cue:44:7
es3.max: 3 errors in empty disjunction:
es3.max: conflicting values 1 and 5:
    ./in.cue:4:16
    ./in.cue:5:15
    ./in.cue:20:6
    ./in.cue:22:7
es3.max: conflicting values 10 and 5:
    ./in.cue:5:15
    ./in.cue:20:6
    ./in.cue:21:7
    ./in.cue:22:7
es3.max: invalid value 5 (out of bound >10):
    ./in.cue:5:7
    ./in.cue:22:7
er3.min: invalid value 5 (out of bound <5):
    ./in.cue:29:7
    ./in.cue:44:7

Result:
(_|_){
  // [eval]
  #Size: (#struct){
    res: (int){ |(*(int){ 0 }, (int){ &(>=0, int) }) }
    min: (number){ |(*(int){ 1 }, (number){ >0 }) }
    max: (number){ |(*(int){ 1 }, (number){ >0 }, (number){ >1 }) }
  }
  s0: (#struct){
    res: (int){ 1 }
    min: (number){ |(*(int){ 2 }, (number){ >1 }) }
    max: (number){ |(*(int){ 2 }, (number){ >1 }, (number){ >2 }) }
  }
  s1: (#struct){
    res: (int){ |(*(int){ 0 }, (int){ &(>=0, int) }) }
    min: (int){ 5 }
    max: (number){ |(*(int){ 5 }, (number){ >5 }) }
  }
  s2: (#struct){
    res: (int){ |(*(int){ 0 }, (int){ &(>=0, int) }) }
    min: (number){ |(*(int){ 1 }, (number){ >0 }) }
    max: (int){ 5 }
  }
  s3: (#struct){
    res: (int){ |(*(int){ 0 }, (int){ &(>=0, int) }) }
    min: (int){ 5 }
    max: (int){ 10 }
  }
  es3: (_|_){
    // [eval]
    res: (int){ |(*(int){ 0 }, (int){ &(>=0, int) }) }
    min: (int){ 10 }
    max: (_|_){
      // [eval] es3.max: 3 errors in empty disjunction:
      // es3.max: conflicting values 1 and 5:
      //     ./in.cue:4:16
      //     ./in.cue:5:15
      //     ./in.cue:20:6
      //     ./in.cue:22:7
      // es3.max: conflicting values 10 and 5:
      //     ./in.cue:5:15
      //     ./in.cue:20:6
      //     ./in.cue:21:7
      //     ./in.cue:22:7
      // es3.max: invalid value 5 (out of bound >10):
      //     ./in.cue:5:7
      //     ./in.cue:22:7
    }
  }
  #nonEmptyRange: (#struct){
    min: (_|_){
      // [cycle] cycle error
    }
    max: (number){ >1 }
  }
  r1: (#struct){
    min: (int){ 3 }
    max: (number){ >3 }
  }
  r2: (#struct){
    min: (int){ |(*(int){ 1 }, (int){ &(<5, int) }) }
    max: (int){ 5 }
  }
  r3: (#struct){
    min: (int){ 3 }
    max: (int){ 6 }
  }
  er3: (_|_){
    // [eval]
    min: (_|_){
      // [eval] er3.min: 2 errors in empty disjunction:
      // er3.min: conflicting values 1 and 5:
      //     ./in.cue:28:8
      //     ./in.cue:43:6
      //     ./in.cue:44:7
      // er3.min: invalid value 5 (out of bound <5):
      //     ./in.cue:29:7
      //     ./in.cue:44:7
    }
    max: (_|_){
      // [eval] er3.min: 2 errors in empty disjunction:
      // er3.min: conflicting values 1 and 5:
      //     ./in.cue:28:8
      //     ./in.cue:43:6
      //     ./in.cue:44:7
      // er3.min: invalid value 5 (out of bound <5):
      //     ./in.cue:29:7
      //     ./in.cue:44:7
    }
  }
}
-- out/compile --
--- in.cue
{
  #Size: {
    res: (&(int, >=0)|*0)
    min: (>〈0;res〉|*(1 + 〈0;res〉))
    max: (>〈0;min〉|*〈0;min〉)
  }
  s0: (〈0;#Size〉 & {
    res: 1
  })
  s1: (〈0;#Size〉 & {
    min: 5
  })
  s2: (〈0;#Size〉 & {
    max: 5
  })
  s3: (〈0;#Size〉 & {
    min: 5
    max: 10
  })
  es3: (〈0;#Size〉 & {
    min: 10
    max: 5
  })
  #nonEmptyRange: {
    min: (*1|int)
    min: <〈0;max〉
    max: >〈0;min〉
  }
  r1: (〈0;#nonEmptyRange〉 & {
    min: 3
  })
  r2: (〈0;#nonEmptyRange〉 & {
    max: 5
  })
  r3: (〈0;#nonEmptyRange〉 & {
    min: 3
    max: 6
  })
  er3: (〈0;#nonEmptyRange〉 & {
    min: 5
    max: 5
  })
}
