# Path: core/kover/learning/common/models.py
# class BaseModel(object):
# class CARTModel(BaseModel):
# class SCMModel(BaseModel):
# class ConjunctionModel(SCMModel):
# class DisjunctionModel(SCMModel):
#     def __init__(self):
#     def predict(self, X):
# 	def predict_proba(self, X):
#     def learner(self):
#     def __str__(self):
#     def __init__(self, class_tags=None):
#     def predict(self, X):
#     def predict_proba(self, X):
#     def learner(self):
#     def _to_string(self, node=None,depth=0):
#     def __len__(self):
#     def depth(self):
#     def __init__(self):
#     def add(self, rule):
#     def predict(self, X):
#     def predict_proba(self, X):
#     def remove(self, index):
#     def example_dependencies(self):
#     def learner(self):
#     def type(self):
#     def _to_string(self, separator=" "):
#     def __eq__(self, other):
#     def __iter__(self):
#     def __len__(self):
#     def predict_proba(self, X):
#     def type(self):
#     def __str__(self):
#     def predict_proba(self, X):
#     def type(self):
#     def __str__(self):
# 
# Path: core/kover/utils.py
# def _class_to_string(instance):
#     """
#     Returns a string representation of the public attributes of a class.
#     
#     Parameters:
#     -----------
#     instance: object
#         An instance of any class.
#         
#     Returns:
#     --------
#     string_rep: string
#         A string representation of the class and its public attributes.
#         
#     Notes:
#     -----
#     Private attributes must be marked with a leading underscore.
#     """
#     return instance.__class__.__name__ + "(" + ",".join(
#         [str(k) + "=" + str(v) for k, v in instance.__dict__.iteritems() if str(k[0]) != "_"]) + ")"


import logging
import numpy as np
from math import ceil
from ..common.models import scm, conjunction, ConjunctionModel, disjunction, DisjunctionModel
from ...utils import _class_to_string
class BaseSetCoveringMachine(object):
    def __init__(self, model_type, max_rules):
        if model_type == conjunction:
            self._add_rule_to_model = self._append_conjunction_model
            self.model_type = conjunction
        elif model_type == disjunction:
            self._add_rule_to_model = self._append_disjunction_model
            self.model_type = disjunction
        else:
            raise ValueError("Unsupported model type.")

        self.max_rules = max_rules
        self._flags = {}
        super(BaseSetCoveringMachine, self).__init__()

    def fit(self, rules, rule_classifications, positive_example_idx, negative_example_idx, rule_blacklist=[],
            tiebreaker=None, iteration_callback=None, iteration_rule_importances=False, **kwargs):
        """
        TODO
        """
        utility_function_additional_args = {}
        if kwargs != None:
            for key, value in kwargs.iteritems():
                if key[:9] == "utility__":
                    utility_function_additional_args[key[9:]] = value

        # Validate that there are some positive and negative examples
        if len(positive_example_idx) == 0 or  len(negative_example_idx) == 0:
            raise ValueError("There must be positive and negative examples to train the SCM.")


# Path: core/kover/learning/common/models.py
# class BaseModel(object):
# class CARTModel(BaseModel):
# class SCMModel(BaseModel):
# class ConjunctionModel(SCMModel):
# class DisjunctionModel(SCMModel):
#     def __init__(self):
#     def predict(self, X):
# 	def predict_proba(self, X):
#     def learner(self):
#     def __str__(self):
#     def __init__(self, class_tags=None):
#     def predict(self, X):
#     def predict_proba(self, X):
#     def learner(self):
#     def _to_string(self, node=None,depth=0):
#     def __len__(self):
#     def depth(self):
#     def __init__(self):
#     def add(self, rule):
#     def predict(self, X):
#     def predict_proba(self, X):
#     def remove(self, index):
#     def example_dependencies(self):
#     def learner(self):
#     def type(self):
#     def _to_string(self, separator=" "):
#     def __eq__(self, other):
#     def __iter__(self):
#     def __len__(self):
#     def predict_proba(self, X):
#     def type(self):
#     def __str__(self):
#     def predict_proba(self, X):
#     def type(self):
#     def __str__(self):
# 
# Path: core/kover/utils.py
# def _class_to_string(instance):
#     """
#     Returns a string representation of the public attributes of a class.
#     
#     Parameters:
#     -----------
#     instance: object
#         An instance of any class.
#         
#     Returns:
#     --------
#     string_rep: string
#         A string representation of the class and its public attributes.
#         
#     Notes:
#     -----
#     Private attributes must be marked with a leading underscore.
#     """
#     return instance.__class__.__name__ + "(" + ",".join(
#         [str(k) + "=" + str(v) for k, v in instance.__dict__.iteritems() if str(k[0]) != "_"]) + ")"


# Path: core/kover/learning/learners/scm.py
import logging
import numpy as np
from math import ceil
from ..common.models import scm, conjunction, ConjunctionModel, disjunction, DisjunctionModel
from ...utils import _class_to_string

class BaseSetCoveringMachine(object):
    def __init__(self, model_type, max_rules):
        if model_type == conjunction:
            self._add_rule_to_model = self._append_conjunction_model
            self.model_type = conjunction
        elif model_type == disjunction:
            self._add_rule_to_model = self._append_disjunction_model
            self.model_type = disjunction
        else:
            raise ValueError("Unsupported model type.")

        self.max_rules = max_rules
        self._flags = {}
        super(BaseSetCoveringMachine, self).__init__()

    def fit(self, rules, rule_classifications, positive_example_idx, negative_example_idx, rule_blacklist=[],
            tiebreaker=None, iteration_callback=None, iteration_rule_importances=False, **kwargs):
        """
        TODO
        """
        utility_function_additional_args = {}
        if kwargs != None:
            for key, value in kwargs.iteritems():
                if key[:9] == "utility__":
                    utility_function_additional_args[key[9:]] = value

        # Validate that there are some positive and negative examples
        if len(positive_example_idx) == 0 or  len(negative_example_idx) == 0:
            raise ValueError("There must be positive and negative examples to train the SCM.")


        if self.model_type == disjunction: