from __future__ import annotations
import typing
from fuzzy_dl_owl2.fuzzydl.concept.concrete.fuzzy_concrete_concept import (
FuzzyConcreteConcept,
)
from fuzzy_dl_owl2.fuzzydl.concept.operator_concept import OperatorConcept
from fuzzy_dl_owl2.fuzzydl.modifier.modifier import Modifier
[docs]
class ModifiedConcreteConcept(FuzzyConcreteConcept):
"""
This class models a fuzzy concrete concept that has been altered by a specific modifier, such as "very" or "somewhat," effectively creating a composite concept like "very tall." It operates by wrapping an existing fuzzy concrete concept and applying a transformation function to the membership degrees generated by that base concept. When evaluating the membership degree of an input value, the implementation strictly enforces a domain constraint: if the input is less than or equal to zero or greater than one, the resulting membership degree is zero. For inputs within the valid range, the class calculates the membership degree using the underlying concept and then applies the modifier's membership function to that intermediate value to determine the final degree of satisfaction. This mechanism allows for the dynamic construction of complex linguistic expressions by mathematically adjusting the truth values of simpler concepts.
:param k1: The lower bound of the support interval for the fuzzy concept, defining the minimum value for which the membership degree is non-zero.
:type k1: float
:param k2: The upper bound of the support interval, defining the threshold above which the membership degree is zero.
:type k2: float
:param _modifier: The fuzzy logic modifier applied to the underlying concept to transform its membership degree.
:type _modifier: Modifier
:param _modified: The fuzzy concrete concept that is subject to modification by the associated modifier.
:type _modified: FuzzyConcreteConcept
"""
def __init__(self, name: str, modifier: Modifier, f: FuzzyConcreteConcept) -> None:
"""
Initializes a modified concrete concept by associating a specific name, a modifier object, and a fuzzy concrete concept to be modified. This method invokes the superclass constructor to handle the naming convention and establishes default scaling parameters, setting `k1` to 0.0 and `k2` to 1.0. The provided modifier and fuzzy concept are stored internally for subsequent operations, effectively wrapping the fuzzy concept to allow for modification logic.
:param name: The identifier or label for the object instance.
:type name: str
:param modifier: The modifier object to be applied to the fuzzy concrete concept.
:type modifier: Modifier
:param f: The fuzzy concrete concept to be stored as the modified concept.
:type f: FuzzyConcreteConcept
"""
super().__init__(name)
self.k1: float = 0.0
self.k2: float = 1.0
self._modifier: Modifier = modifier
self._modified: FuzzyConcreteConcept = f
@property
def modifier(self) -> Modifier:
"""
Sets the value of the `modifier` property for the `ModifiedConcreteConcept` instance. This method accepts a `Modifier` object and assigns it to the internal `_modifier` attribute, effectively updating the instance's state. No validation or additional side effects are performed during this assignment.
:param value: The new modifier instance to assign to the object.
:type value: Modifier
"""
return self._modifier
@modifier.setter
def modifier(self, value: Modifier) -> None:
self._modifier = value
@property
def modified(self) -> FuzzyConcreteConcept:
"""
Sets the internal modification state of the object to the provided `FuzzyConcreteConcept` value. This method acts as the setter for the `modified` property, replacing the existing value stored in the private `_modified` attribute. It directly mutates the instance's state and does not perform any validation or return a value.
:param value: The concept instance to assign as the modified state.
:type value: FuzzyConcreteConcept
"""
return self._modified
@modified.setter
def modified(self, value: FuzzyConcreteConcept) -> None:
self._modified = value
[docs]
def clone(self) -> typing.Self:
"""
Creates and returns a new instance of `ModifiedConcreteConcept` that replicates the state of the current object. The new object is initialized using the existing values of the `name`, `modifier`, and `modified` attributes. This operation performs a shallow copy, meaning that while the instance itself is distinct, any mutable attributes will be shared by reference between the original and the clone. The method has no side effects on the original instance.
:return: A new instance of the class initialized with the same name, modifier, and modified values as the current object.
:rtype: typing.Self
"""
return ModifiedConcreteConcept(self.name, self.modifier, self.modified)
# def solve_assertion(
# self, ind: Individual, lower_limit: Degree, kb: KnowledgeBase
# ) -> None:
# self.modifier.solve_assertion(ind, self, lower_limit, kb)
[docs]
def get_membership_degree(self, x: float) -> float:
"""
Calculates the membership degree of a value `x` by composing the membership functions of a base concept and a modifier. If the input `x` is less than or equal to 0.0 or greater than 1.0, the method returns 0.0, treating values outside this interval as having no membership. For valid inputs, it first computes the membership degree of `x` using the `modified` object and then passes that result to the `modifier` object to determine the final, transformed membership degree.
:param x: The input value for which the membership degree is calculated. Values outside the range (0, 1] result in a degree of 0.0.
:type x: float
:return: The membership degree of the input value x, calculated by applying the modifier to the membership degree of the modified set. Returns 0.0 if x is outside the range (0, 1].
:rtype: float
"""
if x <= 0.0 or x > 1.0:
return 0.0
y: float = self.modified.get_membership_degree(x)
return self.modifier.get_membership_degree(y)
[docs]
def compute_name(self) -> str:
"""
Generates a formatted string representation of the concept's name by combining the `modifier` and `modified` attributes. The output follows the specific pattern "modified(modifier modified)", utilizing the string conversion of the underlying attribute values. This method is read-only and does not alter the state of the object, though it assumes that the `modifier` and `modified` attributes are defined.
:return: A string formatted as "modified({modifier} {modified})", incorporating the object's modifier and modified attributes.
:rtype: str
"""
return f"modified({self.modifier} {self.modified})"
[docs]
def __neg__(self) -> FuzzyConcreteConcept:
"""
Implements the unary negation operator, allowing the concept to be negated using the minus sign syntax. This method computes the logical NOT of the current concept by delegating to the `OperatorConcept.not_` static method. It returns a new `FuzzyConcreteConcept` representing the negated value, leaving the original instance unchanged.
:return: Returns the logical negation (complement) of the current concept.
:rtype: FuzzyConcreteConcept
"""
return OperatorConcept.not_(self)
[docs]
def __and__(self, value: typing.Self) -> typing.Self:
"""
Implements the bitwise AND operation for the instance, allowing it to be combined with another object of the same type using the `&` operator. This method delegates the actual logic to the `and_` function within the `OperatorConcept` class, ensuring consistent behavior across the module. It returns a new instance representing the result of the conjunction without modifying the original objects.
:param value: Another instance of the same class to perform the AND operation with.
:type value: typing.Self
:return: A new instance representing the result of the AND operation between the current object and the provided value.
:rtype: typing.Self
"""
return OperatorConcept.and_(self, value)
[docs]
def __or__(self, value: typing.Self) -> typing.Self:
"""
Implements the bitwise OR operator (`|`) for the instance, allowing it to be combined with another value of the same type. This method delegates the actual computation to the `OperatorConcept.or_` static method, passing the current instance and the provided value as arguments. It returns a new instance of the same class representing the result of the operation, leaving the original operands unmodified.
:param value: Another instance of the same class to perform the OR operation with.
:type value: typing.Self
:return: The result of the OR operation between the current instance and the provided value.
:rtype: typing.Self
"""
return OperatorConcept.or_(self, value)
[docs]
def __hash__(self) -> int:
"""
Computes the hash value for the instance by generating a hash of the object's string representation. This implementation delegates the hashing logic to the result of `str(self)`, ensuring that objects with identical string representations produce the same hash code. Consequently, any modification to the object that alters its string representation will result in a different hash value, which can lead to unexpected behavior if the object is used as a key in a dictionary or stored in a set.
:return: An integer hash value derived from the string representation of the object.
:rtype: int
"""
return hash(str(self))
# def __str__(self) -> str:
# return self.get_name()