def extract_domain(top_domain_file, full_extract=True):
        """
        Extract a dialogue domain from the XML specification

        :param top_domain_file: the filename of the top XML file
        :param full_extract: whether to extract the full domain or only the files
        :return: the extracted dialogue domain
        """
        # create a new, empty domain
        domain = Domain()

        # determine the root path and filename
        fl = open(top_domain_file, 'r')
        domain.set_source_file(Path(top_domain_file))

        # extract the XML document
        document = XMLUtils.get_xml_document(fl)
        main_node = XMLUtils.get_main_node(document)

        root_path = Path(top_domain_file).parent

        for child in main_node:
            domain = XMLDomainReader.extract_partial_domain(
                child, domain, root_path, full_extract)

        return domain
 def start(self):
     """
     Starts the recorder.
     """
     try:
         self._doc = XMLUtils.new_xml_document("interaction")
         self._root_node = XMLUtils.get_main_node(self._doc)
     except Exception as e:
         self.log.warning("could not create dialogue recorder")
         raise ValueError()
    def write_to_file(self, record_file):
        """
        Write the recorded dialogue to a file

        :param record_file: the pathname for the file
        """
        self.log.debug("recording interaction in file " + record_file)
        try:
            XMLUtils.write_xml_document(self._doc, record_file)
        except Exception as e:
            self.log.warning("could not create file " + record_file)
Esempio n. 4
0
    def _get_full_condition(condition_node):
        """
        Extracting the condition associated with an XML specification.

        :param condition_node: the XML node
        :return: the associated condition
        """
        sub_conditions = list()

        for child_node in condition_node:
            if XMLUtils.has_content(child_node):
                sub_condition = XMLRuleReader._get_sub_condition(child_node)
                sub_conditions.append(sub_condition)

        if len(sub_conditions) == 0:
            return VoidCondition()

        operator_str = None
        if 'operator' in condition_node.keys():
            operator_str = condition_node.attrib['operator'].lower().strip()

        if operator_str is not None:
            if operator_str == 'and':
                return ComplexCondition(sub_conditions, BinaryOperator.AND)
            elif operator_str == 'or':
                return ComplexCondition(sub_conditions, BinaryOperator.OR)
            elif operator_str == 'neg' or operator_str == 'not':
                negated_condition = sub_conditions[0] if len(sub_conditions) == 1 else ComplexCondition(sub_conditions, BinaryOperator.AND)
                return NegatedCondition(negated_condition)
            else:
                raise ValueError()

        return sub_conditions[0] if len(sub_conditions) == 1 else ComplexCondition(sub_conditions, BinaryOperator.AND)
Esempio n. 5
0
    def extract_bayesian_network_from_string(full_string):
        """
        Extracts the bayesian network from a XML string.

        :param full_string: the string containing the initial state content
        :return: the corresponding Bayesian network
        """
        # extract the XML document
        document = XMLUtils.get_xml_document(io.StringIO(full_string))
        main_node = XMLUtils.get_main_node(document)

        if main_node.tag == 'state':
            return XMLStateReader.get_bayesian_network(main_node)

        for child_node in main_node:
            if child_node.tag == 'state':
                return XMLStateReader.get_bayesian_network(child_node)

        return BNetwork()
    def extract_dialogue(data_file):
        """
        Extracts the dialogue specified in the data file. The result is a list of
        dialogue state (one for each turn).

        :param data_file: the XML file containing the turns
        :return: the list of dialogue state
        """
        doc = XMLUtils.get_xml_document(data_file)
        main_node = XMLUtils.get_main_node(doc)

        f = open(data_file)
        root_path = f.name

        sample = []

        for node in main_node:
            node_name = node.keys()[0]
            if "Turn" in node_name:
                state = DialogueState(
                    XMLStateReader.get_bayesian_network(node))
                sample.append(state)

                if node_name == "systemTurn" and state.has_chance_node("a_m"):
                    assign = Assignment("a_m",
                                        state.query_prob("a_m").get_best())
                    state.add_evidence(assign)

            elif node_name == "wiazard":
                assign = Assignment.create_from_string(
                    node.get_first_child().get_node_value().trim())
                sample[-1].add_evidence(assign)

            elif node_name == "import":
                file_name = main_node.get_attributes().get_named_item(
                    "href").get_node_value()
                points = XMLDialogueReader.extract_dialogue(root_path + "/" +
                                                            file_name)
                sample.append(points)

        return sample
