Skip to content

Commit

Permalink
Merge pull request #3 from Deric-W/cleanup
Browse files Browse the repository at this point in the history
mark multiple things as final
  • Loading branch information
Deric-W authored Oct 4, 2022
2 parents 44cec67 + d587e33 commit e76764e
Show file tree
Hide file tree
Showing 9 changed files with 44 additions and 39 deletions.
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

0 comments on commit e76764e

Please sign in to comment.