Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SE: Add BitXorOperation #7246

Merged
merged 9 commits into from
Jun 8, 2023
Merged

SE: Add BitXorOperation #7246

merged 9 commits into from
Jun 8, 2023

Conversation

antonioaversa
Copy link
Contributor

@antonioaversa antonioaversa commented May 22, 2023

Part of #7267

Based on the property (holding for positive numbers only) that $a - b \leq a \oplus b \leq a + b$

@antonioaversa antonioaversa force-pushed the Antonio/se-bitwise-xor branch 5 times, most recently from 8407081 to 9df6079 Compare May 25, 2023 06:49
@antonioaversa antonioaversa marked this pull request as ready for review May 25, 2023 12:01
@antonioaversa
Copy link
Contributor Author

public bool IsSingleValue => Min.HasValue && Min == Max; seems fully covered by the following cases:

            NumberConstraint.From(42).IsSingleValue.Should().BeTrue();
            NumberConstraint.From(1, 1).IsSingleValue.Should().BeTrue();
            NumberConstraint.From(null, 42).IsSingleValue.Should().BeFalse();
            NumberConstraint.From(42, null).IsSingleValue.Should().BeFalse();
            NumberConstraint.From(1, 100).IsSingleValue.Should().BeFalse();

So the sub-100% coverage seems a glitch of AltCover.

Copy link
Contributor

@Tim-Pohlmann Tim-Pohlmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there are some things wrong. Let me know what you think and then I'll do another review.

{
return left.CanOverlap(right) ? 0 : Min(left.Max - right.Min, right.Max - left.Min);
}
return null;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should also be true, I think:

Suggested change
return null;
if (left.Min.HasValue && right.Min.HasValue)
{
NegativeMagnitude(BigInteger.Min(left.Min.Value, right.Min.Value));
}
return null;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one breaks multiple cases, and flipping sign either inside and outside NegativeMagnitude doesn't fix it.

Given how little impactful this case can in practice be, I would not invest more time in supporting it.

Copy link
Contributor

@Tim-Pohlmann Tim-Pohlmann May 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try this, it actually fixes two of the existing UTs.

Suggested change
return null;
else if ((left.IsPositive || right.IsNegative) && left.Max.HasValue && right.Min.HasValue)
{
return NegativeMagnitude(-BigInteger.Max(left.Max.Value, BigInteger.Abs(right.Min.Value)));
}
else if ((left.IsNegative || right.IsPositive) && left.Min.HasValue && right.Max.HasValue)
{
return NegativeMagnitude(-BigInteger.Max(BigInteger.Abs(left.Min.Value), right.Max.Value));
}
else if (left.Min.HasValue && left.Max.HasValue && right.Min.HasValue && right.Max.HasValue)
{
return NegativeMagnitude(-BigInteger.Max(
BigInteger.Max(BigInteger.Abs(left.Min.Value), right.Max.Value),
BigInteger.Max(left.Max.Value, BigInteger.Abs(right.Min.Value))));
}
else
{
return null;
}

Copy link
Contributor Author

@antonioaversa antonioaversa May 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tried and worked for existing use cases. However, after some analysis, I could find a case that breaks your code:

[DataRow("i >= -3 && i <= -1 && j >= -4 && j <=-2", 0, 3)]
// Expected SETestContext.CreateCS(code, "int i, int j").Validator.TagValue("Value") 
// to have constraints {NotNull, Number from 0 to 3}, but {Number from 0 to 3} are missing 
// and additional {Number from 3 to 7} are present. Actual are {NotNull, Number from 3 to 7}.

Even if I got CalculateXorMax (see comments below), an issue surely also affects CalculateXorMin.
So, I am not applying these changes, and only keep basic cases where we have solid understanding of how to calculate lower bounds.

Again, given how little impactful these cases can in practice be, I would not invest more time in supporting them.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test case is not affected by the code I suggested. When I add my code suggestion to the current implementation it does what I expect: It improves two test cases ("i == 4 && j >= -6" and "i == -4 && j <= 6").

Comment on lines 177 to 185
if ((left.IsPositive && right.IsPositive) || (left.IsPositive && right.CanBePositive) || (right.IsPositive && left.CanBeNegative))
{
return left.Max.HasValue && right.Max.HasValue ? PositiveMagnitude(left.Max.Value | right.Max.Value) : null;
}
else if ((left.IsPositive && right.IsNegative) || (left.IsNegative && right.IsPositive))
{
return -1;
}
return null;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic confuses me. Shouldn't it be symmetric? From my understanding the following should be correct:

