def bind_mandatory_breaks(self): i = 0 while i < len(self.__units): u = self.__units[i] if u.is_not_bound() and u.is_head(): self.bind_left(i, gnoetics.token_lookup_break()) i += 1 elif u.is_not_bound() and u.is_tail(): self.bind_right(i, gnoetics.token_lookup_break()) else: i += 1
def __from_xml(self, node): assert node.localName == "unit" P = {} P["syllables"] = int(node.getAttribute("syllables")) P["meter"] = node.getAttribute("meter") x = node.getAttribute("rhyme") if x: P["rhyme"] = x P["is_beginning_of_line"] = bool( node.getAttribute("is_beginning_of_line")) P["is_beginning_of_stanza"] = bool( node.getAttribute("is_beginning_of_stanza")) P["is_end_of_line"] = bool(node.getAttribute("is_end_of_line")) P["is_end_of_stanza"] = bool(node.getAttribute("is_end_of_stanza")) P["is_head"] = bool(node.getAttribute("is_head")) P["is_tail"] = bool(node.getAttribute("is_tail")) P["id"] = int(node.getAttribute("id")) self.__populate(**P) if node.getAttribute("is_bound"): tok = None if node.getAttribute("binding_is_break"): tok = gnoetics.token_lookup_break() else: x = node.getAttribute("binding") if node.getAttribute("binding_is_punctuation"): x = "*punct* %s" % x tok = gnoetics.token_lookup(x) assert tok.has_left_glue() == bool( node.getAttribute("has_left_glue")) assert tok.has_right_glue() == bool( node.getAttribute("has_right_glue")) if tok: self.bind(tok)
def __from_xml(self, node): assert node.localName == "unit" P = {} P["syllables"] = int(node.getAttribute("syllables")) P["meter"] = node.getAttribute("meter") x = node.getAttribute("rhyme") if x: P["rhyme"] = x P["is_beginning_of_line"] = bool(node.getAttribute("is_beginning_of_line")) P["is_beginning_of_stanza"] = bool(node.getAttribute("is_beginning_of_stanza")) P["is_end_of_line"] = bool(node.getAttribute("is_end_of_line")) P["is_end_of_stanza"] = bool(node.getAttribute("is_end_of_stanza")) P["is_head"] = bool(node.getAttribute("is_head")) P["is_tail"] = bool(node.getAttribute("is_tail")) P["id"] = int(node.getAttribute("id")) self.__populate(**P) if node.getAttribute("is_bound"): tok = None if node.getAttribute("binding_is_break"): tok = gnoetics.token_lookup_break() else: x = node.getAttribute("binding") if node.getAttribute("binding_is_punctuation"): x = "*punct* %s" % x tok = gnoetics.token_lookup(x) assert tok.has_left_glue() == bool(node.getAttribute("has_left_glue")) assert tok.has_right_glue() == bool(node.getAttribute("has_right_glue")) if tok: self.bind(tok)
#!/usr/bin/python import random, sys, string, time import gnoetics p = gnoetics.Sonnet() p.bind_left(0, gnoetics.token_lookup_break()) p.bind_left(1, gnoetics.token_lookup("the")) p.bind_left(2, gnoetics.token_lookup("insane")) p.bind_left(3, gnoetics.token_lookup("butchershop")) p.bind_left(4, gnoetics.token_lookup("was")) p.bind_left(5, gnoetics.token_lookup("undertow")) p.bind_left(6, gnoetics.token_lookup("before")) p.bind_left(7, gnoetics.token_lookup("*punct* .")) p.bind_left(8, gnoetics.token_lookup_break()) p.bind_left(9, gnoetics.token_lookup("who")) p.bind_left(10, gnoetics.token_lookup("soever")) p.bind_right(13, gnoetics.token_lookup("monkey")) print p.to_string()
def solve_unit(poem, model, leading_tokens, unit, trailing_tokens, weights=None, allow_left_queries=True, allow_right_queries=False, verbose=None, extra_filters=True): # Copy list of leading and trailing tokens, so we can # manipulate them freely leading_tokens = list(leading_tokens) trailing_tokens = list(trailing_tokens) if verbose is None: verbose = os.getenv("GNOETRY_DEBUG") is not None def token_list_is_valid(token_list, allow_break_at): if allow_break_at < 0: allow_break_at += len(token_list) for i, tok in enumerate(token_list): if tok.is_wildcard(): return False # No wildcards! if tok.is_break() and i != allow_break_at: return False # Breaks only where we say it is OK! return True lead_ok = token_list_is_valid(leading_tokens, allow_break_at=0) trail_ok = token_list_is_valid(trailing_tokens, allow_break_at=-1) if (not lead_ok) and verbose: print "Bad leading tokens!" print leading_tokens print if (not trail_ok) and verbose: print "Bad trailing tokens!" print trailing_tokens print assert lead_ok assert trail_ok # Double leading/trailing breaks if leading_tokens and leading_tokens[0].is_break(): leading_tokens.insert(0, gnoetics.token_lookup_break()) if trailing_tokens and trailing_tokens[-1].is_break(): trailing_tokens.append(gnoetics.token_lookup_break()) assert len(leading_tokens) + len(trailing_tokens) >= 2 assert unit.is_not_bound() syl = unit.get_syllables() if syl == 0: print "*** Ouch!" print leading_tokens print unit print trailing_tokens print "*** Ouch!" assert syl > 0 meter = unit.get_meter() rhyme = unit.get_rhyme() rhymes_with = poem.get_bound_rhyme(rhyme) word_count = 0 punct_count = 0 for tok in leading_tokens: if tok.is_punctuation(): punct_count += 1 elif not tok.is_break(): word_count += 1 for tok in trailing_tokens: if tok.is_punctuation(): punct_count += 1 elif not tok.is_break(): word_count += 1 discourage_punct = False if word_count > 2 and word_count < 3 * punct_count: discourage_punct = True def punctution_between(token_list, i0, i1): for i in range(i0, i1 + 1): if -len(token_list) <= i < len(token_list) \ and token_list[i].is_punctuation(): return True return False forbid_punct = False if extra_filters and \ (punctution_between(leading_tokens, -2, -1) \ or punctution_between(trailing_tokens, 0, 1)): forbid_punct = True have_both = False def single_both(s, b): if have_both: return b else: return s left_queries = [] right_queries = [] if leading_tokens and trailing_tokens: have_both = True if trailing_tokens[0].is_break(): allow_left_queries = False allow_right_queries = True discourage_punct = False forbid_punct = False else: Q_filter = { "min_syllables": syl, "max_syllables": syl, "meter_left": meter, } if rhymes_with: Q_filter["rhymes_with"] = rhymes_with elif rhyme: Q_filter["has_rhyme_threshold"] = gnoetics.RHYME_FALSE Q_filter["rhyme_p_threshold"] = 0.20 Q = (leading_tokens[-1], gnoetics.token_lookup_wildcard(), trailing_tokens[0], Q_filter) left_queries.append(Q) # or right if leading_tokens and allow_left_queries: Q_filter = { "min_syllables": 0, "max_syllables": syl - 1, "meter_left": meter, } Q = (leading_tokens[-2], leading_tokens[-1], gnoetics.token_lookup_wildcard(), Q_filter) left_queries.append(Q) if not have_both: Q_filter = { "min_syllables": syl, "max_syllables": syl, "meter_left": meter, } if rhymes_with: Q_filter["rhymes_with"] = rhymes_with elif rhyme: Q_filter["has_rhyme_threshold"] = gnoetics.RHYME_FALSE Q_filter["rhyme_p_threshold"] = 0.20 Q = (leading_tokens[-2], leading_tokens[-1], gnoetics.token_lookup_wildcard(), Q_filter) left_queries.append(Q) if trailing_tokens and allow_right_queries: Q_filter = { "min_syllables": 0, "max_syllables": syl - 1, "meter_right": meter, } Q = (gnoetics.token_lookup_wildcard(), trailing_tokens[0], trailing_tokens[1], Q_filter) right_queries.append(Q) if not have_both: Q_filter = { "min_syllables": syl, "max_syllables": syl, "meter_left": meter, } if rhymes_with: Q_filter["rhymes_with"] = rhymes_with elif rhyme: Q_filter["has_rhyme_threshold"] = gnoetics.RHYME_FALSE Q_filter["rhyme_p_threshold"] = 0.20 Q = (gnoetics.token_lookup_wildcard(), trailing_tokens[0], trailing_tokens[1], Q_filter) right_queries.append(Q) if discourage_punct or forbid_punct: if discourage_punct: pref = 0 else: pref = -1 for Q in left_queries: Q[-1]["punctuation_preference"] = pref for Q in right_queries: Q[-1]["punctuation_preference"] = pref if left_queries: if verbose: print "Left queries:", left_queries ranker = gnoetics.Ranker() if weights is not None: for txt, wt in weights.items(): ranker.set_weight(txt, wt) for t1, t2, t3, filter in left_queries: model.query(t1, t2, t3, filter, ranker) left_solns = ranker.get_solutions() if verbose: print "Left solns:", map(lambda x: x.get_word(), left_solns) else: left_solns = [] if right_queries: if verbose: print "Right queries:", right_queries ranker = gnoetics.Ranker() if weights is not None: for txt, wt in weights.items(): ranker.set_weight(txt, wt) for t1, t2, t3, filter in right_queries: model.query(t1, t2, t3, filter, ranker) right_solns = ranker.get_solutions() if verbose: print "Right solns:", map(lambda x: x.get_word(), right_solns) else: right_solns = [] return left_solns, right_solns
def solve_unit(poem, model, leading_tokens, unit, trailing_tokens, weights=None, allow_left_queries=True, allow_right_queries=False, verbose=None, extra_filters=True): # Copy list of leading and trailing tokens, so we can # manipulate them freely leading_tokens = list(leading_tokens) trailing_tokens = list(trailing_tokens) if verbose is None: verbose = os.getenv("GNOETRY_DEBUG") is not None def token_list_is_valid(token_list, allow_break_at): if allow_break_at < 0: allow_break_at += len(token_list) for i, tok in enumerate(token_list): if tok.is_wildcard(): return False # No wildcards! if tok.is_break() and i != allow_break_at: return False # Breaks only where we say it is OK! return True lead_ok = token_list_is_valid(leading_tokens, allow_break_at=0) trail_ok = token_list_is_valid(trailing_tokens, allow_break_at=-1) if (not lead_ok) and verbose: print "Bad leading tokens!" print leading_tokens print if (not trail_ok) and verbose: print "Bad trailing tokens!" print trailing_tokens print assert lead_ok assert trail_ok # Double leading/trailing breaks if leading_tokens and leading_tokens[0].is_break(): leading_tokens.insert(0, gnoetics.token_lookup_break()) if trailing_tokens and trailing_tokens[-1].is_break(): trailing_tokens.append(gnoetics.token_lookup_break()) assert len(leading_tokens) + len(trailing_tokens) >= 2 assert unit.is_not_bound() syl = unit.get_syllables() if syl == 0: print "*** Ouch!" print leading_tokens print unit print trailing_tokens print "*** Ouch!" assert syl > 0 meter = unit.get_meter() rhyme = unit.get_rhyme() rhymes_with = poem.get_bound_rhyme(rhyme) word_count = 0 punct_count = 0 for tok in leading_tokens: if tok.is_punctuation(): punct_count += 1 elif not tok.is_break(): word_count += 1 for tok in trailing_tokens: if tok.is_punctuation(): punct_count += 1 elif not tok.is_break(): word_count += 1 discourage_punct = False if word_count > 2 and word_count < 3 * punct_count: discourage_punct = True def punctution_between(token_list, i0, i1): for i in range(i0, i1+1): if -len(token_list) <= i < len(token_list) \ and token_list[i].is_punctuation(): return True return False forbid_punct = False if extra_filters and \ (punctution_between(leading_tokens, -2, -1) \ or punctution_between(trailing_tokens, 0, 1)): forbid_punct = True have_both = False def single_both(s, b): if have_both: return b else: return s left_queries = [] right_queries = [] if leading_tokens and trailing_tokens: have_both = True if trailing_tokens[0].is_break(): allow_left_queries = False allow_right_queries = True discourage_punct = False forbid_punct = False else: Q_filter = { "min_syllables": syl, "max_syllables": syl, "meter_left": meter, } if rhymes_with: Q_filter["rhymes_with"] = rhymes_with elif rhyme: Q_filter["has_rhyme_threshold"] = gnoetics.RHYME_FALSE Q_filter["rhyme_p_threshold"] = 0.20 Q = (leading_tokens[-1], gnoetics.token_lookup_wildcard(), trailing_tokens[0], Q_filter) left_queries.append(Q) # or right if leading_tokens and allow_left_queries: Q_filter = { "min_syllables": 0, "max_syllables": syl-1, "meter_left": meter, } Q = (leading_tokens[-2], leading_tokens[-1], gnoetics.token_lookup_wildcard(), Q_filter) left_queries.append(Q) if not have_both: Q_filter = { "min_syllables": syl, "max_syllables": syl, "meter_left": meter, } if rhymes_with: Q_filter["rhymes_with"] = rhymes_with elif rhyme: Q_filter["has_rhyme_threshold"] = gnoetics.RHYME_FALSE Q_filter["rhyme_p_threshold"] = 0.20 Q = (leading_tokens[-2], leading_tokens[-1], gnoetics.token_lookup_wildcard(), Q_filter) left_queries.append(Q) if trailing_tokens and allow_right_queries: Q_filter = { "min_syllables": 0, "max_syllables": syl-1, "meter_right": meter, } Q = (gnoetics.token_lookup_wildcard(), trailing_tokens[0], trailing_tokens[1], Q_filter) right_queries.append(Q) if not have_both: Q_filter = { "min_syllables": syl, "max_syllables": syl, "meter_left": meter, } if rhymes_with: Q_filter["rhymes_with"] = rhymes_with elif rhyme: Q_filter["has_rhyme_threshold"] = gnoetics.RHYME_FALSE Q_filter["rhyme_p_threshold"] = 0.20 Q = (gnoetics.token_lookup_wildcard(), trailing_tokens[0], trailing_tokens[1], Q_filter) right_queries.append(Q) if discourage_punct or forbid_punct: if discourage_punct: pref = 0 else: pref = -1 for Q in left_queries: Q[-1]["punctuation_preference"] = pref for Q in right_queries: Q[-1]["punctuation_preference"] = pref if left_queries: if verbose: print "Left queries:", left_queries ranker = gnoetics.Ranker() if weights is not None: for txt, wt in weights.items(): ranker.set_weight(txt, wt) for t1, t2, t3, filter in left_queries: model.query(t1, t2, t3, filter, ranker) left_solns = ranker.get_solutions() if verbose: print "Left solns:", map(lambda x: x.get_word(), left_solns) else: left_solns = [] if right_queries: if verbose: print "Right queries:", right_queries ranker = gnoetics.Ranker() if weights is not None: for txt, wt in weights.items(): ranker.set_weight(txt, wt) for t1, t2, t3, filter in right_queries: model.query(t1, t2, t3, filter, ranker) right_solns = ranker.get_solutions() if verbose: print "Right solns:", map(lambda x: x.get_word(), right_solns) else: right_solns = [] return left_solns, right_solns