new-lang/checker/props.py

128 lines
3.1 KiB
Python

"""
This module hosts propositions.
"""
from __future__ import annotations
from .terms import Term
from dataclasses import dataclass
@dataclass(frozen=True)
class Context:
"""
The Context is a collection of propositions. These are the hypotheses
that are used to arrive at a proof.
"""
props : list["Prop"]
def with_prop(self, new_prop : "Prop") -> Context:
return Context(props=[ prop for prop in self.props ] + [ new_prop ])
class Prop:
"""
A proposition is a logical statement. It can be proven by the proof
checker, or it can be used as a hypothesis to prove another
proposition.
"""
def as_assumption(self, goal : Prop) -> list[list[tuple[list[Prop], Prop]]]:
"""
Propositions can simplify the proof by creating simpler theorems
and sub-lemmas to prove instead. If this proposition is part of
the assumptions, this function helps transform the goal into
simpler sub-goals.
:return: Tuples of added assumptions with a new goal.
:rtype: list[list[tuple[list[Prop], Prop]]]
"""
return []
def as_proof(self) -> list[list[tuple[list[Prop], Prop]]]:
"""
Determine which hypotheses are required in the context to prove
this proposition.
The function returns a list of various methods to prove the
proposition. If any of the methods is an empty list, it means
the proposition requires no assumptions and can instead be
computed.
:return: Methods to prove this proposition.
:rtype: list[tuple[list[Prop], Prop]]
"""
return []
@dataclass(frozen=True)
class And(Prop):
"""
The logical and-operator `P ^ Q`.
"""
P : Prop
Q : Prop
def as_assumption(self, goal: Prop) -> list[list[tuple[list[Prop], Prop]]]:
return [
[ ( [ self.P, self.Q ], goal )
],
]
def as_proof(self) -> list[list[tuple[list[Prop], Prop]]]:
return [
[ ( [], self.P )
, ( [], self.Q )
],
]
class Eq(Prop):
"""
Compare whether two terms are equal.
"""
x : Term
y : Term
def as_assumption(self, goal: Prop) -> list[list[tuple[list[Prop], Prop]]]:
return []
def as_proof(self) -> list[list[tuple[list[Prop], Prop]]]:
return super().as_proof()
@dataclass(frozen=True)
class Implies(Prop):
"""
The logical operator `P -> Q`.
"""
P : Prop
Q : Prop
def as_assumption(self, goal : Prop) -> list[list[tuple[list[Prop], Prop]]]:
return [
[ ( [], self.P )
, ( [ self.Q ], goal)
],
]
def as_proof(self) -> list[list[tuple[list[Prop], Prop]]]:
return [
[ ( [ self.P ], self.Q )
],
]
# @dataclass(frozen=True)
# class Or(Prop):
# """
# The logical and-operator `P v Q`.
# """
# P : Prop
# Q : Prop
# def as_assumption(self, goal: Prop) -> list[list[tuple[list[Prop], Prop]]]:
# return [
# ]