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

Added a simplify pattern for XOR that reduces A xor 0 to A. #498

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,16 @@ internal static partial class Patterns
Mulf(Rational(var mOne, var den), var any1) when mOne == -1 && den != 1 => -(any1 / den),
Mulf(var any1, Rational(var mOne, var den)) when mOne == -1 && den != 1 => -(any1 / den),

// a xor false = a
Xorf(var any1, Entity.Boolean any2) when any2 == false => any1,
Xorf(var any2, var any1) when any2 == false => any1,
Xorf(var any1, Integer any2) when any2 == 0 => any1,
Xorf(Integer any2, var any1) when any2 == 0 => any1,
Copy link
Member

Choose a reason for hiding this comment

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

There's no logic backing xor on numbers, so this pattern is not particularly useful. Or you have some other, broader idea regarding xor? Please, share!

Copy link
Author

Choose a reason for hiding this comment

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

I'm not sure what you mean about backing logic; are you referring to the solver system? If so, we're just using the symbolic algebra representation and simplification systems so this isn't something we had considered. In quantum notation, you see things like this quite frequently:

image

That is, some variable XOR'd against some other variable. In some cases one of those variables is simply the integer 0, and that can be simplified to just using the other value. That's the use case this was intended to support.

Copy link
Member

@WhiteBlackGoose WhiteBlackGoose Aug 24, 2021

Choose a reason for hiding this comment

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

Right. What I am saying is that we don't support boolean operators on integers. So if we want to add it, it should be added for all boolean operators and for all cases, not only for a few cases for xor. That's what I mean 😅 . But before doing so, we need to think how it will be designed.

Copy link
Member

Choose a reason for hiding this comment

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

By the way, maybe you want to join our discord server (see the repo's readme's green badge)? It's a chat, so we can discuss it more conveniently there (and having others potentially involved)

Copy link
Author

Choose a reason for hiding this comment

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

Sure, I'll hop in tomorrow if you believe there's more to this discussion that what you've mentioned here.


// a xor true = not a
Xorf(var any1, var any2) when any2 == true => new Notf(any1),
Xorf(var any2, var any1) when any2 == true => new Notf(any1),
Copy link
Member

Choose a reason for hiding this comment

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

You can write it as Xorf(var any1, Boolean(true)) => any1.Not() thanks to pattern matching. But don't those rules in fact already exist? Let me check


_ => x
};
}
Expand Down
6 changes: 6 additions & 0 deletions Sources/Tests/UnitTests/PatternsTest/SimplifyTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,12 @@ [Fact] public void Patt2() => AssertSimplify(
// TODO: Smart factorizer
[Fact] public void Divide2() => AssertSimplifyToString("(x3 + 3 x 2 y + 3 x y 2 + y3) / (x + y)", "x ^ 2 + 2 * x * y + y ^ 2");
[Fact] public void Divide3() => AssertSimplifyToString("(x2 + 2 x y + y2 + 1) / (x + y)", "x + 1 / (x + y) + y");
[Fact] public void Xor1() => AssertSimplify(new Entity.Xorf(x, 0), x);
[Fact] public void Xor2() => AssertSimplify(new Entity.Xorf(0, x), x);
[Fact] public void Xor3() => AssertSimplify(new Entity.Xorf(false, x), x);
[Fact] public void Xor4() => AssertSimplify(new Entity.Xorf(x, false), x);
[Fact] public void Xor5() => AssertSimplify(new Entity.Xorf(x, true), new Entity.Notf(x));
[Fact] public void Xor6() => AssertSimplify(new Entity.Xorf(true, x), new Entity.Notf(x));

[Fact] public void BigSimple1() => AssertSimplifyToString(
"1+2x*-1+2x*2+x^2+2x+2x*-4+2x*4+2x*2x*-1+2x*2x*2+2x*x^2+x^2+x^2*-4+x^2*4+x^2*2*x*-1+x^2*2x*2+x^2*x^2",
Expand Down