Generalize normalize function

dev
Bram van den Heuvel 2026-07-10 00:03:13 +02:00
parent eeac39a4fa
commit cbf8e29a84
1 changed files with 48 additions and 28 deletions

View File

@ -29,8 +29,24 @@ def normalize(term : Term) -> Term:
Create a normalization function. This function simplifies functions as Create a normalization function. This function simplifies functions as
much as possible. much as possible.
""" """
def norm_iter(term : Term) -> Term: def norm_iter(term : Term) -> Term:
"""
Normalize a single term. Use both the standard normalization scheme
"""
for func in _known_norms:
term = func(term)
return term
return traverse(f=norm_iter, term=term)
def register_known_const(name : str, value : Term) -> None:
_known_consts[name] = value
def register_known_norm(func : Callable[[Term], Term]) -> None:
_known_norms.append(func)
def std_norm_iter(term : Term) -> Term:
""" """
Normalize a single term. Trust that all children values have Normalize a single term. Trust that all children values have
already been normalized, or that they will be normalized later on. already been normalized, or that they will be normalized later on.
@ -44,7 +60,7 @@ def normalize(term : Term) -> Term:
case App(): case App():
match term.f: match term.f:
case Lambda(): case Lambda():
return term.f.substitute(value=norm_iter(term.x)) return term.f.substitute(value=term.x)
case _: case _:
return term return term
@ -60,17 +76,16 @@ def normalize(term : Term) -> Term:
case Term(): case Term():
return term return term
_known_norms.append(std_norm_iter)
return traverse(f=norm_iter, term=term)
def register_known_const(name : str, value : Term) -> None:
_known_consts[name] = value
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
function as thoroughly as possible to manipulate the term tree. function as thoroughly as possible to manipulate the term tree.
The function quits once no more operations are created.
**WARNING:** This means the tree might traverse forever.
:param f: The traversal function that replaces terms. :param f: The traversal function that replaces terms.
:type f: Callable[[Term], Term] :type f: Callable[[Term], Term]
:param term: The term to traverse. :param term: The term to traverse.
@ -78,7 +93,12 @@ def traverse(f : Callable[[Term], Term], term : Term) -> Term:
:return: The result of the traversed term. :return: The result of the traversed term.
:rtype: Term :rtype: Term
""" """
return traverse_bottom_up(f=f, term=traverse_top_down(f=f, term=term)) a, b = Term(), term
while a != b:
a, b = b, traverse_bottom_up(f=f, term=traverse_top_down(f=f, term=term))
return b
def traverse_bottom_up(f : Callable[[Term], Term], term : Term) -> Term: def traverse_bottom_up(f : Callable[[Term], Term], term : Term) -> Term:
""" """