Commit graph

5 commits

Author SHA1 Message Date
Maximus Gorog
4b6fcec565 Add SymPy bridge and migrate DSL to brace-block syntax.
Symbolic computation via a persistent Python subprocess: new `.sym`
Value variant carries (srepr, pretty), `OctiveLean.SymPyBridge` owns
the subprocess and round-trips expressions, and `evalBinOp`/unary
negation route through SymPy when either operand is `.sym`.  Corpus
adds sym_basic, sym_solve_simplify, sym_calc; demos add Lorenz,
Van der Pol, gravity, SymToolboxDemo, Lab7Interp.

DSL surface changes from `octave! ... octave_end` to `octave! { ... }`.
RosettaStone rewritten against the new syntax; PlotDemo updated.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 02:58:50 -06:00
Maximus Gorog
d86d500b4f Prove preservation theorem for TOC big-step semantics.
OctiveLean/Core/Preservation.lean — the TOC analogue of TGC's
preservation. Statement:

  HasType Γ e T  ∧  HasTypeEnv env Γ  ∧  BigStep env e v env'
    ⟹  HasTypeV v T  ∧  HasTypeEnv env' Γ

No heap-typing extension (Octave has no heap). Γ is unchanged across
big-steps (assign requires x already typed).

Three structural changes were required to make preservation provable
under env-mutation, all small:

  * letIn semantics shifted to scope-restoring: BigStep.letInR now
    returns env1 (the env after evaluating the bound expression)
    rather than env2 (after the body). This drops body's mutations
    at scope-end, matching the lambda-calculus tradition. Determinism
    and Eval updated to match.

  * HasTypeV.vClos uses a two-part premise (he_dom + he_typed)
    instead of nested ∃ — the kernel rejects nested inductive
    parameters with locally-bound vars. The two parts are equivalent
    to HasTypeEnv via the new HasTypeV.vClos_to_env inversion lemma.

  * Inversion via HasTypeV.vClos_to_env exposes the closure's typing
    context as an existential — preservation's appR case uses this
    to construct the body's HasTypeEnv via extend_letIn.

The cross-language symmetry that emerged:

  TGC preservation  : threads heap-typings, weakens via extension.
  TOC preservation  : threads env directly, no extension needed.

In both, the rule cases collapse into the same three structural
shapes — terminal, IH-chain, contradiction-collapse. The case bodies
differ in HOW state is propagated (heap-typing for TGC, env for TOC)
but the SHAPE of each case is identical. That's the cross-language
abstraction speaking.

Zero sorries / axioms / admits across both projects.
2026-05-10 04:32:52 -06:00
Maximus Gorog
567d3d1902 Add Tiny Octave Core (TOC) parallel to golang-lean's TGC.
OctiveLean/Core/ — the kernel-level formal layer that octive-lean's
existing surface BigStep didn't have. Six files:

  Syntax.lean       — Term, BinOp. Twelve constructors: ten shared
                      with TGC plus assign (var mutation in env) and
                      whileT (loop). No refs (Octave has no &/*).
  Semantics.lean    — Value, EnvList, BigStep. Signature
                      `BigStep : Env -> Term -> Value -> Env -> Prop`
                      threading env (vs TGC's `Heap x Env`).
  Determinism.lean  — BigStep.deterministic. Same case shapes as TGC
                      for the shared ten constructors. The whileFR/whileTR
                      cross-case mirrors TGC's ifTR/ifFR via Bool.noConfusion.
  Eval.lean         — fuel-bounded eval + eval_sound. whileT recursion
                      consumes one fuel unit per iteration. Function
                      calls discard the body's post-env (Octave/MATLAB
                      local-scope semantics).
  Types.lean        — Ty (no ref), TyEnv, HasType. Twelve typing rules
                      mirroring the constructors.
  TypeSoundness.lean — HasTypeV inductive, function-form HasTypeEnv.
                      vClos uses two-part formulation (he_dom + he_typed)
                      instead of nested existential — Lean's kernel rejects
                      the natural ∃-form due to nested-inductive parameter
                      restrictions. extend_typed (assign preservation) and
                      extend_letIn (letIn preservation) lemmas.

Cross-language symmetry surfaced this iteration:
  * Determinism proof: ten cases mirror TGC line-for-line. Two new
    cases (assign, while) follow the same three structural shapes.
  * Eval signature: state type differs (Env vs Heap×Env), constructors'
    eval recurrences are otherwise isomorphic.
  * Type system: Ty diverges (no ref vs no whileT/assign), but the
    typing-rule shapes are identical — variables, let, app, if, binop, seq.
  * Typing of runtime data is where the languages most diverge:
    TGC's structural HasTypeEnv works because env is scoped; TOC needs
    function-form because env mutates. This is the *real* asymmetry that
    a cross-language layer would have to abstract over.

Preservation deferred — has a soundness gap with letIn-shadowing-then-
assign that needs a freshness premise on letIn typing. To follow.

Zero sorries / axioms / admits. Full lake build clean (73 jobs).
2026-05-10 04:26:12 -06:00
Maximus Gorog
23162fb93a Add README, CONTRIBUTING, editorconfig, gitattributes, justfile
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 09:44:24 -06:00
Maximus Gorog
db79eb3fde Initial commit: Lean 4 reimplementation of GNU Octave
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 09:40:46 -06:00