def apply(self, chart, grammar, edge): if edge.is_incomplete(): return found = edge.lhs() for prod in grammar.productions(rhs=found): bindings = {} if isinstance(edge, FeatureTreeEdge): _next = prod.rhs()[0] if not is_nonterminal(_next): continue # We rename vars here, because we don't want variables # from the two different productions to match. used_vars = find_variables((prod.lhs(), ) + prod.rhs(), fs_class=FeatStruct) found = found.rename_variables(used_vars=used_vars) result = unify(_next, found, bindings, rename_vars=False) if result is None: continue new_edge = FeatureTreeEdge.from_production( prod, edge.start()).move_dot_forward(edge.end(), bindings) if chart.insert(new_edge, (edge, )): yield new_edge
def apply(self, chart, grammar, edge): if edge.is_incomplete(): return found = edge.lhs() for prod in grammar.productions(rhs=found): bindings = {} if isinstance(edge, FeatureTreeEdge): _next = prod.rhs()[0] if not is_nonterminal(_next): continue # We rename vars here, because we don't want variables # from the two different productions to match. used_vars = find_variables( (prod.lhs(),) + prod.rhs(), fs_class=FeatStruct ) found = found.rename_variables(used_vars=used_vars) result = unify(_next, found, bindings, rename_vars=False) if result is None: continue new_edge = FeatureTreeEdge.from_production( prod, edge.start() ).move_dot_forward(edge.end(), bindings) if chart.insert(new_edge, (edge,)): yield new_edge
def compute_children(self) -> List["FeatureGrammarNode"]: child_list: List["FeatureGrammarNode"] = [] # First we retrieve all variables used in current derivation used_vars: Set[Variable] = set() for symbol in self.symbols: if not isinstance(symbol, str): used_vars |= find_variables(symbol) for idx, symbol in enumerate(self.symbols): if isinstance(symbol, str): continue # For each non terminal symbol in current derivation , we select a production rule # that has a left hand side matching this symbol for production in self.feature_grammar.productions(lhs=symbol): # We rename all the variable in the production rules to avoid name conflicts # TODO put this after a check to avoid to do it if not neccessary new_vars = dict() lhs = rename_variables(production.lhs(), used_vars=used_vars, new_vars=new_vars) rhs = [ rename_variables(rhs_symb, used_vars=used_vars, new_vars=new_vars) for rhs_symb in production.rhs() ] # Compute the new binding new_bindings = dict() lhs = unify(lhs, symbol, bindings=new_bindings) if lhs is None: # Unification failed continue # Propagate the bindings to the siblings new_siblings = [ substitute_bindings(sibling, bindings=new_bindings) for sibling in self.symbols ] # Propagate the bindings to the rhs symbols new_rhs = [ substitute_bindings(rhs_symb, bindings=new_bindings) for rhs_symb in rhs ] # Create the new child new_child = FeatureGrammarNode( tuple(new_siblings[:idx] + new_rhs + new_siblings[idx + 1:]), self.feature_grammar, ) child_list.append(new_child) return child_list if len(child_list) != 0 else [ FeatureGrammarNode("DEAD_END", None) ]
def variables(self): """ @return: The set of variables used by this edge. @rtype: C{set} of L{Variable} """ return find_variables([self._lhs] + list(self._rhs) + self._bindings.keys() + self._bindings.values(), fs_class=FeatStruct)
def variables(self): """ :return: The set of variables used by this edge. :rtype: set(Variable) """ return find_variables([self._lhs] + list(self._rhs) + self._bindings.keys() + self._bindings.values(), fs_class=FeatStruct)