Skip to content

types

types

Definition of intersection types Type and parameterized abstractions Abstraction.

Abstraction dataclass

Abstraction of a term parameter or a literal parameter.

Source code in src/cosy/types.py
@dataclass(frozen=True)
class Abstraction:
    """Abstraction of a term parameter or a literal parameter."""

    parameter: Parameter
    body: Abstraction | Implication | Type

    def __str__(self) -> str:
        return f"{self.parameter}.{self.body}"

body: Abstraction | Implication | Type instance-attribute

parameter: Parameter instance-attribute

__init__(parameter: Parameter, body: Abstraction | Implication | Type) -> None

__str__() -> str

Source code in src/cosy/types.py
def __str__(self) -> str:
    return f"{self.parameter}.{self.body}"

Arrow dataclass

Source code in src/cosy/types.py
@dataclass(frozen=True)
class Arrow(Type):
    source: Type = field(init=True)
    target: Type = field(init=True)
    is_omega: bool = field(init=False, compare=False)
    size: int = field(init=False, compare=False)
    organized: set[Type] = field(init=False, compare=False)
    free_vars: set[str] = field(init=False, compare=False)

    def __post_init__(self) -> None:
        super().__init__(
            is_omega=self._is_omega(),
            size=self._size(),
            organized=self._organized(),
            free_vars=self._free_vars(),
        )

    def _is_omega(self) -> bool:
        return self.target.is_omega

    def _size(self) -> int:
        return 1 + self.source.size + self.target.size

    def _organized(self) -> set[Type]:
        if len(self.target.organized) == 0:
            return set()
        if len(self.target.organized) == 1:
            return {self}
        return {Arrow(self.source, tp) for tp in self.target.organized}

    def _free_vars(self) -> set[str]:
        return set.union(self.source.free_vars, self.target.free_vars)

    def __str__(self) -> str:
        return f"{self.source} -> {self.target}"

    def subst(self, groups: Mapping[str, str], substitution: dict[str, Any]) -> Type:
        if not any(var in substitution for var in self.free_vars):
            return self
        return Arrow(
            self.source.subst(groups, substitution),
            self.target.subst(groups, substitution),
        )

free_vars: set[str] = field(init=False, compare=False) class-attribute instance-attribute

is_omega: bool = field(init=False, compare=False) class-attribute instance-attribute

organized: set[Type] = field(init=False, compare=False) class-attribute instance-attribute

size: int = field(init=False, compare=False) class-attribute instance-attribute

source: Type = field(init=True) class-attribute instance-attribute

target: Type = field(init=True) class-attribute instance-attribute

__init__(source: Type, target: Type, *, is_omega: bool, size: int, organized: set[Type], free_vars: set[str]) -> None

__post_init__() -> None

Source code in src/cosy/types.py
def __post_init__(self) -> None:
    super().__init__(
        is_omega=self._is_omega(),
        size=self._size(),
        organized=self._organized(),
        free_vars=self._free_vars(),
    )

__str__() -> str

Source code in src/cosy/types.py
def __str__(self) -> str:
    return f"{self.source} -> {self.target}"

subst(groups: Mapping[str, str], substitution: dict[str, Any]) -> Type

Source code in src/cosy/types.py
def subst(self, groups: Mapping[str, str], substitution: dict[str, Any]) -> Type:
    if not any(var in substitution for var in self.free_vars):
        return self
    return Arrow(
        self.source.subst(groups, substitution),
        self.target.subst(groups, substitution),
    )

Constructor dataclass

Source code in src/cosy/types.py
@dataclass(frozen=True)
class Constructor(Type):
    name: str = field(init=True)
    arg: Type = field(default=Omega(), init=True)
    is_omega: bool = field(init=False, compare=False)
    size: int = field(init=False, compare=False)
    organized: set[Type] = field(init=False, compare=False)
    free_vars: set[str] = field(init=False, compare=False)

    def __post_init__(self) -> None:
        super().__init__(
            is_omega=self._is_omega(),
            size=self._size(),
            organized=self._organized(),
            free_vars=self._free_vars(),
        )

    def _is_omega(self) -> bool:
        return False

    def _size(self) -> int:
        return 1 + self.arg.size

    def _organized(self) -> set[Type]:
        if len(self.arg.organized) <= 1:
            return {self}
        return {Constructor(self.name, ap) for ap in self.arg.organized}

    def _free_vars(self) -> set[str]:
        return self.arg.free_vars

    def __str__(self) -> str:
        if self.arg == Omega():
            return str(self.name)
        return f"{self.name!s}({self.arg!s})"

    def subst(self, groups: Mapping[str, str], substitution: dict[str, Any]) -> Type:
        if not any(var in substitution for var in self.free_vars):
            return self
        return Constructor(self.name, self.arg.subst(groups, substitution))

