Skip to content

Convert the demos to single-file Spectre.Console apps - #110

Draft
HowardvanRooijen wants to merge 4 commits into
feature/marshalling-readerfrom
feature/spectre-demos
Draft

HowardvanRooijen wants to merge 4 commits into
feature/marshalling-readerfrom
feature/spectre-demos

Conversation

@HowardvanRooijen

@HowardvanRooijen HowardvanRooijen commented Sep 2, 2026

Copy link
Copy Markdown
Member

Replaces the Z3.Linq.Demo project - a single Program.cs that dumped every scenario through
Console.WriteLine - with a series of standalone single-file Spectre.Console
apps
under demos/. Each is a
.NET file-based app:
one .cs file that declares its own dependencies at the top and runs with dotnet run demos/<name>.cs

  • no project, no .slnx entry.

The demos

File Problem Spectre UI
river-crossing.cs Missionaries & Cannibals figlet banner, the crossing as a table, a Solve vs Optimize/orderby comparison
sudoku.cs Two puzzles side-by-side 9x9 puzzle/solution grids, clues in white and Z3-derived cells in green
boolean-logic.cs x XOR y, three ways one table over an anonymous type, a value tuple and a record
linear-systems.cs Integer systems (incl. Bart's TechEd 2012) constraints panel next to a solution table
oil-purchase.cs Least-cost LP purchase table with currency, spinner while optimising
warehouse.cs Least-cost shipping a warehouse x customer matrix
menu.cs Launcher a SelectionPrompt that runs any of the above

Each file references the library with #:project ../solutions/Z3.Linq/... (and
Z3.Linq.Examples where it uses the sample theorems), so the demos build against local source and
pick up the native Z3 package transitively. Sudoku's clues are turned into Cell{r}{c} == v
constraints with expression trees, so the printed puzzle and the constraints come from one array.

Why the examples project is untouched

Z3.Linq.Examples is the reusable theorem library (MissionariesAndCannibals,
SudokuTheorem/SudokuTable, RecordTheorem) - it has no console I/O and even ships as a NuGet
package. The Spectre work is purely presentation, so the demos consume the examples as-is rather
than changing them.

Portability

Non-ASCII is limited to the Sudoku box-drawing (near-universal, and what Spectre's own borders use);
the maths and logic are ASCII, per the guide's advice against fragile Unicode. Spectre auto-detects
terminal capability and degrades to plain text when output is redirected, so the demos are safe to
capture in scripts.

Verified

  • Every content demo run with dotnet run demos/<name>.cs - all six produce correct results
    (both Sudoku puzzles solved, the river-crossing Solve plan at 24 steps vs the minimal 12 from
    Optimize/orderby, the LPs at their known optima). menu.cs compiles.
  • Old project removed: solutions/Z3.Linq.Demo deleted, dropped from Z3.Linq.slnx, README
    updated, and a new demos/README.md added.
  • ./build.ps1 -Configuration Release - 46 tasks, 0 errors, 0 warnings with the Demo project gone.
  • File-based apps build to a temp directory, so nothing new lands in bin/obj or needs ignoring.

Reference

Built following the endjin Spectre.Console guide (read from the local knowledge-base clone; the URL
provided carried an access token, which was not fetched or transmitted).

Release note

No library or public-API change - developer-facing demos only. Releases remain on hold under #60.

🤖 Generated with Claude Code

Replaces the Z3.Linq.Demo project - a single Program.cs that wrote its output
with Console.WriteLine - with a series of standalone .NET file-based apps
(`dotnet run demos/<name>.cs`) that render the same problems with
Spectre.Console: figlet banners, rules, panels, tables, and a 9x9 Sudoku grid.

Each demo is one file that declares its own dependencies at the top
(`#:package Spectre.Console`, `#:project` the Z3.Linq and Z3.Linq.Examples
projects), so it needs no solution entry and builds against local source.
Z3.Linq.Examples is untouched - it is the reusable theorem library the demos
consume, not a presentation concern.

Demos, one file each:
- river-crossing.cs - Missionaries & Cannibals; Solve (any plan) vs
  Optimize/orderby (the shortest), as a crossing table plus a comparison.
- sudoku.cs - two puzzles on a rendered grid, clues driven through
  expression-tree constraints so the puzzle array is the single source of truth.
- boolean-logic.cs - x XOR y over an anonymous type, a value tuple and a record.
- linear-systems.cs - small integer systems incl. Bart's TechEd 2012 example.
- oil-purchase.cs / warehouse.cs - least-cost linear programs.
- menu.cs - a Spectre SelectionPrompt launcher that runs the others.

Non-ASCII is limited to the Sudoku box-drawing; the maths and logic are ASCII,
so the demos render in any terminal and degrade to plain text when redirected.

- Removed solutions/Z3.Linq.Demo and its .slnx entry; README now points at
  demos/, and demos/README.md lists and explains each one.
- Each of the six content demos verified with `dotnet run`; menu.cs builds.
- `./build.ps1 -Configuration Release` - 46 tasks, 0 errors, 0 warnings, with
  the Demo project gone.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PipoHZJsgydrV3JC3fQN6Q
@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown

Test Results

  1 files  ±0    1 suites  ±0   10s ⏱️ ±0s
309 tests ±0  309 ✅ ±0  0 💤 ±0  0 ❌ ±0 
322 runs  ±0  322 ✅ ±0  0 💤 ±0  0 ❌ ±0 

Results for commit b425802. ± Comparison against base commit 8f0659d.

♻️ This comment has been updated with latest results.

HowardvanRooijen and others added 3 commits September 2, 2026 11:30
Theorem<T>.Solve() returns T?, so dereferencing the result of a reference-type
environment without a guard warned CS8602. Value-type environments (the tuples)
were already fine, and the guarded demos (river-crossing, sudoku) already were
too. Null-forgive the reference-type solves - boolean-logic's anonymous-type and
record rows, and linear-systems' two Symbols<...> sections - since XOR and those
small systems are always satisfiable.

All six demos now build with zero warnings and run unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PipoHZJsgydrV3JC3fQN6Q
".NET Interactive" is now "Polyglot Notebooks", and Microsoft deprecated both
in early 2026 and archived dotnet/interactive (read-only since April 2026). No
community-maintained fork has been established - only discussed. Renames the
reference, adds a sourced deprecation note, and leads the Examples section with
the single-file demos as the maintained, tooling-free way to run the examples.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PipoHZJsgydrV3JC3fQN6Q
Microsoft deprecated and archived Polyglot Notebooks / .NET Interactive, so the
examples/z3-problems.dib notebook and every reference to it are removed: the
Examples section now points only to the maintained single-file demos, the
"For Polyglot Notebooks" getting-started subsection is dropped, and the stale
notebook link in the project history is removed. The examples/ folder held only
the notebook, so it is gone too.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PipoHZJsgydrV3JC3fQN6Q
@jsboige

jsboige commented Sep 17, 2026

Copy link
Copy Markdown

Ran the full stack on an independent fresh Windows machine (win-x64, .NET SDK 10.0.400) — validation notes, in case they're useful before the Z3 release unblocks:

Suite: 322/322 green. dotnet run --project solutions/Z3.Linq.Tests/Z3.Linq.Tests.csproj (MTP), ~4.3 s wall. The folder-feed mechanism works exactly as designed: Install-Z3Package.ps1 fetched the hash-pinned 5.1.0 nupkg and restore picked it up. Two Windows-quirk footnotes:

  • powershell -File invoked from Git Bash leaves $PSScriptRoot empty in the param default, so -FeedPath has to be passed explicitly (Windows PowerShell 5.1 only; pwsh unaffected, CI unaffected).
  • dotnet test (as opposed to dotnet run) returns exit code 5 / "zero tests" against the MTP project on SDK 10.0.400 — possibly a known dotnet test ↔ Testing.Platform bridge gap rather than anything in the stack.

Merge rehearsal against our fork (context: MyIntelligenceAgency/Z3.Linq sits 45 commits ahead / 0 behind main, same base as this stack; both lines are unmerged proposals off the same ancestor). Merging this branch's tip into our line conflicts on 10 files — 5 library (ExpressionVisitor.cs, Theorem.cs, Theorem{T}.cs, Z3Context.cs, Environment.cs) and 5 infra (build.yml, .gitignore, README.md, build.ps1, tests csproj). Taking the stack side on all ten, two residual blockers remain, both on ours:

  1. fork-only feature files trip the Generate and validate the XML documentation #94 doc-XML gate (CS1591 on Rational.cs operators, CS1574 on SolverKind.cs) — so feature PRs from our side will carry full XML docs on public members, which is a good gate to have;
  2. the two test projects collide in one folder — our 14 xUnit suites do not compile inside the stack's MSTest/MTP project (221 errors after suppressing the doc gate, a mix of harness mismatch and API drift against the refactored visitor). When the stack lands, our test contributions will be ported to the MSTest/MTP harness.

The rehearsal branch is pushed as integration/howard-stack on our fork for reproducibility.

Also opened #111 in support: a minimal xUnit floor pinned to current main semantics (10 facts) — complementary to your 322-suite, since it documents what main does today and would make any semantic drift introduced along the stack visible as a red test rather than a silent change. No action needed on it for this stack; it's there when you want a pre-stack baseline.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants