# Path: pycryptics/utils/language.py
# def semantic_similarity(word1, word2):
#     words1 = word1.split('_')
#     words2 = word2.split('_')
#     if fast_semantic_similarity(word1, word2) == 1:
#         return 1
#     max_p = 0
#     word1_sim = set([])
#     for s1 in wn.synsets(word1):
#         word1_sim.add(s1)
#         word1_sim.update(s1.similar_tos())
#         # for st1 in [s1] + s1.similar_tos():
#         #     word1_sim.append(st1)
# 
#     word2_sim = set([])
#     for s2 in wn.synsets(word2):
#         word2_sim.add(s2)
#         word2_sim.update(s2.similar_tos())
# 
#     for st1 in word1_sim:
#         for st2 in word2_sim:
#             p = wn.wup_similarity(st1, st2)
#             if p == 1:
#                 return p
#             if p > max_p:
#                 max_p = p
#     if len(words1) > 1 or len(words2) > 1:
#         sub_similarity = .9 * semantic_similarity(words1[-1], words2[-1])
#     else:
#         sub_similarity = 0
#     return max(max_p, sub_similarity)
# 
# Path: pycryptics/grammar/clue_parse.py
# def generate_clues(constraints):
#     g = generate_grammar(constraints.phrases)
#     parser = parse.EarleyChartParser(g, chart_class=MemoChart)
#     clues = parser.nbest_parse(constraints.phrases)
#     for c in clues:
#         c.set_constraints(constraints)
#     return clues
# 
# Path: pycryptics/utils/phrasings.py
# def phrasings(remaining):
#     if len(remaining) <= 1:
#         return [remaining]
#     else:
#         new_active_set = []
#         # for i in range(len(remaining)):
#         for i in range(min(len(remaining), 3)):
#             new_phrase = '_'.join(remaining[:i + 1])
#             new_remaining = remaining[i + 1:]
#             for new_s in phrasings(new_remaining):
#                 new_active_set.append([new_phrase] + new_s)
#         return new_active_set
# 
# Path: pycryptics/utils/synonyms.py
# SYNONYMS = msgpack.load(f, use_list=False)
# 
# Path: pycryptics/grammar/clue_tree.py
# class ClueUnsolvableError(Exception):
#     pass


from pycryptics.utils.language import semantic_similarity
from pycryptics.grammar.clue_parse import generate_clues
from pycryptics.utils.phrasings import phrasings
from pycryptics.utils.synonyms import SYNONYMS
from pycryptics.grammar.clue_tree import ClueUnsolvableError
from collections import namedtuple
import re
        self.clue_text = self.clue_text.encode('ascii', 'ignore')
        constraints = parse_clue_text(self.clue_text)
        return self.solve_all_phrasings(constraints)
        # all_phrasings, lengths, pattern, answer = parse_clue_text(self.clue_text)

    def solve_all_phrasings(self, constraints):
        all_phrasings = phrasings(constraints.phrases)

        self.answers_with_clues = []

        for p in all_phrasings:
            constraints = constraints._replace(phrases=p)
            # constraints = Constraints(p, lengths, pattern, answer)
            if not self.quiet:
                print p
            for ann_ans in self.solve_constraints(constraints):
                self.answers_with_clues.append(ann_ans)
        if len(self.answers_with_clues) == 0 and constraints.pattern.replace('.', '') != "":
            self.answers_with_clues = [PatternAnswer(x, all_phrasings[0]) for x in SYNONYMS if matches_pattern(x, constraints.pattern, constraints.lengths)]
        self.answers_with_clues.sort(reverse=True)
        return self.answers_with_clues

    def solve_constraints(self, constraints):
        answers_with_clues = []
        possible_clues = generate_clues(constraints)

        for i, clue in enumerate(possible_clues):
            # print "solving:", clue
            try:
                answers = clue.answers

# Path: pycryptics/utils/language.py
# def semantic_similarity(word1, word2):
#     words1 = word1.split('_')
#     words2 = word2.split('_')
#     if fast_semantic_similarity(word1, word2) == 1:
#         return 1
#     max_p = 0
#     word1_sim = set([])
#     for s1 in wn.synsets(word1):
#         word1_sim.add(s1)
#         word1_sim.update(s1.similar_tos())
#         # for st1 in [s1] + s1.similar_tos():
#         #     word1_sim.append(st1)
# 
#     word2_sim = set([])
#     for s2 in wn.synsets(word2):
#         word2_sim.add(s2)
#         word2_sim.update(s2.similar_tos())
# 
#     for st1 in word1_sim:
#         for st2 in word2_sim:
#             p = wn.wup_similarity(st1, st2)
#             if p == 1:
#                 return p
#             if p > max_p:
#                 max_p = p
#     if len(words1) > 1 or len(words2) > 1:
#         sub_similarity = .9 * semantic_similarity(words1[-1], words2[-1])
#     else:
#         sub_similarity = 0
#     return max(max_p, sub_similarity)
# 
# Path: pycryptics/grammar/clue_parse.py
# def generate_clues(constraints):
#     g = generate_grammar(constraints.phrases)
#     parser = parse.EarleyChartParser(g, chart_class=MemoChart)
#     clues = parser.nbest_parse(constraints.phrases)
#     for c in clues:
#         c.set_constraints(constraints)
#     return clues
# 
# Path: pycryptics/utils/phrasings.py
# def phrasings(remaining):
#     if len(remaining) <= 1:
#         return [remaining]
#     else:
#         new_active_set = []
#         # for i in range(len(remaining)):
#         for i in range(min(len(remaining), 3)):
#             new_phrase = '_'.join(remaining[:i + 1])
#             new_remaining = remaining[i + 1:]
#             for new_s in phrasings(new_remaining):
#                 new_active_set.append([new_phrase] + new_s)
#         return new_active_set
# 
# Path: pycryptics/utils/synonyms.py
# SYNONYMS = msgpack.load(f, use_list=False)
# 
# Path: pycryptics/grammar/clue_tree.py
# class ClueUnsolvableError(Exception):
#     pass


# Path: pycryptics/solve_clue.py
from pycryptics.utils.language import semantic_similarity
from pycryptics.grammar.clue_parse import generate_clues
from pycryptics.utils.phrasings import phrasings
from pycryptics.utils.synonyms import SYNONYMS
from pycryptics.grammar.clue_tree import ClueUnsolvableError
from collections import namedtuple
import re

        self.clue_text = self.clue_text.encode('ascii', 'ignore')
        constraints = parse_clue_text(self.clue_text)
        return self.solve_all_phrasings(constraints)
        # all_phrasings, lengths, pattern, answer = parse_clue_text(self.clue_text)

    def solve_all_phrasings(self, constraints):
        all_phrasings = phrasings(constraints.phrases)

        self.answers_with_clues = []

        for p in all_phrasings:
            constraints = constraints._replace(phrases=p)
            # constraints = Constraints(p, lengths, pattern, answer)
            if not self.quiet:
                print p
            for ann_ans in self.solve_constraints(constraints):
                self.answers_with_clues.append(ann_ans)
        if len(self.answers_with_clues) == 0 and constraints.pattern.replace('.', '') != "":
            self.answers_with_clues = [PatternAnswer(x, all_phrasings[0]) for x in SYNONYMS if matches_pattern(x, constraints.pattern, constraints.lengths)]
        self.answers_with_clues.sort(reverse=True)
        return self.answers_with_clues

    def solve_constraints(self, constraints):
        answers_with_clues = []
        possible_clues = generate_clues(constraints)

        for i, clue in enumerate(possible_clues):
            # print "solving:", clue
            try:
                answers = clue.answers

            except ClueUnsolvableError: