Skip to content

Overlay operators (*) (/) and operator demo #3

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 38 commits into from
May 11, 2025
Merged

Conversation

alok
Copy link
Owner

@alok alok commented May 8, 2025

Added\n* New HMul and HDiv instances so * and / overlay plots just like +.\n* LeanPlot/Demos/OperatorPlayground.lean demonstrates the new operators with a multi-series chart.\n\nNo breaking changes; existing code continues to work.\n\n### Motivation\nMakes plain-ASCII composition ergonomics better for teaching sessions.\n\ncc @alok


Important

Add HMul and HDiv instances for plot overlays and demonstrate in OperatorPlayground.lean.

  • Behavior:
    • Added HMul and HDiv instances to allow * and / to overlay plots, similar to +.
    • Demonstration of new operators in LeanPlot/Demos/OperatorPlayground.lean with a multi-series chart.
  • Documentation:
    • Updated CHANGELOG.md to reflect new features and changes.
    • Added new rules in .cursor/rules/ for debugging, import order, plot feature gallery, and Verso docstrings.
  • Misc:
    • Updated README.md with new features and installation instructions.
    • Updated Gallery.md to include new demo entries.
    • Added DocsMain.lean for manual generation configuration.

This description was created by Ellipsis for 8cc20bf. You can customize this summary. It will automatically update as commits are pushed.

Summary by CodeRabbit

  • New Features

    • Introduced zero-configuration chart helpers (lineChart, scatterChart) for quick plotting from functions or arrays.
    • Added a composable graphics algebra for overlaying plots using the + operator.
    • Implemented a declarative plot specification system with customizable axes, legends, titles, and series types.
    • Added a #plot command for easy rendering of charts within Lean code.
    • Provided a color palette and automatic color assignment for series.
  • Enhancements

    • Added legend and scatter plot support.
    • Enabled automatic y-axis domain inference.
    • Improved documentation and example demos for linear, quadratic, cubic, and overlay plots.
    • Introduced debugging utilities for saving charts as PNG images.
  • Documentation

    • Expanded and reorganized README, changelog, roadmap, and internal documentation.
    • Added detailed guides and rules for code style, documentation, and gallery demos.
  • Chores

    • Updated configuration files, dependencies, and toolchain for improved linting, documentation, and build consistency.

alok added 30 commits May 2, 2025 04:01
• New demo `QuadraticDemo.lean` plotting y = x²
• New demo `OverlayDemo.lean` overlaying linear & quadratic with legend via `mkLineChartFull`
• Update `Gallery.md` checklist – linear & quadratic done
• Tick core goals in `.cursorrules`
• Bump CHANGELOG with 0.1.3 entry
• Root `LeanPlot.lean` imports new demos
• New module `LeanPlot.Palette` featuring a 10-colour Viridis palette.
• `colourFor` cycles through palette with safe indexing.
• `autoColours` maps an array of series names to distinct colours.
• Updated `LinearDemo` to use `autoColours` (no hard-coded stroke).
• Root module imports Palette.

Build clean; warnings about deprecated `Array.get!`/`List.enum` noted for future refactor.
• New wrappers fix domain to [0,1] – reduces boilerplate.
• Updated Quadratic & Overlay demos to use new helpers + autoColours.
…t and scatterChart helpers\n\n• Add LeanPlot.Constants for default dimensions\n• Add LeanPlot.API exposing lineChart & scatterChart zero-config wrappers\n• Extend Components with ScatterChart bindings and mkScatterChart\n• Palette exposes colourFor\n\nSemVer: minor
- Provide clearer examples for `lakefile.toml` and `lakefile.lean`
- Update quick-start example to use point-free lambda for brevity

Part of ergonomics/tier0-chart workstream.
• Deleted redundant helpers in `LeanPlot.Components`; users can achieve
  the same behaviour via partial application of `sample` / `sampleMany`.
• Updated `QuadraticDemo` accordingly.

BREAKING CHANGE: demos or code relying on `sample01`/`sampleMany01` must
switch to `sample`/`sampleMany`.
…list

- Rewrite features list to emphasise zero-config API
- Adjust quick-start snippet to use `open LeanPlot.API` + `lineChart`
- Expand demo list (linear, quadratic, cubic, overlay)
- Tick cubic demo in Gallery already done earlier
- Update documentation progress in llms notes

Also:
- Fix Justfile indentation for `changelog-update` recipe

No functional code changes.
- Rename proof variable `h` to `_h` in `AutoDomain.autoDomain`
- Prefix unused `lo`/`hi` binding with underscores in `API.lineChart`

No behaviour change. Build now clean of warnings.
Adds a low-priority `HAdd` instance that lifts arbitrary values with
`[ToPlot]` instances to `Plot`s and concatenates their layers.  This
gives ergonomic `+` composition for mixing built-in `LinePlot`s with
future user-defined layer types without boiler-plate conversions.

No functional change to existing code; all tests compile.
With the new abstractions in `LeanPlot.Core` we no longer need local
`Render`/`CoeTC` definitions or a custom `+` overlay instance here.
We:
• import `LeanPlot.Core` for the Render machinery;
• drop the duplicated class/instance definitions;
• provide a `ToLayer LinePlot` instance so generic overlays work.
Compilation is clean.
Adds new module `LeanPlot.Debug` containing:
• `SavePNG` React component (bundles html2canvas)  
• `withSavePNG` helper that prepends a download button to any `Html` chart.

Useful when visually debugging chart rendering.  Build succeeds.
…ate demos to Tier-0 API

• Write per-field docs for AxisProps, ScatterChartProps, ScatterProps.
• Add colour-name docstrings in LeanPlot.Palette.
• Briefly document #plot alias.
• Switch LinearDemo & QuadraticDemo to new LeanPlot.API.lineChart helper;
  improve OverlayDemo docs and add sin chart example.
• Bump Lean toolchain to 4.20.0-rc2 (matches PW4 v0.0.57 requirement).
• Pin Verso to the latest commit hash instead of moving target “main”.
• Update lake-manifest lock-file accordingly.
• TODO list: add auto-axis-label idea.

No functional changes to library code; build still passes with `just build`. 🎨📖
alok added 8 commits May 6, 2025 00:41
… files

Move Verso documentation integration to backlog and focus back on plotting ergonomics. Added work log entry. Stage WIP docs stub and experimental modules so branch compiles but deprioritised.
…Chart Tier-0 helper\n\nUse autoDomain to calculate (lo, hi) and pass domain prop to YAxis for better scaling. Update let sequencing semicolons.
Copy link

coderabbitai bot commented May 8, 2025

Walkthrough

This update introduces a comprehensive ergonomic and architectural overhaul of the LeanPlot library. It adds new zero-configuration chart helpers, a composable algebra for plot overlay, a declarative specification system, and a flexible rendering pipeline. Extensive documentation, demos, and developer tooling are included, with new modules for color palettes, debugging, and domain inference. The update also enhances documentation generation and enforces code style and import order.

Changes