arg: Type = field(default=Omega(), init=True) class-attribute instance-attribute

free_vars: set[str] = field(init=False, compare=False) class-attribute instance-attribute

is_omega: bool = field(init=False, compare=False) class-attribute instance-attribute

name: str = field(init=True) class-attribute instance-attribute

organized: set[Type] = field(init=False, compare=False) class-attribute instance-attribute

size: int = field(init=False, compare=False) class-attribute instance-attribute

__init__(name: str, arg: Type = Omega(), *, is_omega: bool, size: int, organized: set[Type], free_vars: set[str]) -> None

__post_init__() -> None

Source code in src/cosy/types.py
def __post_init__(self) -> None:
    super().__init__(
        is_omega=self._is_omega(),
        size=self._size(),
        organized=self._organized(),
        free_vars=self._free_vars(),
    )

__str__() -> str

Source code in src/cosy/types.py
def __str__(self) -> str:
    if self.arg == Omega():
        return str(self.name)
    return f"{self.name!s}({self.arg!s})"

subst(groups: Mapping[str, str], substitution: dict[str, Any]) -> Type

Source code in src/cosy/types.py
def subst(self, groups: Mapping[str, str], substitution: dict[str, Any]) -> Type:
    if not any(var in substitution for var in self.free_vars):
        return self
    return Constructor(self.name, self.arg.subst(groups, substitution))

Implication dataclass

Source code in src/cosy/types.py
@dataclass(frozen=True)
class Implication:
    predicate: Predicate
    body: Abstraction | Implication | Type

    def __str__(self) -> str:
        return f"{self.predicate} => {self.body}"

body: Abstraction | Implication | Type instance-attribute

predicate: Predicate instance-attribute

__init__(predicate: Predicate, body: Abstraction | Implication | Type) -> None

__str__() -> str

Source code in src/cosy/types.py
def __str__(self) -> str:
    return f"{self.predicate} => {self.body}"

Intersection dataclass

Source code in src/cosy/types.py
@dataclass(frozen=True)
class Intersection(Type):
    left: Type = field(init=True)
    right: Type = field(init=True)
    is_omega: bool = field(init=False, compare=False)
    size: int = field(init=False, compare=False)
    organized: set[Type] = field(init=False, compare=False)
    free_vars: set[str] = field(init=False, compare=False)

    def __post_init__(self) -> None:
        super().__init__(
            is_omega=self._is_omega(),
            size=self._size(),
            organized=self._organized(),
            free_vars=self._free_vars(),
        )

    def _is_omega(self) -> bool:
        return self.left.is_omega and self.right.is_omega

    def _size(self) -> int:
        return 1 + self.left.size + self.right.size

    def _organized(self) -> set[Type]:
        return set.union(self.left.organized, self.right.organized)

    def _free_vars(self) -> set[str]:
        return set.union(self.left.free_vars, self.right.free_vars)

    def __str__(self) -> str:
        return f"{self.left} & {self.right}"

    def subst(self, groups: Mapping[str, str], substitution: dict[str, Any]) -> Type:
        if not any(var in substitution for var in self.free_vars):
            return self
        return Intersection(
            self.left.subst(groups, substitution),
            self.right.subst(groups, substitution),
        )

free_vars: set[str] = field(init=False, compare=False) class-attribute instance-attribute

is_omega: bool = field(init=False, compare=False) class-attribute instance-attribute

left: Type = field(init=True) class-attribute instance-attribute

organized: set[Type] = field(init=False, compare=False) class-attribute instance-attribute

right: Type = field(init=True) class-attribute instance-attribute

size: int = field(init=False, compare=False) class-attribute instance-attribute

__init__(left: Type, right: Type, *, is_omega: bool, size: int, organized: set[Type], free_vars: set[str]) -> None

__post_init__() -> None

Source code in src/cosy/types.py
def __post_init__(self) -> None:
    super().__init__(
        is_omega=self._is_omega(),
        size=self._size(),
        organized=self._organized(),
        free_vars=self._free_vars(),
    )

__str__() -> str

Source code in src/cosy/types.py
def __str__(self) -> str:
    return f"{self.left} & {self.right}"

subst(groups: Mapping[str, str], substitution: dict[str, Any]) -> Type

Source code in src/cosy/types.py
def subst(self, groups: Mapping[str, str], substitution: dict[str, Any]) -> Type:
    if not any(var in substitution for var in self.free_vars):
        return self
    return Intersection(
        self.left.subst(groups, substitution),
        self.right.subst(groups, substitution),
    )

Literal dataclass

Source code in src/cosy/types.py
@dataclass(frozen=True)
class Literal(Type):
    value: Any  # has to be Hashable
    group: str
    is_omega: bool = field(init=False, compare=False)
    size: int = field(init=False, compare=False)
    organized: set[Type] = field(init=False, compare=False)
    free_vars: set[str] = field(init=False, compare=False)

    def __post_init__(self) -> None:
        super().__init__(
            is_omega=self._is_omega(),
            size=self._size(),
            organized=self._organized(),
            free_vars=self._free_vars(),
        )

    def _is_omega(self) -> bool:
        return False

    def _size(self) -> int:
        return 1

    def _organized(self) -> set[Type]:
        return {self}

    def _free_vars(self) -> set[str]:
        return set()

    def __str__(self) -> str:
        return f"[{self.value!s}, {self.group}]"

    def subst(self, _groups: Mapping[str, str], _substitution: dict[str, Any]) -> Type:
        return self

free_vars: set[str] = field(init=False, compare=False) class-attribute instance-attribute

group: str instance-attribute

is_omega: bool = field(init=False, compare=False) class-attribute instance-attribute

organized: set[Type] = field(init=False, compare=False) class-attribute instance-attribute

size: int = field(init=False, compare=False) class-attribute instance-attribute

value: Any instance-attribute

__init__(value: Any, group: str, *, is_omega: bool, size: int, organized: set[Type], free_vars: set[str]) -> None

__post_init__() -> None

Source code in src/cosy/types.py
def __post_init__(self) -> None:
    super().__init__(
        is_omega=self._is_omega(),
        size=self._size(),
        organized=self._organized(),
        free_vars=self._free_vars(),
    )

__str__() -> str

Source code in src/cosy/types.py
def __str__(self) -> str:
    return f"[{self.value!s}, {self.group}]"

subst(_groups: Mapping[str, str], _substitution: dict[str, Any]) -> Type

Source code in src/cosy/types.py
def subst(self, _groups: Mapping[str, str], _substitution: dict[str, Any]) -> Type:
    return self

LiteralParameter dataclass

Specification of a literal parameter.

Source code in src/cosy/types.py
@dataclass(frozen=True)
class LiteralParameter(Parameter):
    """Specification of a literal parameter."""

    group: str
    #  Specification of literal assignment from a collection
    values: Callable[[dict[str, Any]], Sequence[Any]] | None = field(default=None)

group: str instance-attribute

values: Callable[[dict[str, Any]], Sequence[Any]] | None = field(default=None) class-attribute instance-attribute

__init__(name: str, group: str, values: Callable[[dict[str, Any]], Sequence[Any]] | None = None) -> None

Omega dataclass

Source code in src/cosy/types.py
@dataclass(frozen=True)
class Omega(Type):
    is_omega: bool = field(init=False, compare=False)
    size: int = field(init=False, compare=False)
    organized: set[Type] = field(init=False, compare=False)
    free_vars: set[str] = field(init=False, compare=False)

    def __post_init__(self) -> None:
        super().__init__(
            is_omega=self._is_omega(),
            size=self._size(),
            organized=self._organized(),
            free_vars=self._free_vars(),
        )

    def _is_omega(self) -> bool:
        return True

    def _size(self) -> int:
        return 1

    def _organized(self) -> set[Type]:
        return set()

    def __str__(self) -> str:
        return "omega"

    def _free_vars(self) -> set[str]:
        return set()

    def subst(self, _groups: Mapping[str, str], _substitution: dict[str, Any]) -> Type:
        return self

free_vars: set[str] = field(init=False, compare=False) class-attribute instance-attribute

