internal/core/eval: simplify validators upon evaluator

Fixes #545

Change-Id: Ie4a7ca80b6be7a13c3547a31c3f85447fb174d55
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/7222
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
Reviewed-by: CUE cueckoo <cueckoo@gmail.com>
diff --git a/internal/core/eval/eval.go b/internal/core/eval/eval.go
index 5ab7c60..556d1a3 100644
--- a/internal/core/eval/eval.go
+++ b/internal/core/eval/eval.go
@@ -1294,11 +1294,36 @@
 			n.lowerBound = x
 
 		case adt.EqualOp, adt.NotEqualOp, adt.MatchOp, adt.NotMatchOp:
-			n.checks = append(n.checks, x)
+			// This check serves as simplifier, but also to remove duplicates.
+			k := 0
+			match := false
+			for _, c := range n.checks {
+				if y, ok := c.(*adt.BoundValue); ok {
+					switch z := adt.SimplifyBounds(ctx, n.kind, x, y); {
+					case z == y:
+						match = true
+					case z == x:
+						continue
+					}
+				}
+				n.checks[k] = c
+				k++
+			}
+			n.checks = n.checks[:k]
+			if !match {
+				n.checks = append(n.checks, x)
+			}
 			return
 		}
 
 	case adt.Validator:
+		// This check serves as simplifier, but also to remove duplicates.
+		for i, y := range n.checks {
+			if b := adt.SimplifyValidator(ctx, x, y); b != nil {
+				n.checks[i] = b
+				return
+			}
+		}
 		n.checks = append(n.checks, x)
 
 	case *adt.Vertex: