infoductor/Infoductor/Foundation/MetaPath.lean
Maximus Gorog ba0a49823b Phase A: Foundation lib — meta-mirror, Edit/Context, restructure, registries
Initial commit.  Six modules extracted from
cubical-transport-hott-lean4/CubicalTransport/Algebra/ and
re-namespaced as `Infoductor`:

- Foundation/Meta.lean         — MetaCType, MetaClassifier,
                                 MetaArtifact, MetaPosition
                                 (with manual mutual decEq for
                                 MetaClassifier's recursive
                                 lattice arms)
- Foundation/Edit.lean         — Edit monad + Context comonad +
                                 distributive law +
                                 MetaClassifier.atPosition
                                 with lattice laws as theorems
- Foundation/Restructure.lean  — universal `restructure` (5-field
                                 comp-shaped operation), 6 frozen
                                 aliases, headless apply +
                                 brokenRefs / selfConsistent /
                                 Edit.guarded
- Foundation/MacroAlias.lean   — @[macroAlias] attribute +
                                 EnvExtension registry
- Foundation/MetaPath.lean     — @[metaPath src target]
                                 attribute + registry +
                                 findPathsFromSource/ToTarget
- Foundation/Methodology.lean  — @[methodology classifier]
                                 attribute + registry +
                                 deriveByTransport (walks
                                 metaPath registry) +
                                 tryEntryAsClosed primitive +
                                 cubical_search reference
                                 demonstrator

Builds clean on lean4 v4.30.0-rc2, ten oleans.  No deps beyond
Lean stdlib.  Sub-libs Tactics / Pantograph / Runner are planned
under the same lakefile.toml but not yet implemented.

Pairs with Pantograph as the conductor sits atop the pantograph
on an electric train.  "Info-ductor" — conducts information
(structure / classifications / methodology) through a Lean
codebase.

Forgejo: http://maxgit.wg:3000/max/infoductor

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 07:20:36 -06:00

127 lines
5.2 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/-
Infoductor.Foundation.MetaPath — `@[metaPath]` attribute
===========================================================
Phase D'.5 of `docs/ALGEBRA_PLAN.md`. Provides the structural-Path
declaration system that powers methodology-transport in
`cubical_search`.
A `MetaPath` is the meta-level analogue of a cubical `Path`: a
declared equivalence between two `MetaClassifier` shapes, witnessed
by a Lean theorem that exhibits the equivalence.
Example use:
@[metaPath IsFullFace IsConstLine]
theorem fullFace_implies_constLine_on_path (q : CompQ) :
IsFullFace q → IsConstLine q := …
Once such a Path is registered, every methodology indexed against
`IsFullFace` automatically becomes a candidate for `IsConstLine`
via `transp` at the methodology level.
Per ALGEBRA_PLAN §10.1 OQ: the witness theorem is required (a
declared MetaPath without a propositional witness would be
unsound). In v0 we trust the `metaPath` annotation; future REL3+
work can verify the witness type-checks against an expected shape.
-/
import Lean
import Infoductor.Foundation.Meta
namespace Infoductor
open Lean
-- ── MetaPath entries ────────────────────────────────────────────────────────
/-- A registered structural Path between two classifiers.
`sourceClassifier` and `targetClassifier` are `Name`s pointing
to classifier predicates (typically defined in `Question.lean` —
`IsFullFace`, `IsConstLine`, `IsPathLine`, etc.).
`witnessName` names a theorem exhibiting the equivalence /
implication between them.
Direction matters: a Path `A ↦ B` means "every methodology for
A produces a methodology for B" (via post-composition with the
witness). The reverse direction needs a separate `metaPath B A`
declaration. -/
structure MetaPathEntry where
sourceClassifier : Name
targetClassifier : Name
witnessName : Name
description : String := ""
deriving Repr, Inhabited
-- ── The MetaPath registry ───────────────────────────────────────────────────
initialize metaPathRegistryExt :
SimplePersistentEnvExtension MetaPathEntry (Array MetaPathEntry) ←
registerSimplePersistentEnvExtension {
name := `Infoductor.metaPathRegistry
addEntryFn := fun arr e => arr.push e
addImportedFn := fun arrs => arrs.foldl (init := #[]) Array.append
asyncMode := .sync
}
def getMetaPaths : CoreM (Array MetaPathEntry) := do
let env ← getEnv
return metaPathRegistryExt.getState env
def registerMetaPath (entry : MetaPathEntry) : CoreM Unit := do
modifyEnv (metaPathRegistryExt.addEntry · entry)
/-- Find every Path whose source matches a given classifier name. -/
def findPathsFromSource (source : Name) : CoreM (Array MetaPathEntry) := do
let all ← getMetaPaths
return all.filter (·.sourceClassifier == source)
/-- Find every Path whose target matches a given classifier name. -/
def findPathsToTarget (target : Name) : CoreM (Array MetaPathEntry) := do
let all ← getMetaPaths
return all.filter (·.targetClassifier == target)
-- ── The `@[metaPath]` attribute ─────────────────────────────────────────────
/-- Parser-level data for the `@[metaPath]` attribute: takes the
source classifier and the target classifier as identifiers.
The witness is the tagged declaration itself. -/
syntax (name := metaPath) "metaPath" ident ident : attr
/-- The `@[metaPath]` attribute itself. Records the tagged
declaration as a structural Path between two classifiers. -/
initialize metaPathAttr : Unit ←
registerBuiltinAttribute {
name := `metaPath
descr := "Register this declaration as a structural Path \
between two classifiers (Phase D'.5 of \
ALGEBRA_PLAN.md). Usage: `@[metaPath SourceClassifier \
TargetClassifier]`."
add := fun declName stx _kind => do
let parsed? : Option (Name × Name) :=
match stx with
| `(attr| metaPath $src:ident $tgt:ident) =>
some (src.getId, tgt.getId)
| _ => none
let some (src, tgt) := parsed?
| throwError "@[metaPath] requires source and target classifier names"
let env ← getEnv
let docstring? := (← findDocString? env declName).getD ""
registerMetaPath
{ sourceClassifier := src
, targetClassifier := tgt
, witnessName := declName
, description := docstring? }
}
-- ── Diagnostics ─────────────────────────────────────────────────────────────
def printMetaPaths : CoreM Unit := do
let entries ← getMetaPaths
IO.println s!"── MetaPath registry ({entries.size}) ──"
for entry in entries do
let d := if entry.description.isEmpty then "" else s!" — {entry.description}"
IO.println
s!" {entry.sourceClassifier} ↦ {entry.targetClassifier} via {entry.witnessName}{d}"
end Infoductor