Generalize normalize function
parent
eeac39a4fa
commit
cbf8e29a84
|
|
@ -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))
|
||||
for func in _known_norms:
|
||||
term = func(term)
|
||||
|
||||
case _:
|
||||
return term
|
||||
|
||||
case Const():
|
||||
return _known_consts.get(term.name, term)
|
||||
|
||||
case Lambda():
|
||||
return term
|
||||
|
||||
case Var():
|
||||
return 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:
|
||||
"""
|
||||
|
|
|
|||
Loading…
Reference in New Issue