def initialize(self, symbolic_vm: LaserEVM):
        """Initializes the instruction coverage plugin

        Introduces hooks for each instruction
        :param symbolic_vm:
        :return:
        """
        self.coverage = {}
        self.initial_coverage = 0
        self.tx_id = 0

        @symbolic_vm.laser_hook("stop_sym_exec")
        def stop_sym_exec_hook():
            # Print results
            for code, code_cov in self.coverage.items():
                cov_percentage = sum(code_cov[1]) / float(code_cov[0]) * 100

                log.info(
                    "Achieved {:.2f}% coverage for code: {}".format(
                        cov_percentage, code
                    )
                )

        @symbolic_vm.laser_hook("execute_state")
        def execute_state_hook(global_state: GlobalState):
            # Record coverage
            code = global_state.environment.code.bytecode

            if code not in self.coverage.keys():
                number_of_instructions = len(
                    global_state.environment.code.instruction_list
                )
                self.coverage[code] = (
                    number_of_instructions,
                    [False] * number_of_instructions,
                )

            self.coverage[code][1][global_state.mstate.pc] = True

        @symbolic_vm.laser_hook("start_sym_trans")
        def execute_start_sym_trans_hook():
            self.initial_coverage = self._get_covered_instructions()

        @symbolic_vm.laser_hook("stop_sym_trans")
        def execute_stop_sym_trans_hook():
            end_coverage = self._get_covered_instructions()
            log.info(
                "Number of new instructions covered in tx %d: %d"
                % (self.tx_id, end_coverage - self.initial_coverage)
            )
            self.tx_id += 1
Initializes the instruction coverage plugin

        Introduces hooks for each instruction
        :param symbolic_vm:
        :return: