Parametrised modules, instantiated and renaming imports, postfix operators — group theory in textbook notation - #67
Open
Russoul wants to merge 7 commits into
Open
Parametrised modules, instantiated and renaming imports, postfix operators — group theory in textbook notation#67Russoul wants to merge 7 commits into
Russoul wants to merge 7 commits into
Conversation
A file may open, after its imports, with a MODULE HEADER — module
{G : 𝕌} (g : El (IsGroup G)) — that every def abstracts over. The
license is declared, not inferred: defs elaborate at the parameter
context and are Π/λ-closed (skeletons in step) before Σ and the
kernel, so entries are byte-identical to their fully-spelled
selves. Sibling references auto-apply the prefix through
PRE-SEEDED SPINE SLOTS (solutions given, not holes — overrides and
blanks flow past unchanged); instantiated imports
(import (groupTheory g) (…)) elaborate their arguments once, at
the importer's parameter context, through the spine solve itself —
implicit params recovered from the explicit ones' types — and
weaken to each use site. Plain imports see the def's full
telescope with header plicity, unchanged spellings. Distill prints
header and instantiated imports through the same grammar; round
trip and canonical form extend unchanged. Golden tests for all
three paths.
Nineteen defs at (G, g) fixed: gAssoc : (x y z : El G) →
gop (gop x y) z ≡ gop x (gop y z). Σ-α-identical by construction —
plain importers spell what they always spelled. Two external sites
adjusted (gInvUniq's g was per-def implicit, now header-explicit).
subgroup stays plain: its defs mix {g}/(g), and one header fixes
one plicity — recorded in the spec as the migration limit.
A third fixity class — postfix 9 ⁻¹ — parsed at the projection
tier (f x ⁻¹ is (f x) ⁻¹, the .π₁ convention, chains as x ⁻¹ ⁻¹),
excluded from infix climb and atom positions. Any fixity may carry
a target, making the token a FILE-LOCAL notation alias of a def:
infixl 7 · ≔ gop / postfix 9 ⁻¹ ≔ ginv / alias e ≔ ge, resolved
by name before the visibility table. Σ, statements, citations and
every external module are untouched — an alias, not a rename,
because an infix · has no slot for the group argument plain-import
sites spell positionally; the notation lives exactly where the
module sugar elides g.
def gAssoc : (x y z : El G) → x · y · z ≡ x · (y · z)
def gInvUniq : {x y : El G} → (x · y ≡ e) → x ⁻¹ ≡ y
def gOpInv : (x y : El G) → (x · y) ⁻¹ ≡ y ⁻¹ · x ⁻¹
Distill renders postfix at the projection tier with minimal
parenthesization; canonical form enforced as ever. ⁻¹ joins the
operator alphabet. Golden test for all three alias kinds.
def · / def ⁻¹ / def e — actual Σ names, not aliases (the alias mechanism from the previous commit is withdrawn in favor of one mechanism). Compatibility for plain importers, who must spell the group argument positionally, comes from the RENAMING IMPORT: import groupTheory (· as gop, e as ge, ⁻¹ as ginv, gAssoc, …) An "o as x" open installs the importer surface name for the Σ-def — one visibility-table entry — so every external site keeps its prefix spelling byte-for-byte; only import lines and qualified citations (groupTheory.·.eq) moved. A renamed open leaves its fixity behind: the operator role belongs to the spelling, not the def. The postfix class stays as-is.
subgroup at (G, g) with groupTheory INSTANTIATED at its own g — the first real use of instantiating imports, and the notation flows in: IsSubgroup : (N : El G → Ω) → Ω, cosetSplice : x · y ⁻¹ · (y · z ⁻¹) ≡ x · z ⁻¹. quotGroup at (G, g, N) with both groupTheory and subgroup instantiated: qInvLaw : … → qMul nn (qInv s nn u) u ≡ qUnit. The header fixes one plicity per parameter, so per-def-implicit g/N flipped to header-explicit: external sites on the flipped side spell a blank (cosetRefl _ s — solved from the proof argument's type), old explicit-(G) sites drop one. Five importing modules adjusted mechanically; every proof body outside the converted files is untouched.
The pre-application table keys on the importer's LOCAL surface
name, so one module instantiates twice per file with renaming as
the disambiguator: import (groupTheory g) (·, e, ⁻¹) alongside
import (groupTheory h) (· as ∙, e as eH, ⁻¹ as invH) — an
un-renamed duplicate open is refused, not shadowed. groupHom sits
at {G} (g) {H} (h): homInv : (p : El Hom) (x : El G) →
homAp p (x ⁻¹) ≡ invH (homAp p x). groupIso fixes a whole
homomorphism — module {G} (g) {H} (h) (p : El (HomRaw g h)) — all
41 defs at it.
Supporting pieces: f {} suppresses the parameter prefix (a module
referencing its own defs at OTHER instances: Hom {} _
(qIsGroup _ _ s nn) _ h); header types that need a parameterized
import before instantiation use a plain renamed open (HomRaw);
the bare-reference defer heuristic admits pre-applied references
as sources when their implicits are all inside the prefix; and
the qProj family — whose second group is the quotient, not a
parameter — moved to quotGroup (structure lemmas) and qProj.nova
(the projection hom).
·ᴳ ⁻¹ᴳ eG against ·ᴴ ⁻¹ᴴ eH — every group-vocabulary token in groupHom/groupIso names its side (modifier-letter superscripts join the operator alphabet; renamed opens declare their own fixities): homInv : (p : El Hom) (x : El G) → homAp p (x ⁻¹ᴳ) ≡ (homAp p x) ⁻¹ᴴ Single-group modules keep the bare ·, ⁻¹, e.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Parametrised modules for the perfect surface: a file may open, after its imports, with a module header — a telescope every def in the file abstracts over — plus the import forms and operator machinery that make the corpus's group theory read like the textbook. The governing discipline is unchanged: every sugar is declared, not inferred — recovery is a checkable rule, the round trip stays α-strict, and nothing moves the trust boundary (defs are Π/λ-closed over the header before they reach Σ and the kernel, so entries are byte-identical to their fully-spelled selves — the
groupTheorymigration is Σ-α-identical by construction, and the kernel is untouched).What the corpus reads like now
and in the two-group modules, per-side notation via renaming instantiated imports:
The pieces
Module headers.
module {G : 𝕌} (g : El (IsGroup G))after the imports. Defs elaborate at the parameter context and are Π/λ-closed (skeletons in step) before Σ; sibling references auto-apply the prefix through pre-seeded spine slots — solutions given, not holes — so written arguments,{t}overrides, blanks, and every recovery tier flow past them unchanged. Plain importers see the full telescope with the header's plicity: existing call sites spell exactly what they always spelled.Instantiated imports.
import (groupTheory g) (·, e, ⁻¹, …)applies a parameterized module at arguments elaborated once, at the importer's own parameter context, through the spine solve itself — written arguments cover the explicit parameters, implicit ones are recovered from their types — then weakened to each use site.Renaming imports.
o as xon any open installs the importer's surface name for the Σ-def (one visibility-table entry). This is what lets the defs' real names be the notation —def ·,def ⁻¹,def e— while plain importers, who must spell the group argument positionally (a slot infix syntax lacks), keep their prefix spellings byte-for-byte viaimport groupTheory (· as gop, e as ge, ⁻¹ as ginv, …). A renamed open deliberately leaves its fixity behind; a renamed operator declares its own.Double instantiation. The pre-application table keys on the importer's local name, so one module instantiates twice per file with renaming as the disambiguator —
groupTheoryatgand athabove. A second un-renamed open of the same name is refused, not shadowed. (Type-directed resolution across instantiations — one·for both groups — is deliberately deferred; the overload machinery extends to it naturally, but argument-less names likeestay ambiguous at inference positions.)Postfix operators. A third fixity class,
postfix 9 ⁻¹, parsed at the projection tier —f x ⁻¹is(f x) ⁻¹, exactly the.π₁convention, chaining asx ⁻¹ ⁻¹— excluded from infix climb and atom positions; the mention form(⁻¹)passes it as a function.f {}suppresses the parameter prefix too. The no-insert form already meant "the bare def over its full telescope"; extending that to the header prefix is how a module references its own defs at other instances —Hom {} _ (qIsGroup _ _ s nn) _ h, the hom out of the quotient, blanks recovered as ever.The corpus conversion
groupTheory(19 defs at(G, g)),subgroup((G, g);Ndeliberately stays per-def — the module quantifies over subgroups, several defs never mentionN, and its position/plicity varies),quotGroup((G, g, N), instantiating both predecessors, plus a plain renamedgroupTheoryimport for the quotient-group accessor lemmas — one module imported both ways),groupHom((G, g, H, h)), andgroupIso((G, g, H, h, p)— "fix a homomorphism", all 41 defs of the kernel/image/first-isomorphism development). TheqProjfamily split out ofgroupHom(its second group is the quotient, not a parameter): structure lemmas intoquotGroup, the projection hom into a newqProj.nova. Where a header fixed one plicity over defs that varied it, external sites on the flipped side spell a blank solved from the proof argument's type (cosetRefl _ s); everything else outside the converted files is textually untouched.Verification throughout: kernel Σ α-identical across the migration, corpus byte-canonical under
check-distill, 162 golden tests (new: parameterized elaboration, single and double instantiation, distill round trip of headers and instantiated imports, notation), 95/95 module elaborations in both store modes, ~10s full corpus elaboration (unchanged).Recorded limits
One header fixes one plicity per parameter; instantiation arguments resolve at elaboration (the header they mention comes later in the file than the import line);
data/clausal items inside parameterized modules are refused for now; qualified operator references in term position (grp.∙ x y) don't parse — renamed or unqualified access covers current use. All in the spec's Status section, with the conversion recipes.