Suggested change
if ((left.IsPositive && right.IsPositive) || (left.IsPositive && right.CanBePositive) || (right.IsPositive && left.CanBeNegative))
{
return left.Max.HasValue && right.Max.HasValue ? PositiveMagnitude(left.Max.Value | right.Max.Value) : null;
}
else if ((left.IsPositive && right.IsNegative) || (left.IsNegative && right.IsPositive))
{
return -1;
}
return null;
if ((left.IsPositive && right.IsNegative) || (left.IsNegative && right.IsPositive))
{
return -1;
}
else if (left.Max.HasValue && right.Max.HasValue)
{
return PositiveMagnitude(left.Max.Value | right.Max.Value);
}
else
{
return null;
}

Copy link
Contributor

@Tim-Pohlmann Tim-Pohlmann May 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try this, it's the opposite to my suggested min:

        if ((left.IsPositive && right.IsNegative) || (left.IsNegative && right.IsPositive))
        {
            return -1;
        }
        else if ((left.IsPositive || right.IsPositive) && left.Max.HasValue && right.Max.HasValue)
        {
            return PositiveMagnitude(BigInteger.Max(left.Max.Value, right.Max.Value));
        }
        else if ((left.IsNegative || right.IsNegative) && left.Min.HasValue && right.Min.HasValue)
        {
            return PositiveMagnitude(BigInteger.Max(BigInteger.Abs(left.Min.Value), BigInteger.Abs(right.Min.Value)));
        }
        else if (left.Min.HasValue && left.Max.HasValue && right.Min.HasValue && right.Max.HasValue)
        {
            return PositiveMagnitude(BigInteger.Max(
                BigInteger.Max(left.Max.Value, right.Max.Value),
                BigInteger.Max(BigInteger.Abs(left.Min.Value), BigInteger.Abs(right.Min.Value))));
        }
        else
        {
            return null;
        }

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tried that too, and it breaks for the following test case:

[DataRow("i ==  4 && j >= -6", null, null)]  // exact range: -8, null
Expected SETestContext.CreateCS(code, "int i, int j").Validator.TagValue("Value") 
to have constraints {NotNull}, but additional {Number from * to 7} are present. 
Actual are {NotNull, Number from * to 7}.

Counterexample: i = 4 = 0b00000100 and j = 11 = 0b00001011 => i ^ j = 0b00001111 =15 > 7

There is something wrong in the branch that returns 7:

else if ((left.IsNegative || right.IsNegative) && left.Min.HasValue && right.Min.HasValue)
        {
            return PositiveMagnitude(BigInteger.Max(BigInteger.Abs(left.Min.Value), BigInteger.Abs(right.Min.Value)));
        }

So, for max too, I would revert the code to the one surely working, and not invest more time in trying to support these cases, unless there is proven usefulness in doing so.

Also, I am not sure that return left.Max.HasValue && right.Max.HasValue ? PositiveMagnitude(BigInteger.Max(left.Max.Value, right.Max.Value)) : null; works correctly for negative numbers, so I am keeping return left.Max.HasValue && right.Max.HasValue ? PositiveMagnitude(left.Max.Value | right.Max.Value) : null;, for which I have strong intuition than it does and that works on all UTs.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I cannot reproduce the failing test case. Replacing the current implementation with my suggestion improves 5 test cases.

Copy link
Contributor

@Tim-Pohlmann Tim-Pohlmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I cannot reproduce the failing test cases. Applying my code suggestions improves multiple existing test cases. Please try once more to integrate the changes.

@antonioaversa
Copy link
Contributor Author

I cannot reproduce the failing test cases. Applying my code suggestions improves multiple existing test cases. Please try once more to integrate the changes.

I may have missed something when trying to validate your suggestion. Since the release is already happening, and this work won't be included in it, I am keeping this PR on hold until your suggestions in #7310 get merged into this PR.

I still think we have already hit a diminishing return with this development, and we shouldn't invest more effort to cover more cases.

@sonarcloud
Copy link

sonarcloud bot commented Jun 5, 2023

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

No Coverage information No Coverage information
No Duplication information No Duplication information

@sonarcloud
Copy link

sonarcloud bot commented Jun 5, 2023

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

100.0% 100.0% Coverage
0.0% 0.0% Duplication

@antonioaversa
Copy link
Contributor Author

#7310 has been merged into this PR.
We now have 100% coverage, green tests and no wrong ranges derivations, as far as I can tell.

Copy link
Contributor

@Tim-Pohlmann Tim-Pohlmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@antonioaversa antonioaversa merged commit 1614d7d into master Jun 8, 2023
@antonioaversa antonioaversa deleted the Antonio/se-bitwise-xor branch June 8, 2023 07:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants