""" 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 [ # ]