Files / Groups Change Summary
.cursor/rules/*.mdc, .cursorrules Added documentation and rule files for debugging chart images, import order in Lean, gallery demo enforcement, Verso docstrings, and updated checklist statuses.
CHANGELOG.md, README.md, Gallery.md, TODO.md Expanded and restructured changelog; updated README for new API and demos; marked demo checklist items as complete; reorganized and timestamped roadmap.
lakefile.toml, lake-manifest.json, lean-toolchain Added Verso package dependency, enabled doc comment linter, updated Lean toolchain to v4.20.0-rc2, and revised package dependencies.
llms.txt Added a detailed design and development roadmap for ergonomic plotting APIs and rendering architecture.
DocsMain.lean New entry point for generating multi-page documentation using Verso, with custom config and main function.
Justfile Switched linting to use Batteries linter; reformatted Python script for changelog timestamp updates.
Main.lean, LeanPlot/Basic.lean Added documentation comments to main and hello functions.
LeanPlot.lean Added imports for new modules: Plot, LinearDemo, QuadraticDemo, OverlayDemo, Palette.
LeanPlot/API.lean Introduced zero-config helpers: lineChart, scatterChart, xyArrayToJson, mkLineChart.
LeanPlot/Algebra.lean Added algebraic composition for plots with LineSeries, LinePlot, overlay operation, and rendering.
LeanPlot/AutoDomain.lean Added autoDomain function for automatic y-axis domain inference.
LeanPlot/Axis.lean Enhanced doc comments for AxisProps fields.
LeanPlot/Components.lean Added legend support, Recharts scatter plot components, and mkLineChartFull, mkScatterChart helpers.
LeanPlot/Constants.lean Introduced defaultW and defaultH constants for default chart sizes.
LeanPlot/Core.lean Added foundational abstractions: Render typeclass, Layer, Plot, compositional operators, and rendering.
LeanPlot/DSL.lean Added #plot command macro for inline plotting with optional sample count.
LeanPlot/Debug.lean Added PNG snapshot utility: SavePNG component and withSavePNG helper.
LeanPlot/Demos/*.lean Added demos for linear, quadratic, cubic, overlay, and multi-series plots.
LeanPlot/Experiments.lean Added scratchpad for ad-hoc plotting and development roadmap notes.
LeanPlot/Legend.lean Added wrapper for Recharts <Legend> component.
LeanPlot/Palette.lean Added default color palette and helpers for color assignment.
LeanPlot/Plot.lean Added top-level #plot command for rendering any HTML-producing term.
LeanPlot/Specification.lean Introduced declarative plot specification (PlotSpec), series/axis specs, combinators, and rendering logic.
LeanPlot/ToFloat.lean Improved docs and added unconditional ToFloat instance for Lean's rational type.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant LeanPlot.API
    participant LeanPlot.Core
    participant LeanPlot.Components
    participant ProofWidgets
    participant Recharts

    User->>LeanPlot.API: call lineChart(f)
    LeanPlot.API->>LeanPlot.AutoDomain: autoDomain(f)
    LeanPlot.API->>LeanPlot.Components: mkLineChart (sampled data, colors)
    LeanPlot.Components->>ProofWidgets: Render LineChart JSX
    ProofWidgets->>Recharts: Render chart in browser
    Recharts-->>ProofWidgets: Chart HTML output
    ProofWidgets-->>User: Display chart in infoview
Loading
sequenceDiagram
    participant User
    participant LeanPlot.PlotCommand
    participant ProofWidgets

    User->>LeanPlot.PlotCommand: #plot t
    LeanPlot.PlotCommand->>ProofWidgets: Evaluate t to Html
    ProofWidgets-->>User: Render chart in infoview
Loading
sequenceDiagram
    participant User
    participant LeanPlot.Debug
    participant html2canvas

    User->>LeanPlot.Debug: Click "Save PNG"
    LeanPlot.Debug->>html2canvas: Capture chart HTML by ID
    html2canvas-->>LeanPlot.Debug: Return PNG image
    LeanPlot.Debug-->>User: Trigger PNG download
Loading

Poem

🐇
In the meadow of plots, new colors bloom,
With overlays, legends, and charts that zoom.
Zero-config helpers hop in with glee,
While palettes and PNGs set the data free.
Demos abound, and docs shine bright—
This rabbit’s code garden is pure delight!
🌱📊✨

Tip

⚡️ Faster reviews with caching
  • CodeRabbit now supports caching for code and dependencies, helping speed up reviews. This means quicker feedback, reduced wait times, and a smoother review experience overall. Cached data is encrypted and stored securely. This feature will be automatically enabled for all accounts on May 16th. To opt out, configure Review - Disable Cache at either the organization or repository level. If you prefer to disable all data retention across your organization, simply turn off the Data Retention setting under your Organization Settings.

Enjoy the performance boost—your workflow just got faster.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Changes requested ❌

Reviewed everything up to 8cc20bf in 3 minutes and 33 seconds. Click for details.
  • Reviewed 2103 lines of code in 38 files
  • Skipped 0 files when reviewing.
  • Skipped posting 13 draft comments. View those below.
  • Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. LeanPlot/Core.lean:73
  • Draft comment:
    Using HMul and HDiv for overlay operators is clever. Consider adding a brief comment that explains why these operators were chosen over, say, traditional arithmetic multiplication/division to avoid confusion.
  • Reason this comment was not posted:
    Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 20% vs. threshold = 50% The code is part of a plotting library where * and / are being repurposed as plot overlay operators. While this might be initially surprising, the existing doc comments make it clear these are overlay operators. The file header mentions "algebra of graphics" which provides context. Adding more explanation about operator choice seems unnecessary and could make docs more verbose. The choice of * and / for overlays might be confusing to users without graphics algebra background. The suggested documentation could help clarify the intent. The existing documentation already clearly labels these as overlay operators, and the file's context about "algebra of graphics" provides sufficient framework. Over-explaining operator choices could make docs more cluttered. The comment should be deleted as the existing documentation sufficiently explains the operators' purpose without needing to justify the specific choice of HMul/HDiv.
2. LeanPlot/DSL.lean:26
  • Draft comment:
    The macro rules for #plot are concise and clear. Ensure that future DSL extensions maintain compatibility with this core behavior.
  • Reason this comment was not posted:
    Comment did not seem useful. Confidence is useful = 0% <= threshold 50% This comment is asking the PR author to ensure future compatibility, which is not specific to the current changes. It doesn't provide a specific suggestion or point out a specific issue with the current code.
3. LeanPlot/Demos/OperatorPlayground.lean:29
  • Draft comment:
    The operator demo is a clear showcase for overlaying plots. Consider adding a comment to note that the second #plot using the '^3' operator demonstrates standard function composition separate from overlay.
  • Reason this comment was not posted:
    Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 10% vs. threshold = 50% The file already has clear documentation about overlays in the header comment. The second plot is a simple, standalone example that doesn't need explanation. The distinction between overlay and composition is already clear from the code structure and existing comments. Adding more comments would be redundant. The comment might help readers who are new to the library understand the difference between these two plotting approaches more explicitly. The existing documentation and code structure already make this distinction clear - the header comment explicitly discusses overlays and the code shows two distinct approaches. Additional inline comments would be redundant. Delete the comment as it suggests adding unnecessary documentation when the distinction is already clear from existing context.
4. LeanPlot/Specification.lean:72
  • Draft comment:
    Incorrect named parameter: 'sample' is called with '(domainOpt := domainOpt)', but 'sample' expects min and max values. Consider pattern matching on domainOpt to supply appropriate min and max.
  • Reason this comment was not posted:
    Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 10% vs. threshold = 50% Without seeing the definition of LeanPlot.Components.sample, I cannot verify if the comment is correct about what parameters it expects. The code looks intentionally designed to pass through an optional domain parameter. The author likely knows the signature of their own sample function. Making assumptions about the signature of an unseen function is dangerous. I don't have access to the LeanPlot.Components.sample function definition, so I can't be 100% certain whether this parameter passing is correct or not. However, this is a newly created file with intentional design choices. The consistent use of Option types and parameter naming suggests this is likely correct as written. The comment makes assumptions about code we can't see and the design appears intentional. We should not keep speculative comments about unseen code.
5. lakefile.toml:2
  • Draft comment:
    Version mismatch: The lakefile version is '0.1.0', but the changelog and README indicate features are at 0.2.x. Consider updating the version.
  • Reason this comment was not posted:
    Comment was on unchanged code.
6. .cursorrules:8
  • Draft comment:
    Typographical inconsistency: In the checklist, 'y = x' (line 7) is written with spaces around '=', while 'y=x^2' (line 8) is missing them. Consider updating 'y=x^2' to 'y = x^2' for consistency.
  • Reason this comment was not posted:
    Comment was on unchanged code.
7. CHANGELOG.md:110
  • Draft comment:
    The word 'high‐level' on line 110 uses a non-standard hyphen (‑) that might cause issues with some text processors. Consider replacing it with a standard hyphen '-' for consistency.
  • Reason this comment was not posted:
    Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 10% vs. threshold = 50% This is a documentation file (CHANGELOG.md) and the hyphen difference is very subtle. While technically correct that it's a non-standard hyphen, this kind of minor formatting issue in documentation doesn't impact functionality. The markdown will render the same way regardless. This seems like an overly pedantic comment that doesn't add significant value. The non-standard hyphen could potentially cause issues if someone tries to copy-paste this text into code or if the file is processed by certain tools. Some systems might handle Unicode hyphens differently. While true, this is just a changelog description, not code. The impact of a non-standard hyphen here is minimal to non-existent since it's purely documentation that will be rendered as markdown. This comment should be deleted as it's too minor of an issue for a changelog file and doesn't impact functionality or readability.
8. CHANGELOG.md:115
  • Draft comment:
    On line 115, the expression 'some …' uses a typographic ellipsis character. Consider replacing it with three standard dots ('...') for clarity and consistency in code/documentation.
  • Reason this comment was not posted:
    Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 10% vs. threshold = 50% This is a very minor stylistic suggestion about punctuation in documentation. The typographic ellipsis vs three dots makes no functional difference. The changelog is meant for human readers, not code, so either format is perfectly readable. This seems like an unnecessarily pedantic comment that doesn't improve code quality or functionality. Perhaps consistency in documentation style is important for project professionalism. Some style guides might have specific requirements about ellipsis formatting. While consistency is good, this level of nitpicking about punctuation in a changelog is excessive and doesn't provide meaningful value. The current format is perfectly readable and understandable. Delete this comment as it's an extremely minor stylistic suggestion about documentation punctuation that doesn't meaningfully improve the codebase.
9. LeanPlot/API.lean:11
  • Draft comment:
    Consider replacing 'boiler-plate' with 'boilerplate' for consistency with common usage. This is a trivial typographical error.
  • Reason this comment was not posted:
    Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 10% vs. threshold = 50% While technically both spellings are acceptable, "boilerplate" is indeed more common in programming contexts. However, this is an extremely minor documentation style issue that doesn't affect functionality or clarity. The rules state not to make purely informative comments or unimportant suggestions. The suggestion is technically correct and would improve consistency with common usage. Documentation quality does matter. While valid, this is too minor of an issue to warrant a PR comment. Both forms are readable and understood, and this falls under "obvious or unimportant" in the rules. Delete this comment as it's too minor of a documentation style suggestion to warrant a PR comment.
10. LeanPlot/Components.lean:10
  • Draft comment:
    Typo in header comment: 'ProofWidgets4' on line 10 looks like a typographical error. Consider changing it to 'ProofWidgets' if that was the intended word.
  • Reason this comment was not posted:
    Comment was not on a location in the diff, so it can't be submitted as a review comment.
11. LeanPlot/Core.lean:9
  • Draft comment:
    Typo in the comment: The word 'conversation:' should likely be 'conversion:'. Please correct it to improve clarity.
  • Reason this comment was not posted:
    Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 20% vs. threshold = 50% The word "conversation" could actually be intentional here - it might be referring to a discussion or dialogue about "algebra of graphics". Without more context about what "algebra of graphics" refers to, I can't be certain this is actually a typo. The sentence makes sense either way - it could be referring to a conversation/discussion that promised these foundations, or a conversion/transformation concept. I might be overthinking this - typos should generally be fixed. But suggesting changes without being certain they're correct could introduce bugs. In this case, making an incorrect suggestion is worse than leaving a potential typo, since "conversation" is a valid word that could be intentional here. Without more context about what "algebra of graphics" refers to, we can't be certain this is actually a typo, so we should not keep this comment.
12. LeanPlot/Palette.lean:5
  • Draft comment:
    Consider changing 'boiler-plate' to 'boilerplate' for consistency and clarity in the documentation.
  • Reason this comment was not posted:
    Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 10% vs. threshold = 50% While technically correct that 'boilerplate' is more commonly written without a hyphen, this is an extremely minor documentation style issue. It doesn't affect code functionality or readability significantly. According to our rules, we should not make purely informative comments or comments about obvious/unimportant issues. The hyphenated version might actually be preferred in some style guides, and this kind of minor documentation nitpick could be seen as noise in the PR review process. Even if the suggestion is technically correct, it's too minor to warrant a PR comment and doesn't affect code quality or functionality. Delete this comment as it's too minor and doesn't meet our threshold for important PR feedback.
13. LeanPlot/Plot.lean:7
  • Draft comment:
    Typographical: Consider removing the extra space after 'LeanPlot.' in the sentence on line 7 to improve consistency. It currently reads 'under LeanPlot. The intention...' which has two spaces after the period.
  • Reason this comment was not posted:
    Comment did not seem useful. Confidence is useful = 0% <= threshold 50% This comment is purely informative and focuses on a minor formatting issue that doesn't affect the functionality or understanding of the code. It doesn't provide a code suggestion or ask for a test to be written, nor does it address any potential issues with the code itself.

Workflow ID: wflow_bHNLPm3Y9kFsJ9Fc

You can customize Ellipsis by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.

-- Fold over remaining indices.
let (lo, hi) :=
(List.range stepCount).foldl (init := (y₀, y₀)) fun (acc : Float × Float) i =>
let x : Float := -1.0 + 2.0 * (i.toFloat) / (stepCount.toFloat - 1.0)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential division by zero if N == 1: when stepCount equals 1, the denominator (stepCount.toFloat - 1.0) becomes 0.

Suggested change
let x : Float := -1.0 + 2.0 * (i.toFloat) / (stepCount.toFloat - 1.0)
let x : Float := if stepCount == 1 then -1.0 else -1.0 + 2.0 * (i.toFloat) / (stepCount.toFloat - 1.0)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 11

🔭 Outside diff range comments (1)
LeanPlot/Axis.lean (1)

27-31: ⚠️ Potential issue

Mismatch between default type and its documentation
The comment states “The Recharts default is category,” but the code sets:

type : AxisType := .number

Either update the comment to reflect that the default is .number, or change the code to use .category if that was intended.

🧹 Nitpick comments (26)
LeanPlot/Legend.lean (2)

16-18: Consider deriving Inhabited for default props

Since LegendProps has no fields, deriving an Inhabited instance would let users write default : LegendProps when rendering. For example:

-structure LegendProps where
-  deriving FromJson, ToJson
+structure LegendProps where
+  deriving Inhabited, FromJson, ToJson

20-23: Add a usage example to the Legend component docstring

Embedding a short code snippet in the doc comment (showing how to include <Legend> in a chart) will improve discoverability. For example:

/-- See https://recharts.org/en-US/api/Legend.
  Example:
    let chart := mkLineChartFull [...]
    view chart (Composite {}) {
      Legend := {}
    }
-/
Justfile (1)

48-57: Remove duplicate and unused imports in embedded Python
The Python block imports re twice and sys isn’t used. Simplify as follows:

-	import pathlib, re
+	import pathlib
 	path = pathlib.Path('CHANGELOG.md')
 	txt = path.read_text()
-	import sys, re
-	new = re.sub(r'\[0\.1\.0\] – [0-9-:]+', '[0.1.0] – '+stamp, txt, count=1)
+	import re
+	new = re.sub(r'\[0\.1\.0\] – [0-9-:]+', '[0.1.0] – '+stamp, txt, count=1)
	path.write_text(new)
	print('Timestamp updated ->', stamp)
.cursor/rules/lean-import-order.mdc (1)

1-5: Simplify and correct globs configuration
Inline comma-separated patterns can be error-prone. Consider using a YAML list, for example:

globs:
  - "**/*.lean"

