Create contains, eq and replace operations
parent
dcad494c7d
commit
66beff5792
|
|
@ -4,7 +4,7 @@
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
from typing import Callable
|
from typing import Callable, Generator
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
|
|
||||||
|
|
@ -24,6 +24,24 @@ USABLE_VAR_NAMES = [
|
||||||
'μ', 'ν', 'ξ', 'ο', 'π', 'ρ', 'σ', 'τ', 'υ', 'φ', 'χ', 'ψ', 'ω'
|
'μ', 'ν', 'ξ', 'ο', 'π', 'ρ', 'σ', 'τ', 'υ', 'φ', 'χ', 'ψ', 'ω'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
def contains(haystack : Term, needle : Term) -> bool:
|
||||||
|
"""
|
||||||
|
Determine whether a given small term value is contained in a bigger
|
||||||
|
term.
|
||||||
|
|
||||||
|
:param haystack: The term to search through.
|
||||||
|
:type haystack: Term
|
||||||
|
:param needle: The term to find.
|
||||||
|
:type needle: Term
|
||||||
|
:return: Whether the needle was found in the haystack.
|
||||||
|
:rtype: bool
|
||||||
|
"""
|
||||||
|
for term in haystack.rec_iter():
|
||||||
|
if term == needle:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
def normalize(term : Term) -> Term:
|
def normalize(term : Term) -> Term:
|
||||||
"""
|
"""
|
||||||
Create a normalization function. This function simplifies functions as
|
Create a normalization function. This function simplifies functions as
|
||||||
|
|
@ -78,6 +96,21 @@ def std_norm_iter(term : Term) -> Term:
|
||||||
return term
|
return term
|
||||||
_known_norms.append(std_norm_iter)
|
_known_norms.append(std_norm_iter)
|
||||||
|
|
||||||
|
def replace(term : Term, old : Term, new : Term) -> Term:
|
||||||
|
"""
|
||||||
|
Find and replace occurrences of a sub-term in a given term.
|
||||||
|
|
||||||
|
:param term: The original term to update.
|
||||||
|
:type term: Term
|
||||||
|
:param old: The term to find and replace.
|
||||||
|
:type old: Term
|
||||||
|
:param new: The new term to replace the old one with.
|
||||||
|
:type new: Term
|
||||||
|
:return: The replaced term result.
|
||||||
|
:rtype: Term
|
||||||
|
"""
|
||||||
|
return traverse_bottom_up(f=lambda t : new if t == old else t, term=term)
|
||||||
|
|
||||||
def traverse(f : Callable[[Term], Term], term : Term) -> Term:
|
def traverse(f : Callable[[Term], Term], term : Term) -> Term:
|
||||||
"""
|
"""
|
||||||
Traverse through the tree back-and-forth, aiming to run the given
|
Traverse through the tree back-and-forth, aiming to run the given
|
||||||
|
|
@ -96,7 +129,7 @@ def traverse(f : Callable[[Term], Term], term : Term) -> Term:
|
||||||
a, b = Term(), term
|
a, b = Term(), term
|
||||||
|
|
||||||
while a != b:
|
while a != b:
|
||||||
a, b = b, traverse_bottom_up(f=f, term=traverse_top_down(f=f, term=term))
|
a, b = b, traverse_bottom_up(f=f, term=traverse_top_down(f=f, term=b))
|
||||||
|
|
||||||
return b
|
return b
|
||||||
|
|
||||||
|
|
@ -171,12 +204,6 @@ class Term:
|
||||||
Base class for all terms.
|
Base class for all terms.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __eq__(self, other) -> bool:
|
|
||||||
"""
|
|
||||||
Determine whether two terms are equal.
|
|
||||||
"""
|
|
||||||
return str(self) == str(other)
|
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
"""
|
"""
|
||||||
Create a representation of a term.
|
Create a representation of a term.
|
||||||
|
|
@ -185,6 +212,12 @@ class Term:
|
||||||
|
|
||||||
def normalize(self) -> Term:
|
def normalize(self) -> Term:
|
||||||
return normalize(term=self)
|
return normalize(term=self)
|
||||||
|
|
||||||
|
def replace(self, old : Term, new : Term) -> Term:
|
||||||
|
return replace(term=self, old=old, new=new)
|
||||||
|
|
||||||
|
def rec_iter(self) -> Generator[Term, None, None]:
|
||||||
|
yield self
|
||||||
|
|
||||||
def to_str(self, vars : dict[str, Var]) -> str:
|
def to_str(self, vars : dict[str, Var]) -> str:
|
||||||
return "<undefined>"
|
return "<undefined>"
|
||||||
|
|
@ -204,6 +237,11 @@ class App(Term):
|
||||||
Create a representation of a term.
|
Create a representation of a term.
|
||||||
"""
|
"""
|
||||||
return self.to_str(vars={})
|
return self.to_str(vars={})
|
||||||
|
|
||||||
|
def rec_iter(self) -> Generator[Term, None, None]:
|
||||||
|
yield self
|
||||||
|
yield from self.f.rec_iter()
|
||||||
|
yield from self.x.rec_iter()
|
||||||
|
|
||||||
def to_str(self, vars: dict[str, Var]) -> str:
|
def to_str(self, vars: dict[str, Var]) -> str:
|
||||||
f_str = self.f.to_str(vars=vars)
|
f_str = self.f.to_str(vars=vars)
|
||||||
|
|
@ -246,6 +284,18 @@ class Lambda(Term):
|
||||||
out : Term
|
out : Term
|
||||||
var : Var
|
var : Var
|
||||||
|
|
||||||
|
def __eq__(self, value: object) -> bool:
|
||||||
|
if not isinstance(value, Lambda):
|
||||||
|
return False
|
||||||
|
|
||||||
|
for c in USABLE_VAR_NAMES:
|
||||||
|
if not contains(self.out, Const(c)):
|
||||||
|
return self.substitute(Const(c)) == value.substitute((Const(c)))
|
||||||
|
else:
|
||||||
|
raise ValueError(
|
||||||
|
"Ran out of usable variables for comparing lambda structures"
|
||||||
|
)
|
||||||
|
|
||||||
def __init__(self, f : Callable[[Var], Term]) -> None:
|
def __init__(self, f : Callable[[Var], Term]) -> None:
|
||||||
self.var = Var()
|
self.var = Var()
|
||||||
self.out = f(self.var)
|
self.out = f(self.var)
|
||||||
|
|
@ -256,6 +306,10 @@ class Lambda(Term):
|
||||||
"""
|
"""
|
||||||
return self.to_str(vars={})
|
return self.to_str(vars={})
|
||||||
|
|
||||||
|
def rec_iter(self) -> Generator[Term, None, None]:
|
||||||
|
yield self
|
||||||
|
yield from self.out.rec_iter()
|
||||||
|
|
||||||
def replace_content(self, term : Term) -> Lambda:
|
def replace_content(self, term : Term) -> Lambda:
|
||||||
"""
|
"""
|
||||||
Replace the content of the lambda function with the given term.
|
Replace the content of the lambda function with the given term.
|
||||||
|
|
@ -427,3 +481,15 @@ if __name__ == "__main__":
|
||||||
g = L1(lambda b : A2(b, bool_f, bool_t))
|
g = L1(lambda b : A2(b, bool_f, bool_t))
|
||||||
print(g)
|
print(g)
|
||||||
print(g.normalize())
|
print(g.normalize())
|
||||||
|
|
||||||
|
print("\nFIND & REPLACE")
|
||||||
|
print(30 * "=")
|
||||||
|
|
||||||
|
h = A3(Const("f"), Const("x"), Const("y"), Const("z"))
|
||||||
|
i = A3(Const("f"), Const("x"), Const("b"), Const("z")).replace(
|
||||||
|
old=Const("b"), new=Const("y"),
|
||||||
|
)
|
||||||
|
|
||||||
|
print(h)
|
||||||
|
print(i)
|
||||||
|
assert h == i
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue