Skip to content

Commit ddb79c8

Browse files
committed
Describe higher-order logic proof tree in more detail
1 parent b61ee89 commit ddb79c8

6 files changed

Lines changed: 176 additions & 71 deletions

File tree

src/notebook/math/logic/deduction/proof_tree.py

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,15 @@
2323
from .system import NaturalDeductionPremise, NaturalDeductionRule
2424

2525

26+
@dataclass(frozen=True)
27+
class MarkedVariable:
28+
var: Variable
29+
marker: Marker
30+
31+
def __str__(self) -> str:
32+
return f'{self.var}: {self.marker}'
33+
34+
2635
@dataclass(frozen=True)
2736
class AssumptionTree(InferenceTree[FormulaWithSubstitution, Mapping[Marker, Formula]]):
2837
conclusion: FormulaWithSubstitution
@@ -46,6 +55,12 @@ def build_renderer(self, *, conclusion: FormulaWithSubstitution | None = None) -
4655
def get_free_variables(self) -> Collection[Variable]:
4756
return get_free_variables(evaluate_substitution_spec(self.conclusion))
4857

58+
def get_marked_free_variables(self) -> Collection[MarkedVariable]:
59+
return {
60+
MarkedVariable(var, self.marker)
61+
for var in self.get_free_variables()
62+
}
63+
4964
def __str__(self) -> str:
5065
return self.build_renderer().render()
5166

@@ -178,7 +193,7 @@ def _filter_assumptions(self, *, discharged_at_current_step: bool) -> Iterable[t
178193
for marker, assumption in application_premise.tree.get_assumption_map().items():
179194
is_discharged_at_current_step = application_premise.discharge is not None and \
180195
evaluate_substitution_spec(application_premise.discharge) == assumption and \
181-
(application_premise.marker is None or application_premise.marker == marker)
196+
application_premise.marker == marker
182197

183198
if discharged_at_current_step == is_discharged_at_current_step:
184199
yield marker, assumption
@@ -223,19 +238,17 @@ def build_renderer(self, *, conclusion: FormulaWithSubstitution | None = None) -
223238
[premise.build_renderer() for premise in self.premises]
224239
)
225240

226-
def iter_free_variables(self) -> Iterable[Variable]:
227-
for rule_premise, application_premise in zip(self.rule.premises, self.premises, strict=True):
228-
if application_premise.discharge:
229-
continue
241+
def get_marked_free_variables(self) -> Iterable[MarkedVariable]:
242+
discharged_markers = self.get_marker_context()
243+
discharged_eigen = {evar.var for evar in self.get_eigenvariable_context()}
230244

231-
eigen = get_main_eigenvariable(rule_premise, application_premise)
232-
233-
for var in application_premise.tree.get_free_variables():
234-
if var != eigen:
235-
yield var
245+
for application_premise in self.premises:
246+
for mvar in application_premise.tree.get_marked_free_variables():
247+
if mvar.marker not in discharged_markers and mvar.var not in discharged_eigen:
248+
yield mvar
236249

237250
def get_free_variables(self) -> Collection[Variable]:
238-
return set(self.iter_free_variables())
251+
return {mvar.var for mvar in self.get_marked_free_variables()}
239252

240253
def __str__(self) -> str:
241254
return self.build_renderer().render()

src/notebook/math/logic/deduction/test_proof_tree.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ def test_single_implication_intro() -> None:
5454
CLASSICAL_NATURAL_DEDUCTION_SYSTEM['→₊'],
5555
prop_premise(
5656
tree=prop_assume('q', 'u'),
57-
discharge='p'
57+
discharge='p',
58+
marker='u'
5859
)
5960
)
6061

@@ -340,17 +341,20 @@ def test_forall_negation(dummy_signature: FormalLogicSignature) -> None:
340341
),
341342
)
342343
),
343-
discharge=v
344+
discharge=v,
345+
marker=parse_marker('v')
344346
)
345347
),
346348
main_noop_sub=parse_variable('x')
347349
)
348350
)
349351
),
350-
discharge=u
352+
discharge=u,
353+
marker=parse_marker('u')
351354
)
352355
),
353-
discharge=w
356+
discharge=w,
357+
marker=parse_marker('w')
354358
)
355359
)
356360

@@ -418,6 +422,7 @@ def test_exists_elimination(dummy_signature: FormalLogicSignature) -> None:
418422
assume(w, parse_marker('w')), # We avoid discharging w here
419423
),
420424
discharge=parse_formula_with_substitution('p₁(x)[x ↦ y]', dummy_signature), # So that we can discharge it here
425+
marker=parse_marker('w')
421426
),
422427
)
423428

text/curry_howard_correspondence.tex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ \section{Curry-Howard correspondence}\label{sec:curry_howard_correspondence}
1313

1414
Haskell Curry is credited for the realization that, in modern terms, the \hyperref[def:arrow_type]{arrow type} \( \tau \synimplies \rho \) can be regarded as a \hyperref[def:propositional_alphabet/connectives/conditional]{conditional formula}. In this section will extend this to \hyperref[def:simple_algebraic_types]{simple algebraic types}.
1515

16-
William Howard is credited for extending this analogy to \hyperref[sec:first_order_logic]{first-order logic} via what are now called \enquote{dependent types}. We discuss these extensions in \fullref{sec:higher_order_logic}.
16+
William Howard is credited for extending this analogy to \hyperref[sec:first_order_logic]{first-order logic} via what are now called \enquote{dependent types}. We discuss some of these extensions in \fullref{sec:dependent_types}.
1717

1818
Honoring Curry and Howard, we will refer to the overall identification of types and formulas as the \term[en=Curry-Howard correspondence (\cite[def. 4.1.7]{Mimram2020ProgramEqualsProof})]{Curry-Howard correspondence}.
1919

0 commit comments

Comments
 (0)