Source code for moptipy.tests.encoding

"""Functions that can be used to test encodings."""
from typing import Any, Callable

from pycommons.types import type_error

from moptipy.api.encoding import Encoding, check_encoding
from moptipy.api.space import Space
from moptipy.tests.component import validate_component


[docs] def validate_encoding(encoding: Encoding, search_space: Space | None = None, solution_space: Space | None = None, make_search_space_element_valid: Callable[[Any], Any] | None = lambda x: x, is_deterministic: bool = True) -> None: """ Check whether an object is a proper moptipy encoding. :param encoding: the encoding to test :param search_space: the search space :param make_search_space_element_valid: a method that can turn a point from the space into a valid point :param solution_space: the solution space :param is_deterministic: is the mapping deterministic? :raises ValueError: if `encoding` is not a valid :class:`~moptipy.api.encoding.Encoding` :raises TypeError: if `encoding` is of the wrong type or a wrong type is encountered """ if not isinstance(encoding, Encoding): raise type_error(encoding, "encoding", Encoding) check_encoding(encoding) validate_component(encoding) count: int = 0 if search_space is not None: count += 1 if make_search_space_element_valid is not None: count += 1 if solution_space is not None: count += 1 if count <= 0: return if count < 3: raise ValueError( "either provide all of search_space, " "make_search_space_element_valid, and solution_space or none.") x1 = search_space.create() if x1 is None: raise ValueError("Provided search space created None?") x1 = make_search_space_element_valid(x1) search_space.validate(x1) y1 = solution_space.create() if y1 is None: raise ValueError("Provided solution space created None?") if not (hasattr(encoding, "decode") and callable(getattr( encoding, "decode"))): raise ValueError("encoding must have method decode.") encoding.decode(x1, y1) solution_space.validate(y1) s1: str = solution_space.to_str(y1) if s1 is None: raise ValueError("to_str() returned None!") if len(s1) <= 0: raise ValueError("to_str() return empty string") y2 = solution_space.create() if y2 is None: raise ValueError("Provided solution space created None?") if y1 is y2: raise ValueError("Provided solution space created " "identical points?") encoding.decode(x1, y2) solution_space.validate(y2) s2: str = solution_space.to_str(y2) if s2 is None: raise ValueError("to_str() returned None!") if len(s2) <= 0: raise ValueError("to_str() return empty string") if is_deterministic: if not solution_space.is_equal(y1, y2): raise ValueError("Encoding must be deterministic and decode " "identical points to same result.") if s1 != s2: raise ValueError(f"to_str(y1)={s1!r} but to_str(y2)={s2!r}!") x2 = search_space.create() if x2 is None: raise ValueError("Provided search space created None?") if x1 is x2: raise ValueError("Provided search space created " "identical points?") search_space.copy(x2, x1) if not search_space.is_equal(x1, x2): raise ValueError("Copy method of search space did not result in " "is_equal becoming true?") search_space.validate(x2) encoding.decode(x2, y2) solution_space.validate(y2) s2 = solution_space.to_str(y2) if s2 is None: raise ValueError("to_str() returned None!") if len(s2) <= 0: raise ValueError("to_str() return empty string") if is_deterministic: if not solution_space.is_equal(y1, y2): raise ValueError("Encoding must be deterministic and decode " "equal points to same result.") if s1 != s2: raise ValueError(f"to_str(y1)={s1!r} but to_str(y2)={s2!r}!")