def test_initializer_focus_type_error(self, focus, message):
        context = transform.TransformationContext(circuit.Circuit(5, None),
                                                  circuit.Circuit(5, None),
                                                  circuit.Circuit(5, None))

        with self.assertRaisesRegex(TypeError, message):
            transform.AttentionCircuit(focus, context)
    def test_inject(self):
        # preparation work: create operations
        num_qubits = 5
        operation_a = _random_operation(0)
        operation_b = _random_operation(0, 1)
        operation_c1 = _random_operation(1)
        operation_c2 = _random_operation(1, 2)
        operation_c3 = _random_operation(2)
        operation_d1 = _random_operation(2, 3)
        operation_d2 = _random_operation(3)
        operation_e1 = _random_operation(3, 4)
        operation_e2 = _random_operation(4)

        # preparation work: construct the TransformationContext
        context = transform.TransformationContext(
            circuit.Circuit(num_qubits, [operation_a]),
            circuit.Circuit(num_qubits,
                            [operation_c1, operation_c2, operation_c3]),
            circuit.Circuit(num_qubits, [operation_e1, operation_e2]))

        # call the method to be tested
        circ_full = context.inject([operation_b], [operation_d1, operation_d2])

        # check type for circ_full
        self.assertIs(type(circ_full), circuit.Circuit)

        # check value for circ_full
        self.assertTrue(
            _elementwise_is(circ_full.get_operation_sequence(), [
                operation_a, operation_b, operation_c1, operation_c2,
                operation_c3, operation_d1, operation_d2, operation_e1,
                operation_e2
            ]))
    def test_initializer_empty_focus_error(self):
        context = transform.TransformationContext(circuit.Circuit(5, None),
                                                  circuit.Circuit(5, None),
                                                  circuit.Circuit(5, None))

        with self.assertRaisesRegex(ValueError, r'focus must not be empty'):
            transform.AttentionCircuit((), context)
    def test_initializer_and_getters(self):
        # preparation work
        focus_in = [_random_operation(1, 2)]
        context_in = transform.TransformationContext(circuit.Circuit(5, None),
                                                     circuit.Circuit(5, None),
                                                     circuit.Circuit(5, None))
        locations_in = (0, )
        perform_rule = lambda operation_in: [operation_in]
        rule_id = object()

        # initialize the PointTransformation
        transformation = transform.PointTransformation(
            attention_circ=transform.AttentionCircuit(focus=focus_in,
                                                      context=context_in,
                                                      locations=locations_in),
            perform_rule=perform_rule,
            rule_id=rule_id)

        # check type and value transformation.focus()
        focus_out = transformation.focus()
        self.assertIs(type(focus_out), tuple)
        self.assertTrue(_elementwise_is(focus_out, focus_in))

        # check transformation.context()
        self.assertIs(transformation.context(), context_in)

        # check type and value transformation.locations()
        locations_out = transformation.locations()
        self.assertIs(type(locations_out), tuple)
        self.assertTrue(_elementwise_is(locations_out, locations_in))

        # check transformation.context()
        self.assertIs(transformation.rule_id(), rule_id)
    def test_initializer_without_locations_and_getters(self):
        # preparation work
        focus_in = (_random_operation(1, 2), _random_operation(1))
        focus_length = len(focus_in)
        context = transform.TransformationContext(
            circuit.Circuit(5, [
                _random_operation(2),
                _random_operation(3),
                _random_operation(4)
            ]), circuit.Circuit(5, [_random_operation(0)]),
            circuit.Circuit(5, [_random_operation(0),
                                _random_operation(1, 2)]))

        # construct the AttentionCircuit
        att_circ = transform.AttentionCircuit(focus_in,
                                              context,
                                              locations=None)

        # check type and value for att_circ.focus()
        focus_out = att_circ.focus()
        self.assertIs(type(focus_out), tuple)
        self.assertTrue(_elementwise_is(focus_out, focus_in))

        # check att_circ.context()
        self.assertIs(att_circ.context(), context)

        # check that att_circ.locations() is None
        self.assertIsNone(att_circ.locations())

        # check type and value for len(att_circ)
        length = len(att_circ)
        self.assertIs(type(length), int)
        self.assertEqual(length, focus_length)
    def test_perform(self):
        # preparation work
        num_qubits = 5

        operation_before1 = _random_operation(0)
        operation_before2 = _random_operation(1)
        operation_before3 = _random_operation(2)
        operation_between1 = _random_operation(0)
        operation_between2 = _random_operation(1)
        operation_after = _random_operation(1)

        operation_in1 = _random_operation(1)
        operation_in2 = _random_operation(1)
        operation_in3 = _random_operation(1)
        operation_in4 = _random_operation(1)
        operation_out1 = _random_operation(1)
        operation_out2 = _random_operation(1)
        operation_out3 = _random_operation(1)

        # define the transformation rule
        def perform_rule(operations_in):
            # check type and value for operations_in
            self.assertIs(type(operations_in), tuple)
            self.assertTrue(
                _elementwise_is(operations_in, [
                    operation_in1, operation_in2, operation_in3, operation_in4
                ]))

            # return the modified operations
            return [operation_out1, operation_out2, operation_out3]

        # initialize the PointTransformation
        transformation = transform.GroupTransformation(
            attention_circ=transform.AttentionCircuit(
                focus=[
                    operation_in1, operation_in2, operation_in3, operation_in4
                ],
                context=transform.TransformationContext(
                    circuit.Circuit(num_qubits, [
                        operation_before1, operation_before2, operation_before3
                    ]),
                    circuit.Circuit(num_qubits,
                                    [operation_between1, operation_between2]),
                    circuit.Circuit(num_qubits, [operation_after]))),
            perform_rule=perform_rule,
            rule_id=None)

        # call the method to be tested
        circ_out = transformation.perform()

        # check type for circ_out
        self.assertIs(type(circ_out), circuit.Circuit)

        # check the value for circ_out
        self.assertTrue(
            _elementwise_is(circ_out.get_operation_sequence(), [
                operation_before1, operation_before2, operation_before3,
                operation_out1, operation_out2, operation_out3,
                operation_between1, operation_between2, operation_after
            ]))
    def test_initializer_locations_type_error(self, locations, message):
        focus = (_random_operation(1, 2), _random_operation(1))
        context = transform.TransformationContext(circuit.Circuit(5, None),
                                                  circuit.Circuit(5, None),
                                                  circuit.Circuit(5, None))

        with self.assertRaisesRegex(TypeError, message):
            transform.AttentionCircuit(focus, context, locations=locations)
    def test_initializer_inconsistent_num_qubits_error(self, num_before,
                                                       num_between, num_after):
        before = circuit.Circuit(num_before, None)
        between = circuit.Circuit(num_between, None)
        after = circuit.Circuit(num_after, None)

        with self.assertRaisesRegex(
                ValueError,
                r'inconsistent number of qubits for before, between and after:'
                r' \(%d, %d, %d\)' % (num_before, num_between, num_after)):
            transform.TransformationContext(before, between, after)
    def test_initializer_focus_size_error(self):
        attention_circ = transform.AttentionCircuit(
            focus=[_random_operation(2)],
            context=transform.TransformationContext(circuit.Circuit(5, None),
                                                    circuit.Circuit(5, None),
                                                    circuit.Circuit(5, None)))
        perform_rule = lambda operation_in: [operation_in]

        with self.assertRaisesRegex(
                ValueError,
                r'focus of attention_circ for PairTransformation must have size 2'
                r' \(found: 1\)'):
            transform.PairTransformation(attention_circ, perform_rule, None)
    def test_initializer_redundant_transformation_error(self):
        attention_circ = transform.AttentionCircuit(
            focus=[_random_operation(2, 3),
                   _random_operation(5)],
            context=transform.TransformationContext(circuit.Circuit(5, None),
                                                    circuit.Circuit(5, None),
                                                    circuit.Circuit(5, None)))
        perform_rule = lambda operation_in: [operation_in]

        with self.assertRaisesRegex(
                ValueError,
                r'transformation redundant because operations trivially commute'
        ):
            transform.PairTransformation(attention_circ, perform_rule, None)
    def test_initializer_locations_length_error(self):
        focus = (_random_operation(1, 2), _random_operation(1))
        context = transform.TransformationContext(
            circuit.Circuit(5, [
                _random_operation(2),
                _random_operation(3),
                _random_operation(4)
            ]), circuit.Circuit(5, [_random_operation(0)]),
            circuit.Circuit(5, [_random_operation(0),
                                _random_operation(1, 2)]))

        with self.assertRaisesRegex(
                ValueError,
                r'inconsistent lengths for focus and locations: 2 vs. 1'):
            transform.AttentionCircuit(focus, context, locations=(3, ))