# Path: stripstream/algorithms/instantiation.py
# def instantiate_axioms(universe):
#     return instantiate_operators(universe.axioms, universe.type_to_objects)
# 
# Path: stripstream/pddl/logic/atoms.py
# class Atom(Formula, Condition, Effect):
# 
#     def __init__(self, predicate, args):
#         """
#         Atomic formula (P O1 O2 ... ON).
# 
#         :param predicate: the :class:`.Predicate` form of the atom
#         :param args: a list of :class:`.Object` arguments to ``predicate``
#         :raises ValueError: if ``predicate.types`` does not match the types of ``args``
#         .. automethod:: __invert__
#         """
#         if not all(isinstance(arg, Object) for arg in args):
#             raise ValueError(
#                 'Expected atom arguments %s to extend class Object' % args)
#         if len(predicate.types) != len(args):
#             raise ValueError('Expected atom arguments %s to have the same length as predicate types %s' % (
#                 args, predicate.types))
#         arg_types = tuple(arg.type for arg in args)
#         if not all(ty == arg_ty or ty == OBJECT for ty, arg_ty in zip(predicate.types, arg_types)):
#             raise ValueError('Expected atom argument types %s to be the same as predicate types %s' % (
#                 arg_types, predicate.types))
#         self.predicate = predicate
#         self.args = tuple(args)
#         self._hash = None
# 
#     @property
#     def name(self): return self.predicate.name
# 
#     @property
#     def types(self): return self.predicate.types
# 
#     @property
#     def function(self): return self.predicate
# 
#     def get_atoms(self): return {self}
# 
#     def get_literals(self): return [[self]]
# 
#     def get_formulas(self): return []
# 
#     def get_quantified(self): return set()
# 
#     def substitute(self, atom, subformula): pass
# 
#     def holds(self, atoms, constants): return self in atoms
# 
#     def positive_supporters(self, atoms, constants): return {
#         self} if self.holds(atoms, constants) else None
# 
#     def negative_supporters(self, atoms, constants): return None if self.holds(
#         atoms, constants) else {self}
# 
#     def add(self, atoms, constants): return [self]
# 
#     def delete(self, atoms, constants): return []
# 
#     def is_function(self): return isinstance(self.function, Function)
# 
#     def get_parameters(self):
#         return set(arg for arg in self.args if isinstance(arg, Parameter))
# 
#     def propositional(self, constants): return self
# 
#     def dequantify(self, constants): return self
# 
#     def instantiate(self, parameter_map):
#         return Atom(self.predicate, [parameter_map[arg] if arg in parameter_map else arg for arg in self.args])
# 
#     def de_morgan(self, sign=True):
#         return self if sign else stripstream.pddl.logic.connectives.Not(self)
# 
#     def __invert__(self):
#         """
#         Negates the atom.
# 
#         :return: :class:`.Not` of the atom
#         """
#         return stripstream.pddl.logic.connectives.Not(self)
# 
#     def __eq__(self, other):
#         return type(self) == type(other) and self.predicate == other.predicate and self.args == other.args
# 
#     def __ne__(self, other):
#         return not(self == other)
# 
#     def __hash__(self):
#         if self._hash is None:
#             self._hash = hash((self.__class__, self.predicate, self.args))
#         return self._hash
# 
#     def __repr__(self):
#         return self.predicate.name + '(' + ','.join(repr(arg) for arg in self.args) + ')'
# 
#     def pddl(self):
#         return '(' + ' '.join([self.name] + [arg.pddl() for arg in self.args]) + ')'
# 
#     def typed_pddl(self):
#         return '(' + self.name + ''.join(' ' + arg.typed_pddl() for arg in self.args) + ')'
# 
# Path: stripstream/pddl/logic/predicates.py
# class Head(object):
# class Predicate(Head):
# class EasyPredicate(Predicate):
# class Function(Head):
# class EasyFunction(Function):
#     def __init__(self, name, types=tuple()):
#     def __call__(self, *args):
#     def __eq__(self, other):
#     def __ne__(self, other):
#     def __hash__(self):
#     def pddl(self):
#     def __repr__(self):
#     def __init__(self, *types):
#     def __init__(self, *types):
# def convert_args(self, args):
# 
# Path: stripstream/pddl/logic/utils.py
# def get_increases(f):
#     if isinstance(f, atoms.Increase):
#         return [f]
#     if isinstance(f, atoms.Atom):
#         return []
#     if isinstance(f, connectives.Connective):
#         return reduce(operator.add, [get_increases(formula) for formula in f.formulas])
#     return []
# 
# Path: stripstream/utils.py
# INF = float('inf')
# 
# SEPARATOR = '\n' + 85 * '-' + '\n'


from collections import defaultdict
from stripstream.algorithms.instantiation import instantiate_axioms
from stripstream.pddl.logic.atoms import Atom
from stripstream.pddl.logic.predicates import TotalCost
from stripstream.pddl.logic.utils import get_increases
from stripstream.utils import INF, SEPARATOR


def plan_length(universe, plan):
    if plan is None:
        return INF
    return len(plan)


def plan_cost(universe, plan):
    if plan is None:

