qsharp-compiler icon indicating copy to clipboard operation
qsharp-compiler copied to clipboard

Multi bitwise *XOR* and power operations in an expression get misleading results

Open weucode opened this issue 3 years ago • 3 comments

Describe the bug

The details of precedence can be found in page https://docs.microsoft.com/zh-cn/azure/quantum/user-guide/language/expressions/precedenceandassociativity.

It is shown that bitwise XOR has a higher priority than power operator,so we derived the following two formulas,but the result are confusing.

When calculate the expression (~~~(~~~ 2)) ^ 3, the order should be ~~~ 2 = -3, ~~~ (-3) = 2,2 ^ 3 = 8.But the actual order is ~~~ 2 = -3,(-3) ^ 3 = -27,~~~ (-27) = 26.

When calculate the expression (~~~(~~~ 2 ^ 3)),the order should be ~~~ 2 = -3, (-3) ^ 3 = -27,~~~ (-27) = 26.But the actual order is 2 ^ 3 = 8,~~~ 8 = -9,~~~ (-9) = 8.

To Reproduce

namespace NISLNameSpace {
    open Microsoft.Quantum.Intrinsic;
    open Microsoft.Quantum.Convert;


    @EntryPoint()
    operation main() : Unit {
        mutable a = 3;
        mutable b = 2;
        mutable c = (~~~(~~~ b));
        mutable d = c ^ a;
        Message("a:"+IntAsString(a));
        Message("c:"+IntAsString(c));
        Message("d:"+IntAsString(d));
        mutable e = (~~~(~~~ b)) ^ a;
        Message("e:"+IntAsString(e));
        mutable f = (~~~(~~~ b ^ a));
        Message("f:"+IntAsString(f));
    }
}

Expected behavior

The result of first expression should be 8,and the second should be 26.

System information

operating system:Windows 10

dotnet version:6.0.300

QDK:v0.24.210930

weucode avatar May 28 '22 15:05 weucode

After inspecting the relevant specific source code (click here), I could find out that the operators that you are currently using are named the following ways:

  1. Bitwise not (BNOT), with symbol ~~~, and precedence 45 in our source code (high precedence)
  2. Power operator (POW), with symbol ^, and precedence 40 in our source code (high precedence, but lower than bitwise not)

Bitwise XOR (BXOR, with ^^^ symbol) is not currently specified in any source code portion of your description.

However, I would study further the following statements done, for ensuring that the precedence is correctly set in our code:

bitwise XOR has a higher priority than power operator

It could be seen that:

  • qsBXORop has a precedence of 13 in our code (and 7 in the documentation you shared).
  • qsPOWop has precedence of 40 (and 15 in the documentation you shared).

So, power has a higher precedence set than bitwise XOR. A higher precedence at an operator means that the operation would be done first. Then, power would be done first, and bitwise XOR would be done later.

As an outcome of this study, the precedence settings for the given operators are correctly set in qsharp-compiler.

Then, @weucode, Could you kindly clarify why are you currently stating that XOR is not working as expected? In addition, @samarsha, could you review my comment and kindly add the details that I missed during my analysis, considering that this is my first contribution to the project?

Additionally, I attach a screenshot of the precedence for the cited source code at the top of my message; See the highlighted first object, which has the lowest precedence as stated in its comment, which is set to 1. image

sisco0 avatar Oct 03 '22 04:10 sisco0

I‘m sorry to confuse bitwise NOT and bitwise XOR, and give you an incorrect description. The order I want to get a clear understanding is bitwise NOT(~~~) and power(^). According to their precedences, bitwise NOT would be done first, and power would be done later, so when calculating (~~~(~~~ 2 ^ 3)),the order should be ~~~ 2 = -3, (-3) ^ 3 = -27,~~~ (-27) = 26.But the actual order is 2 ^ 3 = 8,~~~ 8 = -9,~~~ (-9) = 8.

weucode avatar Oct 06 '22 08:10 weucode

@weucode The behavior that is described by your side does not consider parsing parenthesis, being these ignored. Is it expected that parenthesis be taken into account by the parser?

sisco0 avatar Nov 07 '22 02:11 sisco0