basedpl 0.1.71__tar.gz → 0.1.72__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {basedpl-0.1.71 → basedpl-0.1.72}/.github/workflows/test.yml +11 -4
- {basedpl-0.1.71 → basedpl-0.1.72}/Cargo.lock +13 -13
- {basedpl-0.1.71 → basedpl-0.1.72}/Cargo.toml +1 -1
- {basedpl-0.1.71 → basedpl-0.1.72}/DEV.md +1 -1
- {basedpl-0.1.71 → basedpl-0.1.72}/PKG-INFO +1 -1
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/downstile.qmd +1 -3
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/upstile.qmd +1 -3
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/numbers.qmd +2 -3
- {basedpl-0.1.71 → basedpl-0.1.72}/py/src/lib.rs +1 -1
- {basedpl-0.1.71 → basedpl-0.1.72}/python/basedpl/bpltests.py +3 -1
- {basedpl-0.1.71 → basedpl-0.1.72}/src/batch.rs +2 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/derivative.rs +27 -43
- {basedpl-0.1.71 → basedpl-0.1.72}/src/eval/operators.rs +10 -3
- {basedpl-0.1.71 → basedpl-0.1.72}/src/fusion.rs +1 -1
- {basedpl-0.1.71 → basedpl-0.1.72}/src/pervasive.rs +50 -47
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/reference/core.bpl +6 -3
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/speed.txt +44 -42
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/wasm.mjs +8 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/.cargo/config.toml +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/.gitattributes +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/.github/workflows/ci.yml +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/.github/workflows/docs.yml +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/.github/workflows/speed.yml +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/.gitignore +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/CONTRIBUTING.md +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/LICENSE +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/README.md +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/_config.yml +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/_layouts/default.html +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/build.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/editors/jetbrains/BPL.tmbundle/Syntaxes/bpl.tmLanguage.json +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/editors/jetbrains/BPL.tmbundle/Syntaxes/hpl.tmLanguage.json +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/editors/jetbrains/BPL.tmbundle/info.plist +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/editors/jetbrains/BPL.xml +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/editors/jetbrains/README.md +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/editors/macos/BasedPL-de.bundle/Contents/Info.plist +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/editors/macos/BasedPL-de.bundle/Contents/Resources/BasedPL-de.icns +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/editors/macos/BasedPL-de.bundle/Contents/Resources/BasedPL-de.keylayout +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/editors/macos/BasedPL-de.bundle/Contents/Resources/en.lproj/InfoPlist.strings +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/editors/macos/BasedPL-de.bundle/Contents/version.plist +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/editors/macos/BasedPL-de.txt +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/editors/macos/BasedPL-es.bundle/Contents/Info.plist +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/editors/macos/BasedPL-es.bundle/Contents/Resources/BasedPL-es.icns +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/editors/macos/BasedPL-es.bundle/Contents/Resources/BasedPL-es.keylayout +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/editors/macos/BasedPL-es.bundle/Contents/Resources/en.lproj/InfoPlist.strings +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/editors/macos/BasedPL-es.bundle/Contents/version.plist +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/editors/macos/BasedPL-es.txt +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/editors/macos/BasedPL-fr.bundle/Contents/Info.plist +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/editors/macos/BasedPL-fr.bundle/Contents/Resources/BasedPL-fr.icns +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/editors/macos/BasedPL-fr.bundle/Contents/Resources/BasedPL-fr.keylayout +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/editors/macos/BasedPL-fr.bundle/Contents/Resources/en.lproj/InfoPlist.strings +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/editors/macos/BasedPL-fr.bundle/Contents/version.plist +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/editors/macos/BasedPL-fr.txt +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/editors/macos/BasedPL-uk.bundle/Contents/Info.plist +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/editors/macos/BasedPL-uk.bundle/Contents/Resources/BasedPL-uk.icns +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/editors/macos/BasedPL-uk.bundle/Contents/Resources/BasedPL-uk.keylayout +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/editors/macos/BasedPL-uk.bundle/Contents/Resources/en.lproj/InfoPlist.strings +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/editors/macos/BasedPL-uk.bundle/Contents/version.plist +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/editors/macos/BasedPL-uk.txt +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/editors/macos/BasedPL-us.bundle/Contents/Info.plist +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/editors/macos/BasedPL-us.bundle/Contents/Resources/BasedPL-us.icns +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/editors/macos/BasedPL-us.bundle/Contents/Resources/BasedPL-us.keylayout +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/editors/macos/BasedPL-us.bundle/Contents/Resources/en.lproj/InfoPlist.strings +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/editors/macos/BasedPL-us.bundle/Contents/version.plist +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/editors/macos/BasedPL-us.txt +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/editors/vim/ftdetect/bpl.vim +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/editors/vim/syntax/bpl.vim +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/editors/windows/README.md +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/editors/windows/build.ps1 +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/editors/windows/install.ps1 +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/editors/windows/keyboard.c +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/editors/windows/keyboard.def +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/editors/windows/keyboard.rc +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/editors/windows/layout.h +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/index_files/figure-commonmark/cell-17-output-1.svg +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/index_files/figure-commonmark/cell-18-output-1.svg +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/index_files/figure-html/cell-17-output-1.svg +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/index_files/figure-html/cell-18-output-1.svg +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/lib/LICENSE-april +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/lib/README.md +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/lib/array.bpl +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/lib/dyalog.bpl +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/lib/graph.bpl +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/lib/numeric.bpl +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/lib/power.bpl +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/lib/regex.bpl +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/lib/string.bpl +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/lib/tree.bpl +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/.gitignore +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/_quarto.yml +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/arrays.ipynb +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/assignment.ipynb +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/bpl.xml +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/bqn.xml +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/bracket-types.ipynb +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/cli.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/comparison.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/data.ipynb +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/dfns.ipynb +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/distributions.ipynb +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/driver.js +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/dyalog.ipynb +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/dyalog.xml +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/evaluation.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/fonts/LICENSE-SAX2 +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/fonts/README.md +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/fonts/SAX2B.ttf +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/fonts/SAX2B.woff2 +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/fonts.css +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/gallery/attractor.bpl +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/gallery/boids.bpl +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/gallery/dragon.bpl +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/gallery/flow.bpl +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/gallery/mandelbrot.bpl +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/gallery/mandelbrot32.bpl +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/gallery/orbits.bpl +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/gallery/phyllotaxis.bpl +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/gallery/prefs.bpl +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/gallery/reaction.bpl +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/gallery.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/getting-started.ipynb +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/_metadata.yml +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/alpha-underbar.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/alpha.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/at.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/backslash-bar.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/backslash.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/braces.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/brackets.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/bullet.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/circle-backslash.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/circle-bar.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/circle-diaeresis.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/circle-divide.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/circle-slash.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/circle-star.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/circle-stile.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/circle-times.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/circle.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/colon.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/comma-bar.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/comma.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/del-diaeresis.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/del-stile.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/del.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/delta-stile.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/diaeresis.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/diamond-underbar.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/diamond.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/domino.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/dot.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/down-arrow.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/down-shoe.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/down-tack.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/epsilon-underbar.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/epsilon.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/equal-underbar-slash.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/equal-underbar.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/equals.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/error-guard.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/exclamation.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/greater-than-or-equal.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/greater-than.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/hash.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/hydrant.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/infinity.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/inverted-question.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/iota-underbar.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/iota.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/jot-diaeresis.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/jot.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/lamp.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/left-arrow.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/left-shoe-underbar.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/left-shoe.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/left-tack.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/left-tail-arrow.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/less-than-or-equal.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/less-than.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/minus.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/not-equals.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/obelus.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/omega-underbar.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/omega.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/overbar.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/parentheses.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/partial.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/pi.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/plus.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/quad-colon.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/quad-diamond.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/quad-equal.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/quad-jot.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/quad.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/question.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/quote.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/radical.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/rho.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/right-arrow-from-bar.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/right-left-arrows.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/right-shoe.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/right-tack.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/right-tail-arrow.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/slash-bar.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/slash.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/squad.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/star-diaeresis.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/star.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/stile-tilde.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/stile.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/superscript-b.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/thorn.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/tilde-diaeresis.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/tilde.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/times.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/up-arrow.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/up-down-arrow.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/up-shoe.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/up-tack.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/vee-bar.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/vee.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/wedge-bar.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/wedge.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs/zilde.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs-study.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/glyphs.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/hanzi-notation-zh.ipynb +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/hanzi-notation.ipynb +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/hpl.xml +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/index.ipynb +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/indexing.ipynb +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/introspection.ipynb +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/keyboard.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/keyed.ipynb +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/llms.txt +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/magics.ipynb +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/modules.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/nbdev.yml +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/notebooks.ipynb +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/overview.ipynb +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/papers/aplwiki-arrays.md +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/papers/brickman-depth-1-scalars.md +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/papers/mercer-based-system.md +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/playground/bpl.js +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/playground/gallery.js +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/playground/hpl.tmLanguage.json +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/playground/monaco-worker.js +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/playground/page.js +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/playground/worker.js +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/playground.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/plot.ipynb +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/principles.ipynb +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/processes.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/puppy.jpg +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/python.ipynb +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/regex.ipynb +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/repl.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/scripts.ipynb +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/sidebar.yml +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/strings.ipynb +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/study/01_basics.ipynb +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/study/02_functions.ipynb +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/study/03_operators.ipynb +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/study/04_nested-arrays.ipynb +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/study/05_searching-indexing.ipynb +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/study/06_rearranging-arrays.ipynb +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/study/07_numerical-tools.ipynb +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/style.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/styles.css +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/syntax.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/_metadata.yml +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/c.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/canvas.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/constants.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/copy.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/csv.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/date.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/decompose.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/deflate.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/delay.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/detach.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/distribution.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/edge.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/element.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/ex.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/explain.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/fetch.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/float.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/hash.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/host.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/image.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/index.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/js.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/json.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/literal.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/load.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/memory.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/metadata.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/mime.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/mkdir.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/nc.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/nget.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/nl.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/normalize.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/nput.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/path.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/plot.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/prefs.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/r.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/rand.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/readdir.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/remove.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/rename.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/signal.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/src.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/storage.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/svg.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/time.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/ucs.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/uuid.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/vfi.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system/xml.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/system-functions.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/terms.qmd +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/web.ipynb +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/nbs/xml.ipynb +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/package-lock.json +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/package.json +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/provenance/README.md +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/provenance/aplcart.jsonl +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/provenance/april.jsonl +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/provenance/bqn.jsonl +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/provenance/core.jsonl +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/provenance/dyalog.jsonl +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/provenance/ngn.jsonl +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/py/Cargo.toml +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/py/build.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/pyproject.toml +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/python/basedpl/__init__.py +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/python/basedpl/_modidx.py +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/python/basedpl/bpl.tmLanguage.json +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/python/basedpl/dyalog.py +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/python/basedpl/editors.py +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/python/basedpl/font.py +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/python/basedpl/fonts.css +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/python/basedpl/functions.py +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/python/basedpl/hpl.tmLanguage.json +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/python/basedpl/input.js +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/python/basedpl/ipython.py +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/python/basedpl/keyboards.json +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/python/basedpl/keyboards.py +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/python/basedpl/layout.json +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/python/basedpl/lb.js +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/python/basedpl/notebook_runner.py +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/python/basedpl/notebooks.py +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/python/basedpl/printing.py +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/python/basedpl/reference.py +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/python/basedpl/syntax.py +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/python/basedpl/windows_keyboard.py +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/python/basedpl/worker.py +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/rustfmt.toml +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/scripts/install-macos.sh +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/scripts/prep.py +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/agreement.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/array/storage.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/array/text.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/array.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/canvas.js +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/canvas.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/csv.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/data.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/date.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/display.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/distribution.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/element.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/error.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/eval/assign.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/eval/binder.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/eval/bindings.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/eval/dissect.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/eval/idioms.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/eval/session.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/eval/tree.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/eval.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/execution.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/explain.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/files.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/fusion/blocks.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/host.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/host_web.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/image/codecs.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/image/imageio.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/image.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/inspection.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/js.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/json.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/keyed.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/lib.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/linear.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/name.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/number.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/number_theory.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/optimize.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/plot.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/polynomial.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/primitive/indexing.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/primitive/numeric.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/primitive/search.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/primitive/structural.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/primitive.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/protocol.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/reference.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/regex.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/search.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/selection.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/settings.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/symbols.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/syntax.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/system.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/timing.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/transform.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/src/xml.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/common/mod.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/conftest.py +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/core.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/derivatives.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/explain.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/highlighting.mjs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/input.mjs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/instructions.txt +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/reference/LICENSE-aplcart +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/reference/LICENSE-april +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/reference/LICENSE-bqn +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/reference/LICENSE-bqncrate +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/reference/LICENSE-dyalog +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/reference/LICENSE-ngn +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/reference/README.md +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/reference/aplcart.bpl +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/reference/april.bpl +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/reference/bqn.bpl +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/reference/distributions.bpl +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/reference/dyalog.bpl +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/reference/graphics.bpl +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/reference/lib.bpl +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/reference/ngn.bpl +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/reference/regex.bpl +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/reference/static-int32.bpl +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/reference/static.bpl +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/reference/support/april.bpl +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/reference/support/avl.bpl +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/reference/support/redblack.bpl +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/reference/support/sbst.bpl +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/reference/support/splay.bpl +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/reference.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/scaling.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/settings.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/speed.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/test_api.py +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/test_basic.py +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/test_bpltests.py +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/test_glyphs.py +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/test_graphics.py +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/test_instructions.py +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/test_ipython.py +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/test_kernel.py +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/test_keylayout.py +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/test_notebooks.py +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/test_reference.py +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/test_repl.py +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/test_windows_keyboard.py +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/test_worker.py +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/units.rs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/wasm-pkg.mjs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/wasm-speed.mjs +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/tests/windows_keyboard.c +0 -0
- {basedpl-0.1.71 → basedpl-0.1.72}/wheel/data/share/jupyter/kernels/bpl/kernel.json +0 -0
|
@@ -8,31 +8,37 @@ on:
|
|
|
8
8
|
permissions:
|
|
9
9
|
contents: read
|
|
10
10
|
|
|
11
|
+
# In each job, every test step after the first runs even when an earlier step fails, to report every test's result in one run.
|
|
11
12
|
jobs:
|
|
12
13
|
test:
|
|
13
14
|
runs-on: ubicloud-standard-4
|
|
14
15
|
steps:
|
|
15
16
|
- uses: actions/checkout@v7
|
|
16
|
-
- run: node tests/input.mjs
|
|
17
17
|
# `tests/highlighting.mjs` reads the TextMate grammar through `shiki`, which `package.json` pins.
|
|
18
18
|
- run: npm ci
|
|
19
|
-
- run: node tests/highlighting.mjs
|
|
20
19
|
- uses: dtolnay/rust-toolchain@stable
|
|
21
20
|
# The repository has no `Cargo.lock`. Creating one first makes rust-cache's key change when a dependency publishes a new version.
|
|
22
21
|
- run: cargo generate-lockfile
|
|
23
22
|
- uses: Swatinem/rust-cache@v2
|
|
24
23
|
with:
|
|
25
24
|
shared-key: native
|
|
26
|
-
# With `BASEDPL_COSTS`, the speed tests here and in the `wasm` job log every case's cost, which `basedpl.bpltests.logged_costs` reads.
|
|
27
|
-
- run: BASEDPL_COSTS=1 cargo test
|
|
28
25
|
- uses: actions/setup-python@v7
|
|
29
26
|
with:
|
|
30
27
|
python-version: '3.12'
|
|
31
28
|
- run: pip install -e '.[dev]'
|
|
32
29
|
- run: cargo develop
|
|
30
|
+
- run: node tests/input.mjs
|
|
31
|
+
- run: node tests/highlighting.mjs
|
|
32
|
+
if: ${{ !cancelled() }}
|
|
33
|
+
# With `BASEDPL_COSTS`, the speed tests here and in the `wasm` job log every case's cost, which `basedpl.bpltests.logged_costs` reads.
|
|
34
|
+
- run: BASEDPL_COSTS=1 cargo test
|
|
35
|
+
if: ${{ !cancelled() }}
|
|
33
36
|
- run: pytest -q
|
|
37
|
+
if: ${{ !cancelled() }}
|
|
34
38
|
- run: bpl-nb
|
|
39
|
+
if: ${{ !cancelled() }}
|
|
35
40
|
- run: nbdev-test
|
|
41
|
+
if: ${{ !cancelled() }}
|
|
36
42
|
|
|
37
43
|
wasm:
|
|
38
44
|
runs-on: ubicloud-standard-4
|
|
@@ -49,3 +55,4 @@ jobs:
|
|
|
49
55
|
- run: cargo wasm --strip
|
|
50
56
|
- run: node --test tests/wasm.mjs
|
|
51
57
|
- run: BASEDPL_COSTS=1 node --no-liftoff --test tests/wasm-speed.mjs
|
|
58
|
+
if: ${{ !cancelled() }}
|
|
@@ -93,7 +93,7 @@ checksum = "ac07cdecf99051d9a5238b80f35af32cdeba5b336e55d957b318b50137e18da5"
|
|
|
93
93
|
|
|
94
94
|
[[package]]
|
|
95
95
|
name = "basedpl"
|
|
96
|
-
version = "0.1.
|
|
96
|
+
version = "0.1.72"
|
|
97
97
|
dependencies = [
|
|
98
98
|
"base64 0.23.1",
|
|
99
99
|
"bytemuck",
|
|
@@ -137,7 +137,7 @@ dependencies = [
|
|
|
137
137
|
|
|
138
138
|
[[package]]
|
|
139
139
|
name = "basedpl-cli"
|
|
140
|
-
version = "0.1.
|
|
140
|
+
version = "0.1.72"
|
|
141
141
|
dependencies = [
|
|
142
142
|
"async-trait",
|
|
143
143
|
"basedpl",
|
|
@@ -150,7 +150,7 @@ dependencies = [
|
|
|
150
150
|
|
|
151
151
|
[[package]]
|
|
152
152
|
name = "basedpl-py"
|
|
153
|
-
version = "0.1.
|
|
153
|
+
version = "0.1.72"
|
|
154
154
|
dependencies = [
|
|
155
155
|
"basedpl",
|
|
156
156
|
"num-bigint",
|
|
@@ -165,7 +165,7 @@ dependencies = [
|
|
|
165
165
|
|
|
166
166
|
[[package]]
|
|
167
167
|
name = "basedpl-wasm"
|
|
168
|
-
version = "0.1.
|
|
168
|
+
version = "0.1.72"
|
|
169
169
|
dependencies = [
|
|
170
170
|
"basedpl",
|
|
171
171
|
"js-sys",
|
|
@@ -256,9 +256,9 @@ checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04"
|
|
|
256
256
|
|
|
257
257
|
[[package]]
|
|
258
258
|
name = "cc"
|
|
259
|
-
version = "1.
|
|
259
|
+
version = "1.10.0"
|
|
260
260
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
261
|
-
checksum = "
|
|
261
|
+
checksum = "86e055fa6e3e40ad6187ba25b6855eeb635d5271f8e0f0e1e9a5826b8d75bea0"
|
|
262
262
|
dependencies = [
|
|
263
263
|
"find-msvc-tools",
|
|
264
264
|
"shlex",
|
|
@@ -303,9 +303,9 @@ dependencies = [
|
|
|
303
303
|
|
|
304
304
|
[[package]]
|
|
305
305
|
name = "clipboard-win"
|
|
306
|
-
version = "5.4.
|
|
306
|
+
version = "5.4.3"
|
|
307
307
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
308
|
-
checksum = "
|
|
308
|
+
checksum = "052af7878466feccda12ba7a6a67d019d712f296809559b47c12c8cc196d3a9a"
|
|
309
309
|
dependencies = [
|
|
310
310
|
"error-code",
|
|
311
311
|
]
|
|
@@ -1413,9 +1413,9 @@ dependencies = [
|
|
|
1413
1413
|
|
|
1414
1414
|
[[package]]
|
|
1415
1415
|
name = "rustymath"
|
|
1416
|
-
version = "0.1.
|
|
1416
|
+
version = "0.1.46"
|
|
1417
1417
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1418
|
-
checksum = "
|
|
1418
|
+
checksum = "f160fb701304e3888885ade3929ef93b7c7d1aaab5ae61f16c0ec0e01f270cab"
|
|
1419
1419
|
dependencies = [
|
|
1420
1420
|
"foldhash",
|
|
1421
1421
|
"half",
|
|
@@ -1434,9 +1434,9 @@ dependencies = [
|
|
|
1434
1434
|
|
|
1435
1435
|
[[package]]
|
|
1436
1436
|
name = "rustymath-buffer"
|
|
1437
|
-
version = "0.1.
|
|
1437
|
+
version = "0.1.46"
|
|
1438
1438
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1439
|
-
checksum = "
|
|
1439
|
+
checksum = "1c1457056dae79ecf521f89d600f82a2a954e601ecd8d478e495b65cb6145010"
|
|
1440
1440
|
dependencies = [
|
|
1441
1441
|
"pyo3",
|
|
1442
1442
|
"rustymath",
|
|
@@ -2086,7 +2086,7 @@ checksum = "3ad82d2a33cdc9674dc7465672f271e096168fcdbe0f799d9e6db8c5892679dc"
|
|
|
2086
2086
|
|
|
2087
2087
|
[[package]]
|
|
2088
2088
|
name = "xtask"
|
|
2089
|
-
version = "0.1.
|
|
2089
|
+
version = "0.1.72"
|
|
2090
2090
|
dependencies = [
|
|
2091
2091
|
"anyhow",
|
|
2092
2092
|
"rustymath",
|
|
@@ -184,7 +184,7 @@ Bare numbers, empty literals and NaN use the parsed float width. Top-level `eval
|
|
|
184
184
|
|
|
185
185
|
Float operations compute at the wider operand width. Exact operands round to the width an operation computes at. f16 operations run on f32 copies. `Numeric::halving` decides when: for a call with an f16 operand, or any call while the default width is 16 bits. `pervasive::halves` applies it to whole operations and `Number::halves` to scalar arithmetic and comparisons. `fusion::defer` declines those calls. Exact inputs convert once, to f32, and float outputs round back to f16. The scalar `Number` path rounds each f16 step. Complex parts have f32/f64 widths; f16 becoming complex uses f32 parts. Scalar Complex32 arithmetic computes at Complex64 and rounds, while kernels can compute at f32. These paths need not agree in their last bits.
|
|
186
186
|
|
|
187
|
-
Floats use IEEE NaN, infinity and signed zero. Comparison treats NaN as unequal; match/search treat it as one value, and grade puts it last. Exact arithmetic involving division by zero can produce those float values. Floor/ceiling retain an exact operand beside infinity
|
|
187
|
+
Floats use IEEE NaN, infinity and signed zero. Comparison treats NaN as unequal; match/search treat it as one value, and grade puts it last. Exact arithmetic involving division by zero can produce those float values. Floor/ceiling retain an exact operand beside infinity. Beside NaN the language leaves their result open: NaN or the other argument, varying by platform. Their folds, scans, windows, products and repeated writes give NaN or the maximum or minimum of the items that aren't NaN, never another number, by the rule in rustymath's `Folds` doc. A loop that folds by them either passes its running result as the right argument, which `rustymath::reduce::maximum` keeps beside NaN, or folds through rustymath's `Max` and `Min`, as `Dyad::extremum` does. Monadic floor/ceiling/sign turn whole finite results into exact integers, including big integers; nonfinite results remain floats. Use `Number::float(value, width)` and explicit-width array construction outside `number.rs` instead of implicit f64 conversion.
|
|
188
188
|
|
|
189
189
|
Under `•prefs ["kinds":"static"]`, a result's kind follows from its arguments' kinds alone, as `meta/kinds.md` describes. `Numeric` carries `kinds` and `int`. `pervasive::map` chooses a dyadic call's kind through `joined`, which applies rustymath's `DType::common` after `Numeric::kind`. Atoms promote as arrays do. Python's API makes its scalar arguments weak through `Value::weakened`. The loops keep the failed results that `keeps` names: floats' NaNs, and the wrapped integers of objects that report `WRAPS`. The kernel tables choose float `⌊ ⌈ ×` and wrapping negation from `run.numeric()`. `Stored::build_at` keeps complex results complex. `Primitive::number` gives every pervasive result on numbers, as well as each step of the fold of numbers, and `statically` adjusts it. `Number::parse` keeps complex literals and checks integer literals against the `int` width.
|
|
190
190
|
|
|
@@ -15,12 +15,10 @@ Complex floor uses APL's Gaussian-integer rule.
|
|
|
15
15
|
⌊1.5j0.5 ⍝ 1j1
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
-
`X⌊Y` takes the real minimum, and for characters the one with the lower code point. A number is less than any character, as [`⍋`](delta-stile.qmd) orders them. Pervasive. Beside NaN it gives
|
|
18
|
+
`X⌊Y` takes the real minimum, and for characters the one with the lower code point. A number is less than any character, as [`⍋`](delta-stile.qmd) orders them. Pervasive. Beside NaN it gives NaN or the other argument. Which one can vary by platform. A reduction, scan, window or inner product by `⌊`, or a write by `⌊←` to one position more than once, gives NaN or the least of the items that aren't NaN, and never another number. Empty reduction identity: `∞`.
|
|
19
19
|
|
|
20
20
|
```bpl
|
|
21
21
|
3⌊1 5 ⍝ 1 3
|
|
22
|
-
3⌊1 $n 5 ⍝ 1 $n 3
|
|
23
|
-
⌊\1 $n 3 ⍝ 1 1 1
|
|
24
22
|
"abc"⌊"bab" ⍝ "aab"
|
|
25
23
|
3⌊'a' ⍝ 3
|
|
26
24
|
```
|
|
@@ -9,12 +9,10 @@ Function. Keys: `Alt-s`. Hanzi: `上`. Ranks: `0` monadic, `0 0` dyadic
|
|
|
9
9
|
⌈3r2 ⍝ 2ₓ
|
|
10
10
|
```
|
|
11
11
|
|
|
12
|
-
`X⌈Y` takes the real maximum, and for characters the one with the higher code point. A character is greater than any number, as [`⍋`](delta-stile.qmd) orders them. Pervasive. Beside NaN it gives
|
|
12
|
+
`X⌈Y` takes the real maximum, and for characters the one with the higher code point. A character is greater than any number, as [`⍋`](delta-stile.qmd) orders them. Pervasive. Beside NaN it gives NaN or the other argument. Which one can vary by platform. A reduction, scan, window or inner product by `⌈`, or a write by `⌈←` to one position more than once, gives NaN or the greatest of the items that aren't NaN, and never another number. Empty reduction identity: `¯∞`.
|
|
13
13
|
|
|
14
14
|
```bpl
|
|
15
15
|
3⌈1 5 ⍝ 3 5
|
|
16
|
-
3⌈1 $n 5 ⍝ 3 $n 5
|
|
17
|
-
⌈\1 $n 3 ⍝ 1 1 3
|
|
18
16
|
"abc"⌈"bab" ⍝ "bbc"
|
|
19
17
|
3⌈'a' ⍝ 'a'
|
|
20
18
|
```
|
|
@@ -199,14 +199,13 @@ An infinity or NaN is a float. Joining one to exact integers makes them floats,
|
|
|
199
199
|
|
|
200
200
|
CSV and JSON imports give NaN for a missing number. An integer column with gaps then becomes floats. A column that also holds an integer too large for a float to hold exactly keeps each item's kind, in mixed storage.
|
|
201
201
|
|
|
202
|
-
`⌊` and `⌈` return an exact argument unchanged beside an infinity
|
|
202
|
+
`⌊` and `⌈` return an exact argument unchanged beside an infinity:
|
|
203
203
|
|
|
204
204
|
```bpl
|
|
205
205
|
3ₓ⌊∞ ⍝ 3ₓ
|
|
206
|
-
3ₓ⌊$n ⍝ $n
|
|
207
206
|
```
|
|
208
207
|
|
|
209
|
-
Arithmetic with an infinity gives floats.
|
|
208
|
+
The [`⌈`](glyphs/upstile.qmd) and [`⌊`](glyphs/downstile.qmd) pages give their results beside NaN. Arithmetic with an infinity gives floats.
|
|
210
209
|
|
|
211
210
|
## Static kinds
|
|
212
211
|
|
|
@@ -208,7 +208,7 @@ fn selection(value: &Value, index: &Bound<'_, PyAny>, convert: &Bound<'_, PyAny>
|
|
|
208
208
|
match v {
|
|
209
209
|
None => Some(rustymath_buffer::selection::selector(layout, axis, p, || unreachable!("a native selector decodes without converting"))),
|
|
210
210
|
Some(v) => match v.view() {
|
|
211
|
-
Some(
|
|
211
|
+
Some(View::Booleans(_)) => Some(rustymath_buffer::selection::array_selector(layout, axis, v.core_layout().clone(), std::sync::Arc::new(v.clone()))),
|
|
212
212
|
_ => None,
|
|
213
213
|
},
|
|
214
214
|
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import json, math, os, re, statistics, subprocess, sys, tempfile, time, tomllib
|
|
3
3
|
from concurrent.futures import ThreadPoolExecutor
|
|
4
4
|
from collections import defaultdict
|
|
5
|
+
from itertools import accumulate
|
|
5
6
|
from decimal import Context, Decimal, ROUND_CEILING
|
|
6
7
|
from dataclasses import dataclass, field, replace
|
|
7
8
|
from pathlib import Path
|
|
@@ -336,7 +337,8 @@ def instructions(
|
|
|
336
337
|
def steps(code):
|
|
337
338
|
if counts: return counts
|
|
338
339
|
rough = max(1, (count(code, 1_000, 1) - count(code, 0, 1)) / 1_000)
|
|
339
|
-
|
|
340
|
+
# Each value is at least one more than the last, for a case that retires more than `_SPAN` instructions a step, whose warm-up is then a small share of a step.
|
|
341
|
+
return list(accumulate((round((_SETTLE + i*_SPAN)/rough) for i in range(4)), lambda last, n: max(n, last + 1)))
|
|
340
342
|
def per_step(code):
|
|
341
343
|
ns = steps(code)
|
|
342
344
|
cs = [count(code, n) for n in ns]
|
|
@@ -31,6 +31,8 @@ impl Batch {
|
|
|
31
31
|
pub(crate) fn rank(&self) -> usize { self.whole.shape().len() - self.frame }
|
|
32
32
|
/// The number of cells: the product of the frame's lengths.
|
|
33
33
|
pub(crate) fn cells(&self) -> usize { self.whole.shape()[..self.frame].iter().product() }
|
|
34
|
+
/// The array that holds every cell, with the frame's axes first.
|
|
35
|
+
pub(crate) fn whole(&self) -> &Value { &self.whole }
|
|
34
36
|
/// The frame's layout: the whole's first `frame` axes, with their keys and names.
|
|
35
37
|
fn frame_layout(&self) -> Layout { self.whole.layout().axes(0..self.frame) }
|
|
36
38
|
/// One `Steps` for each frame axis, reading item `start` of each cell of the whole, cell by cell.
|
|
@@ -806,7 +806,7 @@ fn product_dual(left: &Value, right: &Value, tag: u64, stacked: bool, span: &Spa
|
|
|
806
806
|
|
|
807
807
|
/// The primal and tangent of a fold or scan by `p`, which is `×`, `⌈` or `⌊`, of `x` with tangent `tx`, through the linear operations that reverse mode transposes. A product's tangent scales each item's tangent by the product of the others and sums: the product of the nonzero items, times the sum of `tx÷x` where no item is zero, or times the zero item's tangent where one is, and 0 where more are. A maximum's or minimum's tangent gathers the tangent of the item that gives it, the first of any ties, as dyadic `⌈` and `⌊` give a tie to their left argument.
|
|
808
808
|
fn fold_rule(p: Primitive, kind: FoldKind, axis: Option<usize>, x: &Value, tx: &Value, span: &Span) -> Result<(Value, Value), Error> {
|
|
809
|
-
use {crate::array::Lanes, Arithmetic::*, Comparison::
|
|
809
|
+
use {crate::array::Lanes, Arithmetic::*, Comparison::Equal};
|
|
810
810
|
let call = |p: Primitive, a: &Value, b: &Value, span: &Span| p.call(Some(a), b, span);
|
|
811
811
|
let fold = |p: Primitive, v: &Value| Operation::Fold(p, kind).call(Pairing::Axis(axis), None, v, span);
|
|
812
812
|
let (times, plus) = (Primitive::Arithmetic(Times), Primitive::Arithmetic(Plus));
|
|
@@ -823,51 +823,35 @@ fn fold_rule(p: Primitive, kind: FoldKind, axis: Option<usize>, x: &Value, tx: &
|
|
|
823
823
|
let one = call(times, &call(times, &rest, &call(Primitive::Compare(Equal), &zeros, &Value::integer(1), span)?, span)?, &one, span)?;
|
|
824
824
|
call(plus, &none, &one, span)?
|
|
825
825
|
} else {
|
|
826
|
-
let
|
|
827
|
-
|
|
828
|
-
let
|
|
829
|
-
let
|
|
830
|
-
let
|
|
831
|
-
let (
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
826
|
+
let along = axis.unwrap_or(kind.default_axis(x.shape().len()));
|
|
827
|
+
// One pick on a batch's whole, with the frame's axes first, serves every cell. A batch's scan stops the run, and its map calls the operand once for each cell, because a scan's tangent gathers at each cell's own positions.
|
|
828
|
+
let batch = x.carrier().and_then(Carrier::batch);
|
|
829
|
+
if let (Some(b), true) = (batch, kind.scan) { return Err(Stop::new(b.level, Cause::Rule).into()); }
|
|
830
|
+
let all = batch.map_or(x, |b| b.whole());
|
|
831
|
+
let lanes = Lanes::new(all.shape(), batch.map_or(0, |b| b.frame) + along)?;
|
|
832
|
+
// Windows that slide along the fold's axis give their extremes' positions from their source, with no windows built.
|
|
833
|
+
let windows = (batch.is_none() && along == kind.default_axis(x.shape().len())).then(|| crate::fusion::picks(x, p, kind)).flatten();
|
|
834
|
+
let one_per_lane = !kind.scan && windows.is_none();
|
|
835
|
+
let offsets = match windows {
|
|
836
|
+
Some(offsets) => offsets,
|
|
837
|
+
None => {
|
|
838
|
+
let Lanes { outer, len: n, inner } = lanes;
|
|
839
|
+
let numbers = || Error::domain("∂ takes ⌈ and ⌊ of numbers");
|
|
840
|
+
// Mixed storage picks among its numbers as floats. Two different exact integers beyond 2⁵³ can round to one float. They then tie, and the earlier one is picked.
|
|
841
|
+
let floats = match all.view() { Some(_) => None, None => Some(all.to_float_width(FloatWidth::F64).map_err(|_| numbers())?) };
|
|
842
|
+
let view = floats.as_ref().unwrap_or(all).view().ok_or_else(numbers)?;
|
|
843
|
+
let of = if kind.scan { rustymath::reduce::Picks::Running } else { rustymath::reduce::Picks::Lanes };
|
|
844
|
+
let rows = crate::pervasive::picks(p, view, [outer, n, inner], of).ok_or_else(numbers)?;
|
|
845
|
+
// Each running fold's pick, or each lane's, as a position in the ravel.
|
|
846
|
+
rows.into_iter().enumerate().map(|(j, row)| lanes.offset(if kind.scan { j / (n * inner) } else { j / inner }, row, j % inner) as i64).collect()
|
|
846
847
|
}
|
|
847
|
-
(offsets, false)
|
|
848
|
-
} else if let Some(offsets) = (along == kind.default_axis(shape.len())).then(|| crate::fusion::picks(x, p, kind)).flatten() {
|
|
849
|
-
// Windows that slide along the fold's axis give their extremes' positions from their source, with no windows built.
|
|
850
|
-
(offsets, false)
|
|
851
|
-
} else {
|
|
852
|
-
// `r` takes a length-1 axis in place of the folded axis to pair with `x`, unless the fold removed the last axis.
|
|
853
|
-
let back = if along + 1 < shape.len() {
|
|
854
|
-
let mut shape = r.shape().iter().map(|&n| n as i64).collect::<Vec<_>>();
|
|
855
|
-
shape.insert(along, 1);
|
|
856
|
-
Primitive::Shape.call(Some(&Value::integers(vec![shape.len()], shape).described("invalid shape")?), &r, span)?
|
|
857
|
-
} else { r.clone() };
|
|
858
|
-
let hit = booleans(call(Primitive::Compare(Equal), x, &back, span)?);
|
|
859
|
-
// The first item of each lane that gives its extreme, or the lane's first item where none does, as for NaN.
|
|
860
|
-
let firsts = (0..outer)
|
|
861
|
-
.flat_map(|o| (0..inner).map(move |i| (o, i)))
|
|
862
|
-
.map(|(o, i)| (0..n).map(|k| lanes.offset(o, k, i)).find(|&at| hit[at]).unwrap_or(lanes.offset(o, 0, i)) as i64)
|
|
863
|
-
.collect::<Vec<_>>();
|
|
864
|
-
(firsts, true)
|
|
865
848
|
};
|
|
866
|
-
// Where reverse mode records one item from each lane, the tangent folds the tangent times a mask of the chosen items. Its transpose reads: each item takes its lane's cotangent where it was chosen, and 0 elsewhere. A gather's transpose would scatter.
|
|
867
|
-
if one_per_lane && tx.carried() {
|
|
868
|
-
let mut chosen = vec![false;
|
|
849
|
+
// Where reverse mode records one item from each lane, or `x` is a batch, the tangent folds the tangent times a mask of the chosen items. Its transpose reads: each item takes its lane's cotangent where it was chosen, and 0 elsewhere. A gather's transpose would scatter.
|
|
850
|
+
if one_per_lane && (tx.carried() || batch.is_some()) {
|
|
851
|
+
let mut chosen = vec![false; all.len()];
|
|
869
852
|
for &at in &offsets { chosen[at as usize] = true; }
|
|
870
|
-
let mask =
|
|
853
|
+
let mask = all.layout().booleans(chosen).described("invalid mask")?;
|
|
854
|
+
let mask = match batch { Some(b) => crate::batch::batch(b.level, mask, b.frame), None => mask };
|
|
871
855
|
return Ok((r, fold(plus, &call(times, &mask, tx, span)?)?));
|
|
872
856
|
}
|
|
873
857
|
let offsets = Value::integers(vec![offsets.len()], offsets).described("invalid positions")?.enclose().expect("positions enclose");
|
|
@@ -1612,14 +1612,14 @@ pub(crate) fn primitive_fold(p: Primitive, kind: FoldKind, axis: Option<usize>,
|
|
|
1612
1612
|
let active = crate::transform::carried(None, right);
|
|
1613
1613
|
let (along, plan) = FoldPlan::new(kind, axis, seed, right, || identity(p, &right.prototype(), span))?;
|
|
1614
1614
|
let result = match plan {
|
|
1615
|
-
FoldPlan::One(item) => match seed { Some(seed) if kind.scan => call(seed, &item)?, Some(seed) => call(&item, seed)?, None => lone(item) },
|
|
1615
|
+
FoldPlan::One(item) => match seed { Some(seed) if kind.scan => scan_step(p, call)(seed, &item)?, Some(seed) => call(&item, seed)?, None => lone(item) },
|
|
1616
1616
|
FoldPlan::Whole => lone(right.clone()),
|
|
1617
1617
|
FoldPlan::Done(result) => result,
|
|
1618
1618
|
FoldPlan::Lanes { lanes, shape } if kind.scan => {
|
|
1619
1619
|
if let Some(result) = (!active).then(|| crate::pervasive::scan(p, right, seed, &lanes)).flatten() { result }
|
|
1620
1620
|
else if let (Primitive::Arithmetic(op), false, true) = (p, active, right.all_numbers() && seed.is_none_or(|a| matches!(a, Value::Number(_)))) {
|
|
1621
1621
|
number_lanes(op, true, right, seed, &lanes, shape)?
|
|
1622
|
-
} else { item_lanes(true, &lanes, shape, seed, right, call, active)? }
|
|
1622
|
+
} else { item_lanes(true, &lanes, shape, seed, right, scan_step(p, call), active)? }
|
|
1623
1623
|
}
|
|
1624
1624
|
FoldPlan::Lanes { lanes, shape } => {
|
|
1625
1625
|
// Where `p`'s kernel folds in any order, a number seed joins each lane's result after the fold, as one more item would. The fold then takes the fusion and kernel routes of a fold with no seed. A level that carries `right` keeps the seed in its items, because its kernels don't apply there. So do Booleans under a `ᵇ` table that `sets_high_bits`: they fold by the logical function, and a number seed turns the fold to the integer function.
|
|
@@ -1672,7 +1672,7 @@ fn number_lanes(
|
|
|
1672
1672
|
let (item, seed) = (|i| number(right.at(i)), seed.cloned().map(number));
|
|
1673
1673
|
let (p, t) = (Primitive::Arithmetic(op), Numeric::current());
|
|
1674
1674
|
let step = |x: &crate::Number, y: &crate::Number| { check()?; p.number(Some(x), y, t).map_err(Error::from) };
|
|
1675
|
-
let data = if scan { scan_items(axis, seed, item, step)? } else { fold_items(axis, seed.as_ref(), item, step)? };
|
|
1675
|
+
let data = if scan { scan_items(axis, seed, item, scan_step(p, step))? } else { fold_items(axis, seed.as_ref(), item, step)? };
|
|
1676
1676
|
Value::new(shape, data.into_iter().map(Value::Number).collect()).described("invalid numeric result")
|
|
1677
1677
|
}
|
|
1678
1678
|
|
|
@@ -1690,6 +1690,13 @@ fn fold_items<T: Clone>(axis: &Lanes, seed: Option<&T>, item: impl Fn(usize) ->
|
|
|
1690
1690
|
Ok(data)
|
|
1691
1691
|
}
|
|
1692
1692
|
|
|
1693
|
+
/// `apply` as a step of `p`'s scan, which takes the running result and the next item in the order that keeps rustymath's rule beside NaN. `⌈` and `⌊` take the item on the left, because a maximum or minimum keeps its right argument beside NaN. Every other function takes the running result on the left, as a scan from the left does.
|
|
1694
|
+
fn scan_step<V>(p: Primitive, mut apply: impl FnMut(&V, &V) -> Result<V, Error>) -> impl FnMut(&V, &V) -> Result<V, Error> {
|
|
1695
|
+
let turned = matches!(p, Primitive::Math(crate::number::Math::Ceiling | crate::number::Math::Floor));
|
|
1696
|
+
move |total, item| if turned { apply(item, total) } else { apply(total, item) }
|
|
1697
|
+
}
|
|
1698
|
+
|
|
1699
|
+
/// Each lane of `axis` scanned from the left, starting from `seed` or else the lane's first item: `apply(result, item)`.
|
|
1693
1700
|
fn scan_items<T: Clone>(axis: &Lanes, seed: Option<T>, item: impl Fn(usize) -> T, mut apply: impl FnMut(&T, &T) -> Result<T, Error>) -> Result<Vec<T>, Error> {
|
|
1694
1701
|
let mut data = vec![item(0); axis.outer * axis.len * axis.inner];
|
|
1695
1702
|
for i in 0..axis.outer {
|
|
@@ -486,7 +486,7 @@ pub(crate) fn picks(value: &Value, p: Primitive, kind: FoldKind) -> Option<Vec<i
|
|
|
486
486
|
let shape = value.shape();
|
|
487
487
|
let (_, tables) = w.folded(shape, k, width);
|
|
488
488
|
if !Steps::in_order(&tables) { return None; }
|
|
489
|
-
let rows = pervasive::
|
|
489
|
+
let rows = pervasive::picks(p, w.region()?, w.rows, rustymath::reduce::Picks::Windows(width))?;
|
|
490
490
|
// Each window starts at the position along `q` that the copy's other axes along `q` reach. Its pick lies that many rows before.
|
|
491
491
|
let strides = strides(shape);
|
|
492
492
|
let rest: Vec<usize> = (0..shape.len()).filter(|&r| r != k).collect();
|
|
@@ -32,6 +32,8 @@ pub(crate) trait Dyad<A> {
|
|
|
32
32
|
fn many(self, f: impl rustymath::Binary<A, Out = A> + Copy + Sync) -> Self::Output;
|
|
33
33
|
/// `f`, which gives Booleans, on each pair of items, through its slice form where the loop has slices of items, and its scalar form elsewhere.
|
|
34
34
|
fn booleans(self, f: impl rustymath::Binary<A, Out = bool> + Copy + Sync) -> Self::Output;
|
|
35
|
+
/// `f`, a maximum or minimum, as `many` runs it. A loop that folds values into a running result, as `Scatter` does at a place it writes more than once, folds them by `M` instead. `M`'s step keeps the running result beside a NaN value, where `f`'s keeps the value.
|
|
36
|
+
fn extremum<M: Reduction<A, Total = A>>(self, f: impl rustymath::Binary<A, Out = A> + Copy + Sync, _: M) -> Self::Output where Self: Sized { self.many(f) }
|
|
35
37
|
/// `f`, a comparison, on each pair of items, as `booleans` runs it. A loop that writes floats in place of Booleans writes 1 where `f` holds and 0 elsewhere, through `rustymath::tolerant::Indicator`. The nodes of a fused graph before its last write a comparison this way.
|
|
36
38
|
fn compared<K: rustymath::Binary<A, Out = bool> + Copy + Sync>(self, f: K) -> Self::Output where Self: Sized, rustymath::tolerant::Indicator<K>: rustymath::Binary<A, Out = A> { self.booleans(f) }
|
|
37
39
|
/// The left and the right argument, each when it is one number that every item pairs with. A kernel can then run a loop of its own for that number, as `x*2` squares each item.
|
|
@@ -166,8 +168,8 @@ mod float_kernels {
|
|
|
166
168
|
},
|
|
167
169
|
Primitive::Math(Pi) => run.many(rustymath::PiTimes),
|
|
168
170
|
Primitive::Math(Log) => run.many(rustymath::Logb),
|
|
169
|
-
Primitive::Math(Ceiling) => run.
|
|
170
|
-
Primitive::Math(Floor) => run.
|
|
171
|
+
Primitive::Math(Ceiling) => run.extremum(reduce::Maximum, reduce::Max),
|
|
172
|
+
Primitive::Math(Floor) => run.extremum(reduce::Minimum, reduce::Min),
|
|
171
173
|
Primitive::Math(Magnitude) => run.many(rustymath::tolerant::Residue(t)),
|
|
172
174
|
Primitive::Math(Root) => match run.constants() {
|
|
173
175
|
(Some(n), _) if n == 2.0 => run.many(Right(rustymath::Sqrt)),
|
|
@@ -537,6 +539,9 @@ impl<A: Stored> Dyad<A> for Scatter<'_, A> {
|
|
|
537
539
|
self.writes.combine(self.out, self.values, move |x, y| f.one(x, y));
|
|
538
540
|
Some(Route::InPlace)
|
|
539
541
|
}
|
|
542
|
+
fn extremum<M: Reduction<A, Total = A>>(self, _: impl rustymath::Binary<A, Out = A> + Copy + Sync, _: M) -> Option<Route> {
|
|
543
|
+
self.writes.fold::<M, A>(self.out, self.values).then_some(Route::InPlace)
|
|
544
|
+
}
|
|
540
545
|
fn booleans(self, _: impl rustymath::Binary<A, Out = bool> + Copy + Sync) -> Option<Route> { None }
|
|
541
546
|
}
|
|
542
547
|
|
|
@@ -1298,24 +1303,20 @@ impl<'a, A: Stored> Fold<'a, A> {
|
|
|
1298
1303
|
let tail = match tail { None => None, Some(view) => Some(carried::<A>(view)?) };
|
|
1299
1304
|
Some(Self { data, dims, tail, numeric })
|
|
1300
1305
|
}
|
|
1301
|
-
/// The fold by `f
|
|
1306
|
+
/// The fold by `f` through rustymath's right fold. `None` where a step fails, unless `kept` keeps its failed results, as static kinds keep wrapped integers.
|
|
1302
1307
|
#[inline]
|
|
1303
|
-
fn by(self, f: impl
|
|
1304
|
-
|
|
1308
|
+
fn by<O: Element + Source<A>>(self, f: &impl rustymath::Binary<A, Out = O>) -> Option<Buffer> {
|
|
1309
|
+
let (out, ok) = reduce::right_fold(f, self.data, self.dims, self.tail.as_deref());
|
|
1310
|
+
(ok || kept(f, self.numeric)).then(|| O::buffer(out))
|
|
1305
1311
|
}
|
|
1306
1312
|
}
|
|
1307
1313
|
impl<A: Stored> Dyad<A> for Fold<'_, A> where bool: Source<A> {
|
|
1308
1314
|
type Output = Option<Buffer>;
|
|
1309
1315
|
fn numeric(&self) -> Numeric { self.numeric }
|
|
1310
|
-
/// Each step through `f`'s scalar form. A step that fails gives `None`, unless `keeps` keeps `f`'s failed results, as static kinds keep wrapped integers. An object none of whose steps fails compiles only the first loop.
|
|
1311
1316
|
#[inline]
|
|
1312
|
-
fn many(self, f: impl rustymath::Binary<A, Out = A> + Copy + Sync) -> Self::Output {
|
|
1313
|
-
if total(&f) || kept(&f, self.numeric) { self.by(move |x, y| Some(f.one(x, y))) } else { self.by(move |x, y| f.checked(x, y)) }
|
|
1314
|
-
}
|
|
1317
|
+
fn many(self, f: impl rustymath::Binary<A, Out = A> + Copy + Sync) -> Self::Output { self.by(&f) }
|
|
1315
1318
|
#[inline]
|
|
1316
|
-
fn booleans(self, f: impl rustymath::Binary<A, Out = bool> + Copy + Sync) -> Self::Output {
|
|
1317
|
-
Some(bool::buffer(reduce::right_fold(self.data, self.dims, self.tail.as_deref(), move |x, y| f.checked(x, y), Source::<A>::read)?))
|
|
1318
|
-
}
|
|
1319
|
+
fn booleans(self, f: impl rustymath::Binary<A, Out = bool> + Copy + Sync) -> Self::Output { self.by(&f) }
|
|
1319
1320
|
}
|
|
1320
1321
|
|
|
1321
1322
|
/// A scan of compact values along `axis` by successive left accumulation, as the general scan does. Kernels of approximate numbers compare within the tolerance of their width in the current settings.
|
|
@@ -1389,9 +1390,17 @@ fn scanned_under(p: Primitive, right: &Value, seed: Option<&Value>, axis: &Lanes
|
|
|
1389
1390
|
}
|
|
1390
1391
|
match right.as_items() {
|
|
1391
1392
|
// The logical functions and comparisons keep Booleans, and scan through their truth tables. Other functions read Booleans as integers.
|
|
1392
|
-
Items::Compact(View::Booleans(data)) =>
|
|
1393
|
-
|
|
1394
|
-
|
|
1393
|
+
Items::Compact(View::Booleans(data)) => {
|
|
1394
|
+
let scan = plan(numeric.exact()).of(data)?;
|
|
1395
|
+
match (scan.inverse, logical(p)) {
|
|
1396
|
+
(false, Some(table)) => {
|
|
1397
|
+
let mut result = Vec::with_capacity(data.len());
|
|
1398
|
+
table.scan_along(data, scan.axis.dims(), scan.seed, &mut result);
|
|
1399
|
+
bool::build(scan.shape, result)
|
|
1400
|
+
}
|
|
1401
|
+
_ => match bool::dyad(p, scan) { Some(result) => result, None => integers(Ints::U8(truth_bytes(data))) },
|
|
1402
|
+
}
|
|
1403
|
+
}
|
|
1395
1404
|
Items::Compact(View::Floats(data)) => with_floats!(kernel data, |data| float_scan(p, plan(numeric), data)),
|
|
1396
1405
|
Items::Compact(View::Integers(ints)) => integers(ints),
|
|
1397
1406
|
Items::Compact(View::Complexes(data)) => with_complexes!(data, |data| complex_scan(p, plan(numeric), data)),
|
|
@@ -1443,36 +1452,25 @@ impl<'a> ScanPlan<'a> {
|
|
|
1443
1452
|
}
|
|
1444
1453
|
}
|
|
1445
1454
|
|
|
1446
|
-
///
|
|
1447
|
-
|
|
1448
|
-
impl Dyad<bool> for LogicalScan<'_> {
|
|
1449
|
-
type Output = Option<Value>;
|
|
1450
|
-
fn numeric(&self) -> Numeric { self.0.numeric }
|
|
1451
|
-
#[inline]
|
|
1452
|
-
fn many(self, f: impl rustymath::Binary<bool, Out = bool> + Copy + Sync) -> Option<Value> {
|
|
1453
|
-
let scan = self.0;
|
|
1454
|
-
let row = |r| Some([f.checked(r, false)?, f.checked(r, true)?]);
|
|
1455
|
-
let (false, Some(lo), Some(hi)) = (scan.inverse, row(false), row(true)) else { return scan.many(f) };
|
|
1456
|
-
let mut result = Vec::with_capacity(scan.data.len());
|
|
1457
|
-
reduce::Logical([lo, hi]).scan_along(scan.data, scan.axis.dims(), scan.seed, &mut result);
|
|
1458
|
-
bool::build(scan.shape, result)
|
|
1459
|
-
}
|
|
1460
|
-
#[inline]
|
|
1461
|
-
fn booleans(self, f: impl rustymath::Binary<bool, Out = bool> + Copy + Sync) -> Option<Value> { self.many(f) }
|
|
1462
|
-
}
|
|
1455
|
+
/// The truth table of `p`'s kernel on Booleans, where `p` has one that gives a Boolean for every pair. Folds and scans of Booleans by `p` run through it.
|
|
1456
|
+
fn logical(p: Primitive) -> Option<reduce::Logical> { bool::dyad(p, Truths)? }
|
|
1463
1457
|
|
|
1464
|
-
///
|
|
1465
|
-
pub(crate) fn truth_table(p: Primitive) -> Option<u8> {
|
|
1458
|
+
/// [`logical`]'s table, indexed by `2*x+y`. A dyadic call, fold or scan of `gᵇ` with such a `g` runs as `Primitive::Bitwise` of the table (`Function::dyadic_primitive`).
|
|
1459
|
+
pub(crate) fn truth_table(p: Primitive) -> Option<u8> {
|
|
1460
|
+
let reduce::Logical(t) = logical(p)?;
|
|
1461
|
+
Some((0..4).fold(0u8, |table, i| table | u8::from(t[i >> 1][i & 1]) << i))
|
|
1462
|
+
}
|
|
1466
1463
|
|
|
1467
|
-
/// The runner that reads a Boolean kernel's truth table for `
|
|
1464
|
+
/// The runner that reads a Boolean kernel's truth table for [`logical`], by calling it on the four pairs of Booleans.
|
|
1468
1465
|
struct Truths;
|
|
1469
1466
|
impl Dyad<bool> for Truths {
|
|
1470
|
-
type Output = Option<
|
|
1467
|
+
type Output = Option<reduce::Logical>;
|
|
1471
1468
|
fn numeric(&self) -> Numeric { Numeric::EXACT }
|
|
1472
|
-
fn many(self, f: impl rustymath::Binary<bool, Out = bool> + Copy + Sync) -> Option<
|
|
1473
|
-
|
|
1469
|
+
fn many(self, f: impl rustymath::Binary<bool, Out = bool> + Copy + Sync) -> Option<reduce::Logical> {
|
|
1470
|
+
let row = |x| Some([f.checked(x, false)?, f.checked(x, true)?]);
|
|
1471
|
+
Some(reduce::Logical([row(false)?, row(true)?]))
|
|
1474
1472
|
}
|
|
1475
|
-
fn booleans(self, f: impl rustymath::Binary<bool, Out = bool> + Copy + Sync) -> Option<
|
|
1473
|
+
fn booleans(self, f: impl rustymath::Binary<bool, Out = bool> + Copy + Sync) -> Option<reduce::Logical> { self.many(f) }
|
|
1476
1474
|
}
|
|
1477
1475
|
|
|
1478
1476
|
/// A scan of integers at their own width, or at rustymath's total type for a reduction: `⌈\`, `⌊\` and the scans of `ᵇ`'s and, or, xor and xnor run through rustymath's running reductions, and any other function through its kernel. `None` where a result doesn't fit.
|
|
@@ -1509,12 +1507,12 @@ struct Scan<'a, A> {
|
|
|
1509
1507
|
data: &'a [A], seed: Option<A>, starts: Option<&'a [bool]>, axis: &'a Lanes, shape: Vec<usize>, numeric: Numeric, inverse: bool, flip: bool
|
|
1510
1508
|
}
|
|
1511
1509
|
impl<A: Stored> Scan<'_, A> {
|
|
1512
|
-
/// The scan by `f
|
|
1510
|
+
/// The scan by `f` through rustymath's left scan, each running total stepped by the next item. `None` where a step fails, unless `kept` keeps its failed results, as `Fold::by` does.
|
|
1513
1511
|
#[inline]
|
|
1514
|
-
fn running(self, f: impl
|
|
1512
|
+
fn running<O: Element + Source<A>>(self, f: &impl rustymath::Binary<A, Out = O>) -> Option<Value> {
|
|
1515
1513
|
if self.inverse { return None; }
|
|
1516
1514
|
let mut result = Vec::with_capacity(self.data.len());
|
|
1517
|
-
if !reduce::left_scan(self.data, self.axis.dims(), self.seed,
|
|
1515
|
+
if !reduce::left_scan(f, self.data, self.axis.dims(), self.seed, &mut result) && !kept(f, self.numeric) { return None; }
|
|
1518
1516
|
A::build_narrowed(self.shape, result)
|
|
1519
1517
|
}
|
|
1520
1518
|
/// The scan by rustymath's reduction `R` along the axis, at `R`'s total type, through `reduce::scan_along`. `None` where a result doesn't fit.
|
|
@@ -1572,13 +1570,13 @@ impl<A: Stored> Dyad<A> for Scan<'_, A> where bool: Source<A> {
|
|
|
1572
1570
|
/// A scan runs through `running`, each step through `f`'s scalar form, and its inverse through `paired`, with `f`'s slice form.
|
|
1573
1571
|
#[inline]
|
|
1574
1572
|
fn many(self, f: impl rustymath::Binary<A, Out = A> + Copy + Sync) -> Option<Value> {
|
|
1575
|
-
if self.inverse { self.paired(move |x, y, n, out| f.many(x, y, n, out)) } else { self.running(
|
|
1573
|
+
if self.inverse { self.paired(move |x, y, n, out| f.many(x, y, n, out)) } else { self.running(&f) }
|
|
1576
1574
|
}
|
|
1577
1575
|
/// A comparison runs through `compared`, with `f`'s slice form. Its inverse, and a scan from a seed of the items' type, which only functions other than comparisons get, step through `f`'s scalar form, with the Booleans converted back to the item type.
|
|
1578
1576
|
#[inline]
|
|
1579
1577
|
fn booleans(self, f: impl rustymath::Binary<A, Out = bool> + Copy + Sync) -> Option<Value> {
|
|
1580
1578
|
if self.inverse { return self.paired(move |x, y, n, out| pairs(x, y, n, out, |a, b| item_result(f.checked(a, b).map(Source::<A>::read)))); }
|
|
1581
|
-
if self.seed.is_some() { return self.running(
|
|
1579
|
+
if self.seed.is_some() { return self.running(&f); }
|
|
1582
1580
|
self.compared(&move |t, xs, out| f.many(t, Arg::Many(xs), xs.len(), out))
|
|
1583
1581
|
}
|
|
1584
1582
|
}
|
|
@@ -1696,6 +1694,11 @@ fn untransposed(s: Value, m: Mapping, shape @ [rows, _]: [usize; 2]) -> ((Value,
|
|
|
1696
1694
|
fn native_fold(p: Primitive, data: View<'_>, dims: [usize; 3], tail: Option<View<'_>>, len: usize, numeric: Numeric) -> Option<Buffer> {
|
|
1697
1695
|
match data {
|
|
1698
1696
|
View::Booleans(data) => with_truth_reduction!(p, len, R => reduced::<_, R>(data, dims, tail, false)).flatten()
|
|
1697
|
+
.or_else(|| {
|
|
1698
|
+
if !reduce::Logical::folds(dims) { return None; }
|
|
1699
|
+
let tail = match tail { Some(v) => Some(carried::<bool>(v)?), None => None };
|
|
1700
|
+
Some(bool::buffer(logical(p)?.fold(data, dims[1], tail.as_deref())))
|
|
1701
|
+
})
|
|
1699
1702
|
.or_else(|| bool::dyad(p, Fold::new(data, dims, tail, Numeric::EXACT)?)?)
|
|
1700
1703
|
.or_else(|| integer_fold(p, truth_bytes(data), dims, tail, numeric)),
|
|
1701
1704
|
View::Integers(data) => with_ints!(data, |data| integer_fold(p, data, dims, tail, numeric)),
|
|
@@ -1710,10 +1713,10 @@ pub(crate) fn sliding(p: Primitive, data: View<'_>, dims: [usize; 3], width: usi
|
|
|
1710
1713
|
with_reduction!(p, data, width, Numeric::current().is_static(), |data, R, kept| fitting(reduce::sliding::<_, R>(data, dims, width), kept))
|
|
1711
1714
|
}
|
|
1712
1715
|
|
|
1713
|
-
/// The row of the first item that gives the maximum, for `⌈`, or the minimum, for `⌊`, of each
|
|
1714
|
-
pub(crate) fn
|
|
1716
|
+
/// The row of the first item that gives the maximum, for `⌈`, or the minimum, for `⌊`, of each of the folds that `of` chooses along the middle axis of `data`, an array of shape `dims`. Each row counts from the start of its lane. `None` for any other function, and for storage other than Booleans, integers and 32- and 64-bit floats.
|
|
1717
|
+
pub(crate) fn picks(p: Primitive, data: View<'_>, dims: [usize; 3], of: reduce::Picks) -> Option<Vec<usize>> {
|
|
1715
1718
|
let max = match p { Primitive::Math(Math::Ceiling) => true, Primitive::Math(Math::Floor) => false, _ => return None };
|
|
1716
|
-
reduce::
|
|
1719
|
+
reduce::view_picks(data, dims, of, max)
|
|
1717
1720
|
}
|
|
1718
1721
|
|
|
1719
1722
|
fn carried<A: Element>(view: View<'_>) -> Option<Cow<'_, [A]>> {
|