Skip to content

Commit 2454a06

Browse files
authored
Merge pull request #7 from DigitalFormalLogic/feat/nd-fol
FEAT: Natural deduction for first-order logic
2 parents b359bf0 + e8d8f45 commit 2454a06

4 files changed

Lines changed: 279 additions & 44 deletions

File tree

‎docs/usage/natural-deduction.md‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,31 @@ deriv.apply(deriv[25], rules.Disjunction.Intro("right"))
3636
print(deriv.tree())
3737
```
3838

39+
## First-order Quantifiers
40+
41+
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.
42+
43+
```python exec="1" result="text" source="material-block"
44+
from mathesis.grammars import BasicGrammar
45+
from mathesis.deduction.natural_deduction import NDTree, rules
46+
47+
grammar = BasicGrammar()
48+
49+
premises = grammar.parse(["∀x(P(x)→Q(x))", "∃x P(x)"])
50+
conclusion = grammar.parse("∃x Q(x)")
51+
52+
deriv = NDTree(premises, conclusion)
53+
print(deriv.tree())
54+
55+
deriv.apply(deriv[2], rules.Particular.Elim("a"))
56+
deriv.apply(deriv[5], rules.Universal.Elim("a"))
57+
deriv.apply(deriv[8], rules.Conditional.Elim())
58+
deriv.apply(deriv[24], rules.Particular.Intro("a"))
59+
60+
print(deriv.tree())
61+
print(deriv.tree(style="gentzen"))
62+
```
63+
3964
## Render as Gentzen-style Proof
4065

4166
(WIP) Mathesis has an experimental support for rendering a natural deduction proof as a Gentzen-style proof or its LaTeX code.
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
1-
from mathesis.deduction.natural_deduction.natural_deduction import NDTree # noqa
1+
from mathesis.deduction.natural_deduction import rules
2+
from mathesis.deduction.natural_deduction.natural_deduction import NDTree
3+
4+
__all__ = ["rules", "NDTree"]

‎mathesis/deduction/natural_deduction/natural_deduction.py‎

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ class NDSequentItem(SequentItem):
1818
class NDSubproof(NodeMixin):
1919
derived_by: natural_deduction.rules.Rule | None
2020

21-
def __init__(self, item: SequentItem, *, parent=None, children=[]) -> None:
21+
def __init__(
22+
self, item: SequentItem, *, parent=None, children: list[NDSubproof] = []
23+
) -> None:
2224
super().__init__()
2325
self.name = item
2426
self.item = item
@@ -27,6 +29,12 @@ def __init__(self, item: SequentItem, *, parent=None, children=[]) -> None:
2729

2830
self.derived_by = None
2931

32+
def __str__(self):
33+
return f"<NDSubproof name='{str(self.name)}' children={[self.children]}>"
34+
35+
def __repr__(self):
36+
return self.__str__()
37+
3038

3139
class NDTree:
3240
"""A natural deduction proof tree."""
@@ -41,12 +49,15 @@ def __init__(self, premises: list[Formula], conclusion: Formula):
4149
self.bookkeeper = self._sequent_tree.bookkeeper
4250
self.counter = self._sequent_tree.counter
4351

44-
# Proof tree
52+
## Proof tree
53+
# Premises have empty child subproof
4554
for item in self._sequent_tree.root.left:
4655
item.subproof = NDSubproof(item, children=[])
56+
# Conclusion has premises as child subproofs
4757
self._sequent_tree.root.right[0].subproof = NDSubproof(
4858
self._sequent_tree.root.right[0],
49-
children=[item.subproof for item in self._sequent_tree.root.left],
59+
# children=[item.subproof for item in self._sequent_tree.root.left],
60+
children=[],
5061
)
5162

5263
def __getitem__(self, index):

0 commit comments

Comments
 (0)