"""
Base Constraints on offering constaints
"""
from __future__ import annotations
from abc import ABC, abstractmethod
from attrs import define
from negmas.gb.common import GBState, ThreadState
__all__ = [
"OfferingConstraint",
"LocalOfferingConstraint",
"AnyOfferingConstraint",
"AllOfferingConstraints",
]
[docs]
@define
class OfferingConstraint(ABC):
[docs]
@abstractmethod
def __call__(
self, state: GBState | ThreadState, history: list[GBState | ThreadState]
) -> bool:
"""
Base class for all offering constaints
Args:
offer (Outcome): Outcome to be checked for validity
history (list[GBState]): History of past states
Returns:
bool
"""
...
def __and__(self, other: OfferingConstraint) -> OfferingConstraint:
return AllOfferingConstraints([self, other])
def __or__(self, other: OfferingConstraint) -> OfferingConstraint:
return AnyOfferingConstraint([self, other])
def __not__(self) -> OfferingConstraint:
return InverseOfferingConstraint(self)
[docs]
@define
class LocalOfferingConstraint(OfferingConstraint, ABC):
[docs]
@abstractmethod
def __call__(self, state: ThreadState, history: list[ThreadState]) -> bool:
... # type: ignore
[docs]
def eval_globally(self, source: str, state: GBState, history: list[GBState]):
return self(state.threads[source], [_.threads[source] for _ in history])
[docs]
@define
class AnyOfferingConstraint(OfferingConstraint):
constraints: list[OfferingConstraint]
[docs]
def __call__(self, *args, **kwargs) -> bool:
return any([_(*args, **kwargs) for _ in self.constraints])
[docs]
@define
class AllOfferingConstraints(OfferingConstraint):
constaints: list[OfferingConstraint]
[docs]
def __call__(self, *args, **kwargs) -> bool:
return all([_(*args, **kwargs) for _ in self.constaints])
@define
class InverseOfferingConstraint(OfferingConstraint):
constraint: OfferingConstraint
def __call__(self, *args, **kwargs) -> bool:
return not self.constraint(*args, **kwargs)