# 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)
# 
# def is_constant(v):
#     return not is_parameter(v)
# 
# Path: stripstream/pddl/logic/predicates.py
# class Predicate(Head):
#     pass
#     """
#   Predicate P which extends :class:`.NamedHead`.
#   """
# 
# Path: stripstream/pddl/objects.py
# OBJECT = Type('object')
# 
# Path: stripstream/pddl/cond_streams.py
# class ExternalTestCondStream(TestCondStream):
# 
#     def __init__(self, test, name=None, *args, **kwargs):
#         self.test = test
#         super(ExternalTestCondStream, self).__init__(*args, **kwargs)
#         if name is not None:
#             self.name = name
# 
#     class StreamFn(TestStream):
# 
#         def __init__(self, cs, inputs, **kwargs):
#             self.test = cs.test
#             TestStream.__init__(self, cs, inputs, **kwargs)


from stripstream.fts.variable import FreeParameter, is_constant
from stripstream.pddl.logic.predicates import Predicate
from stripstream.pddl.objects import OBJECT
from stripstream.pddl.cond_streams import ExternalTestCondStream


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)


def make_test_stream(constraint_form):
    assert constraint_form.test is not None
    assert not constraint_form.domain

# 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)
# 
# def is_constant(v):
#     return not is_parameter(v)
# 
# Path: stripstream/pddl/logic/predicates.py
# class Predicate(Head):
#     pass
#     """
#   Predicate P which extends :class:`.NamedHead`.
#   """
# 
# Path: stripstream/pddl/objects.py
# OBJECT = Type('object')
# 
# Path: stripstream/pddl/cond_streams.py
# class ExternalTestCondStream(TestCondStream):
# 
#     def __init__(self, test, name=None, *args, **kwargs):
#         self.test = test
#         super(ExternalTestCondStream, self).__init__(*args, **kwargs)
#         if name is not None:
#             self.name = name
# 
#     class StreamFn(TestStream):
# 
#         def __init__(self, cs, inputs, **kwargs):
#             self.test = cs.test
#             TestStream.__init__(self, cs, inputs, **kwargs)


# Path: stripstream/fts/constraint.py
from stripstream.fts.variable import FreeParameter, is_constant
from stripstream.pddl.logic.predicates import Predicate
from stripstream.pddl.objects import OBJECT
from stripstream.pddl.cond_streams import ExternalTestCondStream



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)


def make_test_stream(constraint_form):
    assert constraint_form.test is not None
    assert not constraint_form.domain

    params = [FreeParameter('%s' % i, dtype)