Esempio n. 7
0
    def extract_bayesian_network(file, tag):
        """
        Returns the initial state or parameters from the XML document, for the given
        domain (where the variable types are already declared)

        :param file: the file to process
        :param tag: the XML tag to search for
        :return: the specified Bayesian network
        """
        # extract the XML document
        document = XMLUtils.get_xml_document(file)
        main_node = XMLUtils.get_main_node(document)

        if main_node.tag == tag:
            return XMLStateReader.get_bayesian_network(main_node)

        for child_node in main_node:
            if child_node.tag == tag:
                return XMLStateReader.get_bayesian_network(child_node)

        raise ValueError()
Esempio n. 8
0
    def get_rule(node):
        """
        Extracts the rule corresponding to the XML specification.

        :param node: topNode the XML node
        :return: the corresponding rule
        """

        # extracting the rule type
        rule_type = RuleType.PROB
        if 'util=' in XMLUtils.serialize(node):
            rule_type = RuleType.UTIL

        # setting the rule identifier
        try:
            rule_id = node.attrib['id']
        except:
            rule_id = 'rule' + str(XMLRuleReader._id_counter)
            XMLRuleReader._id_counter += 1

        # creating the rule
        rule = Rule(rule_id, rule_type)

        priority = 1
        if 'priority' in node.keys():
            priority = int(node.attrib['priority'])

        # extracting the rule cases
        for child_node in node:
            if child_node.tag == 'case':
                condition = XMLRuleReader._get_condition(child_node)
                output = XMLRuleReader._get_output(child_node, rule_type, priority)
                rule.add_case(condition, output)
            elif XMLUtils.has_content(node):
                if node.tag == '#text':
                    raise ValueError()

        return rule
Esempio n. 9
0
    def _get_full_effect(effect_node, priority):
        """
        Extracts a full effect from the XML specification.

        :param effect_node: the XML node
        :param priority: the rule priority
        :return: the corresponding effect
        """
        effects = list()

        for child_node in effect_node:
            if XMLUtils.has_content(child_node) and len(child_node.attrib) > 0:
                sub_effect = XMLRuleReader._get_sub_effect(child_node, priority)
                effects.append(sub_effect)

        return Effect(effects)
Esempio n. 10
0
    def _create_model(node):
        """
        Given an XML node, extracts the rule-based model that corresponds to it.

        :param node: the XML node
        :return: the corresponding model
        """
        model = Model()
        for child in node:
            if child.tag == 'rule':
                rule = XMLRuleReader.get_rule(child)
                model.add_rule(rule)
            elif XMLUtils.has_content(child):
                if child.tag == '#text':
                    raise ValueError()

        if 'trigger' in node.keys():
            trigger_str = node.attrib['trigger']
            matcher_list = re.compile(
                r'([\w\*\^_\-\[\]\{\}]+(?:\([\w\*,\s\^_\-\[\]\{\}]+\))?)[\w\*\^_\-\[\]\{\}]*'
            ).findall(trigger_str)
            for matcher in matcher_list:
                model.add_trigger(matcher)

        if 'blocking' in node.keys():
            if node.attrib['blocking'].lower() == 'true':
                blocking = True
            elif node.attrib['blocking'].lower() == 'false':
                blocking = False
            else:
                raise ValueError()
            model.set_blocking(blocking)

        if 'id' in node.keys():
            model.set_id(node.attrib['id'])

        if 'planning-only' in node.keys():
            model.planning_only = node.attrib['planning-only'].lower(
            ) == 'true'

        return model
Esempio n. 11
0
 def get_record(self):
     """
     Serialises the XML recordings and returns the output.
     :return: the serialised XML content.
     """
     return XMLUtils.serialize(self._root_node)
