Git Product home page Git Product logo

Comments (6)

blakejohnson avatar blakejohnson commented on June 10, 2024 1

All good discussion, @jakelishman. Let's take this over to the OpenQASM spec repo.

from qiskit.

jakelishman avatar jakelishman commented on June 10, 2024

I think this is unclear on whether it ought to be permitted from the OQ3 spec. Personally I'd argue that c[0] == "1" isn't necessarily valid; I'd say c[0] has type bit or bool while "1" has type bit[1], and my view is that those are semantically different types (and we never really did clarify whether bit and bool are the same). The way I wrote parser at the time does that - it'll accept c == "01" as a valid comparison in the equality but not c[0] == "1" because it treats "1" as a bit[1] and says there's no implicit casting rule between bit/bool and bit[1].

I'm happy enough to update that legacy backing parser to allow that, but I think we should clarify the OQ3 spec one way or the other on it.

from qiskit.

jakelishman avatar jakelishman commented on June 10, 2024

Fwiw, my spec justification is these components:

The classical types are divided into the ‘standard’ classical types (bool, int, uint, float, and complex) that exist in languages like C, and the ‘special’ classical types (bit, angle, duration, and stretch) that do not.

so there's no implicit conversion from bool-likes to bit, but an explicit cast of bool to bit[1] is allowed.

Standard and special classical types may only mix in expressions with operators defined for those mixed types, otherwise explicit casts must be provided, unless otherwise noted (such as for assigning float values or expressions to angles).

Since there's no explicit allowance for == between bit and bit[1] (or bool and bit[1]), this semantic analysis forbids it.


That said, my main justifications are predicated on the indexing operation bit[n] * uint -> bit rather than bit[1], and an assertion that bit is distinct from bit[1]. Those two components are the bits that I think the spec is actually pretty silent on, and I think we maybe want to clarify.

from qiskit.

blakejohnson avatar blakejohnson commented on June 10, 2024

Looking closely at that section of the OpenQASM spec, I see that you are right that we are not explicit about whether we should distinguish bit from bit[1]. There are some examples, though, which imply that bitstring syntax can specify values of bit, e.g. the comment next to the assignment of b1:

const uint[16] u1 = 2 * SIZE;  // Compile-time value 10.
const float[64] f1 = 5.0 * SIZE;  // Compile-time value 25.0.
const bit b1 = u1[1];  // Compile-time value `"1"`.

I would be happy to resolve this within the OpenQASM project. I think there are two choices:

  • bit[1] and bit are treated equivalently
  • we have a new syntax for bit literals.

Note that other examples in that section of the spec are no more helpful because they involve implicit casts from integers to bit, e.g.:

bit my_bit = 0;

from qiskit.

jakelishman avatar jakelishman commented on June 10, 2024

Yeah, totally agree there's confusion here.

I do think qiskit-qasm3-import is inconsistent about its type system, for sure - it makes a kind of separation between bitarray (bit[_]) and uint but then treats bitstring literals as uint rather than bit[_].

My main argument for wanting bit and bit[1] to be separate types is because of the broadcasting rules in measure (and similar for gate: a lot of my concerns apply to qubit in the same way).

At the moment, the broadcast rules are that you can broadcast:

  • a single qubit against a single qubit
  • a single qubit against a register
  • a register against a single qubit
  • a register against a register provided they have the same length

The risk I see in blurring the distinction between (particularly qubits, but bits too) qubit and qubit[1] is that the last point now becomes unclear. Consider:

qubit[3] a;
qubit[2] b;
qubit[1] c;

// Now, this should definitely work (OQ3 ranges are double-inclusive):
my_gate a[0:1], b;
// ... as should this:
my_gate a, b[0];
// ... and this:
my_gate a, c[0];
// but what about this?
my_gate a, c;

I'd contend that the last one is supposed to be an error; it's attempting to broadcast two registers of different lengths. If I did my_gate a[0:1], b[0:0]; (OQ3 ranges are double-inclusive, remember), this looks like just as much an error to me, maybe more obviously.

All that said, I haven't thought things through all that much, and the OQ3 importer you're using here was written about a year ago in a short amount of time - I don't think I put too much thought into type system consistency at the time, so I'm not particularly attached to the interpretation I came up with.

from qiskit.

jakelishman avatar jakelishman commented on June 10, 2024

I could see a potential way out being to define bit and bit[1] to be totally different types (my preferred thing), but avoid needing to introduce new syntax / literals by saying "anything that can implicitly coerce to bool can be assigned to bit", and we could make it clear if integer literals and bitstrings can be implicitly cast to bool (though admittedly my preference on that is "no", but I'm much more of a strict typing junky than others).

It's unclear to me whether scalar bit and bool are distinct types in OQ3 as well (or at least, whether they ought to be). I think it's sufficiently clear to say that bit[n] is distinct from array[bool, n] and to forbid array[bit, n] (arrays want to have a minimum stride of a byte, and scalar bool is byte-aligned). I don't know if there's merit in saying that "bool lvalues are completely interchangeable with bit lvalues, but only bit rvalues can be the target of the measure expression" - I don't know if it's helpful for hardware to have that bit/bool storage distinction. If so, I think the follow-up question is "what is the type of indexing uint[8] with a scalar?".

My rough feeling is that bool and scalar bit probably ought to be identical, and that the rvalue restriction on measure I put above is not helpful and shouldn't be made. bit[n] would differ from array[bool, n]; array[bool, n] would have its elements byte aligned (like a Numpy bool array), whereas bit[n] could/should be stored bitpacked and we'd have to make a separate decision about what ABI requirements if bit[n] was going to be a type that's allowed in extern FFI calls or the like.

from qiskit.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.