128 lines
3.1 KiB
Python
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 [
|
|
|
|
# ]
|
|
|
|
|