# Path: stripstream/algorithms/instantiation.py
# def instantiate_axioms(universe):
#     return instantiate_operators(universe.axioms, universe.type_to_objects)
# 
# Path: stripstream/pddl/logic/atoms.py
# class Atom(Formula, Condition, Effect):
# 
#     def __init__(self, predicate, args):
#         """
#         Atomic formula (P O1 O2 ... ON).
# 
#         :param predicate: the :class:`.Predicate` form of the atom
#         :param args: a list of :class:`.Object` arguments to ``predicate``
#         :raises ValueError: if ``predicate.types`` does not match the types of ``args``
#         .. automethod:: __invert__
#         """
#         if not all(isinstance(arg, Object) for arg in args):
#             raise ValueError(
#                 'Expected atom arguments %s to extend class Object' % args)
#         if len(predicate.types) != len(args):
#             raise ValueError('Expected atom arguments %s to have the same length as predicate types %s' % (
#                 args, predicate.types))
#         arg_types = tuple(arg.type for arg in args)
#         if not all(ty == arg_ty or ty == OBJECT for ty, arg_ty in zip(predicate.types, arg_types)):
#             raise ValueError('Expected atom argument types %s to be the same as predicate types %s' % (
#                 arg_types, predicate.types))
#         self.predicate = predicate
#         self.args = tuple(args)
#         self._hash = None
# 
#     @property
#     def name(self): return self.predicate.name
# 
#     @property
#     def types(self): return self.predicate.types
# 
#     @property
#     def function(self): return self.predicate
# 
#     def get_atoms(self): return {self}
# 
#     def get_literals(self): return [[self]]
# 
#     def get_formulas(self): return []
# 
#     def get_quantified(self): return set()
# 
#     def substitute(self, atom, subformula): pass
# 
#     def holds(self, atoms, constants): return self in atoms
# 
#     def positive_supporters(self, atoms, constants): return {
#         self} if self.holds(atoms, constants) else None
# 
#     def negative_supporters(self, atoms, constants): return None if self.holds(
#         atoms, constants) else {self}
# 
#     def add(self, atoms, constants): return [self]
# 
#     def delete(self, atoms, constants): return []
# 
#     def is_function(self): return isinstance(self.function, Function)
# 
#     def get_parameters(self):
#         return set(arg for arg in self.args if isinstance(arg, Parameter))
# 
#     def propositional(self, constants): return self
# 
#     def dequantify(self, constants): return self
# 
#     def instantiate(self, parameter_map):
#         return Atom(self.predicate, [parameter_map[arg] if arg in parameter_map else arg for arg in self.args])
# 
#     def de_morgan(self, sign=True):
#         return self if sign else stripstream.pddl.logic.connectives.Not(self)
# 
#     def __invert__(self):
#         """
#         Negates the atom.
# 
#         :return: :class:`.Not` of the atom
#         """
#         return stripstream.pddl.logic.connectives.Not(self)
# 
#     def __eq__(self, other):
#         return type(self) == type(other) and self.predicate == other.predicate and self.args == other.args
# 
#     def __ne__(self, other):
#         return not(self == other)
# 
#     def __hash__(self):
#         if self._hash is None:
#             self._hash = hash((self.__class__, self.predicate, self.args))
#         return self._hash
# 
#     def __repr__(self):
#         return self.predicate.name + '(' + ','.join(repr(arg) for arg in self.args) + ')'
# 
#     def pddl(self):
#         return '(' + ' '.join([self.name] + [arg.pddl() for arg in self.args]) + ')'
# 
#     def typed_pddl(self):
#         return '(' + self.name + ''.join(' ' + arg.typed_pddl() for arg in self.args) + ')'
# 
# Path: stripstream/pddl/logic/predicates.py
# class Head(object):
# class Predicate(Head):
# class EasyPredicate(Predicate):
# class Function(Head):
# class EasyFunction(Function):
#     def __init__(self, name, types=tuple()):
#     def __call__(self, *args):
#     def __eq__(self, other):
#     def __ne__(self, other):
#     def __hash__(self):
#     def pddl(self):
#     def __repr__(self):
#     def __init__(self, *types):
#     def __init__(self, *types):
# def convert_args(self, args):
# 
# Path: stripstream/pddl/logic/utils.py
# def get_increases(f):
#     if isinstance(f, atoms.Increase):
#         return [f]
#     if isinstance(f, atoms.Atom):
#         return []
#     if isinstance(f, connectives.Connective):
#         return reduce(operator.add, [get_increases(formula) for formula in f.formulas])
#     return []
# 
# Path: stripstream/utils.py
# INF = float('inf')
# 
# SEPARATOR = '\n' + 85 * '-' + '\n'


# Path: stripstream/algorithms/plan.py
from collections import defaultdict
from stripstream.algorithms.instantiation import instantiate_axioms
from stripstream.pddl.logic.atoms import Atom
from stripstream.pddl.logic.predicates import TotalCost
from stripstream.pddl.logic.utils import get_increases
from stripstream.utils import INF, SEPARATOR



def plan_length(universe, plan):
    if plan is None:
        return INF
    return len(plan)


def plan_cost(universe, plan):
    if plan is None:

        return INF