Source code for fosf.syntax.base
#!/usr/bin/env python3
from __future__ import annotations
from typing import ClassVar
[docs]
class Tag(str):
"""Represents a Tag symbol."""
def __repr__(self):
return f"Tag({super().__repr__()})"
def __hash__(self) -> int:
return hash(("Tag", super().__hash__()))
def __eq__(self, other: Tag) -> bool:
return isinstance(other, Tag) and super().__eq__(other)
[docs]
class Feature(str):
"""Represents a Feature symbol."""
def __repr__(self):
return f"Feature({super().__repr__()})"
def __hash__(self) -> int:
return hash(("Feature", super().__hash__()))
def __eq__(self, other: Feature) -> bool:
return isinstance(other, Feature) and super().__eq__(other)
[docs]
class Sort:
def __init__(self, value: str | Sort):
if isinstance(value, Sort) and not isinstance(value, (DisjunctiveSort, FrozenDisjunctiveSort)):
value = value.value
elif not isinstance(value, str):
raise TypeError(
f"Sort must be initialized with a str or Sort, got {type(value).__name__}")
self.value: str = value
def __str__(self):
return self.value
def __repr__(self):
return f"Sort({self.value!r})"
def __hash__(self):
return hash(("Sort", self.value))
def __eq__(self, other):
return isinstance(other, Sort) and self.value == other.value
def __lt__(self, other):
return self.value < other.value
[docs]
class DisjunctiveSort(Sort):
__hash__: ClassVar[None] = None
def __init__(self, *sorts: str | Sort):
self.value: set[Sort] = set()
self.add(*sorts)
[docs]
def add(self, *sorts: str | Sort):
for sort in sorts:
if isinstance(sort, Sort):
self.value.add(sort)
else:
# TODO: check other types, e.g. str
self.value.add(Sort(sort))
[docs]
def freeze(self) -> FrozenDisjunctiveSort:
return FrozenDisjunctiveSort(*self.value)
def __str__(self):
return f'{{ {", ".join(sorted(str(s) for s in self.value))} }}'
def __repr__(self):
return f"DisjunctiveSort({', '.join(sorted(repr(s) for s in self.value))})"
def __eq__(self, other):
return isinstance(other, DisjunctiveSort) and self.value == other.value
def __iter__(self):
return iter(self.value)
def __len__(self):
return len(self.value)
[docs]
class FrozenDisjunctiveSort(Sort):
def __init__(self, *sorts: str | Sort):
self.value: frozenset[Sort] = frozenset(Sort(sort) for sort in sorts)
self._hash: int | None = None
[docs]
def thaw(self) -> DisjunctiveSort:
"Convert to a mutable DisjunctiveSort."
return DisjunctiveSort(*self.value)
def __str__(self):
return f'{{ {", ".join(sorted(str(s) for s in self.value))} }}'
def __repr__(self):
return f"FrozenDisjunctiveSort({', '.join(sorted(repr(s) for s in self.value))})"
def __hash__(self):
if self._hash is None:
self._hash = hash(("DisjunctiveSort", self.value))
return self._hash
def __eq__(self, other):
return isinstance(other, FrozenDisjunctiveSort) and self.value == other.value
def __iter__(self):
return iter(self.value)
def __len__(self):
return len(self.value)