Skip to content

feat(Logics/Propositional): five-primitive formula type with primitive bot#648

Open
benbrastmckie wants to merge 3 commits into
leanprover:mainfrom
benbrastmckie:feat/propositional-v2
Open

feat(Logics/Propositional): five-primitive formula type with primitive bot#648
benbrastmckie wants to merge 3 commits into
leanprover:mainfrom
benbrastmckie:feat/propositional-v2

Conversation

@benbrastmckie

@benbrastmckie benbrastmckie commented Jun 14, 2026

Copy link
Copy Markdown

Summary

Revises PR #648 based on reviewer feedback (thomaskwaring, msg 606970606). Adds bot as a primitive constructor of Proposition (eliminating all [Bot Atom] constraints) and makes IPL the base logic by taking ex falso quodlibet as a primitive natural-deduction rule. Rebased on upstream/main post-#536.

Key changes from #648:

  • bot is a primitive constructor (not an atom), so explosion and IsClassical no longer require [Bot Atom]
  • Ex falso quodlibet is now a primitive rule (efq constructor of Derivation), so has an inference rule and IPL is the base logic; minimal logic (MPL) is set aside for a separate PR/discussion, per the agreed compromise
  • Reconciled with merged PR refactor(Logics/Propositional): classical and intuitionistic inference systems #536's InferenceSystem-parameterized typeclasses
  • Constructor naming uses imp/impI/impE (renamed from impl/implI/implE for consistency with FormalizedFormalLogic convention; open to reverting if reviewers prefer impl)
  • Semantics not included — deferred to a follow-up PR (per thomaskwaring's request)
  • Connective typeclasses removed — a separate development coordinated via PR feat(Logic): logical operators #607 (this PR no longer ships Connectives.lean)
  • References include Avigad 2022, Gentzen 1935, Prawitz 1965, and Troelstra & van Dalen 1988, and a link to the CSLib Zulip design thread is added

Modified files

  • Cslib/Logics/Propositional/Defs.lean -- Proposition with primitive bot; derived neg, top, iff; IPL is the empty base theory and CPL adds double-negation elimination (the MPL / IsIntuitionistic / intuitionisticCompletion layer is set aside for the minimal-logic PR)
  • Cslib/Logics/Propositional/NaturalDeduction/Basic.lean -- derivation constructors impI/impE, andE1/andE2, orI1/orI2 with explicit Γ arguments, plus the new primitive efq (⊥-elimination); implementation notes, references, and Zulip-thread link
  • Cslib/Logics/Propositional/NaturalDeduction/Theory.lean -- [Bot Atom] removed; the classical layer (IsClassical, byContra/lem/pierce, and the CPL/LEM/Pierce instances) re-proved over the new base via the efq constructor
  • references.bib -- added Avigad2022, Gentzen1935, Prawitz1965, TroelstraVanDalen1988

Design rationale

Primitive bot eliminates [Bot Atom] constraints throughout the propositional logic API, gives Proposition.subst a natural recursive case for bot, and follows the standard treatment in Avigad (2022) where bot is a logical constant rather than an atomic proposition. The trade-off (noted by thomaskwaring) is an extra bot case in structural recursions. Relatedly, taking ex falso as a primitive rule rather than leaving a constructor with no inference behaviour follows the standard natural-deduction treatment (Gentzen 1935, Prawitz 1965, Troelstra & van Dalen 1988) and is thomaskwaring's recommendation; minimal logic — the efq-free fragment — is deferred so the fragment design can be settled on its own.

These benefits extend to planned completeness work for modal and temporal logics: primitive bot ensures Proposition.subst preserves bottom structurally (subst f .bot = .bot), whereas atom-encoded bot requires additional constraints to prevent subst f (.atom ⊥) = f ⊥ from mapping bottom to an arbitrary formula. As thomaskwaring notes, non-bottom-preserving maps are also useful (e.g., conservativity results via WithBot.some).

Coordination

  • PR feat(Logic): logical operators #607 (fmontesi): connective typeclasses are a separate development; this PR no longer ships its own Connectives.lean. One design point for feat(Logic): logical operators #607: it makes negation primitive (HasNot) with no / class, but a -primitive Proposition (where ¬φ := φ → ⊥ and ⊤ := ⊥ → ⊥) registers faithfully by reusing Mathlib's Bot/Top together with a derived HasNot (not := neg) and a (φ → ⊥) = ¬φ grind bridge — no separate HasBot class needed. I'll leave a review on feat(Logic): logical operators #607.

Deferred

  • Minimal logic (MPL) + fragment design -- a separate PR/discussion (the agreed deferral).
  • Semantics (Bool.lean, evaluation) -- follow-up PR; the Prop vs Bool vs GeneralizedHeytingAlgebra question (raised by thomaskwaring and ctchou) will be addressed there.
  • Hilbert systems, sequent calculi, and tableau -- stacked PRs.

AI Tools Used

Claude Code was used to refactor for primitive efq/IPL-base, remove the connective typeclasses and the minimal-logic layer, rebase onto upstream/main and resolve the references.bib conflict, and verify CI. All mathematical decisions reviewed.

@benbrastmckie benbrastmckie force-pushed the feat/propositional-v2 branch from 047b396 to b041ae7 Compare June 15, 2026 02:20
benbrastmckie added a commit to benbrastmckie/cslib that referenced this pull request Jun 15, 2026
Session: sess_$(date +%s)_$(od -An -N3 -tx1 /dev/urandom | tr -d ' ')
benbrastmckie added a commit to benbrastmckie/cslib that referenced this pull request Jun 15, 2026
Add Kamp1968, Xu1988, Venema1993SinceUntil to references.bib.
Update pr-description.md with Burgess/Xu/Venema/GHR citations,
Zulip discussion link, and PR leanprover#648 dependency reference.

Session: sess_1781487302_dddcf1
benbrastmckie added a commit to benbrastmckie/cslib that referenced this pull request Jun 15, 2026
Stack Modal PR on feat/propositional-v2 (PR leanprover#648) like PR leanprover#649 does,
keeping it independent of temporal additions. Two-PR chain, not three.

Session: sess_1781531573_4cdbb4
benbrastmckie added a commit to benbrastmckie/cslib that referenced this pull request Jun 15, 2026
Stack on PR leanprover#648 (not leanprover#649), diplomatic PR description as first-class
deliverable, integrate PR landscape audit (report 06).

Session: sess_1781532709_eb0889
benbrastmckie added a commit to benbrastmckie/cslib that referenced this pull request Jun 15, 2026
Diplomatic PR description for Modal/ formula primitives refactoring,
stacking on PR leanprover#648. Coordinates with PRs leanprover#607, leanprover#528, leanprover#535, leanprover#649.

Session: sess_1781535860_c7d8e9

@ctchou ctchou left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some general comments:

  • I like the idea of adding \bot as a primitive.
  • I don't understand why we need both Semantics/Basic.lean and Semantics/Bool.lean. I think the latter alone is enough. Later we can add (for example) Kripke semantics for intuitionistic propositional logic.
  • It is not helpful to the readers to refer to old papers from the 1930s, some of which are in German. A good modern reference is Jeremy Avigad's textbook:
    https://www.cambridge.org/core/books/mathematical-logic-and-computation/300504EAD8410522CE0C27595D2825A2
    whose chapters 2 and 3 covers everything in this PR.
  • You should definitely coordinate this PR with #607 abd #587. #536 is ready to merge, so you should wait for it.

@thomaskwaring

thomaskwaring commented Jun 16, 2026

Copy link
Copy Markdown
Collaborator

I think the refactor to Propositional/* you suggest could be workable, but I have a few concerns (note that while having falsum as a primitive is more conventional, the current design was discussed fairly thoroughly).

  • If is included in minimal logic it behaves precisely like the atomic formulae, so why not represent it as such?
  • Minimal logic works perfectly well without — this is the approach taken in Lectures on the Curry-Howard Correspondence for example. I don't think having [Bot Atom] assumptions where necessary is a big deal.
  • Adding an extra constructor makes all the proofs, and more importantly definitions, more verbose. EG in your semantics development you have to have separate fields in the Kripke structure for the entailment relation on atoms and , which are exact duplicates.
  • I see your point about substitution, but I think it is sometimes important to consider maps which don't preserve the bottom. For example, the informal statement "intuitionistic logic is conservative over minimal logic" translates to "minimal logic proves all statements that don't mention ". The most sensible way to spell this (to me) would be to consider the map WithBot.some : Atom → WithBot Atom and consider mapping formulas / derivations along that. (Another analogy I have in mind is domain theory, where even if your domains have a bottom element, it's important to consider functions which may not preserve it. The correspondence there is a little loose though.)
  • I think the element being a → a for an arbitrary formula is a feature not a bug — proofs about should only depend on the fact that it is provable, not on the specific definition. Note that lean synthesises default = ⊥ anyway, as an example shows.

Re the renaming imp / impl, I think this is fine, but citing "CSLib's existing formula types" as your own as-yet-unmerged work is not exactly convincing. Indeed the actually existing example (Modal) uses "impl".

Please split the semantics development into a separate PR. The point of requesting that large contributions are split up is not just length, but also so that conceptually separate issues can be discussed independently. FWIW, as I mentioned on zulip, imo the right way to resolve the Bool / Prop issue is to define the interpretation in any (generalised) Heyting algebra — this captures both of those as well as non-classical versions, and the proofs of soundness are no harder. Also, your proof of Evaluate_eq_BoolEvaluate, ie that the valuation into Prop factors through Bool, would work for any morphism of Heyting algebras.

Re the references, I agree with @ctchou about citing literature in English — the Gentzen paper is my bad, I read it in translation (in "The Collected Papers of Gerhard Gentzen" ed M. E. Szabo).

@benbrastmckie benbrastmckie force-pushed the feat/propositional-v2 branch from 6083b4c to 7cc0961 Compare June 16, 2026 20:06
@benbrastmckie benbrastmckie changed the title feat(Logics/Propositional): five-primitive formula type with connective typeclasses feat(Logics/Propositional): five-primitive formula type with primitive bot Jun 16, 2026
@benbrastmckie

benbrastmckie commented Jun 16, 2026

Copy link
Copy Markdown
Author

@ctchou @thomaskwaring Thank you both for the thoughtful feedback — I've reworked the PR to address each point.

Changes made:

On the imp vs impl naming: I renamed to imp for consistency with FormalizedFormalLogic, but I'm happy to revert to impl if you both prefer that. Thomas, you're right that Modal uses impl — I don't want to create unnecessary inconsistency.

On bot as primitive vs atom: The key distinction is that in minimal logic bot is an unconstrained logical constant (a nullary operator), not an atom — no axioms constrain its denotation, but it's fixed under substitution. With primitive , subst has | .bot => .bot and axiom scheme closure is automatic. With bot-as-atom, every substitution theorem acquires a side condition σ(⊥) = ⊥ and the free monad on Atom is no longer free. The bot_val parameter gives interpretive freedom without substitutability; bot-as-atom gives both, which is more than the mathematics calls for. Practically, [Bot Atom] constraints also accumulate through every signature in the strong completeness work for propositional, modal, and bimodal logics, making the API noticeably heavier. The trade-off is an extra constructor case in recursions and the bot_val parameter in algebraic semantics, but I think these are the right costs. More on this on Zulip.

On top: The current definition is top := ⊥ → ⊥ — the old a → a definition required [Inhabited Atom]. Both are provable by the same proof (impI + assumption), and as you noted, with [Bot Atom] Lean synthesises default = ⊥ anyway, so they coincide in that setting.

Looking forward to your thoughts on the revised version!

benbrastmckie added a commit to benbrastmckie/cslib that referenced this pull request Jun 16, 2026
Refocused from PR leanprover#649 to PR leanprover#648 (feat/propositional-v2).
Updated task description and created 6-phase plan for bot refactor.

Session: sess_1781632241_ba8d68
benbrastmckie added a commit to benbrastmckie/cslib that referenced this pull request Jun 16, 2026
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
benbrastmckie added a commit to benbrastmckie/cslib that referenced this pull request Jun 16, 2026
3-phase plan for drafting PR description, PR comment, and Zulip response
for PR leanprover#648 review. All outputs target specs/tmp/ for user review.

Session: sess_1781646913_02137d
benbrastmckie added a commit to benbrastmckie/cslib that referenced this pull request Jun 16, 2026
Delete Proposition.instBot_eq and Proposition.instTop_eq theorems from
Cslib/Logics/Propositional/Defs.lean. These two theorems auto-include
the [DecidableEq Atom] section variable which they do not use, triggering
unusedSectionVars/unusedDecidableInType warnings that --wfail promotes
to build errors. PR leanprover#648 already removed these theorems in its direction.

Session: sess_1781650791_5f754f

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
benbrastmckie added a commit to benbrastmckie/cslib that referenced this pull request Jun 17, 2026
Delete Proposition.instBot_eq and Proposition.instTop_eq theorems from
Cslib/Logics/Propositional/Defs.lean. These two theorems auto-include
the [DecidableEq Atom] section variable which they do not use, triggering
unusedSectionVars/unusedDecidableInType warnings that --wfail promotes
to build errors. PR leanprover#648 already removed these theorems in its direction.

Session: sess_1781650791_5f754f

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
benbrastmckie added a commit to benbrastmckie/cslib that referenced this pull request Jun 17, 2026
benbrastmckie added a commit to benbrastmckie/cslib that referenced this pull request Jun 17, 2026
Phase 1: Deleted instBot_eq/instTop_eq from Defs.lean (CI fix)
Phase 2: Removed snce past-time operator from Temporal.Formula
Phase 3: Blocked on PR leanprover#648 approval

Session: sess_1781650791_5f754f
benbrastmckie added a commit to benbrastmckie/cslib that referenced this pull request Jun 17, 2026
Rebase feat/temporal-formula-propositional onto feat/propositional-v2 head
(7cc0961). Resolved conflicts in Connectives.lean, Defs.lean, Basic.lean,
Theory.lean — taking PR leanprover#648 as base, adding temporal classes on top.

All CI checks pass: lake build, checkInitImports, lint-style, lint, lake test.
instIsIntuitionisticIntuitionisticCompletion preserved, instBot_eq/instTop_eq
absent, snce removed. Force-pushed to origin with --force-with-lease.

Session: sess_1781650791_5f754f

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
benbrastmckie added a commit to benbrastmckie/cslib that referenced this pull request Jun 17, 2026
225: Implement GHA algebraic semantics with primitive bot on main
226: Cherry-pick from main to create PR stacked on leanprover#648

Session: sess_1750107600_orchestrate
benbrastmckie added a commit to benbrastmckie/cslib that referenced this pull request Jun 17, 2026
… findings

Session: sess_1750130000_research227

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

task 228: complete implementation

Fix two docstring issues in PR leanprover#648: update intuitionisticCompletion
docstring to reflect primitive bot semantics, and change
"five-primitive propositional signature" to "five constructors" in
Connectives.lean module doc.

Session: sess_1750217870_a3b2c1

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

task 228: complete orchestration

Session: sess_1750217870_a3b2c1

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
benbrastmckie added a commit to benbrastmckie/cslib that referenced this pull request Jun 28, 2026
…#648 refresh

Recreates the four tasks lost during the main cleanup, aligned with Thomas
Waring's closing recommendation in the CSLib Zulip "Propositional Logic"
thread (606970606) and our synthesis decision:

- 398 efq_nd_rule_ipl_base_keep_mpl: make IPL the base logic (efq as a
  primitive ND rule) while PRESERVING all completed MPL metatheory as a
  retained layer. Depends on 397 (green main).
- 399 refresh_pr648_ipl_base_foundation: update PR leanprover#648 to the settled
  IPL-base foundation (refs + Zulip link), small + upstream-based cherry
  pick, connectives excluded. Depends on 398.
- 400 reconcile_connectives_pr607: unbundle connectives, reconcile with
  fmontesi PR leanprover#607 (Waring flag a).
- 401 polymorphic_evaluator_bool_prop_dpll: AlgEvaluate at Bool/Prop for
  DPLL (Doty/Waring).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NarRy36MgZCZP7TRsrL5Df
benbrastmckie added a commit to benbrastmckie/cslib that referenced this pull request Jun 28, 2026
…st-merge)

Post-merge vet of the merged Propositional development. CI: build/test/
checkInitImports/lint-style PASS; lake lint FAILS (54 errors). PR leanprover#648
foundation slice (Defs.lean + NaturalDeduction/Basic.lean) is lint-clean.

- Refresh 386: 21 PL-specific lint violations (accurate post-merge scope).
- New 406: 33 cross-cutting lint (Modal/Temporal/Bimodal/Foundations); absorbs 394.
- Refresh 390 (ORGANISATION.md), 387 (PL->Propositional, upstream-gated),
  384 (sorry location -> Minimal/Completeness.lean:110).
- Abandon 394 (absorbed into 406).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NarRy36MgZCZP7TRsrL5Df
benbrastmckie and others added 2 commits June 29, 2026 09:51
…e bot

Add `bot` as a primitive constructor of `Proposition Atom`, eliminating all
`[Bot Atom]` constraints from propositional logic signatures.

- New `Connectives.lean`: typeclass hierarchy (HasBot, HasImp, HasAnd, HasOr)
- `Defs.lean`: five-primitive Proposition type with derived neg, top, iff
- `Basic.lean`: natural deduction with impI/impE, andI/andE1/andE2, orI1/orI2
- `Theory.lean`: remove [Bot Atom], add instIsIntuitionisticIntuitionisticCompletion
- Replace German-language references with Avigad 2022, Prawitz 1965
- Semantics files deferred to follow-up PR per reviewer request

Reconciles with merged PR leanprover#536 (InferenceSystem-parameterized typeclasses).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Update intuitionisticCompletion docstring — the old wording "Attach a
bottom element" was misleading since bot is already a constructor.
Change "five-primitive propositional signature" to "five constructors"
in Connectives.lean to avoid conflating generators with operations.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@benbrastmckie benbrastmckie force-pushed the feat/propositional-v2 branch from 82f983a to 63cd13c Compare June 29, 2026 16:53
… falso

Promote ex falso quodlibet (bottom-elimination) to an ungated primitive
constructor of the natural-deduction Derivation, so IPL is the base
propositional logic and the primitive bot constructor has an inference
rule. IPL becomes the empty base theory; CPL still adds double negation
elimination.

The minimal-logic (MPL) layer is deferred to a separate PR: this removes
MPL, the IsIntuitionistic typeclass, intuitionisticCompletion, and the
derived efq rules, keeping the classical layer (byContra/lem/pierce and
the IsClassical instances for CPL/LEM/Pierce) intact, re-proved via the
efq constructor.

Per reviewer feedback (Waring, CSLib Zulip 'Propositional Logic'):
- Drop the connective typeclasses (Foundations/Logic/Connectives.lean and
  its registration instances) -- a separate development handled via PR leanprover#607.
- Restore references (Gentzen 1935, Prawitz 1965, Troelstra-van Dalen 1988)
  and add the CSLib Zulip thread link.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019sHZHp7U5qSiEzioK1nGEH
@benbrastmckie benbrastmckie force-pushed the feat/propositional-v2 branch from 63cd13c to 65a3af7 Compare June 29, 2026 17:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants