def test_combined_traces(self): """ Does the same thing as L{test_multiple_source_trace}, but does it by creating two DTs and adding the rules from one to the other. """ trace0 = DerivationTrace(self.sign0, word="IM7") trace1 = DerivationTrace(self.sign1, word="V7") # Pretend the rule was applied to the above signs trace2 = DerivationTrace(self.sign2, rule=self.rule, args=[trace1, trace0]) # This is actually the same as trace2 trace2b = DerivationTrace(self.sign2, rule=self.rule, args=[trace1, trace0]) trace2.add_rules_from_trace(trace2b)
def test_multiple_source_trace(self): """ Creates two derivation traces like that created in L{test_create_rule_trace} and combines them into a single trace. """ trace0 = DerivationTrace(self.sign0, word="IM7") trace1 = DerivationTrace(self.sign1, word="V7") # Pretend the rule was applied to the above signs trace2 = DerivationTrace(self.sign2, rule=self.rule, args=[trace1, trace0]) # This rule app is actually the same as trace2, but the DT shouldn't # care about that, as it's not clever enough trace2.add_rule(self.rule, [trace1, trace0])
def test_create_rule_trace(self): """ First creates two lexical traces (as tested in L{test_create_lexical_trace}) and then a trace for applying the application rule to them. The rule is not actually applied, we just pretend it was. """ trace0 = DerivationTrace(self.sign0, word="IM7") trace1 = DerivationTrace(self.sign1, word="V7") # Pretend the rule was applied to the above signs trace2 = DerivationTrace(self.sign2, rule=self.rule, args=[trace1, trace0])
def test_create_lexical_trace(self): """ Just creates a derivation trace in the simplest possible way, as if it's a lexical production. """ trace = DerivationTrace(self.sign0, word="IM7")
def _apply_binary_rule(self, rule, sign_pair): """ Internal method to apply a given binary rule to a given pair of signs. Note that the supported interface method is apply_binary_rule(), which applies a single rule to all sign pairs between given nodes. This is used internally by L{apply_binary_rule} and L{apply_binary_rules}. """ if sign_pair[0].check_rule_applied(rule, sign_pair[1]): # This sign pair has been combined by this binary rule with this input before. # No need to do it again. If the application is possible, the # result will be in the chart return [] # Get the possible results of applying the rule results = rule.apply_rule(sign_pair) # Note for future attempts that we've already done this sign_pair[0].note_rule_applied(rule, sign_pair[1]) if results is not None: # If storing derivation traces, add them now if self.derivations: for result in results: result.derivation_trace = DerivationTrace(result, rule, [sign.derivation_trace for sign in sign_pair]) return results else: return []
def add_word_signs(self, signs, start_node, word, end_node=None): """ Adds a single-word categories in list "signs" to the chart for the word starting at node C{start_node}. This may span more than one node, in which case C{end_node} should be given as well. By default, C{end_node} will be assumed to be C{start_node}+1. """ # Span is stored in the table internally as # (start_node, end_node-start_node-1) if end_node is None: span_end = 0 else: span_end = end_node-start_node-1 assert span_end >= 0 if self.derivations: for sign in signs: sign.derivation_trace = DerivationTrace(sign, word=word) return self._table[start_node][span_end].extend(signs)
def _apply_binary_rule_semantics(self, rule, sign_pair, category): """ Like _apply_binary_rule, but uses the C{apply_rule_semantics()} of the rule instead of C{apply_rule()} and returns a list of signs built by copying the category and combining it in a sign with the semantics of the result. """ # Get the possible results of applying the rule results = rule.apply_rule_semantics(sign_pair) if results is not None: # Build signs from these and the category given signs = [self.grammar.formalism.Syntax.Sign( category.copy(), result) for result in results] # If storing derivation traces, add them now if self.derivations: for sign in signs: sign.derivation_trace = DerivationTrace(sign, rule, [s.derivation_trace for s in sign_pair]) return signs else: return []
def apply_unary_rule(self, rule, start, end, result_modifier=None): """ Applies a given unary rule to particular arcs and adds the results to the chart. @type result_modifier: 2-arg function @param result_modifier: function to be applied to each result, taking the result sign as the first argument and the input sign as the second. """ signs_added = False input_signs = self.get_signs(start, end) # Apply to each existing sign for sign in input_signs: # Don't try applying unary rules more than once (they'll have the same results) if not sign.check_rule_applied(rule): # Get the possible results of applying the rule results = rule.apply_rule([sign]) # Check the rule was able to apply if results is not None: # If storing derivation traces, add them now if self.derivations: for result in results: result.derivation_trace = DerivationTrace(result, rule, [sign.derivation_trace]) # Apply a result modifier if one was given if result_modifier is not None: result_modifier(result, sign) # Store the results in the table added = self._table[start][end-start-1].extend(results) # If that added anything, return True at the end if added: signs_added = True # Note that the rule has now been applied sign.note_rule_applied(rule) return signs_added