| 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 -- |
| Errors: |
| er3.min: 2 errors in empty disjunction: |
| er3.min: conflicting values 1 and 5: |
| ./in.cue:28:11 |
| ./in.cue:43:6 |
| ./in.cue:44:10 |
| es3.max: 3 errors in empty disjunction: |
| es3.max: conflicting values 1 and 5: |
| ./in.cue:4:19 |
| ./in.cue:5:18 |
| ./in.cue:20:6 |
| ./in.cue:22:10 |
| es3.max: conflicting values 10 and 5: |
| ./in.cue:5:18 |
| ./in.cue:20:6 |
| ./in.cue:21:10 |
| ./in.cue:22:10 |
| es3.max: invalid value 5 (out of bound >10): |
| ./in.cue:5:10 |
| ./in.cue:22:10 |
| er3.max: invalid value 5 (out of bound >5): |
| ./in.cue:30:10 |
| ./in.cue:45:10 |
| |
| 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:19 |
| // ./in.cue:5:18 |
| // ./in.cue:20:6 |
| // ./in.cue:22:10 |
| // es3.max: conflicting values 10 and 5: |
| // ./in.cue:5:18 |
| // ./in.cue:20:6 |
| // ./in.cue:21:10 |
| // ./in.cue:22:10 |
| // es3.max: invalid value 5 (out of bound >10): |
| // ./in.cue:5:10 |
| // ./in.cue:22:10 |
| } |
| } |
| #nonEmptyRange: (#struct){ |
| min: (_|_){ |
| // [incomplete] #nonEmptyRange.min: incomplete cause disjunction |
| } |
| max: (_|_){ |
| // [incomplete] #nonEmptyRange.min: incomplete cause disjunction |
| } |
| } |
| 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:11 |
| // ./in.cue:43:6 |
| // ./in.cue:44:10 |
| // er3.max: invalid value 5 (out of bound >5): |
| // ./in.cue:30:10 |
| // ./in.cue:45:10 |
| } |
| max: (_|_){ |
| // [eval] er3.max: invalid value 5 (out of bound >5): |
| // ./in.cue:30:10 |
| // ./in.cue:45:10 |
| } |
| } |
| } |
| -- 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 |
| }) |
| } |