def test_qubit_declaration(): p = """ qubit q; qubit[4] a; """.strip() program = parse(p) assert program == Program(statements=[ QubitDeclaration(qubit=Identifier(name="q"), size=None), QubitDeclaration( qubit=Identifier(name="a"), size=IntegerLiteral(4), ), ]) SpanGuard().visit(program) qubit_declaration = program.statements[0] assert qubit_declaration.span == Span(1, 0, 1, 7) assert qubit_declaration.qubit.span == Span(1, 6, 1, 6)
def test_selection(): p = """ let a = b[1, 2]; """.strip() program = parse(p) assert program == Program(statements=[ AliasStatement( target=Identifier(name="a"), value=Selection( name="b", indices=[IntegerLiteral( value=1), IntegerLiteral(value=2)]), ) ]) SpanGuard().visit(program) selection = program.statements[0] assert selection.span == Span(1, 0, 1, 15) assert selection.target.span == Span(1, 4, 1, 4) assert selection.value.span == Span(1, 8, 1, 14)
def test_calibration_definition(): p = """ defcal rz(angle[20] theta) $q -> bit { return shift_phase drive($q), -theta; } """.strip() program = parse(p) assert program == Program(statements=[ CalibrationDefinition( name=Identifier("rz"), arguments=[ ClassicalArgument( type=AngleType(size=IntegerLiteral(20)), name=Identifier("theta"), ) ], qubits=[Identifier("$q")], return_type=BitType(None), body="return shift_phase drive ( $q ) , - theta ;", ) ]) SpanGuard().visit(program)
def test_unary_expression(): p = """ ~b; !b; -i; """.strip() program = parse(p) assert program == Program(statements=[ ExpressionStatement(expression=UnaryExpression( op=UnaryOperator["~"], expression=Identifier(name="b"), )), ExpressionStatement(expression=UnaryExpression( op=UnaryOperator["!"], expression=Identifier(name="b"), )), ExpressionStatement(expression=UnaryExpression( op=UnaryOperator["-"], expression=Identifier(name="i"), )), ])
def test_gate_definition3(): p = """ gate rz(λ) a { gphase(-λ/2); U(0, 0, λ) a; } """.strip() program = parse(p) assert program == Program(statements=[ QuantumGateDefinition( name=Identifier("rz"), arguments=[Identifier(name="λ")], qubits=[Identifier(name="a")], body=[ QuantumPhase( quantum_gate_modifiers=[], argument=BinaryExpression( op=BinaryOperator["/"], lhs=UnaryExpression(op=UnaryOperator["-"], expression=Identifier(name="λ")), rhs=IntegerLiteral(value=2), ), qubits=[], ), QuantumGate( modifiers=[], name=Identifier("U"), arguments=[ IntegerLiteral(value=0), IntegerLiteral(value=0), Identifier(name="λ"), ], qubits=[Identifier(name="a")], ), ], ) ]) SpanGuard().visit(program) gate_declaration = program.statements[0] assert gate_declaration.span == Span(1, 0, 1, 43) assert gate_declaration.arguments[0].span == Span(1, 8, 1, 8) assert gate_declaration.qubits[0].span == Span(1, 11, 1, 11)
def test_for_in_loop(): p = """ for i in [0: 2] { majority a[i], b[i + 1], a[i + 1]; } """.strip() program = parse(p) assert program == Program(statements=[ ForInLoop( loop_variable=Identifier("i"), set_declaration=RangeDefinition( start=IntegerLiteral(0), end=IntegerLiteral(2), step=None), block=[ QuantumGate( modifiers=[], name=Identifier("majority"), arguments=[], qubits=[ Subscript(name="a", index=Identifier("i")), Subscript( name="b", index=BinaryExpression( op=BinaryOperator["+"], lhs=Identifier("i"), rhs=IntegerLiteral(1), ), ), Subscript( name="a", index=BinaryExpression( op=BinaryOperator["+"], lhs=Identifier("i"), rhs=IntegerLiteral(1), ), ), ], ), ], ) ]) SpanGuard().visit(program)
def test_measurement(): p = """ measure q; measure q -> c[0]; c[0] = measure q[0]; """.strip() program = parse(p) assert program == Program(statements=[ QuantumMeasurementAssignment(target=None, measure_instruction=QuantumMeasurement( qubit=Identifier("q"))), QuantumMeasurementAssignment( target=Subscript(name="c", index=IntegerLiteral(value=0)), measure_instruction=QuantumMeasurement(qubit=Identifier("q")), ), QuantumMeasurementAssignment( target=Subscript(name="c", index=IntegerLiteral(value=0)), measure_instruction=QuantumMeasurement( qubit=Subscript(name="q", index=IntegerLiteral(value=0))), ), ]) SpanGuard().visit(program)
def test_gate_defs(): p = """ gate xyz q { x q; y q; z q; } """.strip() program = parse(p) assert program == Program(statements=[ QuantumGateDefinition( name=Identifier("xyz"), arguments=[], qubits=[Identifier(name="q")], body=[ QuantumGate( modifiers=[], name=Identifier("x"), arguments=[], qubits=[Identifier(name="q")], ), QuantumGate( modifiers=[], name=Identifier("y"), arguments=[], qubits=[Identifier(name="q")], ), QuantumGate( modifiers=[], name=Identifier("z"), arguments=[], qubits=[Identifier(name="q")], ), ], ) ], ) SpanGuard().visit(program)
def test_subroutine_signatures(): p = """ def a(int[8] b) {} def a(complex[float[32]] b, qubit c) -> int[32] {} def a(bit[5] b, qubit[2] c) -> complex[float[64]] {} def a(qubit b, const array[uint[8], 2, 3] c) {} def a(mutable array[uint[8], #dim=5] b, const array[uint[8], 5] c) {} """.strip() program = parse(p) a, b, c = Identifier(name="a"), Identifier(name="b"), Identifier(name="c") SpanGuard().visit(program) assert program == Program(statements=[ SubroutineDefinition( name=a, arguments=[ClassicalArgument(IntType(IntegerLiteral(8)), b)], return_type=None, body=[], ), SubroutineDefinition( name=a, arguments=[ ClassicalArgument( type=ComplexType(FloatType(IntegerLiteral(32))), name=b, ), QuantumArgument(qubit=c, size=None), ], return_type=IntType(IntegerLiteral(32)), body=[], ), SubroutineDefinition( name=a, arguments=[ ClassicalArgument( type=BitType(size=IntegerLiteral(5)), name=b, ), QuantumArgument(qubit=c, size=IntegerLiteral(2)), ], return_type=ComplexType(FloatType(IntegerLiteral(64))), body=[], ), SubroutineDefinition( name=a, arguments=[ QuantumArgument(qubit=b, size=None), ClassicalArgument( type=ArrayReferenceType( base_type=UintType(IntegerLiteral(8)), dimensions=[IntegerLiteral(2), IntegerLiteral(3)], ), name=c, access=AccessControl.CONST, ), ], return_type=None, body=[], ), SubroutineDefinition( name=a, arguments=[ # Note that the first ArrayReferenceType has dimensions of # IntegerLiteral(5) referring to the number of dimensions, # but the second has dimensions [IntegerLiteral(5)] (with a # list), because the sizes of the dimensions are given # explicitly. ClassicalArgument( type=ArrayReferenceType( base_type=UintType(IntegerLiteral(8)), dimensions=IntegerLiteral(5), ), name=b, access=AccessControl.MUTABLE, ), ClassicalArgument( type=ArrayReferenceType( base_type=UintType(IntegerLiteral(8)), dimensions=[IntegerLiteral(5)], ), name=c, access=AccessControl.CONST, ), ], return_type=None, body=[], ), ])
def test_alias_assignment(): p = """ let a = b; let a = b[0:1]; let a = b[{0, 1, 2}]; let a = b ++ c; let a = b[{0, 1}] ++ b[2:2:4] ++ c; """.strip() program = parse(p) a, b, c = Identifier(name="a"), Identifier(name="b"), Identifier(name="c") assert program == Program(statements=[ AliasStatement(target=a, value=b), AliasStatement( target=a, value=IndexExpression( collection=b, index=[ RangeDefinition( start=IntegerLiteral(0), end=IntegerLiteral(1), step=None, ), ], ), ), AliasStatement( target=a, value=IndexExpression( collection=b, index=DiscreteSet(values=[ IntegerLiteral(0), IntegerLiteral(1), IntegerLiteral(2), ]), ), ), AliasStatement(target=a, value=Concatenation(lhs=b, rhs=c)), AliasStatement( target=a, value=Concatenation( lhs=Concatenation( lhs=IndexExpression( collection=b, index=DiscreteSet( values=[IntegerLiteral(0), IntegerLiteral(1)], ), ), rhs=IndexExpression( collection=b, index=[ RangeDefinition( start=IntegerLiteral(2), end=IntegerLiteral(4), step=IntegerLiteral(2), ), ], ), ), rhs=c, ), ), ], ) SpanGuard().visit(program)
def test_binary_expression_precedence(): p = """ b1 || b2 && b3; b1 | b2 ^ b3; b1 != b2 + b3; i1 >= i2 + i3; i1 - i2 << i3; i1 - i2 / i3; i1[i2] + -i1[i2]; -i1 ** i2; """.strip() program = parse(p) assert program == Program(statements=[ ExpressionStatement(expression=BinaryExpression( op=BinaryOperator["||"], lhs=Identifier(name="b1"), rhs=BinaryExpression( op=BinaryOperator["&&"], lhs=Identifier(name="b2"), rhs=Identifier(name="b3"), ), )), ExpressionStatement(expression=BinaryExpression( op=BinaryOperator["|"], lhs=Identifier(name="b1"), rhs=BinaryExpression( op=BinaryOperator["^"], lhs=Identifier(name="b2"), rhs=Identifier(name="b3"), ), )), ExpressionStatement(expression=BinaryExpression( op=BinaryOperator["!="], lhs=Identifier(name="b1"), rhs=BinaryExpression( op=BinaryOperator["+"], lhs=Identifier(name="b2"), rhs=Identifier(name="b3"), ), )), ExpressionStatement(expression=BinaryExpression( op=BinaryOperator[">="], lhs=Identifier(name="i1"), rhs=BinaryExpression( op=BinaryOperator["+"], lhs=Identifier(name="i2"), rhs=Identifier(name="i3"), ), )), ExpressionStatement(expression=BinaryExpression( op=BinaryOperator["<<"], lhs=BinaryExpression( op=BinaryOperator["-"], lhs=Identifier(name="i1"), rhs=Identifier(name="i2"), ), rhs=Identifier(name="i3"), )), ExpressionStatement(expression=BinaryExpression( op=BinaryOperator["-"], lhs=Identifier(name="i1"), rhs=BinaryExpression( op=BinaryOperator["/"], lhs=Identifier(name="i2"), rhs=Identifier(name="i3"), ), )), ExpressionStatement(expression=BinaryExpression( op=BinaryOperator["+"], lhs=IndexExpression(collection=Identifier("i1"), index=[Identifier("i2")]), rhs=UnaryExpression( op=UnaryOperator["-"], expression=IndexExpression( collection=Identifier("i1"), index=[Identifier("i2")], ), ), ), ), ExpressionStatement(expression=UnaryExpression( op=UnaryOperator["-"], expression=BinaryExpression( op=BinaryOperator["**"], lhs=Identifier("i1"), rhs=Identifier("i2"), ), ), ), ])
def test_binary_expression(): p = """ b1 || b2; b1 && b2; b1 | b2; b1 ^ b2; b1 & b2; b1 != b2; i1 >= i2; i1 << i2; i1 - i2; i1 / i2; """.strip() program = parse(p) assert program == Program(statements=[ ExpressionStatement(expression=BinaryExpression( op=BinaryOperator["||"], lhs=Identifier(name="b1"), rhs=Identifier(name="b2"), )), ExpressionStatement(expression=BinaryExpression( op=BinaryOperator["&&"], lhs=Identifier(name="b1"), rhs=Identifier(name="b2"), )), ExpressionStatement(expression=BinaryExpression( op=BinaryOperator["|"], lhs=Identifier(name="b1"), rhs=Identifier(name="b2"), )), ExpressionStatement(expression=BinaryExpression( op=BinaryOperator["^"], lhs=Identifier(name="b1"), rhs=Identifier(name="b2"), )), ExpressionStatement(expression=BinaryExpression( op=BinaryOperator["&"], lhs=Identifier(name="b1"), rhs=Identifier(name="b2"), )), ExpressionStatement(expression=BinaryExpression( op=BinaryOperator["!="], lhs=Identifier(name="b1"), rhs=Identifier(name="b2"), )), ExpressionStatement(expression=BinaryExpression( op=BinaryOperator[">="], lhs=Identifier(name="i1"), rhs=Identifier(name="i2"), )), ExpressionStatement(expression=BinaryExpression( op=BinaryOperator["<<"], lhs=Identifier(name="i1"), rhs=Identifier(name="i2"), )), ExpressionStatement(expression=BinaryExpression( op=BinaryOperator["-"], lhs=Identifier(name="i1"), rhs=Identifier(name="i2"), )), ExpressionStatement(expression=BinaryExpression( op=BinaryOperator["/"], lhs=Identifier(name="i1"), rhs=Identifier(name="i2"), )), ])