Source code for negmas.preferences.mixins

from __future__ import annotations
from abc import abstractmethod
from typing import TYPE_CHECKING

from negmas.common import Distribution

if TYPE_CHECKING:
    from negmas.common import MechanismState, NegotiatorMechanismInterface
    from negmas.negotiators import Negotiator
    from negmas.outcomes.common import Outcome
    from negmas.preferences import UtilityFunction

__all__ = [
    "VolatileUFunMixin",
    "SessionDependentUFunMixin",
    "StateDependentUFunMixin",
    "StationaryMixin",
]


[docs] class VolatileUFunMixin: """ Indicates that the ufun is volatile """
[docs] def is_volatile(self): return True
[docs] class SessionDependentUFunMixin: """ Indicates that the ufun is session-dependent (i.e. utility value of outcomes depend on the NMI) """
[docs] @abstractmethod def eval_on_session( self, offer: Outcome, nmi: NegotiatorMechanismInterface | None = None ) -> Distribution: """Evaluates the offer given a session"""
[docs] def eval(self, offer: Outcome) -> Distribution: if not self.owner or not self.owner.nmi: return self.eval_on_session(offer, None) self.owner: Negotiator return self.eval_on_session(offer, self.owner.nmi)
[docs] def is_session_dependent(self): """ Does the utiltiy of an outcome depend on the `NegotiatorMechanismInterface`? """ return True
[docs] def is_state_dependent(self): """ Does the utiltiy of an outcome depend on the negotiation state? """ return False
[docs] class StateDependentUFunMixin: """ Indicates that the ufun is state-dependent (i.e. utility value of outcomes depend on the mechanism state) """
[docs] @abstractmethod def eval_on_state( self, offer: Outcome, nmi: NegotiatorMechanismInterface | None = None, state: MechanismState | None = None, ) -> Distribution: """Evaluates the offer given a session and state"""
[docs] def eval(self, offer: Outcome) -> Distribution: if not self.owner or not self.owner.nmi: return self.eval_on_state(offer, None, None) self.owner: Negotiator return self.eval_on_state(offer, self.owner.nmi, self.owner.nmi.state)
[docs] def is_session_dependent(self): """ Does the utiltiy of an outcome depend on the `NegotiatorMechanismInterface`? """ return True
[docs] def is_state_dependent(self): """ Does the utiltiy of an outcome depend on the negotiation state? """ return True
[docs] class StationaryMixin: """ Indicates that the ufun is stationary which means that it is not session or state dependent and not volatile. Negotiators using this type of ufuns can assume that if they call it twice with the same outcome, it will always return the same value. """
[docs] def is_session_dependent(self) -> bool: return False
[docs] def is_volatile(self) -> bool: return False
[docs] def is_state_dependent(self) -> bool: return False
[docs] def is_stationary(self) -> bool: return True
[docs] def to_stationary(self) -> UtilityFunction: return self # type: ignore
# @lru_cache(maxsize=100) # def eval_normalized( # self: BaseUtilityFunction, # type: ignore # offer: Outcome | None, # above_reserve: bool = True, # expected_limits: bool = True, # ) -> Value: # """ # Caches the top 100 results from the ufun because we know they are never going to change. # """ # return super().eval_normalized(offer, above_reserve, expected_limits)