Proof in Natural Deduction¶
Introduction¶
In Mathesis, a state of a natural deduction proof (and its subproofs) consists of the premises and the conclusion that are available to the (sub)proof at a given step.
A state is displayed as <premises> ⇒ <conclusion>.
Intuitively, the formulas on the left side of ⇒ are what to come to the upper part of the final (sub)proof, and those on the right side of ⇒ are what to come to the lower part of the final (sub)proof.
Natural deduction is a proof system that consists of elimination rules and introduction rules. In Mathesis,
- you can apply an elimination rule up-to-down to the premises of a (sub)proof to obtain new premises.
- Similarly, you can apply an introduction rule down-to-up to the conclusion of a (sub)proof and convert it into new subproofs.
from mathesis.grammars import BasicGrammar
from mathesis.deduction.natural_deduction import NDTree, rules
grammar = BasicGrammar()
premises = grammar.parse(["A∨B", "B→C"])
conclusion = grammar.parse("A∨C")
deriv = NDTree(premises, conclusion)
print(deriv.tree())
deriv.apply(deriv[1], rules.Disjunction.Elim())
print(deriv.tree())
deriv.apply(deriv[8], rules.Disjunction.Intro("left"))
print(deriv.tree())
deriv.apply(deriv[10], rules.Conditional.Elim())
print(deriv.tree())
deriv.apply(deriv[25], rules.Disjunction.Intro("right"))
print(deriv.tree())
A ∨ B 1, B → C 2 ⇒ A ∨ C 3
A ∨ B 1, B → C 2 ⇒ A ∨ C 3 [∨E]
├── A 4, A ∨ B 6, B → C 7 ⇒ A ∨ C 8
└── B 5, A ∨ B 9, B → C 10 ⇒ A ∨ C 11
A ∨ B 1, B → C 2 ⇒ A ∨ C 3 [∨E]
├── A 4, A ∨ B 6, B → C 7 ⇒ A ∨ C 8 [∨I]
│ └── A 13, A ∨ B 14, B → C 15 ⇒ A 12
└── B 5, A ∨ B 9, B → C 10 ⇒ A ∨ C 11
A ∨ B 1, B → C 2 ⇒ A ∨ C 3 [∨E]
├── A 4, A ∨ B 6, B → C 7 ⇒ A ∨ C 8 [∨I]
│ └── A 13, A ∨ B 14, B → C 15 ⇒ A 12
└── B 5, A ∨ B 9, B → C 10 ⇒ A ∨ C 11 [→E]
├── B 17, A ∨ B 18, B → C 19 ⇒ B 16
└── C 21, B 22, A ∨ B 23, B → C 24 ⇒ A ∨ C 25
A ∨ B 1, B → C 2 ⇒ A ∨ C 3 [∨E]
├── A 4, A ∨ B 6, B → C 7 ⇒ A ∨ C 8 [∨I]
│ └── A 13, A ∨ B 14, B → C 15 ⇒ A 12
└── B 5, A ∨ B 9, B → C 10 ⇒ A ∨ C 11 [→E]
├── B 17, A ∨ B 18, B → C 19 ⇒ B 16
└── C 21, B 22, A ∨ B 23, B → C 24 ⇒ A ∨ C 25 [∨I]
└── C 27, B 28, A ∨ B 29, B → C 30 ⇒ C 26
First-order logic¶
First-order rules are available through dedicated rules.Universal and rules.Particular classes. Just as in standard textbooks, instantiations use a concrete term while generalizations require fresh terms that do not occur elsewhere in the branch.
from mathesis.grammars import BasicGrammar
from mathesis.deduction.natural_deduction import NDTree, rules
grammar = BasicGrammar()
premises = grammar.parse(["∀x(P(x)→Q(x))", "∃x P(x)"])
conclusion = grammar.parse("∃x Q(x)")
deriv = NDTree(premises, conclusion)
print(deriv.tree())
deriv.apply(deriv[2], rules.Particular.Elim("a"))
deriv.apply(deriv[5], rules.Universal.Elim("a"))
deriv.apply(deriv[8], rules.Conditional.Elim())
deriv.apply(deriv[24], rules.Particular.Intro("a"))
print(deriv.tree())
print(deriv.tree(style="gentzen"))
∀x(P(x) → Q(x)) 1, ∃xP(x) 2 ⇒ ∃xQ(x) 3
∀x(P(x) → Q(x)) 1, ∃xP(x) 2 ⇒ ∃xQ(x) 3 [∃E]
└── P(a) 4, ∀x(P(x) → Q(x)) 5, ∃xP(x) 6 ⇒ ∃xQ(x) 7 [∀E]
└── P(a) → Q(a) 8, P(a) 9, ∀x(P(x) → Q(x)) 10, ∃xP(x) 11 ⇒ ∃xQ(x) 12 [→E]
├── P(a) → Q(a) 14, P(a) 15, ∀x(P(x) → Q(x)) 16, ∃xP(x) 17 ⇒ P(a) 13
└── Q(a) 19, P(a) → Q(a) 20, P(a) 21, ∀x(P(x) → Q(x)) 22, ∃xP(x) 23 ⇒ ∃xQ(x) 24 [∃I]
└── Q(a) 26, P(a) → Q(a) 27, P(a) 28, ∀x(P(x) → Q(x)) 29, ∃xP(x) 30 ⇒ Q(a) 25
∃xQ(x) [∃E]
├── ∃xP(x)
└── ∃xQ(x) [∃I]
└── Q(a) [→E]
├── P(a) → Q(a) [∀E]
│ └── ∀x(P(x) → Q(x))
└── P(a)
Render as Gentzen-style proof¶
(WIP) Mathesis has an experimental support for rendering a natural deduction proof as a Gentzen-style proof or its LaTeX code.
from mathesis.grammars import BasicGrammar
from mathesis.deduction.natural_deduction import NDTree, rules
grammar = BasicGrammar()
premises = grammar.parse(["A∨B", "B→C"])
conclusion = grammar.parse("A∨C")
deriv = NDTree(premises, conclusion)
print(deriv.tree(number=False))
deriv.apply(deriv[1], rules.Disjunction.Elim())
deriv.apply(deriv[8], rules.Disjunction.Intro("left"))
deriv.apply(deriv[10], rules.Conditional.Elim())
deriv.apply(deriv[25], rules.Disjunction.Intro("right"))
print(deriv.tree(style="gentzen"))
print(deriv.latex())
A ∨ B, B → C ⇒ A ∨ C
A ∨ C [∨E]
├── A ∨ C [∨I]
│ └── A
├── A ∨ C [∨I]
│ └── C [→E]
│ ├── B → C
│ └── B
└── A ∨ B
\begin{prooftree}
\AxiomC{$[A]$}
\RightLabel{$\lor$I}
\UnaryInfC{$A \lor C$}
\AxiomC{$B \to C$}
\AxiomC{$[B]$}
\RightLabel{$\to$E}
\BinaryInfC{$C$}
\RightLabel{$\lor$I}
\UnaryInfC{$A \lor C$}
\AxiomC{$A \lor B$}
\RightLabel{$\lor$E}
\TrinaryInfC{$A \lor C$}
\end{prooftree}
Render as Fitch-style proof¶
WIP
Render as Suppes-Lemmon-style proof¶
WIP
Render as Sequent Calculus proof¶
WIP