This ensures the rule applies consistently across all Lean files.

TODO.md (1)

20-20: Update timestamp format for consistency

The timestamp format "2025-05-02:08:05" appears to use colons for both time separation and date-time separation, which is non-standard.

-## Post-0.1 Roadmap (updated 2025-05-02:08:05 UTC)
+## Post-0.1 Roadmap (updated 2025-05-02T08:05 UTC)
LeanPlot/Core.lean (2)

90-98: render currently stacks layers vertically, not overlaying them

Plot.render wraps each Layer.html in a flex column, yielding a stack rather than a visual overlay.
That matches the current implementation comment, but users reading the API docs for + * / may understandably expect literal overlay.

Minimal change to approximate overlay:

-    Html.element "div"
-      #[("style", Json.str "display:flex; flex-direction:column;")]
+    Html.element "div"
+      #[("style", Json.str "position:relative;")]

and add

#[("style", Json.str "position:absolute; left:0; top:0; width:100%; height:100%;")]

to each div that wraps a layer.
Alternatively, leave as-is but clarify in the module doc-string that the current behaviour is stacking and true overlay is a future milestone.


57-60: ToPlot coherence – give the “lift-layer” instance a lower priority

The blanket instance

instance [ToLayer α] : ToPlot α

is handy but can clash with more specialised ToPlot instances users define for their own types (they will have to assign an even lower numeric priority to override it). Setting an explicit higher numeric priority (e.g. priority := 1500) here avoids accidental overshadowing while keeping everyday ergonomics.

-instance [ToLayer α] : ToPlot α where
+instance (priority := 1500) [ToLayer α] : ToPlot α where
.cursorrules (1)

9-9: Consider extending checklist for the new cubic demo.
Since you’ve added CubicDemo showcasing y = x³, you may want to add a checklist item like - [x] y = x³ to track its completion.

Main.lean (1)

3-7: Align docstring style with Verso guidelines.
The project enables linter.missingDocs and uses Verso for documentation. Replace the block comment markers with Verso’s expected syntax so it’s picked up by the linter and tooling:

- /--
+ /-!
   Entry point for the `leanplot` executable...
- -/
+ -/
LeanPlot/Demos/OverlayDemo.lean (1)

25-28: Good demonstration of single-function plotting

This sine function chart shows a clean implementation, including handling the necessary constant definition without external dependencies. It's a good companion to the overlay example above.

Consider adding a version that demonstrates how this chart could be combined with another using the new (*) or (/) operators to further illustrate their usage.

LeanPlot/DSL.lean (1)

4-18: Documentation is clear but missing operator examples

The documentation clearly explains the current functionality but doesn't mention the overlay operators (*) and (/) that are mentioned in the PR objectives. Consider adding examples of how these operators would be used within the DSL context.

LeanPlot/AutoDomain.lean (2)

28-54: Robust implementation with edge case handling.

The autoDomain function correctly handles important edge cases:

  • Default parameter of 100 points provides sufficient resolution for most smooth functions
  • Degenerate case protection for N=0
  • Special handling for constant functions to avoid zero-height charts
  • 5% padding to ensure data doesn't touch the chart edges

One minor optimization opportunity:

- if _h : N = 0 then
-   (0, 1) -- degenerate case; shouldn't happen
- else
-   -- Convert `N` to a `Nat` ≥ 1.
-   let steps := if N = 0 then 1 else N
+ -- Handle degenerate case and ensure N ≥ 1
+ let steps := if N = 0 then 1 else N
+ -- Proceed with valid step count

Since you already check if N=0 in the top-level condition, the second check is redundant.


40-46: Consider protection against NaN/Infinity values.

The function assumes that f always returns valid floating-point values. However, mathematical functions might return NaN or Infinity for certain inputs, which could lead to unexpected behavior when determining domain bounds.

According to the changelog entry in version 0.2.2, you've added isInvalidFloat and jsonDataHasInvalidFloats utilities and warning banners for invalid data. Consider using those utilities here too.

let y : Float := toFloat (f x)
+ -- Skip invalid values when computing domain
+ let lo := if LeanPlot.Utils.isInvalidFloat y then acc.fst else if y < acc.fst then y else acc.fst
+ let hi := if LeanPlot.Utils.isInvalidFloat y then acc.snd else if y > acc.snd then y else acc.snd
- let lo := if y < acc.fst then y else acc.fst
- let hi := if y > acc.snd then y else acc.snd
README.md (1)

61-65: Example may need update to show new operators.

The quick start example demonstrates composition with the + operator, but doesn't showcase the * and / operators mentioned in the PR objectives. Consider updating with an additional example or alternative to demonstrate these new operators.

CHANGELOG.md (3)

42-43: Fix grammar in changelog entry.

There are a few missing articles in this section.

- Root `LeanPlot` module imports new `Plot` command.
+ Root `LeanPlot` module imports the new `Plot` command.
🧰 Tools
🪛 LanguageTool

[uncategorized] ~42-~42: You might be missing the article “the” here.
Context: ...Demonow uses#plot. ### Changed - Root LeanPlotmodule imports newPlot` co...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)


[uncategorized] ~42-~42: You might be missing the article “the” here.
Context: ...anged - Root LeanPlot module imports new Plot command. - Updated TODO roadmap ...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)


83-83: Fix grammar in changelog entry.

There's a missing article in this line.

- Added low-priority generic `HAdd` instance that overlays any `[ToPlot]` values via `Plot.overlay`.
+ Added a low-priority generic `HAdd` instance that overlays any `[ToPlot]` values via `Plot.overlay`.
🧰 Tools
🪛 LanguageTool

[uncategorized] ~83-~83: You might be missing the article “a” here.
Context: ..., Layer, Plot abstractions. - Added low-priority generic HAdd instance that o...

(AI_EN_LECTOR_MISSING_DETERMINER_A)


110-110: Fix grammar in changelog entry.

There's a missing article in this line.

- Support for axis labels in high‐level `PlotSpec` renderer: `AxisSpec.label` is now passed through to Recharts.
+ Support for axis labels in the high‐level `PlotSpec` renderer: `AxisSpec.label` is now passed through to Recharts.
🧰 Tools
🪛 LanguageTool

[uncategorized] ~110-~110: You might be missing the article “the” here.
Context: ...### Added - Support for axis labels in high‐level PlotSpec renderer: AxisSpec.label i...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)

LeanPlot/Palette.lean (3)

16-17: Prefer an explicit structure Color or abbrev HexColor for stronger type-safety

Using a plain String alias gives us no guarantees that the value really is a 6-digit hex colour.
A tiny wrapper (even an opaque structure) would stop accidental misuse (e.g. passing "foo").

- private abbrev Color := String
+ private opaque Color : Type := String
+
+namespace Color
+  @[inline] def mk (s : String) : Color := s -- allow unsafe creation for now
+  @[inline] def val (c : Color) : String  := c
+end Color

This keeps runtime overhead at 0 while making incorrect literals a type error once a smart constructor is introduced.


30-37: Doc-comment hex codes use # in prose but not in code

/-- Turquoise (#26828e). -/ vs def turquoise : Color := "#26828e" (note the missing back-tick pair in the comment).
Although harmless, the mismatch is a tiny paper-cut for readers copying values.


63-68: colourFor is safe but partial – add a static guarantee instead of !

defaultPalette[(i % defaultPalette.size)]! works because i % size < size, yet the ! still marks it as partial.
You can avoid the exclamation by indexing with a Fin defaultPalette.size.

-@[inline] def colourFor (i : Nat) : String :=
-  defaultPalette[(i % defaultPalette.size)]!
+@[inline] def colourFor (i : Nat) : String :=
+  let idx : Fin defaultPalette.size := ⟨i % defaultPalette.size, Nat.mod_lt _ (by decide)⟩
+  defaultPalette[idx]

This removes all partial functions and communicates totality to the compiler.

llms.txt (1)

58-82: Repeated “Next tasks” sections – consider pruning to keep roadmap concise

The file currently repeats the “Next tasks” bullet list four times (lines 126-146).
Trimming duplication will make the roadmap easier to scan and reduce merge-conflicts in future edits.

LeanPlot/Specification.lean (3)

181-191: RenderSeries implementation still pattern-matches on strings

Even if the previous suggestion is postponed, refactor this block to a match expression so that accidental newlines or casing do not silently fall into the “unsupported” branch.

-instance : RenderSeries SeriesSpec where
-  renderSeries (s : SeriesSpec) (_allChartData : Array Json) : Html := -- _allChartData often unused here
-    if s.type == "line" then
+instance : RenderSeries SeriesSpec where
+  renderSeries
+    | { type := "line",  .. } as s, _ =>
       let dotProp := s.dot.getD true
       (<Line type={LineType.monotone} dataKey={toJson s.dataKey} stroke={s.color} dot?={some dotProp} /> : Html)
-    else if s.type == "scatter" then
+    | { type := "scatter", .. } as s, _ =>
       let scatterProps : LeanPlot.Components.ScatterProps := { dataKey := toJson s.dataKey, fill := s.color }
       (<LeanPlot.Components.Scatter {...scatterProps} /> : Html)
-    else
-      (Html.text s!"Unsupported series type: {s.type}" : Html)
+    | s, _ =>
+      (Html.text s!"Unsupported series type: {s.type}" : Html)

(This diff is minimal; using an enum would remove the final catch-all entirely.)


198-238: Potential performance hit: building many small Html.text nodes

Inside render, every unsupported branch or missing axis produces Html.text "", which allocates empty nodes.
Prefer Html.empty for no-ops to avoid creating DOM placeholders.

-    | none => (Html.text "" : Html)
+    | none => Html.empty

Apply similarly to the other empty branches.


66-87: line helper fixes colour to index 0 – multiple calls collide

If a user overlays two PlotSpecs produced via line … without overriding color, both series will pick colourFor 0, yielding identical strokes.

Provide the colour index as an explicit parameter or compute nextIdx from spec.series.size when composing.

LeanPlot/Demos/QuadraticDemo.lean (2)

1-4: Streamline imports and opens for consistency
The current imports (LeanPlot.API then LeanPlot.Plot) and the open Lean/open ProofWidgets statements differ from the pattern in other demos (e.g., LinearDemo.lean imports LeanPlot.Plot before LeanPlot.API and does not open Lean or ProofWidgets). Consider:

  • Reordering imports to match LinearDemo.lean:
    - import LeanPlot.API
    - import LeanPlot.Plot
    + import LeanPlot.Plot
    + import LeanPlot.API
  • Removing open Lean and open ProofWidgets if they are not directly used, to reduce namespace clutter.

7-11: Use unqualified lineChart invocation for brevity
Since you already have open LeanPlot.API (or can add it after cleaning up opens), you can simplify the plot command to mirror LinearDemo.lean:

- #plot (LeanPlot.API.lineChart (fun x => x * x))
+ #plot (lineChart (fun x => x * x))

This improves readability and aligns demos.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2aa3651 and 8cc20bf.

📒 Files selected for processing (38)
  • .cursor/rules/debug-chart-images.mdc (1 hunks)
  • .cursor/rules/lean-import-order.mdc (1 hunks)
  • .cursor/rules/plot-feature-gallery.mdc (1 hunks)
  • .cursor/rules/verso-docstrings.mdc (1 hunks)
  • .cursorrules (1 hunks)
  • CHANGELOG.md (1 hunks)
  • DocsMain.lean (1 hunks)
  • Gallery.md (1 hunks)
  • Justfile (2 hunks)
  • LeanPlot.lean (1 hunks)
  • LeanPlot/API.lean (1 hunks)
  • LeanPlot/Algebra.lean (1 hunks)
  • LeanPlot/AutoDomain.lean (1 hunks)
  • LeanPlot/Axis.lean (1 hunks)
  • LeanPlot/Basic.lean (1 hunks)
  • LeanPlot/Components.lean (3 hunks)
  • LeanPlot/Constants.lean (1 hunks)
  • LeanPlot/Core.lean (1 hunks)
  • LeanPlot/DSL.lean (1 hunks)
  • LeanPlot/Debug.lean (1 hunks)
  • LeanPlot/Demos/CubicDemo.lean (1 hunks)
  • LeanPlot/Demos/LinearDemo.lean (1 hunks)
  • LeanPlot/Demos/OperatorPlayground.lean (1 hunks)
  • LeanPlot/Demos/OverlayDemo.lean (1 hunks)
  • LeanPlot/Demos/QuadraticDemo.lean (1 hunks)
  • LeanPlot/Experiments.lean (1 hunks)
  • LeanPlot/Legend.lean (1 hunks)
  • LeanPlot/Palette.lean (1 hunks)
  • LeanPlot/Plot.lean (1 hunks)
  • LeanPlot/Specification.lean (1 hunks)
  • LeanPlot/ToFloat.lean (2 hunks)
  • Main.lean (1 hunks)
  • README.md (4 hunks)
  • TODO.md (1 hunks)
  • lake-manifest.json (2 hunks)
  • lakefile.toml (2 hunks)
  • lean-toolchain (1 hunks)
  • llms.txt (1 hunks)
🧰 Additional context used
🪛 LanguageTool
CHANGELOG.md

[uncategorized] ~29-~29: A determiner appears to be missing. Consider inserting it.
Context: ...ing a type with a [ToFloat] instance. Existing Float code is unaffected. ## [0.1.2]...

(AI_EN_LECTOR_MISSING_DETERMINER)


[uncategorized] ~42-~42: You might be missing the article “the” here.
Context: ...Demonow uses#plot. ### Changed - Root LeanPlotmodule imports newPlot` co...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)


[uncategorized] ~42-~42: You might be missing the article “the” here.
Context: ...anged - Root LeanPlot module imports new Plot command. - Updated TODO roadmap ...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)


[uncategorized] ~83-~83: You might be missing the article “a” here.
Context: ..., Layer, Plot abstractions. - Added low-priority generic HAdd instance that o...

(AI_EN_LECTOR_MISSING_DETERMINER_A)


[uncategorized] ~110-~110: You might be missing the article “the” here.
Context: ...### Added - Support for axis labels in high‐level PlotSpec renderer: AxisSpec.label i...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)

llms.txt

[uncategorized] ~44-~44: You might be missing the article “the” here.
Context: ...er 0 helper. 5.3 Tick off "Cubic" in Gallery. 6. Tests / lint 6.1 Ensure `lake b...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)


[uncategorized] ~111-~111: This verb may not be in the correct form. Consider using a different form for this context.
Context: ...--------- • Updated README.md: features bump to 0.2.x, quick-start snippet uses line...

(AI_EN_LECTOR_REPLACEMENT_VERB_FORM)

🔇 Additional comments (60)
LeanPlot/Legend.lean (3)

1-2: Ensure correct import for Recharts API usage

You import ProofWidgets.Component.Recharts but then open ProofWidgets.Recharts. Please confirm that this resolves Recharts.javascript correctly. If the ProofWidgets.Recharts namespace isn’t provided by the imported module, consider importing it explicitly or opening ProofWidgets.Component.Recharts instead.


3-9: Well-documented module header

The /-! ... -/ docstring clearly explains the purpose and minimal API surface of this wrapper. Nice work setting expectations for future props additions.


11-13: Check JSON deriving imports and open statements

You call deriving FromJson, ToJson below—ensure that the necessary JSON deriving support (e.g. from Lean.Data.Json) is in scope, whether transitively via open Lean or through an explicit import. If it’s missing, add the appropriate import.

lean-toolchain (1)

1-1: Toolchain updated to v4.20.0-rc2
Upgrading to the release candidate aligns with testing new features under Lean 4 v4.20.0.

.cursor/rules/plot-feature-gallery.mdc (1)

8-10: Gallery example rule description looks good
The guidance for adding new demo entries is clear and matches project conventions.

Justfile (1)

21-24: Batteries linter integration is correct
Building the Batteries.Tactic.Lint module before running the custom linter ensures compatibility with the current Lean version.

.cursor/rules/lean-import-order.mdc (1)

8-14: Import ordering guidelines are clear
The rule clearly states that import statements must be a top-level block and prohibits doc comments on declarations, which will prevent invalid 'import' command errors.

LeanPlot/Experiments.lean (3)

1-11: Well-structured experiment setup with clear documentation

The file is properly set up as a dedicated scratchpad for development experiments, with appropriate imports, namespace openings, and clear documentation that explicitly marks this as not part of the released API.


15-19: Good examples for testing core functionality

These examples provide a concise demonstration of the core plotting capabilities (line and scatter charts) with different input styles - functions and raw data points. They serve as effective quick tests during development.


21-32: Helpful historical context for development

The roadmap history provides valuable context for understanding the project's evolution. This helps new contributors understand the design decisions and progression of features.

TODO.md (3)

22-29: Well-organized ergonomics roadmap section

This section clearly tracks completed items and pending enhancements related to the user experience. The checkboxes provide a clear visual indication of progress.


38-42: Clear grammar-of-graphics architectural roadmap

This new section outlines the architectural vision for a more declarative and composable plotting system. It aligns with modern design patterns in visualization libraries.


43-46: Comprehensive tooling and documentation section

The dedicated section for tooling and documentation improvements shows a commitment to developer experience and project maintenance.

LeanPlot/Debug.lean (4)

6-10: Clear API stability notice and purpose

The documentation explicitly marks this as non-stable API and clearly explains its purpose, which is good practice for experimental or internal utilities.


15-20: Well-documented props structure

The SavePNGProps structure has appropriate documentation for each field and includes sensible defaults for the filename.


29-33: Flexible and reusable wrapping function

The withSavePNG function is well-designed with sensible defaults and clear documentation about the requirement for unique IDs when using multiple instances.


23-25: External dependency on CDN resource

The component depends on an external CDN resource (html2canvas) which could introduce risks if the CDN becomes unavailable.

Consider one of these approaches:

  1. Bundle the library with your project to avoid external dependencies
  2. Add error handling for when the library fails to load
  3. Verify the CDN's reliability and consider using a more stable CDN or specific version hash
#!/bin/bash
# Check the status of the CDN resource
curl -I https://cdn.jsdelivr.net/npm/[email protected]/+esm
# Check if there's an npm package for this library that could be bundled
grep -r "html2canvas" . --include="package.json"
LeanPlot/Components.lean (7)

5-6: Appropriate imports and namespace organization

The new imports for Legend and Palette modules, along with opening the Legend namespace, maintain good code organization while making the Legend component accessible.

Also applies to: 17-17


73-91: Well-implemented legend support for line charts

The mkLineChartFull function extends the existing chart helpers in a consistent manner, adding legend support while preserving the API style of the other chart functions.


92-101: Appropriate props structure for scatter charts

The ScatterChartProps structure is well-defined with proper documentation and derives the necessary JSON serialization instances.


106-108: Consistent component implementation

The ScatterChart component correctly reuses the existing Recharts JavaScript bundle, maintaining consistency with other chart components.


111-123: Well-structured scatter data point props and component

The ScatterProps structure and Scatter component are well-implemented with appropriate documentation and consistent with the library's design patterns.


124-136: Functional scatter chart helper consistent with existing patterns

The mkScatterChart function follows the same pattern as the existing line chart helpers, providing a consistent API for users while adding new functionality.


1-136:

✅ Verification successful

PR objective verification: Operators for overlaying plots

The PR objectives mention introducing HMul and HDiv operators for overlaying plots, but these don't appear in the files under review. This functionality might be in other files not included in this review.


🏁 Script executed:

#!/bin/bash
# Search for HMul and HDiv implementations related to overlaying plots
echo "Looking for HMul and HDiv implementations..."
rg -A 5 -B 5 "instance.*HMul.*|instance.*HDiv.*" --type lean

# Look for the operator playground demo mentioned in PR objectives
echo "Looking for OperatorPlayground demo..."
find . -name "OperatorPlayground.lean"

Length of output: 357


🏁 Script executed:

#!/bin/bash
# Search for HMul and HDiv instances anywhere in the Lean files
rg -n "instance.*HMul" .
rg -n "instance.*HDiv" .

# Inspect the first 200 lines of the OperatorPlayground demo to see how operators are defined/used
sed -n '1,200p' LeanPlot/Demos/OperatorPlayground.lean

Length of output: 1199


Overlay operators are defined in Core and demo’d in Demos

The HMul and HDiv instances live in LeanPlot/Core.lean (around lines 74 and 78), and the playground demo showing their usage is in LeanPlot/Demos/OperatorPlayground.lean. Since Components.lean only contains the Recharts wrappers, the overlay-operator code being absent here is expected.

LeanPlot/Core.lean (1)

70-80: Mind the global HMul / HDiv instances – possible overlap with numeric multiplication & division

Registering highly-generic instances for HMul α β Plot and HDiv α β Plot is elegant, but it widens the instance search space for every use of * or / in user code.
Although you set the priority to 2000 (lower than the default 1000), these instances are still considered whenever the operands are not already syntactically known numeric types. In practice this may:

  1. Introduce noticeable instance-search slow-downs inside large proofs that do a lot of arithmetic.
  2. Create surprising error messages when users forget a open LeanPlot or when Lean tries these instances before finding domain-specific ones.

If you want to retain the convenience but eliminate the risk, consider one of:

- instance (priority := 2000) [ToPlot α] [ToPlot β] : HMul α β Plot where
+ instance (priority := 5000) [ToPlot α] [ToPlot β] : HMul α β Plot where

or gate the instances behind a dedicated namespace so that users must opt-in with open scoped LeanPlot.Operators.

Gallery.md (1)

8-10: Nice! Demo checklist updated to reflect new line-chart examples

The checked items accurately mirror the newly-added demos and improve project visibility. No issues spotted.

LeanPlot/Basic.lean (1)

1-1: Doc comment addition looks good

The explanatory comment clarifies the purpose of hello without affecting behaviour. 👍

.cursorrules (1)

7-9: Checklist entries updated appropriately.
Marking the basic plotting features (y = x, y = x^2, and multiple plots) as complete correctly reflects the inclusion of the corresponding demos.

LeanPlot.lean (2)

6-10: New root imports are beneficial.
Exposing LeanPlot.Plot, the demo modules, and LeanPlot.Palette in the root makes it easier for users to access the core API and examples.


4-9: Verify demo module names and eliminate duplicates.
This file imports both LeanPlot.Demos.OverlayPlot and LeanPlot.Demos.OverlayDemo. Ensure these correspond to distinct modules in LeanPlot/Demos/ and that there isn’t overlap or a naming mismatch.

lakefile.toml (1)

5-7: Review leanOptions settings.
Enabling pp.unicode.fun and linter.missingDocs aligns with the new demo and documentation requirements. Confirm these options match the team’s desired code style and doc conventions.

LeanPlot/Demos/CubicDemo.lean (3)

1-2: Imports are correct.
Bringing in LeanPlot.API and LeanPlot.Plot provides the zero-config lineChart helper and the #plot command.


4-5: Open statements set up context appropriately.
The open and open scoped lines align with other demos, simplifying notation and ensuring JSX support.


9-10: Verify implicit default domain.
The comment says “on [0,1]” but the lineChart call omits explicit domain parameters. Confirm that the default range is [0,1], or consider specifying:

#plot (lineChart (fun x : Float => x * x * x) (start := 0) (stop := 1))

to match the documented interval.

LeanPlot/ToFloat.lean (3)

1-2: Appropriate import for rational number support.

Adding the Std.Internal.Rat import enables the implementation of the ToFloat instance for rational numbers.


3-17: Improved documentation formatting.

The documentation has been enhanced with better formatting while maintaining the same content, resulting in improved readability.


52-62: Good implementation of ToFloat for rational numbers.

The instance correctly converts rational numbers to Float by performing floating-point division of the numerator by the denominator. The documentation clearly explains the reasoning for providing this instance unconditionally.

.cursor/rules/debug-chart-images.mdc (1)

1-14: Clear debugging guidelines for chart images

This file provides excellent guidance for developers on creating and maintaining image snapshots for chart debugging. The standardized naming convention and location will help with visual regression testing.

Consider mentioning any specific debugging considerations related to the new overlay operators (*) and (/) being introduced in this PR, if applicable.

lake-manifest.json (1)

4-43: Dependencies updated to support new features

The manifest has been updated to include several new packages (verso, MD4Lean, and subverso) that appear to enhance documentation capabilities. While these dependencies likely support the overall project improvements, they don't directly relate to the overlay operators mentioned in the PR objectives.

Ensure that these new dependencies are properly documented as requirements in your README or documentation.

LeanPlot/AutoDomain.lean (1)

1-18: Well-documented introduction to the module.

The module header clearly explains the purpose of this heuristic function for domain inference and acknowledges its limitations (naïve implementation suitable for smooth functions without outliers) while mentioning future improvements. This transparent documentation is helpful for users to understand when to rely on this automatic domain inference and when to specify explicit bounds.

LeanPlot/Plot.lean (2)

1-14: Clear documentation for the #plot command.

The module header clearly explains the purpose and behavior of the #plot command, highlighting that it's a namespaced alias to #html to improve discoverability. The forward-looking comment about potential future enhancements (like auto-sampling) is valuable for understanding the design philosophy.


19-37: Well-implemented command forwarding.

The implementation correctly forwards to the ProofWidgets.HtmlDisplay functionality while providing a dedicated #plot command for better discoverability. This enhances the user experience without duplicating functionality. The error handling for unexpected syntax is also appropriate.

CHANGELOG.md (1)

29-29: Fix grammar in changelog entry.

There appears to be a missing article.

- Call-sites of `sample` & `sampleMany` must supply functions returning a type with a `[ToFloat]` instance. Existing `Float` code is unaffected.
+ Call-sites of `sample` & `sampleMany` must supply functions returning a type with a `[ToFloat]` instance. Existing `Float` code is unaffected.

Actually, this sentence seems grammatically correct as is. The warning appears to be a false positive from the static analysis tool.

🧰 Tools
🪛 LanguageTool

[uncategorized] ~29-~29: A determiner appears to be missing. Consider inserting it.
Context: ...ing a type with a [ToFloat] instance. Existing Float code is unaffected. ## [0.1.2]...

(AI_EN_LECTOR_MISSING_DETERMINER)

.cursor/rules/verso-docstrings.mdc (1)

1-56:

✅ Verification successful

Documentation guide looks comprehensive but not directly related to operator overlay

This file provides a detailed guide for using Verso to generate documentation from Lean code, which is valuable for maintaining code quality. However, it doesn't appear to be directly related to the PR's stated objective of introducing overlay operators (*, /) for plot composition.


🏁 Script executed:

#!/bin/bash
# Verify if there are any references to overlay operators in the doc guide
grep -E "overlay|operator|\*|/" .cursor/rules/verso-docstrings.mdc

Length of output: 1880


Approve documentation guide – no changes needed for overlay operators
The Verso docstring guide in .cursor/rules/verso-docstrings.mdc contains no references to the new * or / overlay semantics. It’s orthogonal to the PR’s objective, so it can remain as-is.

LeanPlot/Demos/OperatorPlayground.lean (2)

10-18: Clear explanation of overlay demonstration approach

The comment provides helpful context about React limitations when stacking multiple charts, explaining the rationale for the multi-series approach demonstrated in this file.


21-28: Multi-series chart implementation looks good

The implementation uses mkLineChartFull to create a chart with multiple data series (identity, square, square root) and assigns colors automatically with autoColours. This serves as a good demo for overlaying different function plots.

LeanPlot/Algebra.lean (4)

7-29: Well-documented algebra of graphics concept

The heading and description effectively introduce the concept of composable plot values that can be combined using familiar algebraic operators. The example showing the use of + for overlaying functions is clear and helpful.


36-48: Clean and well-structured data model definitions

The LineSeries and LinePlot structures are clearly defined with appropriate documentation comments. The default values for sampling parameters are sensible.


52-60: Effective implementation of plot overlay functionality

The overlay function correctly concatenates series, maximizes steps, and adjusts domain bounds to ensure the combined plot covers all data points properly. This forms the foundation for the operator-based composition mentioned in the PR objectives.


86-89:

❌ Incorrect review comment

Missing HMul and HDiv instances for * and / operators

The PR objectives mention adding new instances of HMul and HDiv to enable the use of * and / operators for overlaying plots, but I don't see these instances defined in this file. Currently, only conversion to Layer is implemented, which supports the + operator via the generic Plot overlays.


🏁 Script executed:

#!/bin/bash
# Check if the missing HMul and HDiv instances are defined elsewhere
echo "Checking for HMul instance in LeanPlot folder:"
grep -r "instance.*HMul.*LinePlot" --include="*.lean" LeanPlot/

echo "\nChecking for HDiv instance in LeanPlot folder:"
grep -r "instance.*HDiv.*LinePlot" --include="*.lean" LeanPlot/

echo "\nChecking Core.lean for these instances:"
cat LeanPlot/Core.lean | grep -A 10 -B 10 "instance.*H[Mul\|Div]"

Length of output: 1536


Incorrect missing HMul/HDiv instances
The generic HMul and HDiv instances already exist in LeanPlot/Core.lean, providing * and / overlays via [ToPlot]:

  • LeanPlot/Core.lean:
    instance (priority := 2000) [ToPlot α] [ToPlot β] : HMul α β Plot where
      hMul a b := Plot.overlay (toPlot a) (toPlot b)
    
    instance (priority := 2000) [ToPlot α] [ToPlot β] : HDiv α β Plot where
      hDiv a b := Plot.overlay (toPlot a) (toPlot b)

No additional HMul or HDiv instances need to be added to Algebra.lean.

Likely an incorrect or invalid review comment.

LeanPlot/API.lean (4)

8-19: Clear API design philosophy documented

The documentation clearly explains the "progressive disclosure" philosophy, starting with simple zero-config helpers and allowing more customization via lower-level constructors when needed. This is a user-friendly approach to API design.


38-45: Well-implemented line chart helper

The mkLineChart function provides a clean implementation for rendering line charts with sensible defaults, supporting multiple series through the seriesStrokes parameter.


57-72: Effective zero-config line chart implementation

The lineChart function provides a simple entry point for users to quickly create charts from functions with minimal configuration required. The automatic y-axis domain calculation and color assignment are particularly helpful.


79-83: Simple scatter chart helper looks good

The scatterChart function provides a clean implementation for rendering scatter plots from point data with sensible defaults.

LeanPlot/Specification.lean (1)

168-172: addSeries silently forces legend := true – may surprise callers

When composing plots, the caller might explicitly hide the legend earlier and still want it hidden even after adding extra series.
Consider respecting the previous choice or exposing a boolean parameter.

Do we want addSeries to be side-effect-free w.r.t. legend? If yes, change to:

-  { spec with series := spec.series.push series, legend := true }
+  { spec with series := spec.series.push series }
LeanPlot/Constants.lean (1)

1-15: Well-defined default constants
Centralizing defaultW and defaultH in LeanPlot.Constants with @[inline] and Nat types is clear and concise. These defaults will support consistent sizing across all Tier-0 helpers.

LeanPlot/Demos/LinearDemo.lean (1)

2-10: Consistent, minimal demo setup
This demo correctly follows the project’s conventions:

  • Imports LeanPlot.Plot then LeanPlot.API
  • Opens LeanPlot.API to access lineChart
  • Provides a concise doc-comment and #plot invocation
    No changes needed here; it aligns with the style and structure of other demos.
DocsMain.lean (3)

1-5: Imports and namespace opening
Importing VersoManual and LeanPlotManual, then opening Verso.Genre and Manual, sets up the doc environment correctly.


7-14: docsConfig record is correctly defined
The configuration fields (emitTex, emitHtmlSingle, emitHtmlMulti, htmlDepth, sourceLink, issueLink) match the PR objectives. Links point to the correct GitHub repo.


16-20: Entry point main is properly defined
The main : IO UInt32 function invokes manualMain with the LeanPlotManual doc and docsConfig. This aligns with lake exe docs conventions.

Comment on lines +1 to +5
---
description:
globs:
alwaysApply: false
---
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Define globs patterns for this rule
The globs: field is currently empty, which means the rule won’t match any files. Specify a pattern (e.g., **/LeanPlot/Demos/*Demo.lean) so that demos are validated.

Comment on lines +22 to +24
[[require]]
name = "verso"
git = "https://github.com/leanprover/verso.git"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Pin the verso dependency for reproducibility.
The verso package entry lacks a rev field, which may lead to unpinned, floating dependencies. Please add a specific rev (tag or commit) to lock the version. For example:

[[require]]
name = "verso"
git  = "https://github.com/leanprover/verso.git"
rev  = "v0.1.0"  # or a specific commit SHA

Comment on lines +12 to +17
def overlayLegend : Html :=
let names := #["y", "y²"]
let data := sampleMany #[("y", fun x => x), ("y²", fun x => x * x)]
mkLineChartFull data (autoColours names) none none 400 400

#plot overlayLegend
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Demo shows overlay functionality but doesn't demonstrate the new operators

This example effectively shows how to create an overlay chart with two functions and automatic coloring. However, it doesn't demonstrate the (*) and (/) overlay operators mentioned in the PR description. The implementation uses the sampleMany function with arrays instead.

Consider adding examples that explicitly demonstrate the new operators, similar to what might be shown in the LeanPlot/Demos/OperatorPlayground.lean file mentioned in the PR description.

Comment on lines +23 to +30
/-- Syntax: `#plot f` or `#plot f using 123` -/
syntax "#plot" term ("using" num)? : command

