public override IEnumerable <ProgramState> TrySetConstraint(SymbolicValueConstraint constraint, ProgramState programState)
        {
            var boolConstraint = constraint as BoolConstraint;

            if (boolConstraint == null)
            {
                return(new[] { programState });
            }

            SymbolicValueConstraints oldConstraints;
            BoolConstraint           oldBoolConstraint = null;

            if (TryGetConstraints(programState, out oldConstraints))
            {
                oldBoolConstraint = oldConstraints.GetConstraintOrDefault <BoolConstraint>();
            }

            if (oldBoolConstraint != null /* could also be ObjectConstraint.NotNull, which can be overridden */ &&
                oldBoolConstraint != boolConstraint)
            {
                return(Enumerable.Empty <ProgramState>());
            }

            SymbolicValueConstraints leftConstraints;
            var leftHasConstraint = LeftOperand.TryGetConstraints(programState, out leftConstraints);
            SymbolicValueConstraints rightConstraints;
            var rightHasConstraint = RightOperand.TryGetConstraints(programState, out rightConstraints);

            var relationship = GetRelationship(boolConstraint);

            var newProgramState = programState.TrySetRelationship(relationship);

            if (newProgramState == null)
            {
                return(Enumerable.Empty <ProgramState>());
            }

            if (!rightHasConstraint && !leftHasConstraint)
            {
                return(new[] { newProgramState });
            }

            return(SetConstraint(boolConstraint, leftConstraints, rightConstraints, newProgramState));
        }