Skip to content

Commit

Permalink
added composition helper functions: AND, OR, NOT, IFF, IMPLY
Browse files Browse the repository at this point in the history
  • Loading branch information
Vipul-Cariappa committed Oct 23, 2023
1 parent 1b6503e commit 03e68bc
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 39 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -177,3 +177,6 @@ pyrightconfig.json

# vscode
.vscode/

# temparary folder
tmp/
8 changes: 2 additions & 6 deletions logic/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
from .proof import Prover, Proof
from .proposition import Proposition
from .proposition import Proposition, IMPLY, IFF, AND, OR, NOT

__all__ = [
"Proposition",
"Proof",
"Prover"
]
__all__ = ["Proposition", "Proof", "Prover", "IMPLY", "IFF", "AND", "OR", "NOT"]
19 changes: 11 additions & 8 deletions logic/proof.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
CompositePropositionOR,
CompositePropositionBICONDITIONAL,
CompositePropositionCONDITIONAL,
IMPLY,
)

from enum import Enum
Expand Down Expand Up @@ -142,18 +143,18 @@ def _prove_decomposed_conclusion(self) -> tuple[Proof, bool]:
# Applying definition of Bi-Conditional
# (p <-> q) -> (p -> q) & (q -> p)
proof_p_implies_q, truth_p_implies_q = Prover(
self.assumptions.remove(self.conclusion), assumption / conclusion
self.assumptions.remove(self.conclusion), IMPLY(assumption, conclusion)
).prove()
proof_q_implies_p, truth_q_implies_p = Prover(
self.assumptions.remove(self.conclusion), conclusion / assumption
self.assumptions.remove(self.conclusion), IMPLY(conclusion, assumption)
).prove()
if truth_p_implies_q and truth_q_implies_p:
self.proof.extend(proof_p_implies_q)
self.proof.extend(proof_q_implies_p)
self.proof.add(
RulesOfInference.DefinitionOfBiConditional,
assumption / conclusion,
conclusion / assumption,
IMPLY(assumption, conclusion),
IMPLY(conclusion, assumption),
)
return self.proof, True

Expand Down Expand Up @@ -222,7 +223,7 @@ def prove(self) -> tuple[Proof, bool]:
if self.conclusion.conclusion == conclusion:
proof, truth = Prover(
self.assumptions.remove(i),
self.conclusion.assumption / assumption,
IMPLY(self.conclusion.assumption, assumption),
).prove()
if truth:
self.proof.extend(proof)
Expand Down Expand Up @@ -307,9 +308,11 @@ def prove(self) -> tuple[Proof, bool]:
# Applying definition of Bi-Conditional
# (p <-> q) -> (p -> q) & (q -> p)
assumptions = self.assumptions.get()
if not ((assumption / conclusion) in assumptions) or not ((conclusion / assumption) in assumptions):
assumptions.append(assumption / conclusion)
assumptions.append(conclusion / assumption)
if not (IMPLY(assumption, conclusion) in assumptions) or not (
IMPLY(conclusion, assumption) in assumptions
):
assumptions.append(IMPLY(assumption, conclusion))
assumptions.append(IMPLY(conclusion, assumption))

proof, truth = Prover(assumptions, self.conclusion).prove()
if truth:
Expand Down
40 changes: 28 additions & 12 deletions logic/proposition.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,6 @@ def __invert__(self) -> StatementT:
return copy(self.statement)
return CompositePropositionNOT(self)

def __truediv__(self, other: Any) -> StatementT:
if not isinstance(other, Statement):
raise TypeError(f"Cannot perform logical imply of {type(self)} with {type(other)}")
return CompositePropositionCONDITIONAL(self, other)

def __mod__(self, other: Any) -> StatementT:
if not isinstance(other, Statement):
raise TypeError(f"Cannot perform logical bi-conditional of {type(self)} with {type(other)}")
return CompositePropositionBICONDITIONAL(self, other)


@dataclass(frozen=True)
class Proposition(Statement):
Expand Down Expand Up @@ -233,8 +223,8 @@ class CompositePropositionBICONDITIONAL(CompositeProposition):
conclusion: Statement

def remove_conditionals(self) -> StatementT:
return (self.assumption / self.conclusion).remove_conditionals() & (
self.conclusion / self.assumption
return (IMPLY(self.assumption, self.conclusion)).remove_conditionals() & (
IMPLY(self.conclusion, self.assumption)
).remove_conditionals()

def extract(self) -> list[PropositionT]:
Expand Down Expand Up @@ -263,3 +253,29 @@ def __eq__(self, other: Any) -> bool:
return self.assumption == other.assumption and self.conclusion == other.conclusion

return False


def AND(first: Statement, second: Statement, *others: Statement) -> CompositePropositionAND:
if len(others) == 0:
return CompositePropositionAND(first, second)

return CompositePropositionAND(first, AND(second, *others))


def OR(first: Statement, second: Statement, *others: Statement) -> CompositePropositionOR:
if len(others) == 0:
return CompositePropositionOR(first, second)

return CompositePropositionOR(first, OR(second, *others))


def NOT(statement: Statement) -> CompositePropositionNOT:
return CompositePropositionNOT(statement)


def IMPLY(assumption: Statement, conclusion: Statement) -> CompositePropositionCONDITIONAL:
return CompositePropositionCONDITIONAL(assumption, conclusion)


def IFF(assumption: Statement, conclusion: Statement) -> CompositePropositionBICONDITIONAL:
return CompositePropositionBICONDITIONAL(assumption, conclusion)
26 changes: 13 additions & 13 deletions tests/test_prover.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import unittest
from logic import Proposition, Prover
from logic import Proposition, Prover, IMPLY

# TODO: check proof

Expand All @@ -16,7 +16,7 @@ def setUp(self) -> None:
def test_prover_modus_ponens(self):
assumptions = (
self.p,
self.p / self.q,
IMPLY(self.p, self.q),
)
conclusion = self.q

Expand All @@ -29,7 +29,7 @@ def test_prover_modus_ponens(self):
def test_prover_modus_tollens(self):
assumptions = (
~self.q,
self.p / self.q,
IMPLY(self.p, self.q),
)
conclusion = ~self.p

Expand All @@ -41,10 +41,10 @@ def test_prover_modus_tollens(self):

def test_prover_hypothetical_syllogism(self):
assumptions = (
self.p / self.q,
self.q / self.r,
IMPLY(self.p, self.q),
IMPLY(self.q, self.r),
)
conclusion = self.p / self.r
conclusion = IMPLY(self.p, self.r)

_, truth = Prover(
assumptions,
Expand Down Expand Up @@ -184,7 +184,7 @@ def test_prover_multi_step_1(self):

def test_prover_multi_step_2(self):
# modus tollens then demorgans
assumptions = (self.x / self.y, ~self.y)
assumptions = (IMPLY(self.x, self.y), ~self.y)
conclusion = ~(self.x | self.y)

_, truth = Prover(
Expand All @@ -195,7 +195,7 @@ def test_prover_multi_step_2(self):

def test_prover_multi_step_3(self):
# modus tollens then demorgans
assumptions = (self.x / self.y, ~self.y)
assumptions = (IMPLY(self.x, self.y), ~self.y)
conclusion = ~(self.x | self.y)

_, truth = Prover(
Expand All @@ -204,7 +204,7 @@ def test_prover_multi_step_3(self):
).prove()
self.assertTrue(truth)

assumptions = ((self.y | self.z) / self.x, ~self.x)
assumptions = (IMPLY(self.y | self.z, self.x), ~self.x)
conclusion = ~self.y & ~self.z

_, truth = Prover(
Expand Down Expand Up @@ -236,11 +236,11 @@ def test_prove_superman_does_not_exists(self):
f = Proposition("g", "Superman exists")

assumptions = [
(a & b) / e,
(~e) / c,
(~b) / d,
IMPLY(a & b, e),
IMPLY(~e, c),
IMPLY(~b, d),
~e,
f / (~c & ~d),
IMPLY(f, ~c & ~d),
]
conclusion = ~f

Expand Down

0 comments on commit 03e68bc

Please sign in to comment.