# Path: stripstream/pddl/cond_streams.py
# class ExternalGenCondStream(CondStream):
# 
#     def __init__(self, generator, name=None, *args, **kwargs):
#         self.generator = generator
#         super(ExternalGenCondStream, self).__init__(*args, **kwargs)
#         if name is not None:
#             self.name = name
# 
#     class StreamFn(GeneratorStream):
# 
#         def __init__(self, cs, inputs, **kwargs):
#             self.get_generator = cs.generator
#             GeneratorStream.__init__(self, cs, inputs, **kwargs)
# 
# Path: stripstream/fts/variable.py
# class FreeParameter(SSParameter):
#     num = 0
#     prefix = '_param%s'
# 
#     def __init__(self, name, type=None):
#         if type is None:
#             type = name
#             assert isinstance(type, VarType)
#             name = self.prefix % FreeParameter.num
#             FreeParameter.num += 1
#         super(FreeParameter, self).__init__(name, type)
# 
# Path: stripstream/fts/constraint.py
# class Constraint(object):
# 
#     def __init__(self, constraint, values):
#         self.constraint = constraint
#         self.values = values
# 
#     def __eq__(self, other):
#         return type(self) == type(other) and self.constraint == other.constraint and self.values == other.values
# 
#     def __ne__(self, other):
#         return not(self == other)
# 
#     def __hash__(self):
#         return hash((self.__class__, self.constraint, self.values))
# 
#     def __repr__(self):
#         return '%s(%s)' % (self.constraint.name, ','.join(repr(value) for value in self.values))
# 
# def convert_constraint(constraint):
# 
#     assert all(isinstance(item, FreeParameter) for item in constraint.values)
#     return constraint.constraint.predicate(*constraint.values)


from stripstream.pddl.cond_streams import ExternalGenCondStream
from stripstream.fts.variable import FreeParameter
from stripstream.fts.constraint import Constraint, convert_constraint


class Sampler(object):

    def __init__(self, values, gen, inputs=(), domain=(), name=None, **kwargs):
        self.cons = filter(lambda c: isinstance(c, Constraint), values)
        self.gen = gen
        self.inputs = tuple(inputs)
        self.domain = domain

        self.name = name if name is not None else self.__class__.__name__ + \
            str(values)
        self.kwargs = kwargs
        outputs = []
        for val in values:
            if isinstance(val, Constraint):
                for par in val.values:
                    assert isinstance(par, FreeParameter)
                    if par not in self.inputs and par not in outputs:
                        outputs.append(par)

# Path: stripstream/pddl/cond_streams.py
# class ExternalGenCondStream(CondStream):
# 
#     def __init__(self, generator, name=None, *args, **kwargs):
#         self.generator = generator
#         super(ExternalGenCondStream, self).__init__(*args, **kwargs)
#         if name is not None:
#             self.name = name
# 
#     class StreamFn(GeneratorStream):
# 
#         def __init__(self, cs, inputs, **kwargs):
#             self.get_generator = cs.generator
#             GeneratorStream.__init__(self, cs, inputs, **kwargs)
# 
# Path: stripstream/fts/variable.py
# class FreeParameter(SSParameter):
#     num = 0
#     prefix = '_param%s'
# 
#     def __init__(self, name, type=None):
#         if type is None:
#             type = name
#             assert isinstance(type, VarType)
#             name = self.prefix % FreeParameter.num
#             FreeParameter.num += 1
#         super(FreeParameter, self).__init__(name, type)
# 
# Path: stripstream/fts/constraint.py
# class Constraint(object):
# 
#     def __init__(self, constraint, values):
#         self.constraint = constraint
#         self.values = values
# 
#     def __eq__(self, other):
#         return type(self) == type(other) and self.constraint == other.constraint and self.values == other.values
# 
#     def __ne__(self, other):
#         return not(self == other)
# 
#     def __hash__(self):
#         return hash((self.__class__, self.constraint, self.values))
# 
#     def __repr__(self):
#         return '%s(%s)' % (self.constraint.name, ','.join(repr(value) for value in self.values))
# 
# def convert_constraint(constraint):
# 
#     assert all(isinstance(item, FreeParameter) for item in constraint.values)
#     return constraint.constraint.predicate(*constraint.values)


# Path: stripstream/fts/sampler.py
from stripstream.pddl.cond_streams import ExternalGenCondStream
from stripstream.fts.variable import FreeParameter
from stripstream.fts.constraint import Constraint, convert_constraint



class Sampler(object):

    def __init__(self, values, gen, inputs=(), domain=(), name=None, **kwargs):
        self.cons = filter(lambda c: isinstance(c, Constraint), values)
        self.gen = gen
        self.inputs = tuple(inputs)
        self.domain = domain

        self.name = name if name is not None else self.__class__.__name__ + \
            str(values)
        self.kwargs = kwargs
        outputs = []
        for val in values:
            if isinstance(val, Constraint):
                for par in val.values:
                    assert isinstance(par, FreeParameter)
                    if par not in self.inputs and par not in outputs:
                        outputs.append(par)

            elif isinstance(val, FreeParameter):