Initial commit: Common — cross-language abstraction over TGC, TOC, TSM.

A new Lake project with path dependencies on the three sibling kernels
(golang-lean, octive-lean, tsm-lean). Provides typeclass abstractions
that capture what's structurally shared.

Common/ — three files:

  Lang.lean — two typeclasses:
    BigStepLang: Term, Value, State, Eval, deterministic.
                 Captures TGC's and TOC's big-step shape.
    SmallStepLang: State, step.
                   Captures TSM's small-step shape (determinism is
                   automatic from `step` being a function).
    Generic theorems exported once:
      BigStepLang.unique_value, BigStepLang.unique_state
      SmallStepLang.step_deterministic
    Plus a `CompileCorrect` structure for substrate-projection
    theorems (the categorical kernel of CompCert-style results).

  Instances.lean — three instances:
    TGCLang : BigStepLang   (State := Heap × Env)
    TOCLang : BigStepLang   (State := Env)
    TSMLang : SmallStepLang (State := TSM.State)
    Each instance bridges the local kernel's existing
    `BigStep`/`step` + `deterministic` proof into the typeclass.

  Demo.lean — three application examples:
    The SAME `BigStepLang.unique_value` theorem applied to TGC and
    TOC; `SmallStepLang.step_deterministic` to TSM. One abstract
    definition, three concrete payoffs.

The factoring is real: any new theorem stated over the typeclasses
applies to all instances. Future theorems (compilation correctness,
type soundness, simulation) can be expressed abstractly and proved
once.

Zero sorries / axioms / admits across all four projects.
This commit is contained in:
Maximus Gorog 2026-05-10 06:52:25 -06:00
commit a0b719e170
8 changed files with 259 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/.lake

3
Common.lean Normal file
View file

@ -0,0 +1,3 @@
import Common.Lang
import Common.Instances
import Common.Demo

56
Common/Demo.lean Normal file
View file

@ -0,0 +1,56 @@
import Common.Instances
namespace Common.Demo
open Common
/-! # Cross-language abstraction demonstration.
The same generic theorem `BigStepLang.unique_value` is here applied
to TGC and TOC. The `SmallStepLang.step_deterministic` is applied
to TSM. One abstract definition, multiple concrete payoffs. -/
/-! ## Generic theorem statement (in `Common.Lang`):
`BigStepLang.unique_value : Eval s t v₁ s₁ → Eval s t v₂ s₂ → v₁ = v₂`
Below are direct applications. -/
/-! ### TGC (golang-lean) — the `Heap × Env`-stateful instance. -/
example
(h : GolangLean.Core.Heap) (env : GolangLean.Core.Env)
(t : GolangLean.Core.Term)
(v₁ v₂ : GolangLean.Core.Value) (h₁ h₂ : GolangLean.Core.Heap)
(D₁ : GolangLean.Core.BigStep h env t v₁ h₁)
(D₂ : GolangLean.Core.BigStep h env t v₂ h₂) :
v₁ = v₂ := by
-- Package the existing TGC theorem as a Common.BigStepLang application:
exact BigStepLang.unique_value
(L := TGCLang) (s := (h, env)) (s₁ := (h₁, env)) (s₂ := (h₂, env))
⟨D₁, rfl⟩ ⟨D₂, rfl⟩
/-! ### TOC (octive-lean) — the env-mutating instance. -/
example
(env : OctiveLean.Core.Env)
(t : OctiveLean.Core.Term)
(v₁ v₂ : OctiveLean.Core.Value) (env₁ env₂ : OctiveLean.Core.Env)
(D₁ : OctiveLean.Core.BigStep env t v₁ env₁)
(D₂ : OctiveLean.Core.BigStep env t v₂ env₂) :
v₁ = v₂ :=
BigStepLang.unique_value (L := TOCLang) D₁ D₂
/-! ### TSM (tsm-lean) — the small-step instance. -/
example
(s s₁ s₂ : TsmLean.Core.State)
(h₁ : TsmLean.Core.step s = some s₁) (h₂ : TsmLean.Core.step s = some s₂) :
s₁ = s₂ :=
SmallStepLang.step_deterministic (L := TSMLang) h₁ h₂
/-! ## Observation: with three instances now exhibiting `BigStepLang`/
`SmallStepLang`, any new theorem stated abstractly applies to all
of them. The factoring is real. -/
end Common.Demo

46
Common/Instances.lean Normal file
View file

@ -0,0 +1,46 @@
import Common.Lang
import GolangLean.Core.Determinism
import OctiveLean.Core.Determinism
import TsmLean.Core.Determinism
namespace Common
/-! # Instances — TGC, TOC, TSM as `Common` languages.
Each kernel's existing types, semantics, and determinism theorem
package as a typeclass instance. The shared abstractions in
`Common.Lang` then apply uniformly. -/
/-! ## TGC (golang-lean) — big-step over `Heap × Env`. -/
instance TGCLang : BigStepLang where
Term := GolangLean.Core.Term
Value := GolangLean.Core.Value
State := GolangLean.Core.Heap × GolangLean.Core.Env
Eval := fun (he : GolangLean.Core.Heap × GolangLean.Core.Env)
(t : GolangLean.Core.Term)
(v : GolangLean.Core.Value)
(he' : GolangLean.Core.Heap × GolangLean.Core.Env) =>
GolangLean.Core.BigStep he.1 he.2 t v he'.1 ∧ he.2 = he'.2
deterministic := by
rintro ⟨h, env⟩ t v₁ v₂ ⟨h₁, env₁⟩ ⟨h₂, env₂⟩ ⟨D₁, henv₁⟩ ⟨D₂, henv₂⟩
have ⟨hv, hh⟩ := GolangLean.Core.BigStep.deterministic D₁ D₂
subst henv₁; subst henv₂; subst hh
exact ⟨hv, rfl⟩
/-! ## TOC (octive-lean) — big-step over `Env`. -/
instance TOCLang : BigStepLang where
Term := OctiveLean.Core.Term
Value := OctiveLean.Core.Value
State := OctiveLean.Core.Env
Eval := OctiveLean.Core.BigStep
deterministic := fun D₁ D₂ => OctiveLean.Core.BigStep.deterministic D₁ D₂
/-! ## TSM (tsm-lean) — small-step over `State`. -/
instance TSMLang : SmallStepLang where
State := TsmLean.Core.State
step := TsmLean.Core.step
end Common

97
Common/Lang.lean Normal file
View file

@ -0,0 +1,97 @@
/-!
# Common.Lang — cross-language abstraction.
A `BigStepLang` is a programming-language fragment with:
* a syntactic class of terms,
* a class of values,
* a state type carrying everything else (env, heap, etc.),
* a big-step relation `Eval : State → Term → Value → State → Prop`
saying "starting in state `s`, evaluating term `t` produces value
`v` and state `s'`",
* a determinism property (the relation is functional in `(v, s')`).
This generalises TGC's `BigStep : Heap → Env → Term → Value → Heap`
(with State := Heap × Env) and TOC's `BigStep : Env → Term → Value →
Env` (with State := Env). TSM uses small-step semantics and fits a
different class — see `SmallStepLang`.
The point of the abstraction: theorems about *any* deterministic
big-step language are stated and proved once, and apply to all
instances. -/
namespace Common
class BigStepLang where
Term : Type
Value : Type
State : Type
Eval : State → Term → Value → State → Prop
deterministic : ∀ {s : State} {t : Term} {v₁ v₂ : Value} {s₁ s₂ : State},
Eval s t v₁ s₁ → Eval s t v₂ s₂ → v₁ = v₂ ∧ s₁ = s₂
namespace BigStepLang
variable [L : BigStepLang]
/-- Result of an evaluation, when it exists, is unique. -/
theorem unique_value
{s : L.State} {t : L.Term} {v₁ v₂ : L.Value} {s₁ s₂ : L.State}
(h₁ : L.Eval s t v₁ s₁) (h₂ : L.Eval s t v₂ s₂) :
v₁ = v₂ :=
(L.deterministic h₁ h₂).1
theorem unique_state
{s : L.State} {t : L.Term} {v₁ v₂ : L.Value} {s₁ s₂ : L.State}
(h₁ : L.Eval s t v₁ s₁) (h₂ : L.Eval s t v₂ s₂) :
s₁ = s₂ :=
(L.deterministic h₁ h₂).2
end BigStepLang
/-! ## SmallStepLang — small-step semantics (e.g., TSM).
A `SmallStepLang` is structurally simpler: a state type and a step
function. Determinism is automatic since `step` is a function. -/
class SmallStepLang where
State : Type
step : State → Option State
namespace SmallStepLang
variable [L : SmallStepLang]
/-- Reflexive-transitive closure of `step`. -/
inductive MultiStep : L.State → L.State → Prop where
| refl (s : L.State) : MultiStep s s
| cons {s s' s'' : L.State}
(h₁ : L.step s = some s') (h₂ : MultiStep s' s'') :
MultiStep s s''
/-- Single-step is functional. -/
theorem step_deterministic {s s₁ s₂ : L.State}
(h₁ : L.step s = some s₁) (h₂ : L.step s = some s₂) :
s₁ = s₂ := by
rw [h₁] at h₂; exact Option.some.inj h₂
end SmallStepLang
/-! ## Compilation correctness — the substrate-projection theorem.
If `Source` is a `BigStepLang`, `Target` is either kind, and `compile`
maps source specs to target specs preserving evaluation, then the
compilation pipeline inherits determinism.
This is the categorical kernel of CompCert-style theorems. -/
structure CompileCorrect
(Source : BigStepLang)
(Target : Type) (TargetEval : Target → Source.Value → Prop)
(compile : Source.Term → Target) where
/-- Compilation preserves evaluation: source `Eval` implies target
`TargetEval` produces the same value. -/
preservation :
∀ {s : Source.State} {t : Source.Term} {v : Source.Value} {s' : Source.State},
Source.Eval s t v s' → TargetEval (compile t) v
end Common

37
lake-manifest.json Normal file
View file

@ -0,0 +1,37 @@
{"version": "1.2.0",
"packagesDir": ".lake/packages",
"packages":
[{"type": "path",
"scope": "",
"name": "«tsm-lean»",
"manifestFile": "lake-manifest.json",
"inherited": false,
"dir": "../tsm-lean",
"configFile": "lakefile.toml"},
{"type": "path",
"scope": "",
"name": "«octive-lean»",
"manifestFile": "lake-manifest.json",
"inherited": false,
"dir": "../octive-lean",
"configFile": "lakefile.toml"},
{"type": "path",
"scope": "",
"name": "«golang-lean»",
"manifestFile": "lake-manifest.json",
"inherited": false,
"dir": "../golang-lean",
"configFile": "lakefile.toml"},
{"url": "https://github.com/leanprover-community/ProofWidgets4",
"type": "git",
"subDir": null,
"scope": "",
"rev": "2db6054a44326f8c0230ee0570e2ddb894816511",
"name": "proofwidgets",
"manifestFile": "lake-manifest.json",
"inputRev": "v0.0.98",
"inherited": true,
"configFile": "lakefile.lean"}],
"name": "«common-lean»",
"lakeDir": ".lake",
"fixedToolchain": false}

18
lakefile.toml Normal file
View file

@ -0,0 +1,18 @@
name = "common-lean"
version = "0.1.0"
defaultTargets = ["Common"]
[[require]]
name = "golang-lean"
path = "../golang-lean"
[[require]]
name = "octive-lean"
path = "../octive-lean"
[[require]]
name = "tsm-lean"
path = "../tsm-lean"
[[lean_lib]]
name = "Common"

1
lean-toolchain Normal file
View file

@ -0,0 +1 @@
leanprover/lean4:v4.30.0-rc2