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)
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)
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
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
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
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()