Simplify & generalize types to "App" & "Const" types

main
Bram van den Heuvel 2026-06-29 14:50:51 +02:00
parent cca866ae62
commit ffc79f4372
1 changed files with 32 additions and 65 deletions

View File

@ -19,41 +19,29 @@ class App(Term):
class Const(Term): class Const(Term):
name : str name : str
@dataclass(frozen=True)
class Var(Term):
name : str
# --- Bool constructors --- # --- Bool constructors ---
Bool = Union["Truth", "Contradiction"] def Truth() -> Term:
return Const("Bool.Truth")
@dataclass(frozen=True) def Contradiction() -> Term:
class Truth(Term): return Const("Bool.Contradiction")
pass
@dataclass(frozen=True)
class Contradiction(Term):
pass
# --- Nat constructors --- # --- Nat constructors ---
Nat = Union["Zero", "Succ"] def Zero() -> Term:
return Const("Nat.Zero")
@dataclass(frozen=True) def Succ(n : Term) -> Term:
class Zero(Term): return App(Const("Nat.Succ"), n)
pass
@dataclass(frozen=True) def kernel_from_int(n : int) -> Term:
class Succ(Term):
n : Term
def kernel_from_int(n : int) -> Nat:
if n == 0: if n == 0:
return Zero() return Zero()
elif n < 0: elif n < 0:
raise ValueError("Int is not Nat") raise ValueError("Int is not Nat")
else: else:
return Succ(n=kernel_from_int(n=n-1)) return Succ(kernel_from_int(n-1))
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
# Propositions # Propositions
@ -87,40 +75,44 @@ class F:
arity : int arity : int
func : Callable[..., Term | None] func : Callable[..., Term | None]
F_ = lambda a : lambda f : F(arity=a, func=f)
F0, F1, F2, F3 = F_(0), F_(1), F_(2), F_(3)
F4, F5, F6, F7 = F_(4), F_(5), F_(6), F_(7)
def apply_rules() -> dict[str, F]: def apply_rules() -> dict[str, F]:
def __bool_not(x : Term) -> Term | None: def __bool_not(x : Term) -> Term | None:
match x: match x:
case Truth(): case Const("Bool.Truth"):
return Contradiction() return Contradiction()
case Contradiction(): case Const("Bool.Contradiction"):
return Truth() return Truth()
def __nat_add(x : Term, y : Term) -> Term | None: def __nat_add(x : Term, y : Term) -> Term | None:
match x: match x:
case Zero(): case Const("Nat.Zero"):
return y return y
case Succ(): case App(f=Const("Nat.Succ"), x=x_):
return Succ( return Succ(
n=normalize(App( App(
f=App(Const("Nat.add"), x=x.n), f=App(Const("Nat.add"), x_),
x=y, x=y,
)) )
) )
def __nat_iszero(x : Term) -> Term | None: def __nat_iszero(x : Term) -> Term | None:
match x: match x:
case Zero(): case Const("Nat.Zero"):
return Truth() return Truth()
case Succ(): case App(f=Const("Nat.Succ")):
return Contradiction() return Contradiction()
return { return {
"Bool.not": F(arity=1, func=__bool_not), "Bool.not": F1(__bool_not),
"Nat.add" : F(arity=2, func=__nat_add), "Nat.add" : F2(__nat_add),
"Nat.isZero" : F(arity=1, func=__nat_iszero), "Nat.isZero" : F1(__nat_iszero),
} }
@ -154,37 +146,12 @@ def normalize(term : Term) -> Term:
out = rule.func(*reversed([i.x for i in items])) out = rule.func(*reversed([i.x for i in items]))
return out if out is not None else App(f, x) return normalize(out) if out is not None else App(f, x)
case Contradiction():
if len(items) != 2:
# Either evaluating too early or too late
return term
# Return the "second" item
return x
case Truth():
if len(items) != 2:
# Either evaluating too early or too late
return App(f, x)
# Return the "first" item
return cursor.x
case Const(): case Const():
return term return term
case Succ():
return Succ(n=normalize(term.n))
case Term():
return term
case Var(): case Term():
return term
case Zero():
return term return term
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
@ -216,8 +183,8 @@ if __name__ == "__main__":
# 0 + x == x # 0 + x == x
print(check( print(check(
Eq( Eq(
lhs=App(f=App(f=Const("Nat.add"), x=Zero()), x=Var("x")), lhs=App(f=App(f=Const("Nat.add"), x=Zero()), x=Const("x")),
rhs=Var("x") rhs=Const("x")
), ),
Refl(), Refl(),
)) ))
@ -225,8 +192,8 @@ if __name__ == "__main__":
# x + 0 == x # x + 0 == x
print(check( print(check(
Eq( Eq(
lhs=App(f=App(f=Const("Nat.add"), x=Var("x")), x=Zero()), lhs=App(f=App(f=Const("Nat.add"), x=Const("x")), x=Zero()),
rhs=Var("x") rhs=Const("x")
), ),
Refl(), Refl(),
)) ))