Skip to content

Commit 8d6776a

Browse files
committed
add logic lambda terms
1 parent e7d64b2 commit 8d6776a

File tree

5 files changed

+116
-3
lines changed

5 files changed

+116
-3
lines changed

lambda_calculus/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
from .terms import Variable, Abstraction, Application
66

7-
__version__ = "1.8.0"
7+
__version__ = "1.9.0"
88
__author__ = "Eric Niklas Wolf"
99
__email__ = "[email protected]"
1010
__all__ = (

lambda_calculus/terms/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
"Variable",
1717
"Abstraction",
1818
"Application",
19-
"arithmetic"
19+
"arithmetic",
20+
"logic"
2021
)
2122

2223
T = TypeVar("T")

lambda_calculus/terms/logic.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#!/usr/bin/python3
2+
3+
"""Implementations of boolean values and logical operators"""
4+
5+
from . import Variable, Abstraction, Application
6+
7+
__all__ = (
8+
"TRUE",
9+
"FALSE",
10+
"AND",
11+
"OR",
12+
"NOT",
13+
"IF_THEN_ELSE"
14+
)
15+
16+
TRUE = Abstraction.curried(("x", "y"), Variable("x"))
17+
FALSE = Abstraction.curried(("x", "y"), Variable("y"))
18+
19+
AND = Abstraction.curried(
20+
("p", "q"),
21+
Application.with_arguments(Variable("p"), (Variable("q"), Variable("p")))
22+
)
23+
OR = Abstraction.curried(
24+
("p", "q"),
25+
Application.with_arguments(Variable("p"), (Variable("p"), Variable("q")))
26+
)
27+
NOT = Abstraction("p", Application.with_arguments(Variable("p"), (FALSE, TRUE)))
28+
29+
IF_THEN_ELSE = Abstraction.curried(
30+
("p", "a", "b"),
31+
Application.with_arguments(Variable("p"), (Variable("a"), Variable("b")))
32+
)

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "lambda_calculus"
3-
version = "1.8.0"
3+
version = "1.9.0"
44
description = "Implementation of the Lambda calculus"
55
requires-python = ">=3.10"
66
keywords = []

tests/terms/test_logic.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#!/usr/bin/python3
2+
3+
"""Tests for logic terms"""
4+
5+
from unittest import TestCase
6+
from collections.abc import Iterable, Iterator
7+
from lambda_calculus.visitors.normalisation import BetaNormalisingVisitor
8+
from lambda_calculus.terms import Term, Variable, Application, logic
9+
10+
11+
class LogicTest(TestCase):
12+
"""Test for logic terms"""
13+
14+
visitor: BetaNormalisingVisitor
15+
16+
def setUp(self) -> None:
17+
"""create a visitor"""
18+
self.visitor = BetaNormalisingVisitor()
19+
20+
def make_truth_table(self, outputs: Iterable[Term[str]]) -> Iterator[tuple[tuple[Term[str], Term[str]], Term[str]]]:
21+
"""make a truth table with two inputs"""
22+
inputs = (
23+
(logic.FALSE, logic.FALSE),
24+
(logic.TRUE, logic.FALSE),
25+
(logic.FALSE, logic.TRUE),
26+
(logic.TRUE, logic.TRUE)
27+
)
28+
return zip(inputs, outputs)
29+
30+
def test_and(self) -> None:
31+
"""test logical and"""
32+
for (a, b), c in self.make_truth_table((logic.FALSE,) * 3 + (logic.TRUE,)):
33+
self.assertEqual(
34+
self.visitor.skip_intermediate(
35+
Application.with_arguments(logic.AND, (a, b))
36+
),
37+
c
38+
)
39+
40+
def test_or(self) -> None:
41+
"""test logical or"""
42+
for (a, b), c in self.make_truth_table((logic.FALSE,) + (logic.TRUE,) * 3):
43+
self.assertEqual(
44+
self.visitor.skip_intermediate(
45+
Application.with_arguments(logic.OR, (a, b))
46+
),
47+
c
48+
)
49+
50+
def test_not(self) -> None:
51+
"""test logical negation"""
52+
self.assertEqual(
53+
self.visitor.skip_intermediate(Application(logic.NOT, logic.TRUE)),
54+
logic.FALSE
55+
)
56+
self.assertEqual(
57+
self.visitor.skip_intermediate(Application(logic.NOT, logic.FALSE)),
58+
logic.TRUE
59+
)
60+
61+
def test_if_then_else(self) -> None:
62+
"""test if statement"""
63+
self.assertEqual(
64+
self.visitor.skip_intermediate(
65+
Application.with_arguments(
66+
logic.IF_THEN_ELSE,
67+
(logic.TRUE, Variable("a"), Variable("b"))
68+
)
69+
),
70+
Variable("a")
71+
)
72+
self.assertEqual(
73+
self.visitor.skip_intermediate(
74+
Application.with_arguments(
75+
logic.IF_THEN_ELSE,
76+
(logic.FALSE, Variable("a"), Variable("b"))
77+
)
78+
),
79+
Variable("b")
80+
)

0 commit comments

Comments
 (0)