-
Notifications
You must be signed in to change notification settings - Fork 0
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
Conversation
…gend (#plot : new demo)
• 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.
…clean duplicate headers
…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`. 🎨📖
… 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.
…owing multi-series overlay
WalkthroughThis 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
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
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
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
Poem
Tip ⚡️ Faster reviews with caching
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed 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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this 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 in38
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%
<= threshold50%
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 ofLeanPlot.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 ownsample
function. Making assumptions about the signature of an unseen function is dangerous. I don't have access to theLeanPlot.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%
<= threshold50%
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 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) |
There was a problem hiding this comment.
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.
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) |
There was a problem hiding this 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 issueMismatch between default
type
and its documentation
The comment states “The Recharts default iscategory
,” but the code sets:type : AxisType := .numberEither 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 derivingInhabited
for default propsSince
LegendProps
has no fields, deriving anInhabited
instance would let users writedefault : 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 theLegend
component docstringEmbedding 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 importsre
twice andsys
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 correctglobs
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 consistencyThe 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 eachLayer.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 priorityThe 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 addedCubicDemo
showcasingy = 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 enableslinter.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 plottingThis 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 examplesThe 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 countSince 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 returnNaN
orInfinity
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
andjsonDataHasInvalidFloats
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.sndREADME.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 new
Plot` co...(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[uncategorized] ~42-~42: You might be missing the article “the” here.
Context: ...anged - RootLeanPlot
module imports newPlot
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 genericHAdd
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‐levelPlotSpec
renderer:AxisSpec.label
i...(AI_EN_LECTOR_MISSING_DETERMINER_THE)
LeanPlot/Palette.lean (3)
16-17
: Prefer an explicitstructure Color
orabbrev HexColor
for stronger type-safetyUsing a plain
String
alias gives us no guarantees that the value really is a 6-digit hex colour.
A tiny wrapper (even an opaquestructure
) 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 ColorThis 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). -/
vsdef 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 becausei % size < size
, yet the!
still marks it as partial.
You can avoid the exclamation by indexing with aFin 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 conciseThe 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 stringsEven 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 smallHtml.text
nodesInside
render
, every unsupported branch or missing axis producesHtml.text ""
, which allocates empty nodes.
PreferHtml.empty
for no-ops to avoid creating DOM placeholders.- | none => (Html.text "" : Html) + | none => Html.emptyApply similarly to the other empty branches.
66-87
:line
helper fixes colour to index 0 – multiple calls collideIf a user overlays two
PlotSpec
s produced vialine …
without overridingcolor
, both series will pickcolourFor 0
, yielding identical strokes.Provide the colour index as an explicit parameter or compute
nextIdx
fromspec.series.size
when composing.LeanPlot/Demos/QuadraticDemo.lean (2)
1-4
: Streamline imports and opens for consistency
The current imports (LeanPlot.API
thenLeanPlot.Plot
) and theopen Lean
/open ProofWidgets
statements differ from the pattern in other demos (e.g.,LinearDemo.lean
importsLeanPlot.Plot
beforeLeanPlot.API
and does not openLean
orProofWidgets
). Consider:
- Reordering imports to match
LinearDemo.lean
:- import LeanPlot.API - import LeanPlot.Plot + import LeanPlot.Plot + import LeanPlot.API- Removing
open Lean
andopen ProofWidgets
if they are not directly used, to reduce namespace clutter.
7-11
: Use unqualifiedlineChart
invocation for brevity
Since you already haveopen LeanPlot.API
(or can add it after cleaning up opens), you can simplify the plot command to mirrorLinearDemo.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
📒 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 new
Plot` 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 usageYou import
ProofWidgets.Component.Recharts
but thenopen ProofWidgets.Recharts
. Please confirm that this resolvesRecharts.javascript
correctly. If theProofWidgets.Recharts
namespace isn’t provided by the imported module, consider importing it explicitly or openingProofWidgets.Component.Recharts
instead.
3-9
: Well-documented module headerThe
/-! ... -/
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 andopen
statementsYou call
deriving FromJson, ToJson
below—ensure that the necessary JSON deriving support (e.g. fromLean.Data.Json
) is in scope, whether transitively viaopen 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 theBatteries.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 thatimport
statements must be a top-level block and prohibits doc comments on declarations, which will preventinvalid 'import' command
errors.LeanPlot/Experiments.lean (3)
1-11
: Well-structured experiment setup with clear documentationThe 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 functionalityThese 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 developmentThe 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 sectionThis 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 roadmapThis 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 sectionThe 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 purposeThe 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 structureThe
SavePNGProps
structure has appropriate documentation for each field and includes sensible defaults for the filename.
29-33
: Flexible and reusable wrapping functionThe
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 resourceThe component depends on an external CDN resource (html2canvas) which could introduce risks if the CDN becomes unavailable.
Consider one of these approaches:
- Bundle the library with your project to avoid external dependencies
- Add error handling for when the library fails to load
- 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 organizationThe 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 chartsThe
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 chartsThe
ScatterChartProps
structure is well-defined with proper documentation and derives the necessary JSON serialization instances.
106-108
: Consistent component implementationThe
ScatterChart
component correctly reuses the existing Recharts JavaScript bundle, maintaining consistency with other chart components.
111-123
: Well-structured scatter data point props and componentThe
ScatterProps
structure andScatter
component are well-implemented with appropriate documentation and consistent with the library's design patterns.
124-136
: Functional scatter chart helper consistent with existing patternsThe
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
andHDiv
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.leanLength of output: 1199
Overlay operators are defined in Core and demo’d in Demos
The
HMul
andHDiv
instances live inLeanPlot/Core.lean
(around lines 74 and 78), and the playground demo showing their usage is inLeanPlot/Demos/OperatorPlayground.lean
. SinceComponents.lean
only contains the Recharts wrappers, the overlay-operator code being absent here is expected.LeanPlot/Core.lean (1)
70-80
: Mind the globalHMul
/HDiv
instances – possible overlap with numeric multiplication & divisionRegistering highly-generic instances for
HMul α β Plot
andHDiv α β Plot
is elegant, but it widens the instance search space for every use of*
or/
in user code.
Although you set the priority to2000
(lower than the default1000
), these instances are still considered whenever the operands are not already syntactically known numeric types. In practice this may:
- Introduce noticeable instance-search slow-downs inside large proofs that do a lot of arithmetic.
- 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 whereor 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 examplesThe 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 goodThe 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.
ExposingLeanPlot.Plot
, the demo modules, andLeanPlot.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 bothLeanPlot.Demos.OverlayPlot
andLeanPlot.Demos.OverlayDemo
. Ensure these correspond to distinct modules inLeanPlot/Demos/
and that there isn’t overlap or a naming mismatch.lakefile.toml (1)
5-7
: ReviewleanOptions
settings.
Enablingpp.unicode.fun
andlinter.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 inLeanPlot.API
andLeanPlot.Plot
provides the zero-configlineChart
helper and the#plot
command.
4-5
: Open statements set up context appropriately.
Theopen
andopen 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 thelineChart
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 imagesThis 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 featuresThe manifest has been updated to include several new packages (
verso
,MD4Lean
, andsubverso
) 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. ExistingFloat
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.mdcLength 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 approachThe 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 goodThe implementation uses
mkLineChartFull
to create a chart with multiple data series (identity, square, square root) and assigns colors automatically withautoColours
. This serves as a good demo for overlaying different function plots.LeanPlot/Algebra.lean (4)
7-29
: Well-documented algebra of graphics conceptThe 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 definitionsThe
LineSeries
andLinePlot
structures are clearly defined with appropriate documentation comments. The default values for sampling parameters are sensible.
52-60
: Effective implementation of plot overlay functionalityThe
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
andHDiv
to enable the use of*
and/
operators for overlaying plots, but I don't see these instances defined in this file. Currently, only conversion toLayer
is implemented, which supports the+
operator via the genericPlot
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 genericHMul
andHDiv
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
orHDiv
instances need to be added toAlgebra.lean
.Likely an incorrect or invalid review comment.
LeanPlot/API.lean (4)
8-19
: Clear API design philosophy documentedThe 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 helperThe
mkLineChart
function provides a clean implementation for rendering line charts with sensible defaults, supporting multiple series through theseriesStrokes
parameter.
57-72
: Effective zero-config line chart implementationThe
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 goodThe
scatterChart
function provides a clean implementation for rendering scatter plots from point data with sensible defaults.LeanPlot/Specification.lean (1)
168-172
:addSeries
silently forceslegend := true
– may surprise callersWhen 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
CentralizingdefaultW
anddefaultH
inLeanPlot.Constants
with@[inline]
andNat
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
thenLeanPlot.API
- Opens
LeanPlot.API
to accesslineChart
- 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
ImportingVersoManual
andLeanPlotManual
, then openingVerso.Genre
andManual
, 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 pointmain
is properly defined
Themain : IO UInt32
function invokesmanualMain
with theLeanPlotManual
doc anddocsConfig
. This aligns withlake exe docs
conventions.
--- | ||
description: | ||
globs: | ||
alwaysApply: false | ||
--- |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
[[require]] | ||
name = "verso" | ||
git = "https://github.com/leanprover/verso.git" |
There was a problem hiding this comment.
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
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 |
There was a problem hiding this comment.
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.
/-- 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)) |
There was a problem hiding this comment.
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.
|
||
* `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²` |
There was a problem hiding this comment.
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.
* `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 (`+`, `*`, `/`) |
## [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. | ||
|
There was a problem hiding this comment.
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.
## [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)
#plot multiSeries | ||
#plot line (fun x => x^3) |
There was a problem hiding this comment.
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.
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 |
There was a problem hiding this comment.
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 toHMul.hMul x y
x / y
maps toHDiv.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:
- 1: https://lean-lang.org/functional_programming_in_lean/type-classes/standard-classes.html
- 2: https://lean-lang.org/doc/reference/latest/Type-Classes/Basic-Classes/
- 3: https://leanprover-community.github.io/mathlib4_docs/Init/Prelude.html
- 4: https://github.com/leanprover/lean4/blob/master/src/Init/Prelude.lean
- 5: https://people.mpi-sws.org/~dreyer/papers/mtc/main-long.pdf
- 6: https://forums.developer.nvidia.com/t/correct-syntax-for-operator-overloading-in-cuda/13374
- 7: https://www.programiz.com/cpp-programming/operator-overloading
- 8: https://github.com/leanprover/theorem_proving_in_lean4/blob/master/type_classes.md
- 9: https://fstar-lang.org/tutorial/book/part3/part3_typeclasses.html
- 10: Operator Overloading ziglang/zig#871
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 …
andinstance : HDiv …
for plots), - Or adds those definitions here if they were meant to belong in
LeanPlot.API
.
@[inline] def autoColours (names : Array String) : Array (String × String) := | ||
names.zipIdx.map (fun (n, i) => (n, colourFor i)) |
There was a problem hiding this comment.
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.
@[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)) |
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 |
There was a problem hiding this comment.
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.
Added\n* New
HMul
andHDiv
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 @alokImportant
Add
HMul
andHDiv
instances for plot overlays and demonstrate inOperatorPlayground.lean
.HMul
andHDiv
instances to allow*
and/
to overlay plots, similar to+
.LeanPlot/Demos/OperatorPlayground.lean
with a multi-series chart.CHANGELOG.md
to reflect new features and changes..cursor/rules/
for debugging, import order, plot feature gallery, and Verso docstrings.README.md
with new features and installation instructions.Gallery.md
to include new demo entries.DocsMain.lean
for manual generation configuration.This description was created by
for 8cc20bf. You can customize this summary. It will automatically update as commits are pushed.
Summary by CodeRabbit
New Features
lineChart
,scatterChart
) for quick plotting from functions or arrays.+
operator.#plot
command for easy rendering of charts within Lean code.Enhancements
Documentation
Chores