def get_xml_dependency(self): from dangie.utils import get_inverse_relation xml = '<dependency>\n<body>\n' if self.body[-1] == '-': relation = get_inverse_relation(self.body) xml += '<atom name="' + relation + '">\n' xml += '<variable name="y" />\n' xml += '<variable name="x" />\n' else: relation = self.body xml += '<atom name="' + relation + '">\n' xml += '<variable name="x" />\n' xml += '<variable name="y" />\n' xml += '</atom>\n</body>\n<head>\n' if self.head[-1] == '-': relation = get_inverse_relation(self.head) xml += '<atom name="' + relation + '">\n' xml += '<variable name="z" />\n' xml += '<variable name="x" />\n' else: relation = self.head xml += '<atom name="' + relation + '">\n' xml += '<variable name="x" />\n' xml += '<variable name="z" />\n' xml += '</atom>\n</head>\n</dependency>\n' return xml
def process_l(self, word, query, non_terminal): parse_tree = ParseTree(Variable(non_terminal)) parse_tree.sons.append(ParseTree(Terminal(non_terminal[1:]))) parse_tree.sons.append( self.construct_parse_tree( word[1:-1], query, "B" + utils.get_inverse_relation(non_terminal[1:]))) parse_tree.sons.append( ParseTree(Terminal(utils.get_inverse_relation(non_terminal[1:])))) return parse_tree
def _insert_atom(self, atom): self.atoms.add_edge(atom[INPUT_VARIABLE], atom[OUTPUT_VARIABLE], relation=atom[RELATION]) self.atoms.add_edge(atom[OUTPUT_VARIABLE], atom[INPUT_VARIABLE], relation=get_inverse_relation(atom[RELATION]))
def get_relation_xml_dependency_part(self): xml = "" current_node = self.start_node visited_nodes = {current_node} while current_node is not None: next_nodes = self.atoms[current_node] previous_node = current_node current_node = None for next_node in next_nodes: if next_node in visited_nodes: continue current_node = next_node visited_nodes.add(current_node) for relation_d in next_nodes[next_node].values(): relation = relation_d["relation"] if relation[-1] == "-": relation = get_inverse_relation(relation) xml += '<atom name="' + relation + '">\n' xml += '<variable name="' + str( current_node) + '" />\n' xml += '<variable name="' + str( previous_node) + '" />\n' else: xml += '<atom name="' + relation + '">\n' xml += '<variable name="' + str( previous_node) + '" />\n' xml += '<variable name="' + str( current_node) + '" />\n' xml += '</atom>\n' return xml
def add_atom(self, relation, variable0, variable1): if self.start_node is None: self.start_node = variable0 atom = (relation, variable0, variable1) self._add_variables(atom) self._relations.add(relation) self._relations.add(get_inverse_relation(relation)) self._insert_atom(atom)
def _find_cut_pos(word): stack = [word[-1]] for i in range(len(word) - 2, -1, -1): if word[i] == utils.get_inverse_relation(stack[-1]): stack.pop() else: stack.append(word[i]) if not stack: return i return -1
def _process_s(self, word, query): parse_tree = ParseTree(Variable("S")) if word[-1] == query: parse_tree.sons.append( self.construct_parse_tree(word[:-1], query, "B" + query)) parse_tree.sons.append(ParseTree(Terminal(query))) else: cut_pos = self._find_cut_pos(word) parse_tree.sons.append( self.construct_parse_tree(word[:cut_pos], query, "B" + query)) parse_tree.sons.append(ParseTree(Terminal(query))) inverse_query = utils.get_inverse_relation(query) parse_tree.sons.append( self.construct_parse_tree(word[cut_pos + 1:-1], query, "B" + inverse_query)) parse_tree.sons.append(ParseTree(Terminal(inverse_query))) return parse_tree
def get_longest_query_grammar(self, relations, uids): var_s = Variable("S") b_relation_variables = dict() l_relation_variables = dict() for relation in relations: b_relation_variables[relation] = Variable("B" + relation) l_relation_variables[relation] = Variable("L" + relation) productions = set() # For now only single query longest_query = self.get_longest_query() q = Terminal(longest_query[0]) q_minus = Terminal(get_inverse_relation(longest_query[0])) # S -> q productions.add(Production(var_s, [q])) # S -> Bq . q productions.add(Production(var_s, [b_relation_variables[q.value], q])) # S -> q Bq- q- productions.add( Production(var_s, [q, b_relation_variables[q_minus.value], q_minus])) # S -> Bq q Bq- q- productions.add( Production(var_s, [ b_relation_variables[q.value], q, b_relation_variables[q_minus.value], q_minus ])) # Br1 -> Br1 Lr2 for uid in uids: productions.add( Production(b_relation_variables[uid.get_body()], [ b_relation_variables[uid.get_body()], l_relation_variables[uid.get_head()] ])) # Br1 -> Lr2 for uid in uids: productions.add( Production(b_relation_variables[uid.get_body()], [l_relation_variables[uid.get_head()]])) # Lr -> r Br- r- for relation in relations: productions.add( Production(l_relation_variables[relation], [ Terminal(relation), b_relation_variables[get_inverse_relation(relation)], Terminal(get_inverse_relation(relation)) ])) # Lr -> r r- for relation in relations: productions.add( Production(l_relation_variables[relation], [ Terminal(relation), Terminal(get_inverse_relation(relation)) ])) return CFG(start_symbol=var_s, productions=productions)