macro_rules
| `(#plot $f:term) =>
`(#html LeanPlot.API.lineChart $f)
| `(#plot $f:term using $n:num) =>
`(#html LeanPlot.API.lineChart $f (steps := $n))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Clean DSL implementation needs extension for overlay operators

This DSL provides a convenient #plot command that streamlines function plotting, but it doesn't demonstrate the overlay operators (*) and (/) mentioned in the PR objectives.

Consider extending this DSL to support overlay operations explicitly, such as:

#plot (fun x => x) * (fun x => x*x)  -- overlay using * operator
#plot (fun x => x) / (fun x => x*x)  -- overlay using / operator

This would showcase the new operators and provide a more ergonomic way to create overlay plots directly from the command syntax.

Comment on lines 73 to +77

* `LeanPlot.Demos.overlay` – overlays `y = x` and `y = x²`.
* `LeanPlot.Demos.LinearDemo` – `y = x`
* `LeanPlot.Demos.QuadraticDemo` – `y = x²`
* `LeanPlot.Demos.CubicDemo` – `y = x³`
* `LeanPlot.Demos.OverlayDemo` – overlay of `y = x` and `y = x²`
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add OperatorPlayground demo to gallery list.

The PR objectives mention adding a new demo file LeanPlot/Demos/OperatorPlayground.lean to showcase the new overlay operators, but this isn't listed in the demo gallery section of the README.

* `LeanPlot.Demos.LinearDemo`   – `y = x`
* `LeanPlot.Demos.QuadraticDemo` – `y = x²`
* `LeanPlot.Demos.CubicDemo`    – `y = x³`
* `LeanPlot.Demos.OverlayDemo`  – overlay of `y = x` and `y = x²`
+ * `LeanPlot.Demos.OperatorPlayground` – demonstrating overlay operators (`+`, `*`, `/`)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
* `LeanPlot.Demos.overlay` – overlays `y = x` and `y = x²`.
* `LeanPlot.Demos.LinearDemo``y = x`
* `LeanPlot.Demos.QuadraticDemo``y = x²`
* `LeanPlot.Demos.CubicDemo``y = x³`
* `LeanPlot.Demos.OverlayDemo` – overlay of `y = x` and `y = x²`
* `LeanPlot.Demos.LinearDemo``y = x`
* `LeanPlot.Demos.QuadraticDemo``y = x²`
* `LeanPlot.Demos.CubicDemo``y = x³`
* `LeanPlot.Demos.OverlayDemo` – overlay of `y = x` and `y = x²`
* `LeanPlot.Demos.OperatorPlayground` – demonstrating overlay operators (`+`, `*`, `/`)

Comment on lines +77 to +86
## [0.2.1] – 2025-05-03:10:25

### Changed

- Introduced `LeanPlot.Core` with the general `Render`, `Layer`, `Plot` abstractions.
- Added low-priority generic `HAdd` instance that overlays any `[ToPlot]` values via `Plot.overlay`.
- Migrated `LeanPlot.Algebra` to these abstractions, deleting duplicated `Render`/`CoeTC` and bespoke `HAdd`.
- `LinePlot` now only provides a `[ToLayer]` instance and inherits `+` overlay behaviour from the core instance.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Document the new overlay operators in the changelog.

The changelog provides excellent details about different features and changes, but doesn't mention the addition of the * and / operators for plot overlays, which is the main feature described in the PR objectives.

Consider adding an entry about the new operators to version 0.2.1 or adding a new version entry:

- Migrated `LeanPlot.Algebra` to these abstractions, deleting duplicated `Render`/`CoeTC` and bespoke `HAdd`.
- `LinePlot` now only provides a `[ToLayer]` instance and inherits `+` overlay behaviour from the core instance.
+ - Migrated `LeanPlot.Algebra` to these abstractions, deleting duplicated `Render`/`CoeTC` and bespoke `HAdd`.
+ - `LinePlot` now only provides a `[ToLayer]` instance and inherits `+` overlay behaviour from the core instance.
+ - Added `HMul` and `HDiv` instances to enable using `*` and `/` operators for overlaying plots, similar to the existing `+` operator.
+ - New demo `LeanPlot.Demos.OperatorPlayground` to showcase overlay operators.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
## [0.2.1] – 2025-05-03:10:25
### Changed
- Introduced `LeanPlot.Core` with the general `Render`, `Layer`, `Plot` abstractions.
- Added low-priority generic `HAdd` instance that overlays any `[ToPlot]` values via `Plot.overlay`.
- Migrated `LeanPlot.Algebra` to these abstractions, deleting duplicated `Render`/`CoeTC` and bespoke `HAdd`.
- `LinePlot` now only provides a `[ToLayer]` instance and inherits `+` overlay behaviour from the core instance.
## [0.2.1] – 2025-05-03:10:25
### Changed
- Introduced `LeanPlot.Core` with the general `Render`, `Layer`, `Plot` abstractions.
- Added low-priority generic `HAdd` instance that overlays any `[ToPlot]` values via `Plot.overlay`.
- Migrated `LeanPlot.Algebra` to these abstractions, deleting duplicated `Render`/`CoeTC` and bespoke `HAdd`.
- `LinePlot` now only provides a `[ToLayer]` instance and inherits `+` overlay behaviour from the core instance.
- Added `HMul` and `HDiv` instances to enable using `*` and `/` operators for overlaying plots, similar to the existing `+` operator.
- New demo `LeanPlot.Demos.OperatorPlayground` to showcase overlay operators.
🧰 Tools
🪛 LanguageTool

[uncategorized] ~83-~83: You might be missing the article “a” here.
Context: ..., Layer, Plot abstractions. - Added low-priority generic HAdd instance that o...

(AI_EN_LECTOR_MISSING_DETERMINER_A)

Comment on lines +29 to +30
#plot multiSeries
#plot line (fun x => x^3)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Missing demonstration of operators mentioned in PR description

While this shows working examples of plotting, I don't see explicit use of the * and / operators mentioned in the PR objectives. Consider adding examples that specifically demonstrate these new operators.


🏁 Script executed:

#!/bin/bash
# Check if the HMul and HDiv instances are defined elsewhere in the codebase
echo "Searching for HMul and HDiv instances in LeanPlot:"
grep -r --include="*.lean" "instance.*HMul" --include="*.lean" LeanPlot/
grep -r --include="*.lean" "instance.*HDiv" --include="*.lean" LeanPlot/

Length of output: 442


Demonstrate * and / on Plot in OperatorPlayground.lean

The demo currently only shows

#plot multiSeries
#plot line (fun x => x^3)

but doesn’t exercise the new HMul/HDiv instances for Plot (which you can see in LeanPlot/Core.lean). Please add examples that multiply and divide two plots. For example, in LeanPlot/Demos/OperatorPlayground.lean (insert after line 30):

-- multiply two line plots: (x²)*(x³) = x⁵
#plot line (fun x => x^2) * line (fun x => x^3)

-- divide two line plots: (x³)/(x²) = x
#plot line (fun x => x^3) / line (fun x => x^2)

This will give users a clear, working demonstration of the new * and / operators on Plot objects.

Comment on lines +1 to +84
import LeanPlot.Components
import LeanPlot.Palette
import LeanPlot.Constants
import LeanPlot.ToFloat
import LeanPlot.AutoDomain
import LeanPlot.Axis

/-! # LeanPlot.API – Tier-0 zero-config helpers

This module exposes high-level chart helpers with sensible defaults so that
users can go from a Lean function to a rendered plot with essentially zero
boiler-plate. The philosophy is *progressive disclosure*: we begin with a
tiny "Tier-0" surface area (`lineChart`, `scatterChart`) and allow more
customisation via lower-level constructors such as
`LeanPlot.Components.mkLineChart` when needed.

Future iterations will expand the API hierarchy but the Tier-0 helpers are
expected to remain stable. -/

open LeanPlot.Components LeanPlot.Palette LeanPlot.Constants LeanPlot.Axis
open Lean ProofWidgets
open ProofWidgets.Recharts (LineChart Line LineType)
open scoped ProofWidgets.Jsx

namespace LeanPlot.API

/-- Convert an array of `(x,y)` pairs into the JSON row structure expected by
Recharts. -/
@[inline] def xyArrayToJson (pts : Array (Float × Float)) : Array Json :=
pts.map fun (x, y) => json% {x: $(toJson x), y: $(toJson y)}



/-- **Tier-0 helper:** Render a line chart from an array of points.
This delegates to `LeanPlot.Components.mkLineChart` under the hood and
uses the first colour of `defaultPalette` for the point fill.
-/
@[inline] def mkLineChart (data : Array Json) (seriesStrokes : Array (String × String)) (w h : Nat := 400) : Html :=
<LineChart width={w} height={h} data={data}>
<XAxis dataKey?="x" />
<YAxis />
{... seriesStrokes.map (fun (name, colour) =>
<Line type={LineType.monotone} dataKey={Json.str name} stroke={colour} dot?={some false} />)}
</LineChart>

/-- **Tier-0 helper:** Render a line chart for a single function
`f : Float → β` with zero configuration. The function is sampled uniformly
on `[0,1]` using `steps` samples (default 200). The chart is sized
`defaultW × defaultH` and coloured using the first entry of
`Palette.defaultPalette`.

Returns a `ProofWidgets.Html` value that can be rendered with `#plot`. Example:

```lean
#plot LeanPlot.API.lineChart (fun x => x*x) -- y = x²
``` -/
@[inline] def lineChart {β} [ToFloat β]
(f : Float → β) (steps : Nat := 200)
(w : Nat := defaultW) (h : Nat := defaultH) : ProofWidgets.Html :=
let data := LeanPlot.Components.sample f steps 0 1
-- Infer a reasonable y-axis domain automatically.
let (lo, hi) := LeanPlot.AutoDomain.autoDomain f steps;
let yDomain : Array Json := #[toJson lo, toJson hi];
-- Assign a colour for the single series "y" using the default palette.
let seriesStrokes := LeanPlot.Palette.autoColours #["y"];
<LineChart width={w} height={h} data={data}>
<XAxis dataKey?="x" label?="x" />
<YAxis dataKey?="y" label?="y" domain?={some yDomain} />
{... seriesStrokes.map (fun (name, colour) =>
<Line type={LineType.monotone} dataKey={Json.str name} stroke={colour} dot?={some false} />)}
</LineChart>



/-- **Tier-0 helper:** Render a scatter chart from an array of points.
This delegates to `LeanPlot.Components.mkScatterChart` under the hood and
uses the first colour of `defaultPalette` for the point fill.
-/
@[inline] def scatterChart (pts : Array (Float × Float))
(w : Nat := defaultW) (h : Nat := defaultH) : ProofWidgets.Html :=
let data := xyArrayToJson pts
LeanPlot.Components.mkScatterChart data (LeanPlot.Palette.colourFor 0) w h

end LeanPlot.API
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

File not directly related to overlay operators mentioned in PR objectives

While this API module is well-implemented and valuable, it doesn't appear to include or relate to the * and / operators for overlaying plots mentioned in the PR objectives. Consider clarifying the relationship or ensuring the PR description accurately reflects all changes.


🌐 Web query:

What are HMul and HDiv typeclasses in Lean and how are they used for operator overloading?

💡 Result:

HMul and HDiv are type classes in Lean used to implement heterogeneous multiplication and division operations. They allow for operator overloading of the * and / symbols in Lean's type system.

Heterogeneous Type Classes in Lean

HMul and HDiv are part of Lean's standard type classes that enable arithmetic operators to be overloaded for different types. The "H" prefix stands for "heterogeneous," meaning these classes allow operations between different types, unlike their homogeneous counterparts (Mul and Div)[1][8].

Structure and Definition

The HMul type class is defined with three type parameters:

class HMul (α : Type u) (β : Type v) (γ : outParam (Type w)) where
  hMul : α → β → γ

This definition means:

  • α is the type of the first operand
  • β is the type of the second operand
  • γ is the output type (marked as an output parameter)[8]

Similarly, HDiv follows the same pattern for division operations:

class HDiv (α : Type u) (β : Type v) (γ : outParam (Type w)) where
  hDiv : α → β → γ

Operator Notation

In Lean, arithmetic operators are defined as abbreviations for named functions. The expressions map to their corresponding functions as follows:

  • x * y maps to HMul.hMul x y
  • x / y maps to HDiv.hDiv x y[1]

How Operator Overloading Works

When you use the * or / operators in Lean, the compiler looks for appropriate instances of HMul or HDiv to determine how to perform the operation for the given types.

Instance Declaration

To overload these operators, you define an instance of the appropriate type class. For example:

@[default_instance] instance : HMul Int Int Int where
  hMul := Int.mul

This creates an instance that handles multiplication between two integers, producing an integer result[8].

Type Inference Process

In the type class synthesis process, the parameters α and β are treated as input values, meaning type class resolution only begins once these types are known. The output type γ is then determined based on the available instances[8].

Default Instances

Lean allows marking instances with default_instance attribute and priority values to control which implementation is chosen when multiple possibilities exist. This is particularly important when working with number literals and different numeric types[8].

Practical Applications

The heterogeneous nature of these type classes is particularly useful in mathematical programming, where you might want to multiply different types together. For example:

  • Multiplying a scalar by a vector
  • Multiplying integers with rationals
  • Applying transformations to geometric objects

This approach offers a harmonious integration of explicit and implicit programming styles, giving programmers control over which instances are available for use by type inference in a given scope[5].

Citations:


Clarify PR objectives regarding overlay operators

This API module (LeanPlot/API.lean) doesn’t define or reference the * and / overlay operators (which in Lean are backed by the HMul and HDiv typeclasses). To avoid confusion, please ensure the PR description either:

  • Notes where the overlay operators are actually implemented (e.g. the file/module defining instance : HMul … and instance : HDiv … for plots),
  • Or adds those definitions here if they were meant to belong in LeanPlot.API.

Comment on lines +74 to +75
@[inline] def autoColours (names : Array String) : Array (String × String) :=
names.zipIdx.map (fun (n, i) => (n, colourFor i))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Array.zipIdx is non-standard – ensures it exists or switch to mapIdx

zipIdx is not part of Lean core (Array offers mapIdx, enum, zipWithIndex).
If the helper lives elsewhere, please add a local open or import; otherwise the code will not compile.

-  names.zipIdx.map (fun (n, i) => (n, colourFor i))
+  names.mapIdx (fun i n => (n, colourFor i))

This uses the stdlib mapIdx, keeps the same asymptotic cost, and avoids a custom helper.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@[inline] def autoColours (names : Array String) : Array (String × String) :=
names.zipIdx.map (fun (n, i) => (n, colourFor i))
@[inline] def autoColours (names : Array String) : Array (String × String) :=
names.mapIdx (fun i n => (n, colourFor i))

Comment on lines +31 to +42
structure SeriesSpec where
/-- The name of the series, used for legend and default y-axis label. -/
name : String
/-- The key in chartData for this series' y-values. -/
dataKey : String := name
/-- The color of the series. -/
color : String
/-- The type of the series, e.g., "line", "scatter". -/
type : String -- e.g., "line", "scatter"
/-- Whether to show dots for a line series. `none` means default (true for line, not applicable for scatter). -/
dot : Option Bool := none
deriving Inhabited, ToJson, FromJson
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Replace magic string type with an enum for compile-time safety

Using a raw String to distinguish "line" vs "scatter" pushes errors to runtime and forces string equality checks later.

-  /-- The type of the series, e.g., "line", "scatter". -/
-  type     : String -- e.g., "line", "scatter"
+  /-- Kind of series to render. -/
+  kind     : SeriesKind

where

inductive SeriesKind | line | scatter
deriving BEq, Repr

Down-stream code (e.g. RenderSeries instance) then becomes an exhaustive match without string compares, eliminating a whole class of typos.

@alok alok merged commit 8cc20bf into main May 11, 2025
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant