// Tests bound expression evaluation and simplification including binary bound
// simplification (incompatible bounds), simplifyExpr with non-concrete bound
// arguments, and struct equality bounds (== / !=). Also covers issue 4142
// (struct equality in definitions) and issue 4251 (SimplifyBounds panic on ==
// bounds combined with other bound types).
-- cue.mod/module.cue --
module: "x.test"
language: version: "v0.14.0"
-- in.cue --
x0: 5       @test(eq, 5)
x1: b5 & 30 @test(eq, 30)

b0: <x0 & >0        @test(eq, >0 & <5)
b1: b0 & int        @test(eq, >0 & <5 & int)
b2: int & <5.5      @test(eq, <5.5 & int)
b3: <10 & <=5       @test(eq, <=5)
b4: >=20 & >20      @test(eq, >20)
b5: >=21 & >20      @test(eq, >=21)
b6: int & >5 & <=6  @test(eq, >5 & <=6 & int)

simplifyExpr: {
	// TODO: fill out later.
	less1: <(<3)   @test(err, code=incomplete, contains="non-concrete value <3", pos=[0:11])
	less2: <(<=3)  @test(err, code=incomplete, contains="non-concrete value <=3", pos=[0:11])
	less3: <=(<3)  @test(err, code=incomplete, contains="non-concrete value <3", pos=[0:12])
	less4: <=(<=3) @test(err, code=incomplete, contains="non-concrete value <=3", pos=[0:12])
	less5: <(!=3)  @test(err, code=incomplete, contains="non-concrete value !=3", pos=[0:11])
	less6: <=(!=3) @test(err, code=incomplete, contains="non-concrete value !=3", pos=[0:12])

	gtr1: >(>3)   @test(err, code=incomplete, contains="non-concrete value >3", pos=[0:10])
	gtr2: >(>=3)  @test(err, code=incomplete, contains="non-concrete value >=3", pos=[0:10])
	gtr3: >=(>3)  @test(err, code=incomplete, contains="non-concrete value >3", pos=[0:11])
	gtr4: >=(>=3) @test(err, code=incomplete, contains="non-concrete value >=3", pos=[0:11])
	gtr5: >(!=3)  @test(err, code=incomplete, contains="non-concrete value !=3", pos=[0:10])
	gtr6: >=(!=3) @test(err, code=incomplete, contains="non-concrete value !=3", pos=[0:11])

	lg1: <(>3)   @test(err, code=incomplete, contains="non-concrete value >3", pos=[0:9])
	lg2: <(>=3)  @test(err, code=incomplete, contains="non-concrete value >=3", pos=[0:9])
	lg3: <=(>3)  @test(err, code=incomplete, contains="non-concrete value >3", pos=[0:10])
	lg4: <=(>=3) @test(err, code=incomplete, contains="non-concrete value >=3", pos=[0:10])

	gl1: >(<3)   @test(err, code=incomplete, contains="non-concrete value <3", pos=[0:9])
	gl2: >(<=3)  @test(err, code=incomplete, contains="non-concrete value <=3", pos=[0:9])
	gl3: >=(<3)  @test(err, code=incomplete, contains="non-concrete value <3", pos=[0:10])
	gl4: >=(<=3) @test(err, code=incomplete, contains="non-concrete value <=3", pos=[0:10])

	ne1: !=(!=3) @test(err, code=incomplete, contains="non-concrete value !=3", pos=[0:10])
	ne2: !=(<3)  @test(err, code=incomplete, contains="non-concrete value <3", pos=[0:10])
	ne3: !=(<=3) @test(err, code=incomplete, contains="non-concrete value <=3", pos=[0:10])
	ne4: !=(>3)  @test(err, code=incomplete, contains="non-concrete value >3", pos=[0:10])
	ne5: !=(>=3) @test(err, code=incomplete, contains="non-concrete value >=3", pos=[0:10])

	s:      string
	n:      number
	i:      int
	f:      float
	b:      bytes
	basic1: <(i)  @test(err, code=incomplete, contains="non-concrete value %s for bound %s", args=[i, <], pos=[0:12])
	basic2: >(n)  @test(err, code=incomplete, contains="non-concrete value %s for bound %s", args=[n, >], pos=[0:12])
	basic3: >=(s) @test(err, code=incomplete, contains="non-concrete value %s for bound %s", args=[s, >=], pos=[0:13])
	basic4: <=(f) @test(err, code=incomplete, contains="non-concrete value %s for bound %s", args=[f, <=], pos=[0:13])
	basic5: <=(b) @test(err, code=incomplete, contains="non-concrete value %s for bound %s", args=[b, <=], pos=[0:13])

	// Do NOT interpret this the same as `!= type`.
	bne1: !=(s) @test(err, code=incomplete, contains="non-concrete value %s for bound %s", args=[s, !=], pos=[0:11])
	bne2: !=(n) @test(err, code=incomplete, contains="non-concrete value %s for bound %s", args=[n, !=], pos=[0:11])
	bne3: !=(n) @test(err, code=incomplete, contains="non-concrete value %s for bound %s", args=[n, !=], pos=[0:11])
	bne4: !=(i) @test(err, code=incomplete, contains="non-concrete value %s for bound %s", args=[i, !=], pos=[0:11])
	bne5: !=(b) @test(err, code=incomplete, contains="non-concrete value %s for bound %s", args=[b, !=], pos=[0:11])

	e1: <(=~"foo") @test(err, code=incomplete, contains="non-concrete value =~", pos=[0:8])
	e2: >(null)    @test(err, code=eval, contains="cannot use null for bound", pos=[0:8])
}
-- binarystring.cue --
simplifyBinary: strings: {
  err1: {
    p1: <"a" & >"b" @test(err, code=eval, contains="incompatible string bounds", pos=[0:16, 0:9])
    p2: >"b" & <"a" @test(err, code=eval, contains="incompatible string bounds", pos=[0:16, 0:9])
  }
  err2: {
    p1: >"b" & <="a" @test(err, code=eval, contains="incompatible string bounds", pos=[0:16, 0:9])
    p2: <="a" & >"b" @test(err, code=eval, contains="incompatible string bounds", pos=[0:17, 0:9])
  }
  err3: {
    p1: >="b" & <"b" @test(err, code=eval, contains="incompatible string bounds", pos=[0:17, 0:9])
    p2: <"b" & >="b" @test(err, code=eval, contains="incompatible string bounds", pos=[0:16, 0:9])
    p3: >"b" & <="b" @test(err, code=eval, contains="incompatible string bounds", pos=[0:16, 0:9])
    p4: <="b" & >"b" @test(err, code=eval, contains="incompatible string bounds", pos=[0:17, 0:9])
  }
  ok1: {
    p1: >"a" & <"b"  @test(eq, >"a" & <"b")
    p2: <"b" & >"a"  @test(eq, >"a" & <"b")
  }
  ok2: {
    p1: >"a" & <="b"  @test(eq, >"a" & <="b")
    p2: <="b" & >"a"  @test(eq, >"a" & <="b")
    p3: >="a" & <"b"  @test(eq, >="a" & <"b")
    p4: <"b" & >="a"  @test(eq, >="a" & <"b")
  }
  ok3: {
    p1: >="b" & <="c"  @test(eq, >="b" & <="c")
    p2: <="c" & >="b"  @test(eq, >="b" & <="c")
  }
  ok4: {
    p1: >="b" & <="b"  @test(eq, >="b" & <="b")
  }
}
simplifyBinary: byte: {
  err1: {
    p1: <'a' & >'b' @test(err, code=eval, contains="incompatible bytes bounds", pos=[0:16, 0:9])
    p2: >'b' & <'a' @test(err, code=eval, contains="incompatible bytes bounds", pos=[0:16, 0:9])
  }
  err2: {
    p1: >'b' & <='a' @test(err, code=eval, contains="incompatible bytes bounds", pos=[0:16, 0:9])
    p2: <='a' & >'b' @test(err, code=eval, contains="incompatible bytes bounds", pos=[0:17, 0:9])
  }
  err3: {
    p1: >='b' & <'b' @test(err, code=eval, contains="incompatible bytes bounds", pos=[0:17, 0:9])
    p2: <'b' & >='b' @test(err, code=eval, contains="incompatible bytes bounds", pos=[0:16, 0:9])
    p3: >'b' & <='b' @test(err, code=eval, contains="incompatible bytes bounds", pos=[0:16, 0:9])
    p4: <='b' & >'b' @test(err, code=eval, contains="incompatible bytes bounds", pos=[0:17, 0:9])
  }
  ok1: {
    p1: >'a' & <'b'  @test(eq, >'a' & <'b')
    p2: <'b' & >'a'  @test(eq, >'a' & <'b')
  }
  ok2: {
    p1: >'a' & <='b'  @test(eq, >'a' & <='b')
    p2: <='b' & >'a'  @test(eq, >'a' & <='b')
    p3: >='a' & <'b'  @test(eq, >='a' & <'b')
    p4: <'b' & >='a'  @test(eq, >='a' & <'b')
  }
  ok3: {
    p1: >='b' & <='c'  @test(eq, >='b' & <='c')
    p2: <='c' & >='b'  @test(eq, >='b' & <='c')
  }
  ok4: {
    p1: >='b' & <='b'  @test(eq, >='b' & <='b')
  }
}
-- binary.cue --
simplifyBinary: float: {
  err1: {
    p1: <1 & >2 @test(err, code=eval, contains="incompatible number bounds", pos=[0:14, 0:9])
    p2: >2 & <1 @test(err, code=eval, contains="incompatible number bounds", pos=[0:14, 0:9])
  }
  err2: {
    p1: >2 & <=1 @test(err, code=eval, contains="incompatible number bounds", pos=[0:14, 0:9])
    p2: <=1 & >2 @test(err, code=eval, contains="incompatible number bounds", pos=[0:15, 0:9])
  }
  err3: {
    p1: >=2 & <2 @test(err, code=eval, contains="incompatible number bounds", pos=[0:15, 0:9])
    p2: <2 & >=2 @test(err, code=eval, contains="incompatible number bounds", pos=[0:14, 0:9])
    p3: >2 & <=2 @test(err, code=eval, contains="incompatible number bounds", pos=[0:14, 0:9])
    p4: <=2 & >2 @test(err, code=eval, contains="incompatible number bounds", pos=[0:15, 0:9])
  }
  ok1: {
    p1: >1 & <2  @test(eq, >1 & <2)
    p2: <2 & >1  @test(eq, >1 & <2)
  }
  ok2: {
    p1: >=2 & <=2 @test(eq, >=2 & <=2)
    p2: <=2 & >=2 @test(eq, >=2 & <=2)
  }
}

simplifyBinary: integer: {
  [_]: [_]: int
  err1: {
    p1: <1 & >2 @test(err, code=eval, contains="incompatible integer bounds", pos=[0:14, 0:9])
    p2: >2 & <1 @test(err, code=eval, contains="incompatible integer bounds", pos=[0:14, 0:9])
  }
  err2: {
    p1: >2 & <=1 @test(err, code=eval, contains="incompatible integer bounds", pos=[0:14, 0:9])
    p2: <=1 & >2 @test(err, code=eval, contains="incompatible integer bounds", pos=[0:15, 0:9])
  }
  err3: {
    p1: >=2 & <2 @test(err, code=eval, contains="incompatible integer bounds", pos=[0:15, 0:9])
    p2: <2 & >=2 @test(err, code=eval, contains="incompatible integer bounds", pos=[0:14, 0:9])
    p3: >2 & <=2 @test(err, code=eval, contains="incompatible integer bounds", pos=[0:14, 0:9])
    p4: <=2 & >2 @test(err, code=eval, contains="incompatible integer bounds", pos=[0:15, 0:9])
  }
  err4: {
    p1: >1 & <2 @test(err, code=eval, contains="incompatible integer bounds", pos=[0:14, 0:9])
    p2: <2 & >1 @test(err, code=eval, contains="incompatible integer bounds", pos=[0:14, 0:9])
  }
  ok1: {
    p1: >=2 & <=3 @test(eq, >=2 & <=3 & int)
    p2: <=3 & >=2 @test(eq, >=2 & <=3 & int)
  }
  ok2: {
    p1: >=2 & <=2 @test(eq, >=2 & <=2 & int)
    p2: <=2 & >=2 @test(eq, >=2 & <=2 & int)
  }
  ok3: {
    p1: >=2 & <3 @test(eq, >=2 & <3 & int)
    p2: >2 & <=3 @test(eq, >2 & <=3 & int)
    p3: <3 & >=2 @test(eq, >=2 & <3 & int)
    p4: <=3 & >2 @test(eq, >2 & <=3 & int)
  }
}
-- equals.cue --
@experiment(structcmp)

equalScalar: {
	ok1: ==1  @test(eq, 1)
	ok1: 1

	ok2: [1, 2]
	ok2: ==[1, 2] @test(eq, [1, 2])

	err1: ==1
	err1: 2    @test(err, code=eval, contains="out of bound ==1", pos=[-1:8, 0:8])

	err2: [1, 2]
	err2: !=[1, 2] @test(err, code=eval, contains="out of bound !=", pos=[0:8, -1:8])
}
equalStruct: {
	ok1: =={} @test(eq, {})
	ok1: {}

	ok2: {a: 1, b: 2}
	ok2: =={a: 1, b: 2} @test(eq, {a: 1, b: 2})

	err1: =={}
	err1: {a: 1, b: 2} @test(err, code=eval, contains="out of bound ==", pos=[-1:8, 0:8])

	err2: {a: 1, b: 2}
	err2: !={a: 1, b: 2} @test(err, code=eval, contains="out of bound !=", pos=[0:8, -1:8])
}
nonConcrete: {
	ok0: =="foo" @test(eq, =="foo")

	_int: int

	iErr1: ==_int @test(err, code=incomplete, contains="non-concrete value", pos=[0:11])

	iErr2: !=_int @test(err, code=incomplete, contains="non-concrete value", pos=[0:11])

	iErr3: ==_int
	iErr3: == 1 @test(err, code=incomplete, contains="non-concrete value", pos=[-1:11])

	ok4: ==1
	ok4: _int @test(eq, ==1 & int) // v3: ==1 & int is not an error

	eErr5: =="foo"
	eErr5: _int @test(err, code=eval, contains="conflicting values", pos=[-13:8, -1:9, 0:9])

	eErr6: ==_int
	eErr6: "foo" @test(err, code=incomplete|eval,
		hint="incompatible types, so this SHOULD be a permanent error",
		contains="non-concrete value", pos=[-1:11]) @test(err:todo, code=eval)
}
-- issue4142.cue --
@experiment(structcmp)

inDefinitions: ok1: {
	#X: =={ name: "X" }
	x: #X & { name: "X" }
	@test(eq, {#X: {=={ name: "X" }}, x: {name: "X"}})
}
inDefinitions: ok2: {
	x: #X & { name: "Y" }
	#X: !={ name: "X" }
	@test(eq, {x: {name: "Y"}, #X: {!={name: "X"}}})
}
inDefinitions: err1: {
	#X: =={ name: "X" }
	x: #X & { name: "Y" }
	@test(err, code=eval, at=x, contains="out of bound ==", pos=[1:6, 2:5])
}
inDefinitions: err2: {
	#X: !={ name: "X" }
	x: #X & { name: "X" }
	@test(err, code=eval, at=x, contains="out of bound !=", pos=[1:6, 2:5])
}
-- issue4251-panic.cue --
@experiment(structcmp)

// SimplifyBounds should handle EqualOp bounds
// without panicking, including in combination
// with other bound types.
// Regression: SimplifyBounds panicked on == bounds combined with other bound types.
// https://cuelang.org/issue/4251
issue4251: ok: {
	a: !="c" & =="a" & "a" @test(eq, "a")
	b: =="b" & !="c" & "b" @test(eq, "b")
	c: =="x" & >="a" & "x" @test(eq, "x")
	d: <="z" & =="y" & "y" @test(eq, "y")
}
issue4251: fail: {
	b: =="b" & !="b" & "b" @test(err, code=eval, contains="out of bound !=", pos=[0:13, 0:5, 0:21])
}
-- out/errors.txt --
[eval] simplifyBinary.float.err1.p1: incompatible number bounds <1 and >2:
    ./binary.cue:3:14
    ./binary.cue:3:9
[eval] simplifyBinary.float.err1.p2: incompatible number bounds <1 and >2:
    ./binary.cue:4:14
    ./binary.cue:4:9
[eval] simplifyBinary.float.err2.p1: incompatible number bounds <=1 and >2:
    ./binary.cue:7:14
    ./binary.cue:7:9
[eval] simplifyBinary.float.err2.p2: incompatible number bounds <=1 and >2:
    ./binary.cue:8:15
    ./binary.cue:8:9
[eval] simplifyBinary.float.err3.p1: incompatible number bounds <2 and >=2:
    ./binary.cue:11:15
    ./binary.cue:11:9
[eval] simplifyBinary.float.err3.p2: incompatible number bounds <2 and >=2:
    ./binary.cue:12:14
    ./binary.cue:12:9
[eval] simplifyBinary.float.err3.p3: incompatible number bounds <=2 and >2:
    ./binary.cue:13:14
    ./binary.cue:13:9
[eval] simplifyBinary.float.err3.p4: incompatible number bounds <=2 and >2:
    ./binary.cue:14:15
    ./binary.cue:14:9
[eval] simplifyBinary.integer.err1.p1: incompatible integer bounds <1 and >2:
    ./binary.cue:29:14
    ./binary.cue:29:9
[eval] simplifyBinary.integer.err1.p2: incompatible integer bounds <1 and >2:
    ./binary.cue:30:14
    ./binary.cue:30:9
[eval] simplifyBinary.integer.err2.p1: incompatible integer bounds <=1 and >2:
    ./binary.cue:33:14
    ./binary.cue:33:9
[eval] simplifyBinary.integer.err2.p2: incompatible integer bounds <=1 and >2:
    ./binary.cue:34:15
    ./binary.cue:34:9
[eval] simplifyBinary.integer.err3.p1: incompatible integer bounds <2 and >=2:
    ./binary.cue:37:15
    ./binary.cue:37:9
[eval] simplifyBinary.integer.err3.p2: incompatible integer bounds <2 and >=2:
    ./binary.cue:38:14
    ./binary.cue:38:9
[eval] simplifyBinary.integer.err3.p3: incompatible integer bounds <=2 and >2:
    ./binary.cue:39:14
    ./binary.cue:39:9
[eval] simplifyBinary.integer.err3.p4: incompatible integer bounds <=2 and >2:
    ./binary.cue:40:15
    ./binary.cue:40:9
[eval] simplifyBinary.integer.err4.p1: incompatible integer bounds >1 and <2:
    ./binary.cue:43:14
    ./binary.cue:43:9
[eval] simplifyBinary.integer.err4.p2: incompatible integer bounds >1 and <2:
    ./binary.cue:44:14
    ./binary.cue:44:9
[eval] simplifyBinary.strings.err1.p1: incompatible string bounds <"a" and >"b":
    ./binarystring.cue:3:16
    ./binarystring.cue:3:9
[eval] simplifyBinary.strings.err1.p2: incompatible string bounds <"a" and >"b":
    ./binarystring.cue:4:16
    ./binarystring.cue:4:9
[eval] simplifyBinary.strings.err2.p1: incompatible string bounds <="a" and >"b":
    ./binarystring.cue:7:16
    ./binarystring.cue:7:9
[eval] simplifyBinary.strings.err2.p2: incompatible string bounds <="a" and >"b":
    ./binarystring.cue:8:17
    ./binarystring.cue:8:9
[eval] simplifyBinary.strings.err3.p1: incompatible string bounds <"b" and >="b":
    ./binarystring.cue:11:17
    ./binarystring.cue:11:9
[eval] simplifyBinary.strings.err3.p2: incompatible string bounds <"b" and >="b":
    ./binarystring.cue:12:16
    ./binarystring.cue:12:9
[eval] simplifyBinary.strings.err3.p3: incompatible string bounds <="b" and >"b":
    ./binarystring.cue:13:16
    ./binarystring.cue:13:9
[eval] simplifyBinary.strings.err3.p4: incompatible string bounds <="b" and >"b":
    ./binarystring.cue:14:17
    ./binarystring.cue:14:9
[eval] simplifyBinary.byte.err1.p1: incompatible bytes bounds <'a' and >'b':
    ./binarystring.cue:36:16
    ./binarystring.cue:36:9
[eval] simplifyBinary.byte.err1.p2: incompatible bytes bounds <'a' and >'b':
    ./binarystring.cue:37:16
    ./binarystring.cue:37:9
[eval] simplifyBinary.byte.err2.p1: incompatible bytes bounds <='a' and >'b':
    ./binarystring.cue:40:16
    ./binarystring.cue:40:9
[eval] simplifyBinary.byte.err2.p2: incompatible bytes bounds <='a' and >'b':
    ./binarystring.cue:41:17
    ./binarystring.cue:41:9
[eval] simplifyBinary.byte.err3.p1: incompatible bytes bounds <'b' and >='b':
    ./binarystring.cue:44:17
    ./binarystring.cue:44:9
[eval] simplifyBinary.byte.err3.p2: incompatible bytes bounds <'b' and >='b':
    ./binarystring.cue:45:16
    ./binarystring.cue:45:9
[eval] simplifyBinary.byte.err3.p3: incompatible bytes bounds <='b' and >'b':
    ./binarystring.cue:46:16
    ./binarystring.cue:46:9
[eval] simplifyBinary.byte.err3.p4: incompatible bytes bounds <='b' and >'b':
    ./binarystring.cue:47:17
    ./binarystring.cue:47:9
[eval] equalScalar.err1: invalid value 2 (out of bound ==1):
    ./equals.cue:10:8
    ./equals.cue:11:8
[eval] equalScalar.err2: invalid value [1,2] (out of bound !=[1,2]):
    ./equals.cue:14:8
    ./equals.cue:13:8
[eval] equalStruct.err1: invalid value {a:1,b:2} (out of bound =={}):
    ./equals.cue:23:8
    ./equals.cue:24:8
[eval] equalStruct.err2: invalid value {a:1,b:2} (out of bound !={a:1,b:2}):
    ./equals.cue:27:8
    ./equals.cue:26:8
[incomplete] nonConcrete.iErr1: non-concrete value _int for bound ==:
    ./equals.cue:34:11
[incomplete] nonConcrete.iErr2: non-concrete value _int for bound !=:
    ./equals.cue:36:11
[incomplete] nonConcrete.iErr3: non-concrete value _int for bound ==:
    ./equals.cue:38:11
[eval] nonConcrete.eErr5: conflicting values =="foo" and int (mismatched types string and int):
    ./equals.cue:32:8
    ./equals.cue:44:9
    ./equals.cue:45:9
[incomplete] nonConcrete.eErr6: non-concrete value _int for bound ==:
    ./equals.cue:47:11
[incomplete] simplifyExpr.less1: non-concrete value <3 for bound <:
    ./in.cue:14:11
[incomplete] simplifyExpr.less2: non-concrete value <=3 for bound <:
    ./in.cue:15:11
[incomplete] simplifyExpr.less3: non-concrete value <3 for bound <=:
    ./in.cue:16:12
[incomplete] simplifyExpr.less4: non-concrete value <=3 for bound <=:
    ./in.cue:17:12
[incomplete] simplifyExpr.less5: non-concrete value !=3 for bound <:
    ./in.cue:18:11
[incomplete] simplifyExpr.less6: non-concrete value !=3 for bound <=:
    ./in.cue:19:12
[incomplete] simplifyExpr.gtr1: non-concrete value >3 for bound >:
    ./in.cue:21:10
[incomplete] simplifyExpr.gtr2: non-concrete value >=3 for bound >:
    ./in.cue:22:10
[incomplete] simplifyExpr.gtr3: non-concrete value >3 for bound >=:
    ./in.cue:23:11
[incomplete] simplifyExpr.gtr4: non-concrete value >=3 for bound >=:
    ./in.cue:24:11
[incomplete] simplifyExpr.gtr5: non-concrete value !=3 for bound >:
    ./in.cue:25:10
[incomplete] simplifyExpr.gtr6: non-concrete value !=3 for bound >=:
    ./in.cue:26:11
[incomplete] simplifyExpr.lg1: non-concrete value >3 for bound <:
    ./in.cue:28:9
[incomplete] simplifyExpr.lg2: non-concrete value >=3 for bound <:
    ./in.cue:29:9
[incomplete] simplifyExpr.lg3: non-concrete value >3 for bound <=:
    ./in.cue:30:10
[incomplete] simplifyExpr.lg4: non-concrete value >=3 for bound <=:
    ./in.cue:31:10
[incomplete] simplifyExpr.gl1: non-concrete value <3 for bound >:
    ./in.cue:33:9
[incomplete] simplifyExpr.gl2: non-concrete value <=3 for bound >:
    ./in.cue:34:9
[incomplete] simplifyExpr.gl3: non-concrete value <3 for bound >=:
    ./in.cue:35:10
[incomplete] simplifyExpr.gl4: non-concrete value <=3 for bound >=:
    ./in.cue:36:10
[incomplete] simplifyExpr.ne1: non-concrete value !=3 for bound !=:
    ./in.cue:38:10
[incomplete] simplifyExpr.ne2: non-concrete value <3 for bound !=:
    ./in.cue:39:10
[incomplete] simplifyExpr.ne3: non-concrete value <=3 for bound !=:
    ./in.cue:40:10
[incomplete] simplifyExpr.ne4: non-concrete value >3 for bound !=:
    ./in.cue:41:10
[incomplete] simplifyExpr.ne5: non-concrete value >=3 for bound !=:
    ./in.cue:42:10
[incomplete] simplifyExpr.basic1: non-concrete value i for bound <:
    ./in.cue:49:12
[incomplete] simplifyExpr.basic2: non-concrete value n for bound >:
    ./in.cue:50:12
[incomplete] simplifyExpr.basic3: non-concrete value s for bound >=:
    ./in.cue:51:13
[incomplete] simplifyExpr.basic4: non-concrete value f for bound <=:
    ./in.cue:52:13
[incomplete] simplifyExpr.basic5: non-concrete value b for bound <=:
    ./in.cue:53:13
[incomplete] simplifyExpr.bne1: non-concrete value s for bound !=:
    ./in.cue:56:11
[incomplete] simplifyExpr.bne2: non-concrete value n for bound !=:
    ./in.cue:57:11
[incomplete] simplifyExpr.bne3: non-concrete value n for bound !=:
    ./in.cue:58:11
[incomplete] simplifyExpr.bne4: non-concrete value i for bound !=:
    ./in.cue:59:11
[incomplete] simplifyExpr.bne5: non-concrete value b for bound !=:
    ./in.cue:60:11
[incomplete] simplifyExpr.e1: non-concrete value =~"foo" for bound <:
    ./in.cue:62:8
[eval] simplifyExpr.e2: cannot use null for bound >:
    ./in.cue:63:8
[eval] inDefinitions.err1.x: invalid value {name:"Y"} (out of bound =={name:"X"}):
    ./issue4142.cue:14:6
    ./issue4142.cue:15:5
[eval] inDefinitions.err2.x: invalid value {name:"X"} (out of bound !={name:"X"}):
    ./issue4142.cue:19:6
    ./issue4142.cue:20:5
[eval] issue4251.fail.b: invalid value "b" (out of bound !="b"):
    ./issue4251-panic.cue:15:13
    ./issue4251-panic.cue:15:5
    ./issue4251-panic.cue:15:21
-- out/eval/stats --
Leaks:  0
Freed:  254
Reused: 195
Allocs: 59
Retain: 0

Unifications: 238
Conjuncts:    422
Disjuncts:    0

NumCloseIDs: 8
