lambda-calculus 3.0.0__py3-none-any.whl → 3.1.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,17 +1,8 @@
1
- #!/usr/bin/python3
2
-
3
1
  """Implementation of the Lambda calculus"""
4
2
 
5
- from .terms import Variable, Abstraction, Application
3
+ from ._version import version as __version__ # noqa: F401
4
+ from .terms import Abstraction, Application, Variable
6
5
 
7
- __version__ = "3.0.0"
8
- __author__ = "Eric Niklas Wolf"
9
- __email__ = "eric_niklas.wolf@mailbox.tu-dresden.de"
10
- __all__ = (
11
- "Variable",
12
- "Abstraction",
13
- "Application",
14
- "terms",
15
- "visitors",
16
- "errors"
17
- )
6
+ __author__ = "Eric Niklas Wolf"
7
+ __email__ = "eric_niklas.wolf@mailbox.tu-dresden.de"
8
+ __all__ = ("Abstraction", "Application", "Variable", "errors", "terms", "visitors")
@@ -0,0 +1,24 @@
1
+ # file generated by vcs-versioning
2
+ # don't change, don't track in version control
3
+ from __future__ import annotations
4
+
5
+ __all__ = [
6
+ "__version__",
7
+ "__version_tuple__",
8
+ "version",
9
+ "version_tuple",
10
+ "__commit_id__",
11
+ "commit_id",
12
+ ]
13
+
14
+ version: str
15
+ __version__: str
16
+ __version_tuple__: tuple[int | str, ...]
17
+ version_tuple: tuple[int | str, ...]
18
+ commit_id: str | None
19
+ __commit_id__: str | None
20
+
21
+ __version__ = version = '3.1.1'
22
+ __version_tuple__ = version_tuple = (3, 1, 1)
23
+
24
+ __commit_id__ = commit_id = None
lambda_calculus/errors.py CHANGED
@@ -1,14 +1,11 @@
1
- #!/usr/bin/python3
2
-
3
1
  """Errors raised by Term operations"""
4
2
 
5
3
  from __future__ import annotations
4
+
6
5
  from collections.abc import Collection
7
- from typing import TypeVar, Generic
6
+ from typing import Generic, TypeVar
8
7
 
9
- __all__ = (
10
- "CollisionError",
11
- )
8
+ __all__ = ("CollisionError",)
12
9
 
13
10
  V = TypeVar("V")
14
11
 
@@ -1,26 +1,27 @@
1
- #!/usr/bin/python3
2
-
3
1
  """Lambda Terms"""
4
2
 
5
3
  from __future__ import annotations
4
+
6
5
  from abc import abstractmethod
7
- from collections.abc import Sequence, Set, Iterable, Iterator
6
+ from collections.abc import Iterable, Iterator, Sequence
7
+ from collections.abc import Set as AbstractSet
8
8
  from dataclasses import dataclass
9
- from typing import TypeVar, final
10
- from .. import visitors
9
+ from typing import Self, TypeVar, final
10
+
11
11
  from ..errors import CollisionError
12
- from ..visitors import walking
12
+ from ..visitors import Visitor, walking
13
13
  from ..visitors.substitution import checked
14
14
 
15
15
  __all__ = (
16
- "Term",
17
- "Variable",
18
16
  "Abstraction",
19
17
  "Application",
18
+ "Term",
19
+ "Variable",
20
+ "abc",
20
21
  "arithmetic",
22
+ "combinators",
21
23
  "logic",
22
24
  "pairs",
23
- "combinators"
24
25
  )
25
26
 
26
27
  T = TypeVar("T")
@@ -51,25 +52,25 @@ class Term(Iterable["Term[V]"]):
51
52
 
52
53
  :return: lambda term string
53
54
  """
54
- raise NotImplementedError()
55
+ raise NotImplementedError
55
56
 
56
57
  @abstractmethod
57
- def free_variables(self) -> Set[V]:
58
+ def free_variables(self) -> AbstractSet[V]:
58
59
  """
59
60
  Calculate the free variables of this Term.
60
61
 
61
62
  :return: variables not bound by an abstraction
62
63
  """
63
- raise NotImplementedError()
64
+ raise NotImplementedError
64
65
 
65
66
  @abstractmethod
66
- def bound_variables(self) -> Set[V]:
67
+ def bound_variables(self) -> AbstractSet[V]:
67
68
  """
68
69
  Calculate the bound variables of this Term.
69
70
 
70
71
  :return: variables bound by an abstraction
71
72
  """
72
- raise NotImplementedError()
73
+ raise NotImplementedError
73
74
 
74
75
  @abstractmethod
75
76
  def is_beta_normal_form(self) -> bool:
@@ -78,17 +79,17 @@ class Term(Iterable["Term[V]"]):
78
79
 
79
80
  :return: if no beta reductions can be performed
80
81
  """
81
- raise NotImplementedError()
82
+ raise NotImplementedError
82
83
 
83
84
  @abstractmethod
84
- def accept(self, visitor: visitors.Visitor[T, V]) -> T:
85
+ def accept(self, visitor: Visitor[T, V]) -> T:
85
86
  """
86
87
  Accept a visitor by calling his corresponding method.
87
88
 
88
89
  :param visitor: Visitor to accept
89
90
  :return: value returned by the visitors corresponding method
90
91
  """
91
- raise NotImplementedError()
92
+ raise NotImplementedError
92
93
 
93
94
  def abstract(self, *variables: V) -> Abstraction[V]:
94
95
  """
@@ -140,7 +141,7 @@ class Variable(Term[V]):
140
141
  name: V
141
142
 
142
143
  @classmethod
143
- def with_valid_name(cls, name: V) -> Variable[V]:
144
+ def with_valid_name(cls, name: V) -> Self:
144
145
  """
145
146
  Create an instance with a valid name.
146
147
 
@@ -150,10 +151,12 @@ class Variable(Term[V]):
150
151
  """
151
152
  string = str(name)
152
153
  if not string:
153
- raise ValueError("empty string representation")
154
+ msg = "empty string representation"
155
+ raise ValueError(msg)
154
156
  for character in string:
155
157
  if character in "().λ" or character.isspace():
156
- raise ValueError(f"invalid character: '{character}'")
158
+ msg = f"invalid character: '{character}'"
159
+ raise ValueError(msg)
157
160
  return cls(name)
158
161
 
159
162
  def __str__(self) -> str:
@@ -164,7 +167,7 @@ class Variable(Term[V]):
164
167
  """
165
168
  return str(self.name)
166
169
 
167
- def free_variables(self) -> Set[V]:
170
+ def free_variables(self) -> AbstractSet[V]:
168
171
  """
169
172
  Calculate the free variables of this Term.
170
173
 
@@ -172,7 +175,7 @@ class Variable(Term[V]):
172
175
  """
173
176
  return {self.name}
174
177
 
175
- def bound_variables(self) -> Set[V]:
178
+ def bound_variables(self) -> AbstractSet[V]:
176
179
  """
177
180
  Calculate the bound variables of this Term.
178
181
 
@@ -188,7 +191,7 @@ class Variable(Term[V]):
188
191
  """
189
192
  return True
190
193
 
191
- def accept(self, visitor: visitors.Visitor[T, V]) -> T:
194
+ def accept(self, visitor: Visitor[T, V]) -> T:
192
195
  """
193
196
  Accept a visitor by calling visitors.Visitor.visit_variable.
194
197
 
@@ -213,7 +216,7 @@ class Abstraction(Term[V]):
213
216
  body: Term[V]
214
217
 
215
218
  @classmethod
216
- def curried(cls, variables: Sequence[V], body: Term[V]) -> Abstraction[V]:
219
+ def curried(cls, variables: Sequence[V], body: Term[V]) -> Self:
217
220
  """
218
221
  Create an Abstraction binding multiple variables.
219
222
 
@@ -229,7 +232,8 @@ class Abstraction(Term[V]):
229
232
  term = cls(variable, term)
230
233
  return term
231
234
  case _:
232
- raise ValueError("no variables to bind")
235
+ msg = "no variables to bind"
236
+ raise ValueError(msg)
233
237
 
234
238
  def __str__(self) -> str:
235
239
  """
@@ -239,7 +243,7 @@ class Abstraction(Term[V]):
239
243
  """
240
244
  return f"(λ{self.bound}.{self.body})"
241
245
 
242
- def free_variables(self) -> Set[V]:
246
+ def free_variables(self) -> AbstractSet[V]:
243
247
  """
244
248
  Calculate the free variables of this Term.
245
249
 
@@ -247,7 +251,7 @@ class Abstraction(Term[V]):
247
251
  """