is_omega: bool = field(init=False, compare=False) class-attribute instance-attribute

organized: set[Type] = field(init=False, compare=False) class-attribute instance-attribute

size: int = field(init=False, compare=False) class-attribute instance-attribute

__init__(*, is_omega: bool, size: int, organized: set[Type], free_vars: set[str]) -> None

__post_init__() -> None

Source code in src/cosy/types.py
def __post_init__(self) -> None:
    super().__init__(
        is_omega=self._is_omega(),
        size=self._size(),
        organized=self._organized(),
        free_vars=self._free_vars(),
    )

__str__() -> str

Source code in src/cosy/types.py
def __str__(self) -> str:
    return "omega"

subst(_groups: Mapping[str, str], _substitution: dict[str, Any]) -> Type

Source code in src/cosy/types.py
def subst(self, _groups: Mapping[str, str], _substitution: dict[str, Any]) -> Type:
    return self

Parameter dataclass

Abstract base class for parameter specification.

Source code in src/cosy/types.py
@dataclass(frozen=True)
class Parameter(ABC):
    """Abstract base class for parameter specification."""

    name: str
    group: str | Type

    def __str__(self) -> str:
        return f"<{self.name}, {self.group}>"

group: str | Type instance-attribute

name: str instance-attribute

__init__(name: str, group: str | Type) -> None

__str__() -> str

Source code in src/cosy/types.py
def __str__(self) -> str:
    return f"<{self.name}, {self.group}>"

Predicate dataclass

Source code in src/cosy/types.py
@dataclass(frozen=True)
class Predicate:
    constraint: Callable[[dict[str, Any]], bool]
    only_literals: bool

    def __str__(self) -> str:
        return f"[{self.constraint.__name__}, only literals]" if self.only_literals else f"[{self.constraint.__name__}]"

constraint: Callable[[dict[str, Any]], bool] instance-attribute

only_literals: bool instance-attribute

__init__(constraint: Callable[[dict[str, Any]], bool], only_literals: bool) -> None

__str__() -> str

Source code in src/cosy/types.py
def __str__(self) -> str:
    return f"[{self.constraint.__name__}, only literals]" if self.only_literals else f"[{self.constraint.__name__}]"

TermParameter dataclass

Specification of a term parameter.

Source code in src/cosy/types.py
@dataclass(frozen=True)
class TermParameter(Parameter):
    """Specification of a term parameter."""

    group: Type

group: Type instance-attribute

__init__(name: str, group: Type) -> None

Type dataclass

Source code in src/cosy/types.py
@dataclass(frozen=True)
class Type(ABC):
    is_omega: bool = field(init=True, kw_only=True, compare=False)
    size: int = field(init=True, kw_only=True, compare=False)
    organized: set[Type] = field(init=True, kw_only=True, compare=False)
    free_vars: set[str] = field(init=True, kw_only=True, compare=False)

    @abstractmethod
    def __str__(self) -> str:
        pass

    @abstractmethod
    def _organized(self) -> set[Type]:
        pass

    @abstractmethod
    def _size(self) -> int:
        pass

    @abstractmethod
    def _is_omega(self) -> bool:
        pass

    @abstractmethod
    def _free_vars(self) -> set[str]:
        pass

    @abstractmethod
    def subst(self, groups: Mapping[str, str], substitution: dict[str, Any]) -> Type:
        pass

    @staticmethod
    def intersect(types: Sequence[Type]) -> Type:
        if len(types) > 0:
            rtypes = reversed(types)
            result: Type = next(rtypes)
            for ty in rtypes:
                result = Intersection(ty, result)
            return result
        return Omega()

    def __getstate__(self) -> dict[str, Any]:
        state = self.__dict__.copy()
        del state["is_omega"]
        del state["size"]
        del state["organized"]
        return state

    def __setstate__(self, state: dict[str, Any]) -> None:
        self.__dict__.update(state)
        self.__dict__["is_omega"] = self._is_omega()
        self.__dict__["size"] = self._size()
        self.__dict__["organized"] = self._organized()

    def __pow__(self, other: Type) -> Type:
        return Arrow(self, other)

    def __and__(self, other: Type) -> Type:
        return Intersection(self, other)

    def __rmatmul__(self, name: str) -> Type:
        return Constructor(name, self)

free_vars: set[str] = field(init=True, kw_only=True, compare=False) class-attribute instance-attribute

is_omega: bool = field(init=True, kw_only=True, compare=False) class-attribute instance-attribute

organized: set[Type] = field(init=True, kw_only=True, compare=False) class-attribute instance-attribute

size: int = field(init=True, kw_only=True, compare=False) class-attribute instance-attribute

__and__(other: Type) -> Type

Source code in src/cosy/types.py
def __and__(self, other: Type) -> Type:
    return Intersection(self, other)

__getstate__() -> dict[str, Any]

Source code in src/cosy/types.py
def __getstate__(self) -> dict[str, Any]:
    state = self.__dict__.copy()
    del state["is_omega"]
    del state["size"]
    del state["organized"]
    return state

__init__(*, is_omega: bool, size: int, organized: set[Type], free_vars: set[str]) -> None

__pow__(other: Type) -> Type

Source code in src/cosy/types.py
def __pow__(self, other: Type) -> Type:
    return Arrow(self, other)

__rmatmul__(name: str) -> Type

Source code in src/cosy/types.py
def __rmatmul__(self, name: str) -> Type:
    return Constructor(name, self)

__setstate__(state: dict[str, Any]) -> None

Source code in src/cosy/types.py
def __setstate__(self, state: dict[str, Any]) -> None:
    self.__dict__.update(state)
    self.__dict__["is_omega"] = self._is_omega()
    self.__dict__["size"] = self._size()
    self.__dict__["organized"] = self._organized()

__str__() -> str abstractmethod

Source code in src/cosy/types.py
@abstractmethod
def __str__(self) -> str:
    pass

intersect(types: Sequence[Type]) -> Type staticmethod

Source code in src/cosy/types.py
@staticmethod
def intersect(types: Sequence[Type]) -> Type:
    if len(types) > 0:
        rtypes = reversed(types)
        result: Type = next(rtypes)
        for ty in rtypes:
            result = Intersection(ty, result)
        return result
    return Omega()

subst(groups: Mapping[str, str], substitution: dict[str, Any]) -> Type abstractmethod

Source code in src/cosy/types.py
@abstractmethod
def subst(self, groups: Mapping[str, str], substitution: dict[str, Any]) -> Type:
    pass

Var dataclass

Source code in src/cosy/types.py
@dataclass(frozen=True)
class Var(Type):
    name: str
    is_omega: bool = field(init=False, compare=False)
    size: int = field(init=False, compare=False)
    organized: set[Type] = field(init=False, compare=False)
    free_vars: set[str] = field(init=False, compare=False)

    def __post_init__(self) -> None:
        super().__init__(
            is_omega=self._is_omega(),
            size=self._size(),
            organized=self._organized(),
            free_vars=self._free_vars(),
        )

    def _is_omega(self) -> bool:
        return False

    def _size(self) -> int:
        return 1

    def _organized(self) -> set[Type]:
        return {self}

    def _free_vars(self) -> set[str]:
        return {self.name}

    def __str__(self) -> str:
        return f"<{self.name!s}>"

    def subst(self, groups: Mapping[str, str], substitution: dict[str, Any]) -> Type:
        if self.name in substitution:
            return Literal(substitution[self.name], groups[self.name])
        return self

free_vars: set[str] = field(init=False, compare=False) class-attribute instance-attribute

is_omega: bool = field(init=False, compare=False) class-attribute instance-attribute

name: str instance-attribute

organized: set[Type] = field(init=False, compare=False) class-attribute instance-attribute

size: int = field(init=False, compare=False) class-attribute instance-attribute

__init__(name: str, *, is_omega: bool, size: int, organized: set[Type], free_vars: set[str]) -> None

__post_init__() -> None

Source code in src/cosy/types.py
def __post_init__(self) -> None:
    super().__init__(
        is_omega=self._is_omega(),
        size=self._size(),
        organized=self._organized(),
        free_vars=self._free_vars(),
    )

__str__() -> str

Source code in src/cosy/types.py
def __str__(self) -> str:
    return f"<{self.name!s}>"

subst(groups: Mapping[str, str], substitution: dict[str, Any]) -> Type

Source code in src/cosy/types.py
def subst(self, groups: Mapping[str, str], substitution: dict[str, Any]) -> Type:
    if self.name in substitution:
        return Literal(substitution[self.name], groups[self.name])
    return self