def __solve_at(self, i, weights=None, verbose=None): if verbose is None: verbose = os.getenv("GNOETRY_DEBUG") is not None assert self.__poem assert 0 <= i < len(self.__poem) u = self.__poem[i] assert u.is_not_bound() # If the stuff in our action queue isn't immediately # adjacent to where we are now, obviously rolling back # won't help us. # FIXME: Obviously this will have to be more subtle once # we have cross-line constraints. if self.__actions and abs(self.__actions[-1][0] - i) > 1: self.__actions = [] if u.get_syllables() == 0 and verbose: print "Hit 0-length unit at %d" % i for j in range(len(self.__poem)): if i == j: print "*****", print j, self.__poem[j] print leading_tokens, trailing_tokens = self.__poem.extract_surrounding_tokens( i) left_solns, right_solns = gnoetics.solve_unit(self.__poem, self.__model, leading_tokens, u, trailing_tokens, weights=weights) # If we found no solutions, try again w/o the extra filters. if not left_solns and not right_solns: left_solns, right_solns = gnoetics.solve_unit(self.__poem, self.__model, leading_tokens, u, trailing_tokens, extra_filters=False, weights=weights) if verbose: print "pos=%d left_solns=%d right_solns=%d" % (i, len(left_solns), len(right_solns)) if left_solns: self.__actions.append([i, "left", left_solns, right_solns]) elif right_solns: self.__actions.append([i, "right", left_solns, right_solns]) else: while 1: if not self.__actions: raise SolveFailed act = self.__actions[-1] i = act[0] mode = act[1] if mode == "left": self.__poem.unbind(i) if verbose: print "left-unbind at %d" % i else: self.__poem.unbind(i + 1) if verbose: print "right-unbind at %d" % i left_solns = act[2] right_solns = act[3] if right_solns and not left_solns: act[1] = "right" if left_solns or right_solns: break self.__actions.pop(-1) if left_solns: tok = left_solns.pop(0) if verbose: print "left-bind at %d" % i self.__poem.bind_left(i, tok) else: tok = right_solns.pop(0) if verbose: print "right-bind at %d" % i self.__poem.bind_right(i, tok)
def generate_poem(verse): t1 = time.time() verse.bind_mandatory_breaks() # Actions are three-tuples of the form: # (unit index, left_solns, right_solns) actions = [] while verse.is_not_fully_bound(): i = verse.find_first_unbound() u = verse[i] leading_tokens, trailing_tokens = verse.extract_surrounding_tokens(i) left_solns, right_solns = gnoetics.solve_unit(tri, leading_tokens, u, trailing_tokens) if left_solns: actions.append([i, "left", left_solns, right_solns]) elif right_solns: actions.append([i, "right", left_solns, right_solns]) else: while 1: assert actions act = actions[-1] i = act[0] mode = act[1] if mode == "left": verse.unbind(i) else: verse.unbind(i+1) left_solns = act[2] right_solns = act[3] if right_solns and not left_solns: act[1] = "right" if left_solns or right_solns: break actions.pop(-1) if left_solns: tok = left_solns.pop(0) verse.bind_left(i, tok) else: tok = right_solns.pop(0) verse.bind_right(i, tok) t2 = time.time() print verse.to_string() print print verse.to_list_with_breaks() print "(Generated poem in %.2fs)\n\n" % (t2-t1) print print "Press return for another poem: ", sys.stdin.readline() print print print
def __solve_at(self, i, weights=None, verbose=None): if verbose is None: verbose = os.getenv("GNOETRY_DEBUG") is not None assert self.__poem assert 0 <= i < len(self.__poem) u = self.__poem[i] assert u.is_not_bound() # If the stuff in our action queue isn't immediately # adjacent to where we are now, obviously rolling back # won't help us. # FIXME: Obviously this will have to be more subtle once # we have cross-line constraints. if self.__actions and abs(self.__actions[-1][0] - i) > 1: self.__actions = [] if u.get_syllables() == 0 and verbose: print "Hit 0-length unit at %d" % i for j in range(len(self.__poem)): if i == j: print "*****", print j, self.__poem[j] print leading_tokens, trailing_tokens = self.__poem.extract_surrounding_tokens(i) left_solns, right_solns = gnoetics.solve_unit(self.__poem, self.__model, leading_tokens, u, trailing_tokens, weights=weights) # If we found no solutions, try again w/o the extra filters. if not left_solns and not right_solns: left_solns, right_solns = gnoetics.solve_unit(self.__poem, self.__model, leading_tokens, u, trailing_tokens, extra_filters=False, weights=weights) if verbose: print "pos=%d left_solns=%d right_solns=%d" % (i, len(left_solns), len(right_solns)) if left_solns: self.__actions.append([i, "left", left_solns, right_solns]) elif right_solns: self.__actions.append([i, "right", left_solns, right_solns]) else: while 1: if not self.__actions: raise SolveFailed act = self.__actions[-1] i = act[0] mode = act[1] if mode == "left": self.__poem.unbind(i) if verbose: print "left-unbind at %d" % i else: self.__poem.unbind(i+1) if verbose: print "right-unbind at %d" % i left_solns = act[2] right_solns = act[3] if right_solns and not left_solns: act[1] = "right" if left_solns or right_solns: break self.__actions.pop(-1) if left_solns: tok = left_solns.pop(0) if verbose: print "left-bind at %d" % i self.__poem.bind_left(i, tok) else: tok = right_solns.pop(0) if verbose: print "right-bind at %d" % i self.__poem.bind_right(i, tok)