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,48 +29,63 @@ 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. Trust that all children values have Normalize a single term. Use both the standard normalization scheme
already been normalized, or that they will be normalized later on.
:param term: The term to normalize.
:type term: Term
:return: A normalized version of the term.
:rtype: Term
""" """
match term: for func in _known_norms:
case App(): term = func(term)
match term.f:
case Lambda():
return term.f.substitute(value=norm_iter(term.x))
case _: return term
return term
case Const():
return _known_consts.get(term.name, term)
case Lambda():
return term
case Var():
return term
case Term():
return term
return traverse(f=norm_iter, term=term) return traverse(f=norm_iter, term=term)
def register_known_const(name : str, value : Term) -> None: def register_known_const(name : str, value : Term) -> None:
_known_consts[name] = value _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
already been normalized, or that they will be normalized later on.
:param term: The term to normalize.
:type term: Term
:return: A normalized version of the term.
:rtype: Term
"""
match term:
case App():
match term.f:
case Lambda():
return term.f.substitute(value=term.x)
case _:
return term
case Const():
return _known_consts.get(term.name, term)
case Lambda():
return term
case Var():
return term
case Term():
return term
_known_norms.append(std_norm_iter)
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:
""" """