Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mark multiple things as final #3

Merged
merged 5 commits into from
Oct 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lambda_calculus/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from .terms import Variable, Abstraction, Application

__version__ = "2.2.3"
__version__ = "3.0.0"
__author__ = "Eric Niklas Wolf"
__email__ = "eric_niklas.wolf@mailbox.tu-dresden.de"
__all__ = (
Expand Down
5 changes: 4 additions & 1 deletion lambda_calculus/terms/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from abc import abstractmethod
from collections.abc import Sequence, Set, Iterable, Iterator
from dataclasses import dataclass
from typing import TypeVar
from typing import TypeVar, final
from .. import visitors
from ..errors import CollisionError
from ..visitors import walking
Expand Down Expand Up @@ -128,6 +128,7 @@ def is_combinator(self) -> bool:
return not self.free_variables()


@final
@dataclass(unsafe_hash=True, slots=True)
class Variable(Term[V]):
"""
Expand Down Expand Up @@ -197,6 +198,7 @@ def accept(self, visitor: visitors.Visitor[T, V]) -> T:
return visitor.visit_variable(self)


@final
@dataclass(unsafe_hash=True, slots=True)
class Abstraction(Term[V]):
"""
Expand Down Expand Up @@ -316,6 +318,7 @@ def replace(self, *, bound: V | None = None, body: Term[V] | None = None) -> Abs
)


@final
@dataclass(unsafe_hash=True, slots=True)
class Application(Term[V]):
"""
Expand Down
15 changes: 8 additions & 7 deletions lambda_calculus/terms/arithmetic.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

"""Implementations of natural numbers and arithmetic operators"""

from typing import Final
from . import Term, Variable, Abstraction, Application
from .logic import TRUE, FALSE

Expand All @@ -16,13 +17,13 @@
"number"
)

ISZERO = Variable("n").apply_to(FALSE.abstract("x"), TRUE).abstract("n")
ISZERO: Final = Variable("n").apply_to(FALSE.abstract("x"), TRUE).abstract("n")
"""
Term which evaluates to :const:`lambda_calculus.terms.logic.TRUE`
if its argument is zero, :const:`lambda_calculus.terms.logic.FALSE` otherwise
"""

SUCCESSOR = Abstraction.curried(
SUCCESSOR: Final = Abstraction.curried(
("n", "f", "x"),
Application(
Variable("f"),
Expand All @@ -36,7 +37,7 @@
Term evaluating to its argument incremented by one.
"""

PREDECESSOR = Abstraction.curried(
PREDECESSOR: Final = Abstraction.curried(
("n", "f", "x"),
Application.with_arguments(
Variable("n"),
Expand All @@ -60,7 +61,7 @@
Term ealuating to its argument decremented by one.
"""

ADD = Abstraction.curried(
ADD: Final = Abstraction.curried(
("m", "n", "f", "x"),
Application.with_arguments(
Variable("m"),
Expand All @@ -77,7 +78,7 @@
Term evaluating to the sum of its two arguments.
"""

SUBTRACT = Abstraction.curried(
SUBTRACT: Final = Abstraction.curried(
("m", "n"),
Application.with_arguments(
Variable("n"),
Expand All @@ -88,7 +89,7 @@
Term evaluating to the difference of its two arguments.
"""

MULTIPLY = Abstraction.curried(
MULTIPLY: Final = Abstraction.curried(
("m", "n", "f"),
Application(
Variable("m"),
Expand All @@ -102,7 +103,7 @@
Term evaluating to the product of its two arguments.
"""

POWER = Abstraction.curried(
POWER: Final = Abstraction.curried(
("b", "e"),
Application(
Variable("e"),
Expand Down
19 changes: 10 additions & 9 deletions lambda_calculus/terms/combinators.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

"""Common combinators"""

from typing import Final
from . import Variable, Application

__all__ = (
Expand All @@ -16,7 +17,7 @@
"OMEGA"
)

Y = Application(
Y: Final = Application(
Variable("g").apply_to(
Variable("x").apply_to(Variable("x"))
).abstract("x"),
Expand All @@ -28,55 +29,55 @@
Y combinator used to define recursive terms.
"""

S = Variable("x").apply_to(
S: Final = Variable("x").apply_to(
Variable("z"),
Variable("y").apply_to(Variable("z"))
).abstract("x", "y", "z")
"""
S combinator of the SKI combinator calculus.
"""

K = Variable("x").abstract("x", "y")
K: Final = Variable("x").abstract("x", "y")
"""
K combinator of the SKI combinator calculus.
"""

I = Variable("x").abstract("x")
I: Final = Variable("x").abstract("x")
"""
I combinator of the SKI combinator calculus.
"""

B = Variable("x").apply_to(
B: Final = Variable("x").apply_to(
Variable("y").apply_to(Variable("z"))
).abstract("x", "y", "z")
"""
B combinator of the BCKW combinator calculus.
"""

C = Variable("x").apply_to(
C: Final = Variable("x").apply_to(
Variable("z"),
Variable("y")
).abstract("x", "y", "z")
"""
C combinator of the BCKW combinator calculus.
"""

W = Variable("x").apply_to(
W: Final = Variable("x").apply_to(
Variable("y"),
Variable("y")
).abstract("x", "y")
"""
W combinator of the BCKW combinator calculus.
"""

DELTA = Variable("x").apply_to(
DELTA: Final = Variable("x").apply_to(
Variable("x")
).abstract("x")
"""
Term applying its argument to itself.
"""

OMEGA = DELTA.apply_to(DELTA)
OMEGA: Final = DELTA.apply_to(DELTA)
"""
Smallest term with no beta normal form.
"""
13 changes: 7 additions & 6 deletions lambda_calculus/terms/logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

"""Implementations of boolean values and logical operators"""

from typing import Final
from . import Variable, Abstraction, Application

__all__ = (
Expand All @@ -13,38 +14,38 @@
"IF_THEN_ELSE"
)

TRUE = Abstraction.curried(("x", "y"), Variable("x"))
TRUE: Final = Abstraction.curried(("x", "y"), Variable("x"))
"""
Term representing True.
"""

FALSE = Abstraction.curried(("x", "y"), Variable("y"))
FALSE: Final = Abstraction.curried(("x", "y"), Variable("y"))
"""
Term representing False
"""

AND = Abstraction.curried(
AND: Final = Abstraction.curried(
("p", "q"),
Application.with_arguments(Variable("p"), (Variable("q"), Variable("p")))
)
"""
Term implementing logical conjunction between its two arguments.
"""

OR = Abstraction.curried(
OR: Final = Abstraction.curried(
("p", "q"),
Application.with_arguments(Variable("p"), (Variable("p"), Variable("q")))
)
"""
Term implementing logical disjunction between its two arguments.
"""

NOT = Abstraction("p", Application.with_arguments(Variable("p"), (FALSE, TRUE)))
NOT: Final = Abstraction("p", Application.with_arguments(Variable("p"), (FALSE, TRUE)))
"""
Term performing logical negation of its argument.
"""

IF_THEN_ELSE = Abstraction.curried(
IF_THEN_ELSE: Final = Abstraction.curried(
("p", "a", "b"),
Application.with_arguments(Variable("p"), (Variable("a"), Variable("b")))
)
Expand Down
11 changes: 6 additions & 5 deletions lambda_calculus/terms/pairs.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

"""Implementation of pairs"""

from typing import Final
from . import Variable, Abstraction, Application
from .logic import TRUE, FALSE

Expand All @@ -13,7 +14,7 @@
"NULL"
)

PAIR = Abstraction.curried(
PAIR: Final = Abstraction.curried(
("x", "y", "f"),
Application.with_arguments(
Variable("f"),
Expand All @@ -24,22 +25,22 @@
Term evaluating to a ordered pair of its two arguments.
"""

FIRST = Abstraction("p", Application(Variable("p"), TRUE))
FIRST: Final = Abstraction("p", Application(Variable("p"), TRUE))
"""
Term evaluating to the first value in its argument.
"""

SECOND = Abstraction("p", Application(Variable("p"), FALSE))
SECOND: Final = Abstraction("p", Application(Variable("p"), FALSE))
"""
Term evaluating to the second value in its argument.
"""

NIL = Abstraction("x", TRUE)
NIL: Final = Abstraction("x", TRUE)
"""
Special Term encoding an empty pair.
"""

NULL = Abstraction(
NULL: Final = Abstraction(
"p",
Application(
Variable("p"),
Expand Down
11 changes: 3 additions & 8 deletions lambda_calculus/visitors/substitution/unsafe.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
"""Substitutions which dont check if the substitutions are valid"""

from __future__ import annotations
from collections.abc import Set
from typing import TypeVar, final
from ... import terms
from . import DeferrableSubstitution
Expand All @@ -28,18 +27,14 @@ class UnsafeSubstitution(DeferrableSubstitution[V]):

value: terms.Term[V]

free_variables: Set[V]

__slots__ = (
"variable",
"value",
"free_variables"
"value"
)

def __init__(self, variable: V, value: terms.Term[V], free_variables: Set[V]) -> None:
def __init__(self, variable: V, value: terms.Term[V]) -> None:
self.variable = variable
self.value = value
self.free_variables = free_variables

@classmethod
def from_substitution(cls, variable: V, value: terms.Term[V]) -> UnsafeSubstitution[V]:
Expand All @@ -50,7 +45,7 @@ def from_substitution(cls, variable: V, value: terms.Term[V]) -> UnsafeSubstitut
:param value: value which should be substituted
:return: new instance
"""
return cls(variable, value, value.free_variables())
return cls(variable, value)

def visit_variable(self, variable: terms.Variable[V]) -> terms.Term[V]:
"""
Expand Down
5 changes: 4 additions & 1 deletion lambda_calculus/visitors/walking.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from __future__ import annotations
from collections.abc import Iterator
from typing import TypeVar
from typing import TypeVar, final
from .. import terms
from . import BottomUpVisitor

Expand All @@ -15,6 +15,7 @@
V = TypeVar("V")


@final
class DepthFirstVisitor(BottomUpVisitor[Iterator["terms.Term[V]"], V]):
"""
Visitor yielding subterms depth first
Expand All @@ -24,6 +25,8 @@ class DepthFirstVisitor(BottomUpVisitor[Iterator["terms.Term[V]"], V]):
V: represents the type of variables used in terms
"""

__slots__ = ()

def visit_variable(self, variable: terms.Variable[V]) -> Iterator[terms.Term[V]]:
"""
Visit a Variable term.
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "lambda_calculus"
version = "2.2.3"
version = "3.0.0"
description = "Implementation of the Lambda calculus"
requires-python = ">=3.10"
keywords = []
Expand Down