from __future__ import annotations
from dataclasses import dataclass
from typing import TYPE_CHECKING, Optional, Any
from numpy.typing import NDArray

from .Constant import Constant
from .Variable import Variable

# hacky solution to solving circular import for type-checking only
# from https://stackoverflow.com/a/39757388/245362
if TYPE_CHECKING:
    from .Atom import Atom


@dataclass(frozen=True, eq=False)
class Predicate:
    symbol: str
    vector: Optional[NDArray[Any]] = None

    # shorthand for creating an Atom out of this predicate and terms
    def __call__(self, *terms: Constant | Variable) -> Atom:
        # need to import inside of here to avoid circular references
        from .Atom import Atom

        return Atom(self, terms)

    def __str__(self) -> str:
        return f"PRED:{self.symbol}"
