From cbf8e29a84f9d23f775a8e0c3bc395b1ab55352a Mon Sep 17 00:00:00 2001 From: Bram van den Heuvel Date: Fri, 10 Jul 2026 00:03:13 +0200 Subject: [PATCH] Generalize normalize function --- checker/terms.py | 76 ++++++++++++++++++++++++++++++------------------ 1 file changed, 48 insertions(+), 28 deletions(-) diff --git a/checker/terms.py b/checker/terms.py index 09642ee..4257bef 100644 --- a/checker/terms.py +++ b/checker/terms.py @@ -29,48 +29,63 @@ def normalize(term : Term) -> Term: Create a normalization function. This function simplifies functions as much as possible. """ - def 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 + Normalize a single term. Use both the standard normalization scheme """ - match term: - case App(): - match term.f: - case Lambda(): - return term.f.substitute(value=norm_iter(term.x)) - - case _: - return term - - case Const(): - return _known_consts.get(term.name, term) - - case Lambda(): - return term - - case Var(): - return term + for func in _known_norms: + term = func(term) - case Term(): - return 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 + 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: """ Traverse through the tree back-and-forth, aiming to run the given 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. :type f: Callable[[Term], Term] :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. :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: """