def respond(self):
        """
        Consult the policy to retrieve nlg template and generate the response.
        :return: the DTL user Simulator's utterance (response)
        """

        if self.curr_patience <= 0 or self.goal_met:
            return 'bye'

        if not self.input_system_acts:
            # Randomly sample from hello + responses to requests, as there is
            # where informs most likely live.
            sys_act_slot = \
                random.choice([act for act in self.policy if 'request' in act])

            replies = list(self.policy[sys_act_slot]['responses'].keys())
            probs = \
                [self.policy[sys_act_slot]['responses'][i] for i in replies]

            response = deepcopy(random.choices(replies, weights=probs)[0])

            # Replace placeholders with values from goal
            for slot in self.ontology.ontology['informable']:
                if slot.upper() in response:
                    if slot in self.goal.constraints:
                        response = \
                            response.replace(
                                '<' + slot.upper() + '>',
                                self.goal.constraints[slot].value)
                    else:
                        # If there is no constraint, replace with slot 'any'
                        response = \
                            response.replace(
                                '<' + slot.upper() + '>', 'any')

            for slot in self.ontology.ontology['requestable']:
                # This check is necessary to know when to mark this as an
                # actual request
                if slot.upper() in response:
                    response = response.replace('<' + slot.upper() + '>', slot)

                    self.goal.actual_requests[slot] = \
                        DialogueActItem(slot, Operator.EQ, '')

            return random.choice([response, 'hello'])

        response_template = ''

        for system_act in self.input_system_acts:

            # 'bye' doesn't seem to appear in the CamRest data
            if system_act.intent == 'bye':
                response_template += 'thank you, goodbye'

            sys_act_slot = \
                'inform' if system_act.intent == 'offer' else system_act.intent

            if system_act.params and system_act.params[0].slot:
                sys_act_slot += '_' + system_act.params[0].slot

            # Attempt to recover
            if sys_act_slot not in self.policy:
                if sys_act_slot == 'inform_name':
                    sys_act_slot = 'offer_name'

            if sys_act_slot not in self.policy:
                print('Warning! DACT-nlg policy does not know what to do for '
                      '%s' % sys_act_slot)
                # return ''
            else:
                replies = list(self.policy[sys_act_slot]['responses'].keys())
                probs = [
                    self.policy[sys_act_slot]['responses'][i] for i in replies]

                response = deepcopy(random.choices(replies, weights=probs)[0])

                # Replace placeholders with values from goal
                for slot in self.ontology.ontology['informable']:
                    if slot.upper() in response:
                        if slot in self.goal.constraints:
                            response = \
                                response.replace(
                                    '<' + slot.upper() + '>',
                                    self.goal.constraints[slot].value)
                        else:
                            # If there is no constraint, replace with
                            # slot 'any'
                            response = \
                                response.replace(
                                    '<' + slot.upper() + '>', 'any')

                for slot in self.ontology.ontology['requestable']:
                    # This check is necessary to know when to mark this as an
                    # actual request
                    if slot.upper() in response:
                        if slot == 'addr':
                            response = \
                                response.replace(
                                    '<' + slot.upper() + '>', 'address')
                        elif slot == 'postcode':
                            response = \
                                response.replace(
                                    '<' + slot.upper() + '>', 'post code')
                        elif slot == 'pricerange':
                            response = \
                                response.replace(
                                    '<' + slot.upper() + '>', 'price range')
                        else:
                            response = \
                                response.replace(
                                    '<' + slot.upper() + '>', slot)

                        self.goal.actual_requests[slot] = \
                            DialogueActItem(slot, Operator.EQ, '')
                        
                response_template += response + ' '

        return response_template

        Consult the policy to retrieve nlg template and generate the response.
        :return: the DTL user Simulator's utterance (response)
        
plato/agent/component/user_simulator/dact_to_language_user_simulator/dtl_user_simulator.py