class SearchCoord: def __init__(self): self.coord = Rule() self.search_lvl = 1 def extrapolate_rule_with_labels(self): extrapolated_rules = [] rule = self.coord for prev_conv_range in range(0, len(rule.prev) + 1): for next_conv_range in range(0, len(rule.next) + 1): rule_tmp = copy.deepcopy(rule) new_search_coord = SearchCoord() if prev_conv_range > 0: for i in range(prev_conv_range): if rule_tmp.prev[i] != DELIMITER: rule_tmp.prev[i] = map_letter_to_label( rule_tmp.prev[i]) if next_conv_range > 0: for j in reversed( range( len(rule_tmp.next) - next_conv_range, len(rule_tmp.next))): if rule_tmp.next[j] != DELIMITER: rule_tmp.next[j] = map_letter_to_label( rule_tmp.next[j]) new_search_coord.coord = rule_tmp extrapolated_rules.append(new_search_coord) return extrapolated_rules def further_extrapolate_rule(self): extrapolated_rules = [] rule = self.coord for prev_conv_range in range(0, len(rule.prev) + 1): for next_conv_range in range(0, len(rule.next) + 1): new_search_coord = SearchCoord() rule_tmp = copy.deepcopy(rule) if prev_conv_range < len(rule.prev): rule_tmp.prev = rule_tmp.prev[prev_conv_range:len(rule_tmp. prev)] else: rule_tmp.prev = [] if next_conv_range < len(rule.next): rule_tmp.next = rule_tmp.next[0:len(rule_tmp.next) - next_conv_range] else: rule_tmp.next = [] new_search_coord.coord = rule_tmp extrapolated_rules.append(new_search_coord) return extrapolated_rules def further_further_extrapolate_rule(self): rule_tmp = copy.deepcopy(self.coord) rule_tmp.curr = [map_letter_to_label(rule_tmp.curr[0])] new_search_coord = SearchCoord() new_search_coord.coord = rule_tmp new_search_coord.search_lvl = self.search_lvl + 2 return new_search_coord def get_gram_len(self): coord = self.coord tok_list = coord.prev + coord.curr + coord.next gram_len = 0 for tok in tok_list: if tok != CONSONANT and tok != VOWEL: gram_len = gram_len + 1 if coord.curr[0] == CONSONANT or coord.curr[0] == VOWEL: gram_len = 0 return gram_len def get_gram_balance(self): coord = self.coord left_gram = 0 right_gram = 0 for tok in reversed(coord.prev): if tok == CONSONANT or tok == VOWEL: break left_gram = left_gram + 1 for tok in coord.next: if tok == CONSONANT or tok == VOWEL: break right_gram = right_gram + 1 return math.fabs(left_gram - right_gram) def compute_search_lvl(self): gram_len = self.get_gram_len() gram_balance = self.get_gram_balance() if gram_len > 0: # self.search_lvl = math.factorial(N_GRAM_LEN) / math.factorial(gram_len) / math.factorial(N_GRAM_LEN - gram_len) * int(math.pow(2, N_GRAM_LEN-gram_len)) self.search_lvl = (N_GRAM_LEN - gram_len) * int( math.pow(N_GRAM_WEIGHT, N_GRAM_LEN - gram_len)) + int( math.pow(GRAM_BAL_WEIGHT, gram_balance)) coord = self.coord for tok in coord.prev: if tok == CONSONANT or tok == VOWEL: self.search_lvl = self.search_lvl - 1 for tok in coord.next: if tok == CONSONANT or tok == VOWEL: self.search_lvl = self.search_lvl - 1 else: #self.search_lvl = math.factorial(N_GRAM_LEN-1) * int(math.pow(2, N_GRAM_LEN-1)) self.search_lvl = (N_GRAM_LEN - gram_len) * int( math.pow(N_GRAM_WEIGHT, N_GRAM_LEN)) + int( math.pow(GRAM_BAL_WEIGHT, gram_balance)) coord = self.coord for tok in coord.prev: if tok != CONSONANT and tok != VOWEL: self.search_lvl = self.search_lvl - 1 for tok in coord.next: if tok != CONSONANT and tok != VOWEL: self.search_lvl = self.search_lvl - 1 def __eq__(self, other): if isinstance(other, SearchCoord): if self.coord == other.coord: return True else: return False return NotImplemented def __ne__(self, other): result = self.__eq__(other) if result is NotImplemented: return result return not result def to_str(self): return self.coord.to_str() + " | " + str(self.search_lvl)