248
252
  return self.body.free_variables() - {self.bound}
249
253
 
250
- def bound_variables(self) -> Set[V]:
254
+ def bound_variables(self) -> AbstractSet[V]:
251
255
  """
252
256
  Calculate the free variables of this Term.
253
257
 
@@ -273,14 +277,12 @@ class Abstraction(Term[V]):
273
277
  """
274
278
  if new == self.bound:
275
279
  return self
276
- elif new not in self.body.free_variables():
277
- return Abstraction(
278
- new,
279
- self.body.substitute(self.bound, Variable(new))
280
- )
281
- raise CollisionError("new variable would bind free variable in body", (new,))
280
+ if new not in self.body.free_variables():
281
+ return Abstraction(new, self.body.substitute(self.bound, Variable(new)))
282
+ msg = "new variable would bind free variable in body"
283
+ raise CollisionError(msg, (new,))
282
284
 
283
- def eta_reduction(self) -> Term[V]: # type: ignore[return]
285
+ def eta_reduction(self) -> Term[V]:
284
286
  """
285
287
  Remove a useless abstraction.
286
288
 
@@ -291,11 +293,10 @@ class Abstraction(Term[V]):
291
293
  case Application(f, Variable(x)) if x == self.bound and x not in f.free_variables():
292
294
  return f
293
295
  case _:
294
- # mypy detects missing returns
295
- # because of https://github.com/python/mypy/issues/12534
296
- raise ValueError("abstraction is not useless")
296
+ msg = "abstraction is not useless"
297
+ raise ValueError(msg)
297
298
 
298
- def accept(self, visitor: visitors.Visitor[T, V]) -> T:
299
+ def accept(self, visitor: Visitor[T, V]) -> T:
299
300
  """
300
301
  Accept a visitor by calling visitors.Visitor.visit_abstraction.
301
302
 
@@ -313,8 +314,7 @@ class Abstraction(Term[V]):
313
314
  :return: new term
314
315
  """
315
316
  return Abstraction(
316
- self.bound if bound is None else bound,
317
- self.body if body is None else body
317
+ self.bound if bound is None else bound, self.body if body is None else body
318
318
  )
319
319
 
320
320
 
@@ -333,7 +333,7 @@ class Application(Term[V]):
333
333
  argument: Term[V]
334
334
 
335
335
  @classmethod
336
- def with_arguments(cls, abstraction: Term[V], arguments: Sequence[Term[V]]) -> Application[V]:
336
+ def with_arguments(cls, abstraction: Term[V], arguments: Sequence[Term[V]]) -> Self:
337
337
  """
338
338
  Create an Application applying the abstraction to multiple arguments.
339
339
 
@@ -349,7 +349,8 @@ class Application(Term[V]):
349
349
  term = cls(term, argument)
350
350
  return term
351
351
  case _:
352
- raise ValueError("no arguments to apply abstraction to")
352
+ msg = "no arguments to apply abstraction to"
353
+ raise ValueError(msg)
353
354
 
354
355
  def __str__(self) -> str:
355
356
  """
@@ -359,7 +360,7 @@ class Application(Term[V]):
359
360
  """
360
361
  return f"({self.abstraction} {self.argument})"
361
362
 
362
- def free_variables(self) -> Set[V]:
363
+ def free_variables(self) -> AbstractSet[V]:
363
364
  """
364
365
  Calculate the free variables of this Term.
365
366
 
@@ -367,7 +368,7 @@ class Application(Term[V]):
367
368
  """
368
369
  return self.abstraction.free_variables() | self.argument.free_variables()
369
370
 
370
- def bound_variables(self) -> Set[V]:
371
+ def bound_variables(self) -> AbstractSet[V]:
371
372
  """
372
373
  Calculate the free variables of this Term.
373
374
 
@@ -389,9 +390,11 @@ class Application(Term[V]):
389
390
 
390
391
  :return: if no beta reductions can be performed
391
392
  """
392
- return not self.is_redex() \
393
- and self.abstraction.is_beta_normal_form() \
393
+ return (
394
+ not self.is_redex()
395
+ and self.abstraction.is_beta_normal_form()
394
396
  and self.argument.is_beta_normal_form()
397
+ )
395
398
 
396
399
  def beta_reduction(self) -> Term[V]:
397
400
  """
@@ -404,9 +407,10 @@ class Application(Term[V]):
404
407
  case Abstraction(bound, body):
405
408
  return body.substitute(bound, self.argument)
406
409
  case _:
407
- raise ValueError("can not perform reduction without known Abstraction")
410
+ msg = "can not perform reduction without known Abstraction"
411
+ raise ValueError(msg)
408
412
 
409
- def accept(self, visitor: visitors.Visitor[T, V]) -> T:
413
+ def accept(self, visitor: Visitor[T, V]) -> T:
410
414
  """
411
415
  Accept a visitor by calling visitors.Visitor.visit_application.
412
416
 
@@ -415,7 +419,9 @@ class Application(Term[V]):
415
419
  """
416
420
  return visitor.visit_application(self)
417
421
 
418
- def replace(self, *, abstraction: Term[V] | None = None, argument: Term[V] | None = None) -> Application[V]:
422
+ def replace(
423
+ self, *, abstraction: Term[V] | None = None, argument: Term[V] | None = None
424
+ ) -> Application[V]:
419
425
  """
420
426
  Return a copy with specific attributes replaced.
421
427
 
@@ -425,5 +431,5 @@ class Application(Term[V]):
425
431
  """
426
432
  return Application(
427
433
  self.abstraction if abstraction is None else abstraction,
428
- self.argument if argument is None else argument
434
+ self.argument if argument is None else argument,
429
435
  )
@@ -0,0 +1,17 @@
1
+ """Predefined Variables for all ASCII letters"""
2
+
3
+ from string import ascii_letters
4
+
5
+ from . import Variable
6
+
7
+ __all__ = tuple(ascii_letters)
8
+
9
+ # better IDE autocompletion
10
+ # ruff: noqa: E741
11
+ a, b, c, d, e, f, g, h, i, j = map(Variable, "abcdefghij")
12
+ k, l, m, n, o, p, q, r, s, t = map(Variable, "klmnopqrst")
13
+ u, v, w, x, y, z = map(Variable, "uvwxyz")
14
+
15
+ A, B, C, D, E, F, G, H, I, J = map(Variable, "ABCDEFGHIJ")
16
+ K, L, M, N, O, P, Q, R, S, T = map(Variable, "KLMNOPQRST")
17
+ U, V, W, X, Y, Z = map(Variable, "UVWXYZ")
@@ -1,21 +1,11 @@
1
- #!/usr/bin/python3
2
-
3
1
  """Implementations of natural numbers and arithmetic operators"""
4
2
 
5
3
  from typing import Final
6
- from . import Term, Variable, Abstraction, Application
7
- from .logic import TRUE, FALSE
8
4
 
9
- __all__ = (
10
- "ISZERO",
11
- "SUCCESSOR",
12
- "PREDECESSOR",
13
- "ADD",
14
- "SUBTRACT",
15
- "MULTIPLY",
16
- "POWER",
17
- "number"
18
- )
5
+ from . import Abstraction, Application, Term, Variable
6
+ from .logic import FALSE, TRUE
7
+
8
+ __all__ = ("ADD", "ISZERO", "MULTIPLY", "POWER", "PREDECESSOR", "SUBTRACT", "SUCCESSOR", "number")
19
9
 
20
10
  ISZERO: Final = Variable("n").apply_to(FALSE.abstract("x"), TRUE).abstract("n")
21
11
  """
@@ -26,12 +16,8 @@ if its argument is zero, :const:`lambda_calculus.terms.logic.FALSE` otherwise
26
16
  SUCCESSOR: Final = Abstraction.curried(
27
17
  ("n", "f", "x"),
28
18
  Application(
29
- Variable("f"),
30
- Application.with_arguments(
31
- Variable("n"),
32
- (Variable("f"), Variable("x"))
33
- )
34
- )
19
+ Variable("f"), Application.with_arguments(Variable("n"), (Variable("f"), Variable("x")))
20
+ ),
35
21
  )
36
22
  """
37
23
  Term evaluating to its argument incremented by one.
@@ -43,19 +29,12 @@ PREDECESSOR: Final = Abstraction.curried(
43
29
  Variable("n"),
44
30
  (
45
31
  Abstraction.curried(
46
- ("g", "h"),
47
- Application(
48
- Variable("h"),
49
- Application(
50
- Variable("g"),
51
- Variable("f")
52
- )
53
- )
32
+ ("g", "h"), Application(Variable("h"), Application(Variable("g"), Variable("f")))
54
33
  ),
55
34
  Abstraction("u", Variable("x")),
56
35
  Abstraction("u", Variable("u")),
57
- )
58
- )
36
+ ),
37
+ ),
59
38
  )
60
39
  """
61
40
  Term ealuating to its argument decremented by one.
@@ -65,51 +44,28 @@ ADD: Final = Abstraction.curried(
65
44
  ("m", "n", "f", "x"),
66
45
  Application.with_arguments(
67
46
  Variable("m"),
68
- (
69
- Variable("f"),
70
- Application.with_arguments(
71
- Variable("n"),
72
- (Variable("f"), Variable("x"))
73
- )
74
- )
75
- )
47
+ (Variable("f"), Application.with_arguments(Variable("n"), (Variable("f"), Variable("x")))),
48
+ ),
76
49
  )
77
50
  """
78
51
  Term evaluating to the sum of its two arguments.
79
52
  """
80
53
 
81
54
  SUBTRACT: Final = Abstraction.curried(
82
- ("m", "n"),
83
- Application.with_arguments(
84
- Variable("n"),
85
- (PREDECESSOR, Variable("m"))
86
- )
55
+ ("m", "n"), Application.with_arguments(Variable("n"), (PREDECESSOR, Variable("m")))
87
56
  )
88
57
  """
89
58
  Term evaluating to the difference of its two arguments.
90
59
  """
91
60
 
92
61
  MULTIPLY: Final = Abstraction.curried(
93
- ("m", "n", "f"),
94
- Application(
95
- Variable("m"),
96
- Application(
97
- Variable("n"),
98
- Variable("f")
99
- )
100
- )
62
+ ("m", "n", "f"), Application(Variable("m"), Application(Variable("n"), Variable("f")))
101
63
  )
102
64
  """
103
65
  Term evaluating to the product of its two arguments.
104
66
  """
105
67
 
106
- POWER: Final = Abstraction.curried(
107
- ("b", "e"),
108
- Application(
109
- Variable("e"),
110
- Variable("b")
111
- )
112
- )
68
+ POWER: Final = Abstraction.curried(("b", "e"), Application(Variable("e"), Variable("b")))
113
69
  """
114
70
  Term evaluating to its first argument to the power of its second argument.
115
71
  """
@@ -124,12 +80,10 @@ def number(n: int) -> Abstraction[str]:
124
80
  :return: requested term
125
81
  """
126
82
  if n < 0:
127
- raise ValueError("number is not natural")
83
+ msg = "number is not natural"
84
+ raise ValueError(msg)
128
85
  f = Variable("f")
129
86
  body: Term[str] = Variable("x")
130
87
  for _ in range(n):
131
88
  body = Application(f, body)
132
- return Abstraction.curried(
133
- ("f", "x"),
134
- body
135
- )
89
+ return Abstraction.curried(("f", "x"), body)
@@ -1,38 +1,24 @@
1
- #!/usr/bin/python3
2
-
3
1
  """Common combinators"""
4
2
 
5
3
  from typing import Final
6
- from . import Variable, Application
7
4
 
8
- __all__ = (
9
- "Y",
10
- "S",
11
- "K",
12
- "I",
13
- "B",
14
- "C",
15
- "W",
16
- "DELTA",
17
- "OMEGA"
18
- )
5
+ from . import Application, Variable
6
+
7
+ __all__ = ("DELTA", "OMEGA", "B", "C", "I", "K", "S", "W", "Y")
19
8
 
20
9
  Y: Final = Application(
21
- Variable("g").apply_to(
22
- Variable("x").apply_to(Variable("x"))
23
- ).abstract("x"),
24
- Variable("g").apply_to(
25
- Variable("x").apply_to(Variable("x"))
26
- ).abstract("x")
10
+ Variable("g").apply_to(Variable("x").apply_to(Variable("x"))).abstract("x"),
11
+ Variable("g").apply_to(Variable("x").apply_to(Variable("x"))).abstract("x"),
27
12
  ).abstract("g")
28
13
  """
29
14
  Y combinator used to define recursive terms.
30
15
  """
31
16
 
32
- S: Final = Variable("x").apply_to(
33
- Variable("z"),
34
- Variable("y").apply_to(Variable("z"))
35
- ).abstract("x", "y", "z")
17
+ S: Final = (
18
+ Variable("x")
19
+ .apply_to(Variable("z"), Variable("y").apply_to(Variable("z")))
20
+ .abstract("x", "y", "z")
21
+ )
36
22
  """
37
23
  S combinator of the SKI combinator calculus.
38
24
  """
@@ -42,37 +28,27 @@ K: Final = Variable("x").abstract("x", "y")
42
28
  K combinator of the SKI combinator calculus.
43
29
  """
44
30
 
45
- I: Final = Variable("x").abstract("x")
31
+ I: Final = Variable("x").abstract("x") # noqa: E741
46
32
  """
47
33
  I combinator of the SKI combinator calculus.
48
34
  """
49
35
 
50
- B: Final = Variable("x").apply_to(
51
- Variable("y").apply_to(Variable("z"))
52
- ).abstract("x", "y", "z")
36
+ B: Final = Variable("x").apply_to(Variable("y").apply_to(Variable("z"))).abstract("x", "y", "z")
53
37
  """
54
38
  B combinator of the BCKW combinator calculus.
55
39
  """
56
40
 
57
- C: Final = Variable("x").apply_to(
58
- Variable("z"),
59
- Variable("y")
60
- ).abstract("x", "y", "z")
41
+ C: Final = Variable("x").apply_to(Variable("z"), Variable("y")).abstract("x", "y", "z")
61
42
  """
62
43
  C combinator of the BCKW combinator calculus.
63
44
  """
64
45
 
65
- W: Final = Variable("x").apply_to(
66
- Variable("y"),
67
- Variable("y")
68
- ).abstract("x", "y")
46
+ W: Final = Variable("x").apply_to(Variable("y"), Variable("y")).abstract("x", "y")
69
47
  """
70
48
  W combinator of the BCKW combinator calculus.
71
49
  """
72
50
 
73
- DELTA: Final = Variable("x").apply_to(
74
- Variable("x")
75
- ).abstract("x")
51
+ DELTA: Final = Variable("x").apply_to(Variable("x")).abstract("x")
76
52
  """
77
53
  Term applying its argument to itself.
78
54
  """
@@ -1,18 +1,10 @@
1
- #!/usr/bin/python3
2
-
3
1
  """Implementations of boolean values and logical operators"""
4
2
 
5
3
  from typing import Final
6
- from . import Variable, Abstraction, Application
7
-
8
- __all__ = (
9
- "TRUE",
10
- "FALSE",
11
- "AND",
12
- "OR",
13
- "NOT",
14
- "IF_THEN_ELSE"
15
- )
4
+
5
+ from . import Abstraction, Application, Variable
6
+
7
+ __all__ = ("AND", "FALSE", "IF_THEN_ELSE", "NOT", "OR", "TRUE")
16
8
 
17
9
  TRUE: Final = Abstraction.curried(("x", "y"), Variable("x"))
18
10
  """
@@ -25,16 +17,14 @@ Term representing False
25
17
  """
26
18
 
27
19
  AND: Final = Abstraction.curried(
28
- ("p", "q"),
29
- Application.with_arguments(Variable("p"), (Variable("q"), Variable("p")))
20
+ ("p", "q"), Application.with_arguments(Variable("p"), (Variable("q"), Variable("p")))
30
21
  )
31
22
  """
32
23
  Term implementing logical conjunction between its two arguments.
33
24
  """
34
25
 
35
26
  OR: Final = Abstraction.curried(
36
- ("p", "q"),
37
- Application.with_arguments(Variable("p"), (Variable("p"), Variable("q")))
27
+ ("p", "q"), Application.with_arguments(Variable("p"), (Variable("p"), Variable("q")))
38
28
  )
39
29
  """
40
30
  Term implementing logical disjunction between its two arguments.
@@ -46,8 +36,7 @@ Term performing logical negation of its argument.
46
36
  """
47
37
 
48
38
  IF_THEN_ELSE: Final = Abstraction.curried(
49
- ("p", "a", "b"),
50
- Application.with_arguments(Variable("p"), (Variable("a"), Variable("b")))
39
+ ("p", "a", "b"), Application.with_arguments(Variable("p"), (Variable("a"), Variable("b")))
51
40
  )
52
41
  """
53
42
  Term evaluating to its second argument if its first argument is TRUE