Esempio n. 12
0
    def extract_partial_domain(main_node, domain, root_path, full_extract):
        """
        Extracts a partially specified domain from the XML node and add its content to
        the dialogue domain.

        :param main_node: main XML node
        :param domain: dialogue domain
        :param root_path: root path (necessary to handle references)
        :param full_extract: whether to extract the full domain or only the files
        :return: the augmented dialogue domain
        """
        tag = main_node.tag

        if tag == 'domain':
            # extracting rule-based probabilistic model
            for child in main_node:
                domain = XMLDomainReader.extract_partial_domain(
                    child, domain, root_path, full_extract)
        elif tag == 'import':
            # extracting imported references
            try:
                file_name = main_node.attrib['href']
                file_path = str(root_path) + os.sep + file_name
                fl = Path(file_path)
                domain.add_imported_files(fl)
                sub_document = XMLUtils.get_xml_document(file_path)
                domain = XMLDomainReader.extract_partial_domain(
                    XMLUtils.get_main_node(sub_document), domain, root_path,
                    full_extract)
            except:
                raise ValueError()

        if not full_extract:
            return domain

        if tag == 'settings':
            # extracting settings
            settings = XMLUtils.extract_mapping(main_node)
            domain.get_settings().fill_settings(settings)
        if tag == 'function':
            # extracting custom functions
            # try:
            domain_function_name = main_node.attrib['name'].strip()

            module_name, actual_function_name = main_node.text.rsplit('.', 1)
            mod = importlib.import_module(module_name)
            func = getattr(mod, actual_function_name)

            domain.get_settings().add_function(domain_function_name, func)
            # except:
            #     raise ValueError()
        if tag == 'initialstate':
            # extracting initial state
            state = XMLStateReader.get_bayesian_network(main_node)
            domain.set_initial_state(DialogueState(state))
        if tag == 'model':
            # extracting rule-based probabilistic model
            model = XMLDomainReader._create_model(main_node)
            domain.add_model(model)
        if tag == 'parameters':
            # extracting parameters
            parameters = XMLStateReader.get_bayesian_network(main_node)
            domain.set_parameters(parameters)
        if XMLUtils.has_content(main_node):
            if main_node == '#text':  # TODO: main_node -> main_node.tag ??
                raise ValueError()

        return domain
Esempio n. 13
0
    def _get_sub_condition(node):
        """
        Extracting a partial condition from a rule specification

        :param node: the XML node
        :return: the corresponding condition
        """
        # extracting a basic condition
        if node.tag == 'if':
            if 'var' not in node.keys():
                raise ValueError()

            variable_name = node.attrib['var']
            template = Template.create(variable_name)

            if template.is_under_specified():
                template = Template.create(str(template).replace('*', '{' + str(random.randint(1, 99)) + '}'))

            value_str = None
            if 'value' in node.keys():
                value_str = node.attrib['value']

            if value_str is not None:
                relation = XMLRuleReader._get_relation(node)
                condition = BasicCondition(variable_name, value_str, relation)
            else:
                if 'var2' not in node.keys():
                    raise ValueError()

                second_variable = node.attrib['var2']
                relation = XMLRuleReader._get_relation(node)
                condition = BasicCondition(variable_name, '{' + second_variable + '}', relation)

            for attrib_key in node.attrib.keys():
                if attrib_key not in ['var', 'var2', 'value', 'relation']:
                    raise ValueError()

            return condition

        # extracting a conjunction or disjunction
        if node.tag == 'or' or node.tag == 'and':
            conditions = list()

            for child_node in node:
                if XMLUtils.has_content(child_node):
                    conditions.append(XMLRuleReader._get_sub_condition(child_node))

            return ComplexCondition(conditions, BinaryOperator.OR if node.tag == 'or' else BinaryOperator.AND)

        # extracting a negated conjunction
        if node.tag == 'neg' or node.tag == 'not':
            conditions = list()

            for child_node in node:
                if XMLUtils.has_content(child_node):
                    conditions.append(XMLRuleReader._get_sub_condition(child_node))

            return conditions[0] if len(conditions) == 1 else ComplexCondition(conditions, BinaryOperator.AND)

        if XMLUtils.has_content(node):
            raise ValueError()

        return VoidCondition()
Esempio n. 14
0
 def export_dialog(self):
     fname = QFileDialog.getSaveFileName(self, 'Save File')
     XMLUtils.export_content(self._system, fname[0], 'state')