# Path: preimage/models/generic_string_model.py
# class GenericStringModel(Model):
#     def __init__(self, alphabet, n, is_using_length=True, seed=42, max_time=30, sigma_position=1.):
#         Model.__init__(self, alphabet, n, is_using_length)
#         self._graph_builder = GraphBuilder(alphabet, n)
#         self._is_normalized = True
#         self._seed = seed
#         self._max_time = max_time
#         self._sigma_position = sigma_position
#         self._n_grams = list(get_n_grams(alphabet, n))
#         self._n_gram_to_index = get_n_gram_to_index(alphabet, n)
# 
#     def fit(self, inference_parameters):
#         Model.fit(self, inference_parameters)
#         self._feature_space_ = GenericStringFeatureSpace(self._alphabet, self._n, inference_parameters.Y_train,
#                                                          self._sigma_position, self._is_normalized)
# 
#     def predict(self, Y_weights, y_lengths):
#         if self._is_using_length:
#             self._verify_y_lengths_is_not_none_when_use_length(y_lengths)
#             Y_predictions = self._predict_with_length(Y_weights, y_lengths)
#         else:
#             Y_predictions = self._predict_without_length(Y_weights)
#         return Y_predictions
# 
#     def _predict_with_length(self, Y_weights, y_lengths):
#         Y_predictions = []
#         for y_weights, y_length in zip(Y_weights, y_lengths):
#             n_gram_weights = self._feature_space_.compute_weights(y_weights, y_length)
#             graph = self._graph_builder.build_graph(n_gram_weights, y_length)
#             node_creator = get_gs_node_creator(self._n, graph, n_gram_weights, y_length, self._n_gram_to_index,
#                                                self._n_grams, self._sigma_position)
#             y_predicted, y_bound = branch_and_bound(node_creator, y_length, self._alphabet, self._max_time)
#             Y_predictions.append(y_predicted)
#         return Y_predictions
# 
#     def _predict_without_length(self, Y_weights):
#         Y_predictions = []
#         for y_weights in Y_weights:
#             n_gram_weights = self._feature_space_.compute_weights(y_weights, self._max_length_)
#             graph = self._graph_builder.build_graph(n_gram_weights, self._max_length_)
#             node_creator = get_gs_node_creator(self._n, graph, n_gram_weights, self._max_length_,
#                                                self._n_gram_to_index, self._n_grams, self._sigma_position)
#             y_predicted, y_bound = branch_and_bound_no_length(node_creator, self._min_length_, self._max_length_,
#                                                               self._alphabet, self._max_time)
#             Y_predictions.append(y_predicted)
#         return Y_predictions
# 
# Path: preimage/learners/structured_krr.py
# class InferenceFitParameters:
#     """Parameters for the inference model.
# 
#     That way inference_model.fit(parameters) doesn't have unused parameters but only access the one it needs
#     .
#     Attributes
#     ----------
#     weights : array, shape = [n_samples, n_samples]
#         Learned weights, where n_samples is the number of training samples.
#     gram_matrix : array, shape = [n_samples, n_samples]
#         Gram_matrix of the training samples.
#     Y_train : array, shape = [n_samples, ]
#         Training strings.
#     y_lengths : array, shape = [n_samples]
#         Length of each training string in Y_train.
#     """
#     def __init__(self, weights, gram_matrix, Y, y_lengths):
#         self.weights = weights
#         self.gram_matrix = gram_matrix
#         self.Y_train = Y
#         self.y_lengths = y_lengths


import unittest2
import numpy
import numpy.testing
from mock import patch, Mock
from preimage.models.generic_string_model import GenericStringModel
from preimage.learners.structured_krr import InferenceFitParameters
__author__ = 'amelie'




def branch_and_bound_side_effect(node_creator, y_length, alphabet, max_time):
    solution_dict = {1: ('a', 1), 2: ('ba', 3)}
    return solution_dict[y_length]


class TestGenericStringModel(unittest2.TestCase):
    def setUp(self):
        self.setup_feature_space()
        self.setup_fit_parameters()
        self.setup_graph_builder()
        self.setup_branch_and_bound()
        self.alphabet = ['a', 'b', 'c']
        self.sigma_position = 0.5
        self.model_with_length = GenericStringModel(self.alphabet, n=1, is_using_length=True,
                                                    sigma_position=self.sigma_position)

# Path: preimage/models/generic_string_model.py
# class GenericStringModel(Model):
#     def __init__(self, alphabet, n, is_using_length=True, seed=42, max_time=30, sigma_position=1.):
#         Model.__init__(self, alphabet, n, is_using_length)
#         self._graph_builder = GraphBuilder(alphabet, n)
#         self._is_normalized = True
#         self._seed = seed
#         self._max_time = max_time
#         self._sigma_position = sigma_position
#         self._n_grams = list(get_n_grams(alphabet, n))
#         self._n_gram_to_index = get_n_gram_to_index(alphabet, n)
# 
#     def fit(self, inference_parameters):
#         Model.fit(self, inference_parameters)
#         self._feature_space_ = GenericStringFeatureSpace(self._alphabet, self._n, inference_parameters.Y_train,
#                                                          self._sigma_position, self._is_normalized)
# 
#     def predict(self, Y_weights, y_lengths):
#         if self._is_using_length:
#             self._verify_y_lengths_is_not_none_when_use_length(y_lengths)
#             Y_predictions = self._predict_with_length(Y_weights, y_lengths)
#         else:
#             Y_predictions = self._predict_without_length(Y_weights)
#         return Y_predictions
# 
#     def _predict_with_length(self, Y_weights, y_lengths):
#         Y_predictions = []
#         for y_weights, y_length in zip(Y_weights, y_lengths):
#             n_gram_weights = self._feature_space_.compute_weights(y_weights, y_length)
#             graph = self._graph_builder.build_graph(n_gram_weights, y_length)
#             node_creator = get_gs_node_creator(self._n, graph, n_gram_weights, y_length, self._n_gram_to_index,
#                                                self._n_grams, self._sigma_position)
#             y_predicted, y_bound = branch_and_bound(node_creator, y_length, self._alphabet, self._max_time)
#             Y_predictions.append(y_predicted)
#         return Y_predictions
# 
#     def _predict_without_length(self, Y_weights):
#         Y_predictions = []
#         for y_weights in Y_weights:
#             n_gram_weights = self._feature_space_.compute_weights(y_weights, self._max_length_)
#             graph = self._graph_builder.build_graph(n_gram_weights, self._max_length_)
#             node_creator = get_gs_node_creator(self._n, graph, n_gram_weights, self._max_length_,
#                                                self._n_gram_to_index, self._n_grams, self._sigma_position)
#             y_predicted, y_bound = branch_and_bound_no_length(node_creator, self._min_length_, self._max_length_,
#                                                               self._alphabet, self._max_time)
#             Y_predictions.append(y_predicted)
#         return Y_predictions
# 
# Path: preimage/learners/structured_krr.py
# class InferenceFitParameters:
#     """Parameters for the inference model.
# 
#     That way inference_model.fit(parameters) doesn't have unused parameters but only access the one it needs
#     .
#     Attributes
#     ----------
#     weights : array, shape = [n_samples, n_samples]
#         Learned weights, where n_samples is the number of training samples.
#     gram_matrix : array, shape = [n_samples, n_samples]
#         Gram_matrix of the training samples.
#     Y_train : array, shape = [n_samples, ]
#         Training strings.
#     y_lengths : array, shape = [n_samples]
#         Length of each training string in Y_train.
#     """
#     def __init__(self, weights, gram_matrix, Y, y_lengths):
#         self.weights = weights
#         self.gram_matrix = gram_matrix
#         self.Y_train = Y
#         self.y_lengths = y_lengths


# Path: preimage/tests/models/test_generic_string_model.py
import unittest2
import numpy
import numpy.testing
from mock import patch, Mock
from preimage.models.generic_string_model import GenericStringModel
from preimage.learners.structured_krr import InferenceFitParameters

__author__ = 'amelie'




def branch_and_bound_side_effect(node_creator, y_length, alphabet, max_time):
    solution_dict = {1: ('a', 1), 2: ('ba', 3)}
    return solution_dict[y_length]


class TestGenericStringModel(unittest2.TestCase):
    def setUp(self):
        self.setup_feature_space()
        self.setup_fit_parameters()
        self.setup_graph_builder()
        self.setup_branch_and_bound()
        self.alphabet = ['a', 'b', 'c']
        self.sigma_position = 0.5
        self.model_with_length = GenericStringModel(self.alphabet, n=1, is_using_length=True,
                                                    sigma_position=self.sigma_position)

        self.model_no_length = GenericStringModel(self.alphabet, n=1, is_using_length=False,