commit
4ecb692e80
87
.github/workflows/ci-cachix.yml
vendored
Normal file
87
.github/workflows/ci-cachix.yml
vendored
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
name: Nix build
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
- develop
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
- develop
|
||||||
|
- reducer-dev
|
||||||
|
- epic-reducer-project
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
flake-lints:
|
||||||
|
name: All lint
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: Install nix
|
||||||
|
uses: cachix/install-nix-action@v17
|
||||||
|
with:
|
||||||
|
nix_path: nixpkgs=channel:nixos-22.05
|
||||||
|
- name: Use cachix
|
||||||
|
uses: cachix/cachix-action@v10
|
||||||
|
with:
|
||||||
|
name: quantified-uncertainty
|
||||||
|
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
||||||
|
|
||||||
|
- name: Check that lang lints
|
||||||
|
run: nix build .#lang-lint
|
||||||
|
- name: Check that components lints
|
||||||
|
run: nix build .#components-lint
|
||||||
|
- name: Check that website lints
|
||||||
|
run: nix build .#docusaurus-lint
|
||||||
|
- name: Check that vscode extension lints
|
||||||
|
run: nix build .#vscode-lint
|
||||||
|
- name: Check that cli lints
|
||||||
|
run: nix build .#cli-lint
|
||||||
|
|
||||||
|
flake-packages:
|
||||||
|
name: Builds, tests, and bundles
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: flake-lints
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: Install nix
|
||||||
|
uses: cachix/install-nix-action@v17
|
||||||
|
with:
|
||||||
|
nix_path: nixpkgs=channel:nixos-22.05
|
||||||
|
- name: Use cachix
|
||||||
|
uses: cachix/cachix-action@v10
|
||||||
|
with:
|
||||||
|
name: quantified-uncertainty
|
||||||
|
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
||||||
|
|
||||||
|
- name: Check all lang tests
|
||||||
|
run: nix build .#lang-test
|
||||||
|
- name: Check that lang bundles
|
||||||
|
run: nix build .#lang-bundle
|
||||||
|
- name: Check that components builds
|
||||||
|
run: nix build .#components
|
||||||
|
- name: Check that components bundles
|
||||||
|
run: nix build .#components-bundle
|
||||||
|
|
||||||
|
flake-devshells:
|
||||||
|
name: Development shell environment
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: Install nix
|
||||||
|
uses: cachix/install-nix-action@v17
|
||||||
|
with:
|
||||||
|
nix_path: nixpkgs=channel:nixos-22.05
|
||||||
|
- name: Use cachix
|
||||||
|
uses: cachix/cachix-action@v10
|
||||||
|
with:
|
||||||
|
name: quantified-uncertainty
|
||||||
|
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
||||||
|
- name: Build js devshell
|
||||||
|
run: nix develop .#js --profile just-js
|
||||||
|
- name: Build js & wasm devshell
|
||||||
|
run: nix develop --profile full-shell
|
251
.github/workflows/ci.yml
vendored
251
.github/workflows/ci.yml
vendored
|
@ -10,6 +10,7 @@ on:
|
||||||
- master
|
- master
|
||||||
- develop
|
- develop
|
||||||
- reducer-dev
|
- reducer-dev
|
||||||
|
- epic-reducer-project
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
pre_check:
|
pre_check:
|
||||||
|
@ -48,26 +49,26 @@ jobs:
|
||||||
with:
|
with:
|
||||||
paths: '["packages/cli/**"]'
|
paths: '["packages/cli/**"]'
|
||||||
|
|
||||||
lang-lint:
|
# lang-lint:
|
||||||
name: Language lint
|
# name: Language lint
|
||||||
runs-on: ubuntu-latest
|
# runs-on: ubuntu-latest
|
||||||
needs: pre_check
|
# needs: pre_check
|
||||||
if: ${{ needs.pre_check.outputs.should_skip_lang != 'true' }}
|
# if: ${{ needs.pre_check.outputs.should_skip_lang != 'true' }}
|
||||||
defaults:
|
# defaults:
|
||||||
run:
|
# run:
|
||||||
shell: bash
|
# shell: bash
|
||||||
working-directory: packages/squiggle-lang
|
# working-directory: packages/squiggle-lang
|
||||||
steps:
|
# steps:
|
||||||
- uses: actions/checkout@v3
|
# - uses: actions/checkout@v3
|
||||||
- name: Install Dependencies
|
# - name: Install Dependencies
|
||||||
run: cd ../../ && yarn
|
# run: cd ../../ && yarn
|
||||||
- name: Check rescript lint
|
# - name: Check rescript lint
|
||||||
run: yarn lint:rescript
|
# run: yarn lint:rescript
|
||||||
- name: Check javascript, typescript, and markdown lint
|
# - name: Check javascript, typescript, and markdown lint
|
||||||
uses: creyD/prettier_action@v4.2
|
# uses: creyD/prettier_action@v4.2
|
||||||
with:
|
# with:
|
||||||
dry: true
|
# dry: true
|
||||||
prettier_options: --check packages/squiggle-lang
|
# prettier_options: --check packages/squiggle-lang
|
||||||
|
|
||||||
lang-build-test-bundle:
|
lang-build-test-bundle:
|
||||||
name: Language build, test, and bundle
|
name: Language build, test, and bundle
|
||||||
|
@ -97,95 +98,96 @@ jobs:
|
||||||
- name: Upload typescript coverage report
|
- name: Upload typescript coverage report
|
||||||
run: yarn coverage:ts:ci
|
run: yarn coverage:ts:ci
|
||||||
|
|
||||||
components-lint:
|
# components-lint:
|
||||||
name: Components lint
|
# name: Components lint
|
||||||
runs-on: ubuntu-latest
|
# runs-on: ubuntu-latest
|
||||||
needs: pre_check
|
# needs: pre_check
|
||||||
if: ${{ needs.pre_check.outputs.should_skip_components != 'true' }}
|
# if: ${{ needs.pre_check.outputs.should_skip_components != 'true' }}
|
||||||
defaults:
|
# defaults:
|
||||||
run:
|
# run:
|
||||||
shell: bash
|
# shell: bash
|
||||||
working-directory: packages/components
|
# working-directory: packages/components
|
||||||
steps:
|
# steps:
|
||||||
- uses: actions/checkout@v3
|
# - uses: actions/checkout@v3
|
||||||
- name: Check javascript, typescript, and markdown lint
|
# - name: Check javascript, typescript, and markdown lint
|
||||||
uses: creyD/prettier_action@v4.2
|
# uses: creyD/prettier_action@v4.2
|
||||||
with:
|
# with:
|
||||||
dry: true
|
# dry: true
|
||||||
prettier_options: --check packages/components --ignore-path packages/components/.prettierignore
|
# prettier_options: --check packages/components --ignore-path packages/components/.prettierignore
|
||||||
|
#
|
||||||
|
# components-bundle-build:
|
||||||
|
# name: Components bundle and build
|
||||||
|
# runs-on: ubuntu-latest
|
||||||
|
# needs: pre_check
|
||||||
|
# if: ${{ (needs.pre_check.outputs.should_skip_components != 'true') || (needs.pre_check.outputs.should_skip_lang != 'true') }}
|
||||||
|
# defaults:
|
||||||
|
# run:
|
||||||
|
# shell: bash
|
||||||
|
# working-directory: packages/components
|
||||||
|
# steps:
|
||||||
|
# - uses: actions/checkout@v3
|
||||||
|
# - name: Install dependencies from monorepo level
|
||||||
|
# run: cd ../../ && yarn
|
||||||
|
# - name: Build rescript codebase in squiggle-lang
|
||||||
|
# run: cd ../squiggle-lang && yarn build
|
||||||
|
# - name: Run webpack
|
||||||
|
# run: yarn bundle
|
||||||
|
# - name: Build storybook
|
||||||
|
# run: yarn build
|
||||||
|
|
||||||
components-bundle-build:
|
# website-lint:
|
||||||
name: Components bundle and build
|
# name: Website lint
|
||||||
runs-on: ubuntu-latest
|
# runs-on: ubuntu-latest
|
||||||
needs: pre_check
|
# needs: pre_check
|
||||||
if: ${{ (needs.pre_check.outputs.should_skip_components != 'true') || (needs.pre_check.outputs.should_skip_lang != 'true') }}
|
# if: ${{ needs.pre_check.outputs.should_skip_website != 'true' }}
|
||||||
defaults:
|
# defaults:
|
||||||
run:
|
# run:
|
||||||
shell: bash
|
# shell: bash
|
||||||
working-directory: packages/components
|
# working-directory: packages/website
|
||||||
steps:
|
# steps:
|
||||||
- uses: actions/checkout@v3
|
# - uses: actions/checkout@v3
|
||||||
- name: Install dependencies from monorepo level
|
# - name: Check javascript, typescript, and markdown lint
|
||||||
run: cd ../../ && yarn
|
# uses: creyD/prettier_action@v4.2
|
||||||
- name: Build rescript codebase in squiggle-lang
|
# with:
|
||||||
run: cd ../squiggle-lang && yarn build
|
# dry: true
|
||||||
- name: Run webpack
|
# prettier_options: --check packages/website
|
||||||
run: yarn bundle
|
#
|
||||||
- name: Build storybook
|
# website-build:
|
||||||
run: yarn build
|
# name: Website build
|
||||||
|
# runs-on: ubuntu-latest
|
||||||
website-lint:
|
# needs: pre_check
|
||||||
name: Website lint
|
# if: ${{ (needs.pre_check.outputs.should_skip_website != 'true') || (needs.pre_check.outputs.should_skip_lang != 'true') || (needs.pre_check.outputs.should_skip_components != 'true') }}
|
||||||
runs-on: ubuntu-latest
|
# defaults:
|
||||||
needs: pre_check
|
# run:
|
||||||
if: ${{ needs.pre_check.outputs.should_skip_website != 'true' }}
|
# shell: bash
|
||||||
defaults:
|
# working-directory: packages/website
|
||||||
run:
|
# steps:
|
||||||
shell: bash
|
# - uses: actions/checkout@v3
|
||||||
working-directory: packages/website
|
# - name: Install dependencies from monorepo level
|
||||||
steps:
|
# run: cd ../../ && yarn
|
||||||
- uses: actions/checkout@v3
|
# - name: Build rescript in squiggle-lang
|
||||||
- name: Check javascript, typescript, and markdown lint
|
# run: cd ../squiggle-lang && yarn build
|
||||||
uses: creyD/prettier_action@v4.2
|
# - name: Build components
|
||||||
with:
|
# run: cd ../components && yarn build
|
||||||
dry: true
|
# - name: Build website assets
|
||||||
prettier_options: --check packages/website
|
# run: yarn build
|
||||||
|
#
|
||||||
website-build:
|
# vscode-ext-lint:
|
||||||
name: Website build
|
# name: VS Code extension lint
|
||||||
runs-on: ubuntu-latest
|
# runs-on: ubuntu-latest
|
||||||
needs: pre_check
|
# needs: pre_check
|
||||||
if: ${{ (needs.pre_check.outputs.should_skip_website != 'true') || (needs.pre_check.outputs.should_skip_lang != 'true') || (needs.pre_check.outputs.should_skip_components != 'true') }}
|
# if: ${{ needs.pre_check.outputs.should_skip_vscodeext != 'true' }}
|
||||||
defaults:
|
# defaults:
|
||||||
run:
|
# run:
|
||||||
shell: bash
|
# shell: bash
|
||||||
working-directory: packages/website
|
# working-directory: packages/vscode-ext
|
||||||
steps:
|
# steps:
|
||||||
- uses: actions/checkout@v3
|
# - uses: actions/checkout@v3
|
||||||
- name: Install dependencies from monorepo level
|
# - name: Check javascript, typescript, and markdown lint
|
||||||
run: cd ../../ && yarn
|
# uses: creyD/prettier_action@v4.2
|
||||||
- name: Build rescript in squiggle-lang
|
# with:
|
||||||
run: cd ../squiggle-lang && yarn build
|
# dry: true
|
||||||
- name: Build components
|
# prettier_options: --check packages/vscode-ext
|
||||||
run: cd ../components && yarn build
|
|
||||||
- name: Build website assets
|
|
||||||
run: yarn build
|
|
||||||
|
|
||||||
vscode-ext-lint:
|
|
||||||
name: VS Code extension lint
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: pre_check
|
|
||||||
if: ${{ needs.pre_check.outputs.should_skip_vscodeext != 'true' }}
|
|
||||||
defaults:
|
|
||||||
run:
|
|
||||||
shell: bash
|
|
||||||
working-directory: packages/vscode-ext
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- name: Install dependencies from monorepo level
|
|
||||||
run: cd ../../ && yarn
|
|
||||||
- name: Lint the VSCode Extension source code
|
|
||||||
run: yarn lint
|
|
||||||
|
|
||||||
vscode-ext-build:
|
vscode-ext-build:
|
||||||
name: VS Code extension build
|
name: VS Code extension build
|
||||||
|
@ -202,20 +204,19 @@ jobs:
|
||||||
run: cd ../../ && yarn
|
run: cd ../../ && yarn
|
||||||
- name: Build
|
- name: Build
|
||||||
run: yarn compile
|
run: yarn compile
|
||||||
|
# cli-lint:
|
||||||
cli-lint:
|
# name: CLI lint
|
||||||
name: CLI lint
|
# runs-on: ubuntu-latest
|
||||||
runs-on: ubuntu-latest
|
# needs: pre_check
|
||||||
needs: pre_check
|
# if: ${{ needs.pre_check.outputs.should_skip_cli != 'true' }}
|
||||||
if: ${{ needs.pre_check.outputs.should_skip_cli != 'true' }}
|
# defaults:
|
||||||
defaults:
|
# run:
|
||||||
run:
|
# shell: bash
|
||||||
shell: bash
|
# working-directory: packages/cli
|
||||||
working-directory: packages/cli
|
# steps:
|
||||||
steps:
|
# - uses: actions/checkout@v3
|
||||||
- uses: actions/checkout@v3
|
# - name: Check javascript, typescript, and markdown lint
|
||||||
- name: Check javascript, typescript, and markdown lint
|
# uses: creyD/prettier_action@v4.2
|
||||||
uses: creyD/prettier_action@v4.2
|
# with:
|
||||||
with:
|
# dry: true
|
||||||
dry: true
|
# prettier_options: --check packages/cli
|
||||||
prettier_options: --check packages/cli
|
|
||||||
|
|
61
.github/workflows/release-please.yml
vendored
61
.github/workflows/release-please.yml
vendored
|
@ -3,7 +3,7 @@ name: Run Release Please
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- develop
|
- master
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
pre_check:
|
pre_check:
|
||||||
|
@ -55,21 +55,22 @@ jobs:
|
||||||
token: ${{secrets.GITHUB_TOKEN}}
|
token: ${{secrets.GITHUB_TOKEN}}
|
||||||
command: manifest-pr
|
command: manifest-pr
|
||||||
path: packages/squiggle-lang
|
path: packages/squiggle-lang
|
||||||
bump-patch-for-minor-pre-major: true
|
# bump-patch-for-minor-pre-major: true
|
||||||
skip-github-release: true
|
skip-github-release: true
|
||||||
# - name: Publish: Checkout source
|
- name: Publish- Checkout source
|
||||||
# uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
# # these if statements ensure that a publication only occurs when
|
# these if statements ensure that a publication only occurs when
|
||||||
# # a new release is created:
|
# a new release is created:
|
||||||
# if: ${{ steps.release.outputs.release_created }}
|
if: ${{ steps.release.outputs.release_created }}
|
||||||
# - name: Publish: Install dependencies
|
- name: Publish- Install dependencies
|
||||||
# run: yarn
|
run: yarn
|
||||||
# if: ${{ steps.release.outputs.release_created }}
|
if: ${{ steps.release.outputs.release_created }}
|
||||||
# - name: Publish
|
- name: Publish
|
||||||
# run: cd packages/squiggle-lang && yarn publish
|
run: cd packages/squiggle-lang && yarn publish
|
||||||
# env:
|
env:
|
||||||
# NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
|
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
|
||||||
# if: ${{ steps.release.outputs.release_created }}
|
if: ${{ steps.release.outputs.release_created }}
|
||||||
|
|
||||||
relplz-components:
|
relplz-components:
|
||||||
name: for components
|
name: for components
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
@ -82,20 +83,20 @@ jobs:
|
||||||
token: ${{secrets.GITHUB_TOKEN}}
|
token: ${{secrets.GITHUB_TOKEN}}
|
||||||
command: manifest-pr
|
command: manifest-pr
|
||||||
path: packages/components
|
path: packages/components
|
||||||
bump-patch-for-minor-pre-major: true
|
# bump-patch-for-minor-pre-major: true
|
||||||
skip-github-release: true
|
skip-github-release: true
|
||||||
# - name: Publish: Checkout source
|
- name: Publish- Checkout source
|
||||||
# uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
# # these if statements ensure that a publication only occurs when
|
# these if statements ensure that a publication only occurs when
|
||||||
# # a new release is created:
|
# a new release is created:
|
||||||
# if: ${{ steps.release.outputs.release_created }}
|
if: ${{ steps.release.outputs.release_created }}
|
||||||
# - name: Publish: Install dependencies
|
- name: Publish- Install dependencies
|
||||||
# run: yarn
|
run: yarn
|
||||||
# if: ${{ steps.release.outputs.release_created }}
|
if: ${{ steps.release.outputs.release_created }}
|
||||||
# - name: Publish
|
- name: Publish
|
||||||
# run: cd packages/components && yarn publish
|
run: cd packages/components && yarn publish
|
||||||
# env:
|
env:
|
||||||
# NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
|
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
|
||||||
relplz-website:
|
relplz-website:
|
||||||
name: for website
|
name: for website
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
@ -108,7 +109,7 @@ jobs:
|
||||||
token: ${{secrets.GITHUB_TOKEN}}
|
token: ${{secrets.GITHUB_TOKEN}}
|
||||||
command: manifest-pr
|
command: manifest-pr
|
||||||
path: packages/website
|
path: packages/website
|
||||||
bump-patch-for-minor-pre-major: true
|
# bump-patch-for-minor-pre-major: true
|
||||||
skip-github-release: true
|
skip-github-release: true
|
||||||
relplz-vscodeext:
|
relplz-vscodeext:
|
||||||
name: for vscode-ext
|
name: for vscode-ext
|
||||||
|
@ -122,7 +123,7 @@ jobs:
|
||||||
token: ${{secrets.GITHUB_TOKEN}}
|
token: ${{secrets.GITHUB_TOKEN}}
|
||||||
command: manifest-pr
|
command: manifest-pr
|
||||||
path: packages/vscode-ext
|
path: packages/vscode-ext
|
||||||
bump-patch-for-minor-pre-major: true
|
# bump-patch-for-minor-pre-major: true
|
||||||
skip-github-release: true
|
skip-github-release: true
|
||||||
relplz-cl:
|
relplz-cl:
|
||||||
name: for cli
|
name: for cli
|
||||||
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -7,3 +7,4 @@ yarn-error.log
|
||||||
**/.sync.ffs_db
|
**/.sync.ffs_db
|
||||||
.direnv
|
.direnv
|
||||||
.log
|
.log
|
||||||
|
result
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
.direnv
|
.direnv
|
||||||
*.bs.js
|
*.bs.js
|
||||||
*.gen.tsx
|
*.gen.tsx
|
||||||
packages/*/dist
|
|
||||||
packages/components/storybook-static
|
packages/components/storybook-static
|
||||||
node_modules
|
node_modules
|
||||||
packages/*/node_modules
|
packages/*/node_modules
|
||||||
packages/website/.docusaurus
|
packages/website/.docusaurus
|
||||||
packages/squiggle-lang/lib
|
packages/squiggle-lang/lib
|
||||||
packages/squiggle-lang/.nyc_output/
|
|
||||||
packages/squiggle-lang/coverage/
|
packages/squiggle-lang/coverage/
|
||||||
packages/squiggle-lang/.cache/
|
packages/squiggle-lang/.cache/
|
||||||
packages/website/build/
|
packages/website/build/
|
||||||
packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_GeneratedParser.js
|
packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_GeneratedParser.js
|
||||||
packages/vscode-ext/media/vendor/
|
packages/vscode-ext/media/vendor/
|
||||||
|
packages/squiggle-lang/.nyc_output/
|
||||||
|
packages/*/dist
|
||||||
|
result
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"packages/cli": "0.0.3",
|
"packages/cli": "0.0.3",
|
||||||
"packages/components": "0.2.24",
|
"packages/components": "0.3.1",
|
||||||
"packages/squiggle-lang": "0.2.11",
|
"packages/squiggle-lang": "0.3.0",
|
||||||
"packages/vscode-ext": "0.3.1",
|
"packages/vscode-ext": "0.3.1",
|
||||||
"packages/website": "0.2.1"
|
"packages/website": "0.3.0"
|
||||||
}
|
}
|
||||||
|
|
79
flake.lock
Normal file
79
flake.lock
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"flake-utils": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1659877975,
|
||||||
|
"narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"flake-utils_2": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1659877975,
|
||||||
|
"narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"gentype": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-utils": "flake-utils_2",
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1661855866,
|
||||||
|
"narHash": "sha256-+q0OOTyaq8eOn9BOWdPOCtSDOISW4A59v3mq3JOZyug=",
|
||||||
|
"owner": "rescript-association",
|
||||||
|
"repo": "genType",
|
||||||
|
"rev": "6b5f164b4f6ced456019b7579a0ab7e0a86518ad",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "rescript-association",
|
||||||
|
"repo": "genType",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1661617163,
|
||||||
|
"narHash": "sha256-NN9Ky47j8ohgPhA9JZyfkYIbbAo6RJkGz+7h8/exVpE=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "0ba2543f8c855d7be8e90ef6c8dc89c1617e8a08",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"id": "nixpkgs",
|
||||||
|
"ref": "nixos-22.05",
|
||||||
|
"type": "indirect"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-utils": "flake-utils",
|
||||||
|
"gentype": "gentype",
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
99
flake.nix
Normal file
99
flake.nix
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
{
|
||||||
|
description = "Squiggle packages";
|
||||||
|
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "nixpkgs/nixos-22.05";
|
||||||
|
gentype = {
|
||||||
|
url = "github:rescript-association/genType";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
flake-utils.url = "github:numtide/flake-utils";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = { self, nixpkgs, gentype, flake-utils }:
|
||||||
|
let
|
||||||
|
version = builtins.substring 0 8 self.lastModifiedDate;
|
||||||
|
overlays = [
|
||||||
|
(final: prev: {
|
||||||
|
# set the node version here
|
||||||
|
nodejs = prev.nodejs-18_x;
|
||||||
|
# The override is the only way to get it into mkYarnModules
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
|
commonFn = pkgs: {
|
||||||
|
buildInputs = with pkgs; [ nodejs yarn ];
|
||||||
|
prettier = with pkgs.nodePackages; [ prettier ];
|
||||||
|
which = [ pkgs.which ];
|
||||||
|
};
|
||||||
|
gentypeOutputFn = pkgs: gentype.outputs.packages.${pkgs.system}.default;
|
||||||
|
langFn = { pkgs, ... }:
|
||||||
|
# Probably doesn't work on i686-linux
|
||||||
|
import ./nix/squiggle-lang.nix {
|
||||||
|
inherit pkgs commonFn gentypeOutputFn;
|
||||||
|
};
|
||||||
|
componentsFn = { pkgs, ... }:
|
||||||
|
import ./nix/squiggle-components.nix { inherit pkgs commonFn langFn; };
|
||||||
|
websiteFn = { pkgs, ... }:
|
||||||
|
import ./nix/squiggle-website.nix {
|
||||||
|
inherit pkgs commonFn langFn componentsFn;
|
||||||
|
};
|
||||||
|
vscodeextFn = { pkgs, ... }:
|
||||||
|
import ./nix/squiggle-vscode.nix {
|
||||||
|
inherit pkgs commonFn langFn componentsFn;
|
||||||
|
};
|
||||||
|
cliFn = { pkgs, ... }:
|
||||||
|
import ./nix/squiggle-cli.nix {
|
||||||
|
inherit pkgs commonFn;
|
||||||
|
};
|
||||||
|
|
||||||
|
# local machines
|
||||||
|
localFlakeOutputs = { pkgs, ... }:
|
||||||
|
let
|
||||||
|
lang = langFn pkgs;
|
||||||
|
components = componentsFn pkgs;
|
||||||
|
website = websiteFn pkgs;
|
||||||
|
vscodeext = vscodeextFn pkgs;
|
||||||
|
cli = cliFn pkgs;
|
||||||
|
in {
|
||||||
|
# validating
|
||||||
|
checks = flake-utils.lib.flattenTree {
|
||||||
|
lang-lint = lang.lint;
|
||||||
|
lang-test = lang.test;
|
||||||
|
components-lint = components.lint;
|
||||||
|
docusaurus-lint = website.lint;
|
||||||
|
cli-lint = cli.lint;
|
||||||
|
};
|
||||||
|
# building
|
||||||
|
packages = flake-utils.lib.flattenTree {
|
||||||
|
default = components.build;
|
||||||
|
lang = lang.build;
|
||||||
|
lang-bundle = lang.bundle;
|
||||||
|
lang-test = lang.test;
|
||||||
|
components = components.build;
|
||||||
|
components-bundle = components.bundle;
|
||||||
|
|
||||||
|
# Lint
|
||||||
|
lang-lint = lang.lint;
|
||||||
|
components-lint = components.lint;
|
||||||
|
docusaurus-lint = website.lint;
|
||||||
|
vscode-lint = vscodeext.lint;
|
||||||
|
cli-lint = cli.lint;
|
||||||
|
};
|
||||||
|
|
||||||
|
# developing
|
||||||
|
devShells = let shellNix = import ./nix/shell.nix { inherit pkgs; };
|
||||||
|
in flake-utils.lib.flattenTree {
|
||||||
|
default = shellNix.all;
|
||||||
|
js = shellNix.just-js;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in flake-utils.lib.eachDefaultSystem (system:
|
||||||
|
let
|
||||||
|
pkgs = import nixpkgs {
|
||||||
|
inherit system;
|
||||||
|
overlays = overlays;
|
||||||
|
};
|
||||||
|
|
||||||
|
in localFlakeOutputs pkgs);
|
||||||
|
}
|
1
nix/README.md
Normal file
1
nix/README.md
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Visit `quantified-uncertainty.cachix.org` for information about how to add our binary cache to your local dev environment.
|
25
nix/shell.nix
Normal file
25
nix/shell.nix
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
{ pkgs }:
|
||||||
|
with pkgs;
|
||||||
|
let
|
||||||
|
js = [ yarn nodejs nodePackages.ts-node ];
|
||||||
|
rust = [
|
||||||
|
wasm-pack
|
||||||
|
cargo
|
||||||
|
rustup
|
||||||
|
pkg-config
|
||||||
|
libressl
|
||||||
|
rustfmt
|
||||||
|
wasmtime
|
||||||
|
binaryen
|
||||||
|
wasm-bindgen-cli
|
||||||
|
];
|
||||||
|
in {
|
||||||
|
all = mkShell {
|
||||||
|
name = "squiggle_yarn-wasm-devshell";
|
||||||
|
buildInputs = builtins.concatLists [ js rust [ nixfmt ] ];
|
||||||
|
};
|
||||||
|
just-js = mkShell {
|
||||||
|
name = "squiggle_yarn-devshell";
|
||||||
|
buildInputs = js ++ [ nixfmt ];
|
||||||
|
};
|
||||||
|
}
|
13
nix/squiggle-cli.nix
Normal file
13
nix/squiggle-cli.nix
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
{ pkgs, commonFn }:
|
||||||
|
|
||||||
|
rec {
|
||||||
|
common = commonFn pkgs;
|
||||||
|
|
||||||
|
lint = pkgs.stdenv.mkDerivation {
|
||||||
|
name = "squiggle-cli-lint";
|
||||||
|
buildInputs = common.buildInputs ++ common.prettier;
|
||||||
|
src = ../packages/cli;
|
||||||
|
buildPhase = "prettier --check .";
|
||||||
|
installPhase = "mkdir -p $out";
|
||||||
|
};
|
||||||
|
}
|
75
nix/squiggle-components.nix
Normal file
75
nix/squiggle-components.nix
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
{ pkgs, commonFn, langFn }:
|
||||||
|
|
||||||
|
rec {
|
||||||
|
common = commonFn pkgs;
|
||||||
|
lang = langFn pkgs;
|
||||||
|
componentsPackageJson = let
|
||||||
|
raw = pkgs.lib.importJSON ../packages/components/package.json;
|
||||||
|
modified =
|
||||||
|
pkgs.lib.recursiveUpdate raw { dependencies.react-dom = "^18.2.0"; };
|
||||||
|
packageJsonString = builtins.toJSON modified;
|
||||||
|
in pkgs.writeText "packages/components/patched-package.json"
|
||||||
|
packageJsonString;
|
||||||
|
yarn-source = pkgs.mkYarnPackage {
|
||||||
|
name = "squiggle-components_yarnsource";
|
||||||
|
buildInputs = common.buildInputs;
|
||||||
|
src = ../packages/components;
|
||||||
|
packageJSON = componentsPackageJson;
|
||||||
|
yarnLock = ../yarn.lock;
|
||||||
|
packageResolutions."@quri/squiggle-lang" = lang.build;
|
||||||
|
};
|
||||||
|
lint = pkgs.stdenv.mkDerivation {
|
||||||
|
name = "squiggle-components-lint";
|
||||||
|
src = ../packages/components;
|
||||||
|
buildInputs = common.buildInputs ++ common.prettier;
|
||||||
|
buildPhase = "yarn lint";
|
||||||
|
installPhase = "mkdir -p $out";
|
||||||
|
};
|
||||||
|
build = pkgs.stdenv.mkDerivation {
|
||||||
|
name = "squiggle-components-build";
|
||||||
|
src = yarn-source + "/libexec/@quri/squiggle-components";
|
||||||
|
buildInputs = common.buildInputs;
|
||||||
|
buildPhase = ''
|
||||||
|
cp -r node_modules/@quri/squiggle-lang deps/@quri
|
||||||
|
pushd deps/@quri/squiggle-components
|
||||||
|
|
||||||
|
yarn --offline build:cjs
|
||||||
|
yarn --offline build:css
|
||||||
|
popd
|
||||||
|
'';
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out
|
||||||
|
|
||||||
|
# annoying hack because permissions on transitive dependencies later on
|
||||||
|
mv deps/@quri/squiggle-components/node_modules deps/@quri/squiggle-components/NODE_MODULES
|
||||||
|
mv node_modules deps/@quri/squiggle-components
|
||||||
|
|
||||||
|
# patching .gitignore so flake keeps build artefacts
|
||||||
|
sed -i /dist/d deps/@quri/squiggle-components/.gitignore
|
||||||
|
cp -r deps/@quri/squiggle-components/. $out
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
bundle = pkgs.stdenv.mkDerivation {
|
||||||
|
name = "squiggle-components-bundle";
|
||||||
|
src = yarn-source + "/libexec/@quri/squiggle-components";
|
||||||
|
buildInputs = common.buildInputs;
|
||||||
|
buildPhase = ''
|
||||||
|
cp -r node_modules/@quri/squiggle-lang deps/@quri
|
||||||
|
pushd deps/@quri/squiggle-components
|
||||||
|
|
||||||
|
yarn --offline bundle
|
||||||
|
popd
|
||||||
|
'';
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out
|
||||||
|
|
||||||
|
# annoying hack because permissions on transitive dependencies later on
|
||||||
|
mv deps/@quri/squiggle-components/node_modules deps/@quri/squiggle-components/NODE_MODULES
|
||||||
|
mv node_modules deps/@quri/squiggle-components
|
||||||
|
|
||||||
|
# patching .gitignore so flake keeps build artefacts
|
||||||
|
sed -i /dist/d deps/@quri/squiggle-components/.gitignore
|
||||||
|
cp -r deps/@quri/squiggle-components/. $out
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
125
nix/squiggle-lang.nix
Normal file
125
nix/squiggle-lang.nix
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
{ pkgs, commonFn, gentypeOutputFn }:
|
||||||
|
|
||||||
|
rec {
|
||||||
|
common = commonFn pkgs;
|
||||||
|
langPackageJson = let
|
||||||
|
raw = pkgs.lib.importJSON ../packages/squiggle-lang/package.json;
|
||||||
|
modified = pkgs.lib.recursiveUpdate raw {
|
||||||
|
devDependencies."@types/lodash" = "^4.14.167";
|
||||||
|
};
|
||||||
|
packageJsonString = builtins.toJSON modified;
|
||||||
|
in pkgs.writeText "packages/squiggle-lang/patched-package.json"
|
||||||
|
packageJsonString;
|
||||||
|
yarn-source = pkgs.mkYarnPackage {
|
||||||
|
name = "squiggle-lang_yarnsource";
|
||||||
|
src = ../packages/squiggle-lang;
|
||||||
|
packageJSON = langPackageJson;
|
||||||
|
yarnLock = ../yarn.lock;
|
||||||
|
pkgConfig = {
|
||||||
|
rescript = {
|
||||||
|
buildInputs = common.which
|
||||||
|
++ (if pkgs.system != "i686-linux" then [ pkgs.gcc_multi ] else [ ]);
|
||||||
|
postInstall = ''
|
||||||
|
echo "PATCHELF'ING RESCRIPT EXECUTABLES (INCL NINJA)"
|
||||||
|
# Patching interpreter for linux/*.exe's
|
||||||
|
THE_LD=$(patchelf --print-interpreter $(which mkdir))
|
||||||
|
patchelf --set-interpreter $THE_LD linux/*.exe && echo "- patched interpreter for linux/*.exe's"
|
||||||
|
|
||||||
|
# Replacing needed shared library for linux/ninja.exe
|
||||||
|
THE_SO=$(find /nix/store/*/lib64 -name libstdc++.so.6 | head -n 1)
|
||||||
|
patchelf --replace-needed libstdc++.so.6 $THE_SO linux/ninja.exe && echo "- replaced needed for linux/ninja.exe"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
bisect_ppx = {
|
||||||
|
buildInputs = common.which;
|
||||||
|
postInstall = ''
|
||||||
|
echo "PATCHELF'ING BISECT_PPX EXECUTABLE"
|
||||||
|
THE_LD=$(patchelf --print-interpreter $(which mkdir))
|
||||||
|
patchelf --set-interpreter $THE_LD bin/linux/ppx
|
||||||
|
patchelf --set-interpreter $THE_LD bin/linux/bisect-ppx-report
|
||||||
|
cp bin/linux/ppx ppx
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
gentype = {
|
||||||
|
postInstall = ''
|
||||||
|
mv gentype.exe ELFLESS-gentype.exe
|
||||||
|
cp ${gentypeOutputFn pkgs}/src/GenType.exe gentype.exe
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
lint = pkgs.stdenv.mkDerivation {
|
||||||
|
name = "squiggle-lang-lint";
|
||||||
|
src = yarn-source + "/libexec/@quri/squiggle-lang/deps/@quri/squiggle-lang";
|
||||||
|
buildInputs = common.buildInputs ++ common.prettier;
|
||||||
|
buildPhase = ''
|
||||||
|
yarn lint:prettier
|
||||||
|
yarn lint:rescript
|
||||||
|
'';
|
||||||
|
installPhase = "mkdir -p $out";
|
||||||
|
};
|
||||||
|
build = pkgs.stdenv.mkDerivation {
|
||||||
|
name = "squiggle-lang-build";
|
||||||
|
# `peggy` is in the `node_modules` that's adjacent to `deps`.
|
||||||
|
src = yarn-source + "/libexec/@quri/squiggle-lang";
|
||||||
|
buildInputs = common.buildInputs;
|
||||||
|
buildPhase = ''
|
||||||
|
# so that the path to ppx doesn't need to be patched.
|
||||||
|
mv node_modules deps
|
||||||
|
|
||||||
|
pushd deps/@quri/squiggle-lang
|
||||||
|
yarn --offline build:peggy
|
||||||
|
yarn --offline build:rescript
|
||||||
|
yarn --offline build:typescript
|
||||||
|
|
||||||
|
# custom gitignore so that the flake keeps build artefacts
|
||||||
|
mv .gitignore GITIGNORE
|
||||||
|
sed -i /Reducer_Peggy_GeneratedParser.js/d GITIGNORE
|
||||||
|
sed -i /\*.bs.js/d GITIGNORE
|
||||||
|
sed -i /\*.gen.ts/d GITIGNORE
|
||||||
|
sed -i /\*.gen.tsx/d GITIGNORE
|
||||||
|
sed -i /\*.gen.js/d GITIGNORE
|
||||||
|
sed -i /helpers.js/d GITIGNORE
|
||||||
|
|
||||||
|
popd
|
||||||
|
'';
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out
|
||||||
|
# mkdir -p $out/node_modules
|
||||||
|
mv deps/@quri/squiggle-lang/GITIGNORE deps/@quri/squiggle-lang/.gitignore
|
||||||
|
|
||||||
|
# annoying hack because permissions on transitive dependencies later on
|
||||||
|
mv deps/@quri/squiggle-lang/node_modules deps/@quri/squiggle-lang/NODE_MODULES
|
||||||
|
mv deps/node_modules deps/@quri/squiggle-lang
|
||||||
|
|
||||||
|
# the proper install phase
|
||||||
|
cp -r deps/@quri/squiggle-lang/. $out
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
test = pkgs.stdenv.mkDerivation {
|
||||||
|
name = "squiggle-lang-test";
|
||||||
|
src = build;
|
||||||
|
buildInputs = common.buildInputs;
|
||||||
|
buildPhase = ''
|
||||||
|
yarn --offline test
|
||||||
|
'';
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out
|
||||||
|
cp -r . $out
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
bundle = pkgs.stdenv.mkDerivation {
|
||||||
|
name = "squiggle-lang-bundle";
|
||||||
|
src = test;
|
||||||
|
buildInputs = common.buildInputs;
|
||||||
|
buildPhase = ''
|
||||||
|
yarn --offline bundle
|
||||||
|
'';
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out
|
||||||
|
cp -r dist $out
|
||||||
|
cp *.json $out/dist
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
24
nix/squiggle-vscode.nix
Normal file
24
nix/squiggle-vscode.nix
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
{ pkgs, commonFn, langFn, componentsFn }:
|
||||||
|
|
||||||
|
rec {
|
||||||
|
common = commonFn pkgs;
|
||||||
|
lang = langFn pkgs;
|
||||||
|
components = componentsFn pkgs;
|
||||||
|
|
||||||
|
yarn-source = pkgs.mkYarnPackage {
|
||||||
|
name = "squiggle-vscodeext_yarnsource";
|
||||||
|
src = ../packages/vscode-ext;
|
||||||
|
packageJson = ../packages/vscode-ext/package.json;
|
||||||
|
yarnLock = ../yarn.lock;
|
||||||
|
packageResolutions."@quri/squiggle-lang" = lang.build;
|
||||||
|
packageResolutions."@quri/squiggle-components" = components.build;
|
||||||
|
};
|
||||||
|
lint = pkgs.stdenv.mkDerivation {
|
||||||
|
name = "squiggle-vscode-lint";
|
||||||
|
buildInputs = common.buildInputs ++ common.prettier;
|
||||||
|
src =
|
||||||
|
../packages/vscode-ext; # yarn-source + "/libexec/vscode-squiggle/deps/vscode-squiggle";
|
||||||
|
buildPhase = "prettier --check .";
|
||||||
|
installPhase = "mkdir -p $out";
|
||||||
|
};
|
||||||
|
}
|
30
nix/squiggle-website.nix
Normal file
30
nix/squiggle-website.nix
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
{ pkgs, commonFn, langFn, componentsFn }:
|
||||||
|
|
||||||
|
rec {
|
||||||
|
common = commonFn pkgs;
|
||||||
|
lang = langFn pkgs;
|
||||||
|
components = componentsFn pkgs;
|
||||||
|
websitePackageJson = let
|
||||||
|
raw = pkgs.lib.importJSON ../packages/website/package.json;
|
||||||
|
modified = pkgs.lib.recursiveUpdate raw {
|
||||||
|
dependencies.postcss-import = "^14.1.0";
|
||||||
|
dependencies.tailwindcss = "^3.1.8";
|
||||||
|
};
|
||||||
|
packageJsonString = builtins.toJSON modified;
|
||||||
|
in pkgs.writeText "packages/website/patched-package.json" packageJsonString;
|
||||||
|
yarn-source = pkgs.mkYarnPackage {
|
||||||
|
name = "squiggle-website_yarnsource";
|
||||||
|
src = ../packages/website;
|
||||||
|
packageJSON = websitePackageJson;
|
||||||
|
yarnLock = ../yarn.lock;
|
||||||
|
packageResolutions."@quri/squiggle-lang" = lang.build;
|
||||||
|
packageResolutions."@quri/squiggle-components" = components.build;
|
||||||
|
};
|
||||||
|
lint = pkgs.stdenv.mkDerivation {
|
||||||
|
name = "squiggle-website-lint";
|
||||||
|
buildInputs = common.buildInputs ++ common.prettier;
|
||||||
|
src = ../packages/website;
|
||||||
|
buildPhase = "yarn lint";
|
||||||
|
installPhase = "mkdir -p $out";
|
||||||
|
};
|
||||||
|
}
|
8
nixos.sh
8
nixos.sh
|
@ -5,14 +5,14 @@
|
||||||
# We need to patchelf rescript executables. https://github.com/NixOS/nixpkgs/issues/107375
|
# We need to patchelf rescript executables. https://github.com/NixOS/nixpkgs/issues/107375
|
||||||
set -x
|
set -x
|
||||||
|
|
||||||
fhsShellName="squiggle-development"
|
fhsShellName="squiggle-fhs-development"
|
||||||
fhsShellDotNix="{pkgs ? import <nixpkgs> {} }: (pkgs.buildFHSUserEnv { name = \"${fhsShellName}\"; targetPkgs = pkgs: [pkgs.yarn]; runScript = \"yarn\"; }).env"
|
fhsShellDotNix="{pkgs ? import <nixpkgs> {} }: (pkgs.buildFHSUserEnv { name = \"${fhsShellName}\"; targetPkgs = pkgs: [pkgs.yarn pkgs.glibc]; runScript = \"yarn\"; }).env"
|
||||||
nix-shell - <<<"$fhsShellDotNix"
|
nix-shell - <<<"$fhsShellDotNix"
|
||||||
|
|
||||||
theLd=$(patchelf --print-interpreter $(which mkdir))
|
theLd=$(patchelf --print-interpreter $(which mkdir))
|
||||||
patchelf --set-interpreter $theLd ./node_modules/gentype/gentype.exe
|
patchelf --set-interpreter $theLd ./node_modules/gentype/gentype.exe
|
||||||
patchelf --set-interpreter $theLd ./node_modules/rescript/linux/*.exe
|
patchelf --set-interpreter $theLd ./node_modules/rescript/linux/*.exe
|
||||||
patchelf --set-interpreter $theLd ./node_modules/bisect_ppx/ppx
|
patchelf --set-interpreter $theLd ./node_modules/bisect_ppx/ppx
|
||||||
patchelf --set-interpreter $theLd ./node_moduels/bisect_ppx/bisect-ppx-report
|
patchelf --set-interpreter $theLd ./node_modules/bisect_ppx/bisect-ppx-report
|
||||||
theSo=$(find /nix/store/*$fhsShellName*/lib64 -name libstdc++.so.6 | grep $fhsShellName | head -n 1)
|
theSo=$(find /nix/store/*$fhsShellName*/lib64 -name libstdc++.so.6 | head -n 1)
|
||||||
patchelf --replace-needed libstdc++.so.6 $theSo ./node_modules/rescript/linux/ninja.exe
|
patchelf --replace-needed libstdc++.so.6 $theSo ./node_modules/rescript/linux/ninja.exe
|
||||||
|
|
|
@ -1,26 +1,26 @@
|
||||||
{
|
{
|
||||||
"name": "@quri/squiggle-components",
|
"name": "@quri/squiggle-components",
|
||||||
"version": "0.2.24",
|
"version": "0.3.2",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@floating-ui/react-dom": "^1.0.0",
|
"@floating-ui/react-dom": "^1.0.0",
|
||||||
"@floating-ui/react-dom-interactions": "^0.9.1",
|
"@floating-ui/react-dom-interactions": "^0.9.3",
|
||||||
"@headlessui/react": "^1.6.6",
|
"@headlessui/react": "^1.6.6",
|
||||||
"@heroicons/react": "^1.0.6",
|
"@heroicons/react": "^1.0.6",
|
||||||
"@hookform/resolvers": "^2.9.7",
|
"@hookform/resolvers": "^2.9.7",
|
||||||
"@quri/squiggle-lang": "^0.2.8",
|
"@quri/squiggle-lang": "^0.3.0",
|
||||||
"@react-hook/size": "^2.1.2",
|
"@react-hook/size": "^2.1.2",
|
||||||
"clsx": "^1.2.1",
|
"clsx": "^1.2.1",
|
||||||
"framer-motion": "^7.0.0",
|
"framer-motion": "^7.2.1",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"react": "^18.1.0",
|
"react": "^18.1.0",
|
||||||
"react-ace": "^10.1.0",
|
"react-ace": "^10.1.0",
|
||||||
"react-hook-form": "^7.34.0",
|
"react-hook-form": "^7.34.2",
|
||||||
"react-use": "^17.4.0",
|
"react-use": "^17.4.0",
|
||||||
"react-vega": "^7.6.0",
|
"react-vega": "^7.6.0",
|
||||||
"vega": "^5.22.1",
|
"vega": "^5.22.1",
|
||||||
"vega-embed": "^6.21.0",
|
"vega-embed": "^6.21.0",
|
||||||
"vega-lite": "^5.4.0",
|
"vega-lite": "^5.5.0",
|
||||||
"vscode-uri": "^3.0.3",
|
"vscode-uri": "^3.0.3",
|
||||||
"yup": "^0.32.11"
|
"yup": "^0.32.11"
|
||||||
},
|
},
|
||||||
|
@ -36,12 +36,12 @@
|
||||||
"@storybook/react": "^6.5.10",
|
"@storybook/react": "^6.5.10",
|
||||||
"@testing-library/jest-dom": "^5.16.5",
|
"@testing-library/jest-dom": "^5.16.5",
|
||||||
"@testing-library/react": "^13.3.0",
|
"@testing-library/react": "^13.3.0",
|
||||||
"@testing-library/user-event": "^14.4.2",
|
"@testing-library/user-event": "^14.4.3",
|
||||||
"@types/jest": "^27.5.0",
|
"@types/jest": "^27.5.0",
|
||||||
"@types/lodash": "^4.14.182",
|
"@types/lodash": "^4.14.184",
|
||||||
"@types/node": "^18.6.4",
|
"@types/node": "^18.7.13",
|
||||||
"@types/react": "^18.0.9",
|
"@types/react": "^18.0.9",
|
||||||
"@types/styled-components": "^5.1.24",
|
"@types/styled-components": "^5.1.26",
|
||||||
"@types/webpack": "^5.28.0",
|
"@types/webpack": "^5.28.0",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"mini-css-extract-plugin": "^2.6.1",
|
"mini-css-extract-plugin": "^2.6.1",
|
||||||
|
@ -54,11 +54,11 @@
|
||||||
"tailwindcss": "^3.1.8",
|
"tailwindcss": "^3.1.8",
|
||||||
"ts-loader": "^9.3.0",
|
"ts-loader": "^9.3.0",
|
||||||
"tsconfig-paths-webpack-plugin": "^4.0.0",
|
"tsconfig-paths-webpack-plugin": "^4.0.0",
|
||||||
"typescript": "^4.7.4",
|
"typescript": "^4.8.2",
|
||||||
"web-vitals": "^2.1.4",
|
"web-vitals": "^3.0.0",
|
||||||
"webpack": "^5.74.0",
|
"webpack": "^5.74.0",
|
||||||
"webpack-cli": "^4.10.0",
|
"webpack-cli": "^4.10.0",
|
||||||
"webpack-dev-server": "^4.9.3"
|
"webpack-dev-server": "^4.10.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": "^16.8.0 || ^17 || ^18",
|
"react": "^16.8.0 || ^17 || ^18",
|
||||||
|
|
|
@ -4,6 +4,8 @@ import {
|
||||||
result,
|
result,
|
||||||
distributionError,
|
distributionError,
|
||||||
distributionErrorToString,
|
distributionErrorToString,
|
||||||
|
squiggleExpression,
|
||||||
|
resultMap,
|
||||||
} from "@quri/squiggle-lang";
|
} from "@quri/squiggle-lang";
|
||||||
import { Vega } from "react-vega";
|
import { Vega } from "react-vega";
|
||||||
import { ErrorAlert } from "./Alert";
|
import { ErrorAlert } from "./Alert";
|
||||||
|
@ -14,6 +16,8 @@ import {
|
||||||
DistributionChartSpecOptions,
|
DistributionChartSpecOptions,
|
||||||
} from "../lib/distributionSpecBuilder";
|
} from "../lib/distributionSpecBuilder";
|
||||||
import { NumberShower } from "./NumberShower";
|
import { NumberShower } from "./NumberShower";
|
||||||
|
import { Plot, parsePlot } from "../lib/plotParser";
|
||||||
|
import { flattenResult } from "../lib/utility";
|
||||||
import { hasMassBelowZero } from "../lib/distributionUtils";
|
import { hasMassBelowZero } from "../lib/distributionUtils";
|
||||||
|
|
||||||
export type DistributionPlottingSettings = {
|
export type DistributionPlottingSettings = {
|
||||||
|
@ -23,26 +27,41 @@ export type DistributionPlottingSettings = {
|
||||||
} & DistributionChartSpecOptions;
|
} & DistributionChartSpecOptions;
|
||||||
|
|
||||||
export type DistributionChartProps = {
|
export type DistributionChartProps = {
|
||||||
distribution: Distribution;
|
plot: Plot;
|
||||||
width?: number;
|
width?: number;
|
||||||
height: number;
|
height: number;
|
||||||
} & DistributionPlottingSettings;
|
} & DistributionPlottingSettings;
|
||||||
|
|
||||||
|
export function defaultPlot(distribution: Distribution): Plot {
|
||||||
|
return { distributions: [{ name: "default", distribution }] };
|
||||||
|
}
|
||||||
|
|
||||||
|
export function makePlot(record: {
|
||||||
|
[key: string]: squiggleExpression;
|
||||||
|
}): Plot | void {
|
||||||
|
const plotResult = parsePlot(record);
|
||||||
|
if (plotResult.tag === "Ok") {
|
||||||
|
return plotResult.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const DistributionChart: React.FC<DistributionChartProps> = (props) => {
|
export const DistributionChart: React.FC<DistributionChartProps> = (props) => {
|
||||||
const {
|
const { plot, height, showSummary, width, logX, actions = false } = props;
|
||||||
distribution,
|
|
||||||
height,
|
|
||||||
showSummary,
|
|
||||||
width,
|
|
||||||
logX,
|
|
||||||
actions = false,
|
|
||||||
} = props;
|
|
||||||
const shape = distribution.pointSet();
|
|
||||||
const [sized] = useSize((size) => {
|
const [sized] = useSize((size) => {
|
||||||
if (shape.tag === "Error") {
|
let shapes = flattenResult(
|
||||||
|
plot.distributions.map((x) =>
|
||||||
|
resultMap(x.distribution.pointSet(), (shape) => ({
|
||||||
|
name: x.name,
|
||||||
|
// color: x.color, // not supported yet
|
||||||
|
continuous: shape.continuous,
|
||||||
|
discrete: shape.discrete,
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
if (shapes.tag === "Error") {
|
||||||
return (
|
return (
|
||||||
<ErrorAlert heading="Distribution Error">
|
<ErrorAlert heading="Distribution Error">
|
||||||
{distributionErrorToString(shape.value)}
|
{distributionErrorToString(shapes.value)}
|
||||||
</ErrorAlert>
|
</ErrorAlert>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -56,24 +75,29 @@ export const DistributionChart: React.FC<DistributionChartProps> = (props) => {
|
||||||
);
|
);
|
||||||
widthProp = 20;
|
widthProp = 20;
|
||||||
}
|
}
|
||||||
|
const domain = shapes.value.flatMap((shape) =>
|
||||||
|
shape.discrete.concat(shape.continuous)
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ width: widthProp }}>
|
<div style={{ width: widthProp }}>
|
||||||
{logX && hasMassBelowZero(shape.value) ? (
|
{logX && shapes.value.some(hasMassBelowZero) ? (
|
||||||
<ErrorAlert heading="Log Domain Error">
|
<ErrorAlert heading="Log Domain Error">
|
||||||
Cannot graph distribution with negative values on logarithmic scale.
|
Cannot graph distribution with negative values on logarithmic scale.
|
||||||
</ErrorAlert>
|
</ErrorAlert>
|
||||||
) : (
|
) : (
|
||||||
<Vega
|
<Vega
|
||||||
spec={spec}
|
spec={spec}
|
||||||
data={{ con: shape.value.continuous, dis: shape.value.discrete }}
|
data={{ data: shapes.value, domain }}
|
||||||
width={widthProp - 10}
|
width={widthProp - 10}
|
||||||
height={height}
|
height={height}
|
||||||
actions={actions}
|
actions={actions}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<div className="flex justify-center">
|
<div className="flex justify-center">
|
||||||
{showSummary && <SummaryTable distribution={distribution} />}
|
{showSummary && plot.distributions.length === 1 && (
|
||||||
|
<SummaryTable distribution={plot.distributions[0].distribution} />
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -16,6 +16,7 @@ import * as percentilesSpec from "../vega-specs/spec-percentiles.json";
|
||||||
import {
|
import {
|
||||||
DistributionChart,
|
DistributionChart,
|
||||||
DistributionPlottingSettings,
|
DistributionPlottingSettings,
|
||||||
|
defaultPlot,
|
||||||
} from "./DistributionChart";
|
} from "./DistributionChart";
|
||||||
import { NumberShower } from "./NumberShower";
|
import { NumberShower } from "./NumberShower";
|
||||||
import { ErrorAlert } from "./Alert";
|
import { ErrorAlert } from "./Alert";
|
||||||
|
@ -179,7 +180,7 @@ export const FunctionChart1Dist: React.FC<FunctionChart1DistProps> = ({
|
||||||
let showChart =
|
let showChart =
|
||||||
mouseItem.tag === "Ok" && mouseItem.value.tag === "distribution" ? (
|
mouseItem.tag === "Ok" && mouseItem.value.tag === "distribution" ? (
|
||||||
<DistributionChart
|
<DistributionChart
|
||||||
distribution={mouseItem.value.value}
|
plot={defaultPlot(mouseItem.value.value)}
|
||||||
width={400}
|
width={400}
|
||||||
height={50}
|
height={50}
|
||||||
{...distributionPlotSettings}
|
{...distributionPlotSettings}
|
||||||
|
|
|
@ -37,10 +37,7 @@ import { InputItem } from "./ui/InputItem";
|
||||||
import { Text } from "./ui/Text";
|
import { Text } from "./ui/Text";
|
||||||
import { ViewSettings, viewSettingsSchema } from "./ViewSettings";
|
import { ViewSettings, viewSettingsSchema } from "./ViewSettings";
|
||||||
import { HeadedSection } from "./ui/HeadedSection";
|
import { HeadedSection } from "./ui/HeadedSection";
|
||||||
import {
|
import { defaultTickFormat } from "../lib/distributionSpecBuilder";
|
||||||
defaultColor,
|
|
||||||
defaultTickFormat,
|
|
||||||
} from "../lib/distributionSpecBuilder";
|
|
||||||
import { Button } from "./ui/Button";
|
import { Button } from "./ui/Button";
|
||||||
|
|
||||||
type PlaygroundProps = SquiggleChartProps & {
|
type PlaygroundProps = SquiggleChartProps & {
|
||||||
|
@ -234,13 +231,12 @@ export const PlaygroundContext = React.createContext<PlaygroundContextShape>({
|
||||||
export const SquigglePlayground: FC<PlaygroundProps> = ({
|
export const SquigglePlayground: FC<PlaygroundProps> = ({
|
||||||
defaultCode = "",
|
defaultCode = "",
|
||||||
height = 500,
|
height = 500,
|
||||||
showSummary = false,
|
showSummary = true,
|
||||||
logX = false,
|
logX = false,
|
||||||
expY = false,
|
expY = false,
|
||||||
title,
|
title,
|
||||||
minX,
|
minX,
|
||||||
maxX,
|
maxX,
|
||||||
color = defaultColor,
|
|
||||||
tickFormat = defaultTickFormat,
|
tickFormat = defaultTickFormat,
|
||||||
distributionChartActions,
|
distributionChartActions,
|
||||||
code: controlledCode,
|
code: controlledCode,
|
||||||
|
@ -268,7 +264,6 @@ export const SquigglePlayground: FC<PlaygroundProps> = ({
|
||||||
title,
|
title,
|
||||||
minX,
|
minX,
|
||||||
maxX,
|
maxX,
|
||||||
color,
|
|
||||||
tickFormat,
|
tickFormat,
|
||||||
distributionChartActions,
|
distributionChartActions,
|
||||||
showSummary,
|
showSummary,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { squiggleExpression, declaration } from "@quri/squiggle-lang";
|
import { squiggleExpression, declaration } from "@quri/squiggle-lang";
|
||||||
import { NumberShower } from "../NumberShower";
|
import { NumberShower } from "../NumberShower";
|
||||||
import { DistributionChart } from "../DistributionChart";
|
import { DistributionChart, defaultPlot, makePlot } from "../DistributionChart";
|
||||||
import { FunctionChart, FunctionChartSettings } from "../FunctionChart";
|
import { FunctionChart, FunctionChartSettings } from "../FunctionChart";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import { VariableBox } from "./VariableBox";
|
import { VariableBox } from "./VariableBox";
|
||||||
|
@ -102,7 +102,7 @@ export const ExpressionViewer: React.FC<Props> = ({
|
||||||
{(settings) => {
|
{(settings) => {
|
||||||
return (
|
return (
|
||||||
<DistributionChart
|
<DistributionChart
|
||||||
distribution={expression.value}
|
plot={defaultPlot(expression.value)}
|
||||||
{...settings.distributionPlotSettings}
|
{...settings.distributionPlotSettings}
|
||||||
height={settings.height}
|
height={settings.height}
|
||||||
width={width}
|
width={width}
|
||||||
|
@ -241,9 +241,9 @@ export const ExpressionViewer: React.FC<Props> = ({
|
||||||
case "module": {
|
case "module": {
|
||||||
return (
|
return (
|
||||||
<VariableList path={path} heading="Module">
|
<VariableList path={path} heading="Module">
|
||||||
{(settings) =>
|
{(_) =>
|
||||||
Object.entries(expression.value)
|
Object.entries(expression.value)
|
||||||
.filter(([key, r]) => !key.match(/^(Math|System)\./))
|
.filter(([key, _]) => !key.match(/^(Math|System)\./))
|
||||||
.map(([key, r]) => (
|
.map(([key, r]) => (
|
||||||
<ExpressionViewer
|
<ExpressionViewer
|
||||||
key={key}
|
key={key}
|
||||||
|
@ -257,9 +257,45 @@ export const ExpressionViewer: React.FC<Props> = ({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
case "record":
|
case "record":
|
||||||
|
const plot = makePlot(expression.value);
|
||||||
|
if (plot) {
|
||||||
|
return (
|
||||||
|
<VariableBox
|
||||||
|
path={path}
|
||||||
|
heading={"Plot"}
|
||||||
|
renderSettingsMenu={({ onChange }) => {
|
||||||
|
let disableLogX = plot.distributions.some((x) => {
|
||||||
|
let pointSet = x.distribution.pointSet();
|
||||||
|
return (
|
||||||
|
pointSet.tag === "Ok" && hasMassBelowZero(pointSet.value)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
<ItemSettingsMenu
|
||||||
|
path={path}
|
||||||
|
onChange={onChange}
|
||||||
|
disableLogX={disableLogX}
|
||||||
|
withFunctionSettings={false}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{(settings) => {
|
||||||
|
return (
|
||||||
|
<DistributionChart
|
||||||
|
plot={plot}
|
||||||
|
{...settings.distributionPlotSettings}
|
||||||
|
height={settings.height}
|
||||||
|
width={width}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
</VariableBox>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
return (
|
return (
|
||||||
<VariableList path={path} heading="Record">
|
<VariableList path={path} heading="Record">
|
||||||
{(settings) =>
|
{(_) =>
|
||||||
Object.entries(expression.value).map(([key, r]) => (
|
Object.entries(expression.value).map(([key, r]) => (
|
||||||
<ExpressionViewer
|
<ExpressionViewer
|
||||||
key={key}
|
key={key}
|
||||||
|
@ -271,10 +307,11 @@ export const ExpressionViewer: React.FC<Props> = ({
|
||||||
}
|
}
|
||||||
</VariableList>
|
</VariableList>
|
||||||
);
|
);
|
||||||
|
}
|
||||||
case "array":
|
case "array":
|
||||||
return (
|
return (
|
||||||
<VariableList path={path} heading="Array">
|
<VariableList path={path} heading="Array">
|
||||||
{(settings) =>
|
{(_) =>
|
||||||
expression.value.map((r, i) => (
|
expression.value.map((r, i) => (
|
||||||
<ExpressionViewer
|
<ExpressionViewer
|
||||||
key={i}
|
key={i}
|
||||||
|
|
|
@ -6,10 +6,7 @@ import { Modal } from "../ui/Modal";
|
||||||
import { ViewSettings, viewSettingsSchema } from "../ViewSettings";
|
import { ViewSettings, viewSettingsSchema } from "../ViewSettings";
|
||||||
import { Path, pathAsString } from "./utils";
|
import { Path, pathAsString } from "./utils";
|
||||||
import { ViewerContext } from "./ViewerContext";
|
import { ViewerContext } from "./ViewerContext";
|
||||||
import {
|
import { defaultTickFormat } from "../../lib/distributionSpecBuilder";
|
||||||
defaultColor,
|
|
||||||
defaultTickFormat,
|
|
||||||
} from "../../lib/distributionSpecBuilder";
|
|
||||||
import { PlaygroundContext } from "../SquigglePlayground";
|
import { PlaygroundContext } from "../SquigglePlayground";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
@ -46,7 +43,6 @@ const ItemSettingsModal: React.FC<
|
||||||
tickFormat:
|
tickFormat:
|
||||||
mergedSettings.distributionPlotSettings.format || defaultTickFormat,
|
mergedSettings.distributionPlotSettings.format || defaultTickFormat,
|
||||||
title: mergedSettings.distributionPlotSettings.title,
|
title: mergedSettings.distributionPlotSettings.title,
|
||||||
color: mergedSettings.distributionPlotSettings.color || defaultColor,
|
|
||||||
minX: mergedSettings.distributionPlotSettings.minX,
|
minX: mergedSettings.distributionPlotSettings.minX,
|
||||||
maxX: mergedSettings.distributionPlotSettings.maxX,
|
maxX: mergedSettings.distributionPlotSettings.maxX,
|
||||||
distributionChartActions: mergedSettings.distributionPlotSettings.actions,
|
distributionChartActions: mergedSettings.distributionPlotSettings.actions,
|
||||||
|
@ -66,7 +62,6 @@ const ItemSettingsModal: React.FC<
|
||||||
expY: vars.expY,
|
expY: vars.expY,
|
||||||
format: vars.tickFormat,
|
format: vars.tickFormat,
|
||||||
title: vars.title,
|
title: vars.title,
|
||||||
color: vars.color,
|
|
||||||
minX: vars.minX,
|
minX: vars.minX,
|
||||||
maxX: vars.maxX,
|
maxX: vars.maxX,
|
||||||
actions: vars.distributionChartActions,
|
actions: vars.distributionChartActions,
|
||||||
|
|
|
@ -5,10 +5,7 @@ import { InputItem } from "./ui/InputItem";
|
||||||
import { Checkbox } from "./ui/Checkbox";
|
import { Checkbox } from "./ui/Checkbox";
|
||||||
import { HeadedSection } from "./ui/HeadedSection";
|
import { HeadedSection } from "./ui/HeadedSection";
|
||||||
import { Text } from "./ui/Text";
|
import { Text } from "./ui/Text";
|
||||||
import {
|
import { defaultTickFormat } from "../lib/distributionSpecBuilder";
|
||||||
defaultColor,
|
|
||||||
defaultTickFormat,
|
|
||||||
} from "../lib/distributionSpecBuilder";
|
|
||||||
|
|
||||||
export const viewSettingsSchema = yup.object({}).shape({
|
export const viewSettingsSchema = yup.object({}).shape({
|
||||||
chartHeight: yup.number().required().positive().integer().default(350),
|
chartHeight: yup.number().required().positive().integer().default(350),
|
||||||
|
@ -18,7 +15,6 @@ export const viewSettingsSchema = yup.object({}).shape({
|
||||||
expY: yup.boolean().required(),
|
expY: yup.boolean().required(),
|
||||||
tickFormat: yup.string().default(defaultTickFormat),
|
tickFormat: yup.string().default(defaultTickFormat),
|
||||||
title: yup.string(),
|
title: yup.string(),
|
||||||
color: yup.string().default(defaultColor).required(),
|
|
||||||
minX: yup.number(),
|
minX: yup.number(),
|
||||||
maxX: yup.number(),
|
maxX: yup.number(),
|
||||||
distributionChartActions: yup.boolean(),
|
distributionChartActions: yup.boolean(),
|
||||||
|
@ -114,12 +110,6 @@ export const ViewSettings: React.FC<{
|
||||||
register={register}
|
register={register}
|
||||||
label="Tick Format"
|
label="Tick Format"
|
||||||
/>
|
/>
|
||||||
<InputItem
|
|
||||||
name="color"
|
|
||||||
type="color"
|
|
||||||
register={register}
|
|
||||||
label="Color"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</HeadedSection>
|
</HeadedSection>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { Path, UseFormRegister } from "react-hook-form";
|
import { Path, UseFormRegister, FieldValues } from "react-hook-form";
|
||||||
|
|
||||||
export function Checkbox<T>({
|
export function Checkbox<T extends FieldValues>({
|
||||||
name,
|
name,
|
||||||
label,
|
label,
|
||||||
register,
|
register,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { Path, UseFormRegister } from "react-hook-form";
|
import { Path, UseFormRegister, FieldValues } from "react-hook-form";
|
||||||
|
|
||||||
export function InputItem<T>({
|
export function InputItem<T extends FieldValues>({
|
||||||
name,
|
name,
|
||||||
label,
|
label,
|
||||||
type,
|
type,
|
||||||
|
|
|
@ -10,8 +10,6 @@ export type DistributionChartSpecOptions = {
|
||||||
minX?: number;
|
minX?: number;
|
||||||
/** The maximum x coordinate shown on the chart */
|
/** The maximum x coordinate shown on the chart */
|
||||||
maxX?: number;
|
maxX?: number;
|
||||||
/** The color of the chart */
|
|
||||||
color?: string;
|
|
||||||
/** The title of the chart */
|
/** The title of the chart */
|
||||||
title?: string;
|
title?: string;
|
||||||
/** The formatting of the ticks */
|
/** The formatting of the ticks */
|
||||||
|
@ -25,36 +23,14 @@ export let linearXScale: LinearScale = {
|
||||||
range: "width",
|
range: "width",
|
||||||
zero: false,
|
zero: false,
|
||||||
nice: false,
|
nice: false,
|
||||||
domain: {
|
domain: { data: "domain", field: "x" },
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
data: "con",
|
|
||||||
field: "x",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
data: "dis",
|
|
||||||
field: "x",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
export let linearYScale: LinearScale = {
|
export let linearYScale: LinearScale = {
|
||||||
name: "yscale",
|
name: "yscale",
|
||||||
type: "linear",
|
type: "linear",
|
||||||
range: "height",
|
range: "height",
|
||||||
zero: true,
|
zero: true,
|
||||||
domain: {
|
domain: { data: "domain", field: "y" },
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
data: "con",
|
|
||||||
field: "y",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
data: "dis",
|
|
||||||
field: "y",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export let logXScale: LogScale = {
|
export let logXScale: LogScale = {
|
||||||
|
@ -65,18 +41,7 @@ export let logXScale: LogScale = {
|
||||||
base: 10,
|
base: 10,
|
||||||
nice: false,
|
nice: false,
|
||||||
clamp: true,
|
clamp: true,
|
||||||
domain: {
|
domain: { data: "domain", field: "x" },
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
data: "con",
|
|
||||||
field: "x",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
data: "dis",
|
|
||||||
field: "x",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export let expYScale: PowScale = {
|
export let expYScale: PowScale = {
|
||||||
|
@ -86,29 +51,16 @@ export let expYScale: PowScale = {
|
||||||
range: "height",
|
range: "height",
|
||||||
zero: true,
|
zero: true,
|
||||||
nice: false,
|
nice: false,
|
||||||
domain: {
|
domain: { data: "domain", field: "y" },
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
data: "con",
|
|
||||||
field: "y",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
data: "dis",
|
|
||||||
field: "y",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const defaultTickFormat = ".9~s";
|
export const defaultTickFormat = ".9~s";
|
||||||
export const defaultColor = "#739ECC";
|
|
||||||
|
|
||||||
export function buildVegaSpec(
|
export function buildVegaSpec(
|
||||||
specOptions: DistributionChartSpecOptions
|
specOptions: DistributionChartSpecOptions
|
||||||
): VisualizationSpec {
|
): VisualizationSpec {
|
||||||
let {
|
const {
|
||||||
format = defaultTickFormat,
|
format = defaultTickFormat,
|
||||||
color = defaultColor,
|
|
||||||
title,
|
title,
|
||||||
minX,
|
minX,
|
||||||
maxX,
|
maxX,
|
||||||
|
@ -127,20 +79,32 @@ export function buildVegaSpec(
|
||||||
|
|
||||||
let spec: VisualizationSpec = {
|
let spec: VisualizationSpec = {
|
||||||
$schema: "https://vega.github.io/schema/vega/v5.json",
|
$schema: "https://vega.github.io/schema/vega/v5.json",
|
||||||
description: "A basic area chart example",
|
description: "Squiggle plot chart",
|
||||||
width: 500,
|
width: 500,
|
||||||
height: 100,
|
height: 100,
|
||||||
padding: 5,
|
padding: 5,
|
||||||
data: [
|
data: [
|
||||||
{
|
{
|
||||||
name: "con",
|
name: "data",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "dis",
|
name: "domain",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
signals: [],
|
signals: [],
|
||||||
scales: [xScale, expY ? expYScale : linearYScale],
|
scales: [
|
||||||
|
xScale,
|
||||||
|
expY ? expYScale : linearYScale,
|
||||||
|
{
|
||||||
|
name: "color",
|
||||||
|
type: "ordinal",
|
||||||
|
domain: {
|
||||||
|
data: "data",
|
||||||
|
field: "name",
|
||||||
|
},
|
||||||
|
range: { scheme: "blues" },
|
||||||
|
},
|
||||||
|
],
|
||||||
axes: [
|
axes: [
|
||||||
{
|
{
|
||||||
orient: "bottom",
|
orient: "bottom",
|
||||||
|
@ -152,13 +116,40 @@ export function buildVegaSpec(
|
||||||
domainOpacity: 0.0,
|
domainOpacity: 0.0,
|
||||||
format: format,
|
format: format,
|
||||||
tickCount: 10,
|
tickCount: 10,
|
||||||
|
labelOverlap: "greedy",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
marks: [
|
marks: [
|
||||||
{
|
{
|
||||||
|
name: "all_distributions",
|
||||||
|
type: "group",
|
||||||
|
from: {
|
||||||
|
facet: {
|
||||||
|
name: "distribution_facet",
|
||||||
|
data: "data",
|
||||||
|
groupby: ["name"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
marks: [
|
||||||
|
{
|
||||||
|
name: "continuous_distribution",
|
||||||
|
type: "group",
|
||||||
|
from: {
|
||||||
|
facet: {
|
||||||
|
name: "continuous_facet",
|
||||||
|
data: "distribution_facet",
|
||||||
|
field: "continuous",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
encode: {
|
||||||
|
update: {},
|
||||||
|
},
|
||||||
|
marks: [
|
||||||
|
{
|
||||||
|
name: "continuous_area",
|
||||||
type: "area",
|
type: "area",
|
||||||
from: {
|
from: {
|
||||||
data: "con",
|
data: "continuous_facet",
|
||||||
},
|
},
|
||||||
encode: {
|
encode: {
|
||||||
update: {
|
update: {
|
||||||
|
@ -171,23 +162,37 @@ export function buildVegaSpec(
|
||||||
scale: "yscale",
|
scale: "yscale",
|
||||||
field: "y",
|
field: "y",
|
||||||
},
|
},
|
||||||
|
fill: {
|
||||||
|
scale: "color",
|
||||||
|
field: { parent: "name" },
|
||||||
|
},
|
||||||
y2: {
|
y2: {
|
||||||
scale: "yscale",
|
scale: "yscale",
|
||||||
value: 0,
|
value: 0,
|
||||||
},
|
},
|
||||||
fill: {
|
|
||||||
value: color,
|
|
||||||
},
|
|
||||||
fillOpacity: {
|
fillOpacity: {
|
||||||
value: 1,
|
value: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "discrete_distribution",
|
||||||
|
type: "group",
|
||||||
|
from: {
|
||||||
|
facet: {
|
||||||
|
name: "discrete_facet",
|
||||||
|
data: "distribution_facet",
|
||||||
|
field: "discrete",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
marks: [
|
||||||
{
|
{
|
||||||
type: "rect",
|
type: "rect",
|
||||||
from: {
|
from: {
|
||||||
data: "dis",
|
data: "discrete_facet",
|
||||||
},
|
},
|
||||||
encode: {
|
encode: {
|
||||||
enter: {
|
enter: {
|
||||||
|
@ -209,7 +214,8 @@ export function buildVegaSpec(
|
||||||
value: 0,
|
value: 0,
|
||||||
},
|
},
|
||||||
fill: {
|
fill: {
|
||||||
value: "#2f65a7",
|
scale: "color",
|
||||||
|
field: { parent: "name" },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -217,7 +223,7 @@ export function buildVegaSpec(
|
||||||
{
|
{
|
||||||
type: "symbol",
|
type: "symbol",
|
||||||
from: {
|
from: {
|
||||||
data: "dis",
|
data: "discrete_facet",
|
||||||
},
|
},
|
||||||
encode: {
|
encode: {
|
||||||
enter: {
|
enter: {
|
||||||
|
@ -239,21 +245,49 @@ export function buildVegaSpec(
|
||||||
field: "y",
|
field: "y",
|
||||||
},
|
},
|
||||||
fill: {
|
fill: {
|
||||||
value: "#1e4577",
|
scale: "color",
|
||||||
|
field: { parent: "name" },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
},
|
||||||
if (title) {
|
],
|
||||||
spec = {
|
},
|
||||||
...spec,
|
],
|
||||||
|
legends: [
|
||||||
|
{
|
||||||
|
fill: "color",
|
||||||
|
orient: "top",
|
||||||
|
labelFontSize: 12,
|
||||||
|
encode: {
|
||||||
|
symbols: {
|
||||||
|
update: {
|
||||||
|
fill: [
|
||||||
|
{ test: "length(domain('color')) == 1", value: "transparent" },
|
||||||
|
{ scale: "color", field: "value" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
labels: {
|
||||||
|
interactive: true,
|
||||||
|
update: {
|
||||||
|
fill: [
|
||||||
|
{ test: "length(domain('color')) == 1", value: "transparent" },
|
||||||
|
{ value: "black" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
...(title && {
|
||||||
title: {
|
title: {
|
||||||
text: title,
|
text: title,
|
||||||
},
|
},
|
||||||
|
}),
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
return spec;
|
return spec;
|
||||||
}
|
}
|
||||||
|
|
72
packages/components/src/lib/plotParser.ts
Normal file
72
packages/components/src/lib/plotParser.ts
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
import * as yup from "yup";
|
||||||
|
import { Distribution, result, squiggleExpression } from "@quri/squiggle-lang";
|
||||||
|
|
||||||
|
export type LabeledDistribution = {
|
||||||
|
name: string;
|
||||||
|
distribution: Distribution;
|
||||||
|
color?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Plot = {
|
||||||
|
distributions: LabeledDistribution[];
|
||||||
|
};
|
||||||
|
|
||||||
|
function error<a, b>(err: b): result<a, b> {
|
||||||
|
return { tag: "Error", value: err };
|
||||||
|
}
|
||||||
|
|
||||||
|
function ok<a, b>(x: a): result<a, b> {
|
||||||
|
return { tag: "Ok", value: x };
|
||||||
|
}
|
||||||
|
|
||||||
|
const schema = yup
|
||||||
|
.object()
|
||||||
|
.strict()
|
||||||
|
.noUnknown()
|
||||||
|
.shape({
|
||||||
|
distributions: yup.object().shape({
|
||||||
|
tag: yup.mixed().oneOf(["array"]),
|
||||||
|
value: yup
|
||||||
|
.array()
|
||||||
|
.of(
|
||||||
|
yup.object().shape({
|
||||||
|
tag: yup.mixed().oneOf(["record"]),
|
||||||
|
value: yup.object({
|
||||||
|
name: yup.object().shape({
|
||||||
|
tag: yup.mixed().oneOf(["string"]),
|
||||||
|
value: yup.string().required(),
|
||||||
|
}),
|
||||||
|
// color: yup
|
||||||
|
// .object({
|
||||||
|
// tag: yup.mixed().oneOf(["string"]),
|
||||||
|
// value: yup.string().required(),
|
||||||
|
// })
|
||||||
|
// .default(undefined),
|
||||||
|
distribution: yup.object({
|
||||||
|
tag: yup.mixed().oneOf(["distribution"]),
|
||||||
|
value: yup.mixed(),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.required(),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
export function parsePlot(record: {
|
||||||
|
[key: string]: squiggleExpression;
|
||||||
|
}): result<Plot, string> {
|
||||||
|
try {
|
||||||
|
const plotRecord = schema.validateSync(record);
|
||||||
|
return ok({
|
||||||
|
distributions: plotRecord.distributions.value.map((x) => ({
|
||||||
|
name: x.value.name.value,
|
||||||
|
// color: x.value.color?.value, // not supported yet
|
||||||
|
distribution: x.value.distribution.value,
|
||||||
|
})),
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
const message = e instanceof Error ? e.message : "Unknown error";
|
||||||
|
return error(message);
|
||||||
|
}
|
||||||
|
}
|
37
packages/components/src/lib/utility.ts
Normal file
37
packages/components/src/lib/utility.ts
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
import { result } from "@quri/squiggle-lang";
|
||||||
|
|
||||||
|
export function flattenResult<a, b>(x: result<a, b>[]): result<a[], b> {
|
||||||
|
if (x.length === 0) {
|
||||||
|
return { tag: "Ok", value: [] };
|
||||||
|
} else {
|
||||||
|
if (x[0].tag === "Error") {
|
||||||
|
return x[0];
|
||||||
|
} else {
|
||||||
|
let rest = flattenResult(x.splice(1));
|
||||||
|
if (rest.tag === "Error") {
|
||||||
|
return rest;
|
||||||
|
} else {
|
||||||
|
return { tag: "Ok", value: [x[0].value].concat(rest.value) };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function resultBind<a, b, c>(
|
||||||
|
x: result<a, b>,
|
||||||
|
fn: (y: a) => result<c, b>
|
||||||
|
): result<c, b> {
|
||||||
|
if (x.tag === "Ok") {
|
||||||
|
return fn(x.value);
|
||||||
|
} else {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function all(arr: boolean[]): boolean {
|
||||||
|
return arr.reduce((x, y) => x && y, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function some(arr: boolean[]): boolean {
|
||||||
|
return arr.reduce((x, y) => x || y, false);
|
||||||
|
}
|
|
@ -93,6 +93,33 @@ could be continuous, discrete or mixed.
|
||||||
</Story>
|
</Story>
|
||||||
</Canvas>
|
</Canvas>
|
||||||
|
|
||||||
|
## Multiple plots
|
||||||
|
|
||||||
|
<Canvas>
|
||||||
|
<Story
|
||||||
|
name="Multiple plots"
|
||||||
|
args={{
|
||||||
|
code: `
|
||||||
|
{
|
||||||
|
distributions: [
|
||||||
|
{
|
||||||
|
name: "one",
|
||||||
|
distribution: mx(0.5, normal(0,1))
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "two",
|
||||||
|
distribution: mx(2, normal(5, 2)),
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
width,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{Template.bind({})}
|
||||||
|
</Story>
|
||||||
|
</Canvas>
|
||||||
|
|
||||||
## Constants
|
## Constants
|
||||||
|
|
||||||
A constant is a simple number as a result. This has special formatting rules
|
A constant is a simple number as a result. This has special formatting rules
|
||||||
|
|
21
packages/squiggle-lang/__tests__/E/A_test.res
Normal file
21
packages/squiggle-lang/__tests__/E/A_test.res
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
open Jest
|
||||||
|
open TestHelpers
|
||||||
|
|
||||||
|
describe("E.A.getByFmap", () => {
|
||||||
|
makeTest("Empty list returns None", E.A.getByFmap([], x => x + 1, x => mod(x, 2) == 0), None)
|
||||||
|
makeTest(
|
||||||
|
"Never predicate returns None",
|
||||||
|
E.A.getByFmap([1, 2, 3, 4, 5, 6], x => x + 1, _ => false),
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
makeTest(
|
||||||
|
"function evaluates",
|
||||||
|
E.A.getByFmap([1, 1, 1, 1, 1, 1, 1, 2, 1, 1], x => 3 * x, x => x > 4),
|
||||||
|
Some(6),
|
||||||
|
)
|
||||||
|
makeTest(
|
||||||
|
"always predicate returns fn(fst(a))",
|
||||||
|
E.A.getByFmap([0, 1, 2, 3, 4, 5, 6], x => 10 + x, _ => true),
|
||||||
|
Some(10),
|
||||||
|
)
|
||||||
|
})
|
|
@ -1,4 +0,0 @@
|
||||||
open Jest
|
|
||||||
open Expect
|
|
||||||
|
|
||||||
test("todo", () => expect("1")->toBe("1"))
|
|
|
@ -68,3 +68,5 @@ myTypeCheckTest(test, "number | string", "1", "Ok")
|
||||||
myTypeCheckTest(test, "date | string", "1", "Expected type: (date | string) but got: 1")
|
myTypeCheckTest(test, "date | string", "1", "Expected type: (date | string) but got: 1")
|
||||||
myTypeCheckTest(test, "number<-min(10)", "10", "Ok")
|
myTypeCheckTest(test, "number<-min(10)", "10", "Ok")
|
||||||
myTypeCheckTest(test, "number<-min(10)", "0", "Expected type: number<-min(10) but got: 0")
|
myTypeCheckTest(test, "number<-min(10)", "0", "Expected type: number<-min(10) but got: 0")
|
||||||
|
myTypeCheckTest(test, "any", "0", "Ok")
|
||||||
|
myTypeCheckTest(test, "any", "'a'", "Ok")
|
||||||
|
|
|
@ -0,0 +1,123 @@
|
||||||
|
open Jest
|
||||||
|
open Expect
|
||||||
|
|
||||||
|
module DispatchT = Reducer_Dispatch_T
|
||||||
|
module Expression = Reducer_Expression
|
||||||
|
module ExpressionT = Reducer_Expression_T
|
||||||
|
module TypeCompile = Reducer_Type_Compile
|
||||||
|
module TypeChecker = Reducer_Type_TypeChecker
|
||||||
|
open ReducerInterface_InternalExpressionValue
|
||||||
|
|
||||||
|
type errorValue = Reducer_ErrorValue.errorValue
|
||||||
|
|
||||||
|
// Let's build a function to replace switch statements
|
||||||
|
// In dispatchChainPiece, we execute an return the result of execution if there is a type match.
|
||||||
|
// Otherwise we return None so that the call chain can continue.
|
||||||
|
// So we want to build a function like
|
||||||
|
// dispatchChainPiece = (call: functionCall, environment): option<result<internalExpressionValue, errorValue>>
|
||||||
|
|
||||||
|
// Now lets make the dispatchChainPiece itself.
|
||||||
|
// Note that I am not passing the reducer to the dispatchChainPiece as an argument because it is in the context anyway.
|
||||||
|
// Keep in mind that reducerFn is necessary for map/reduce so dispatchChainPiece should have a reducerFn in context.
|
||||||
|
|
||||||
|
let makeMyDispatchChainPiece = (reducer: ExpressionT.reducerFn): DispatchT.dispatchChainPiece => {
|
||||||
|
// Let's have a pure implementations
|
||||||
|
module Implementation = {
|
||||||
|
let stringConcat = (a: string, b: string): string => Js.String2.concat(a, b)
|
||||||
|
let arrayConcat = (
|
||||||
|
a: Js.Array2.t<internalExpressionValue>,
|
||||||
|
b: Js.Array2.t<internalExpressionValue>,
|
||||||
|
): Js.Array2.t<internalExpressionValue> => Js.Array2.concat(a, b)
|
||||||
|
let plot = _r => "yey, plotted"
|
||||||
|
}
|
||||||
|
|
||||||
|
let extractStringString = args =>
|
||||||
|
switch args {
|
||||||
|
| [IEvString(a), IEvString(b)] => (a, b)
|
||||||
|
| _ => raise(Reducer_Exception.ImpossibleException("extractStringString developer error"))
|
||||||
|
}
|
||||||
|
|
||||||
|
let extractArrayArray = args =>
|
||||||
|
switch args {
|
||||||
|
| [IEvArray(a), IEvArray(b)] => (a, b)
|
||||||
|
| _ => raise(Reducer_Exception.ImpossibleException("extractArrayArray developer error"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Let's bridge the pure implementation to expression values
|
||||||
|
module Bridge = {
|
||||||
|
let stringConcat: DispatchT.genericIEvFunction = (args, _environment) => {
|
||||||
|
let (a, b) = extractStringString(args)
|
||||||
|
Implementation.stringConcat(a, b)->IEvString->Ok
|
||||||
|
}
|
||||||
|
let arrayConcat: DispatchT.genericIEvFunction = (args, _environment) => {
|
||||||
|
let (a, b) = extractArrayArray(args)
|
||||||
|
Implementation.arrayConcat(a, b)->IEvArray->Ok
|
||||||
|
}
|
||||||
|
let plot: DispatchT.genericIEvFunction = (args, _environment) => {
|
||||||
|
switch args {
|
||||||
|
// Just assume that we are doing the business of extracting and converting the deep record
|
||||||
|
| [IEvRecord(_)] => Implementation.plot({"title": "This is a plot"})->IEvString->Ok
|
||||||
|
| _ => raise(Reducer_Exception.ImpossibleException("plot developer error"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// concat functions are to illustrate polymoprhism. And the plot function is to illustrate complex types
|
||||||
|
let jumpTable = [
|
||||||
|
(
|
||||||
|
"concat",
|
||||||
|
TypeCompile.fromTypeExpressionExn("string=>string=>string", reducer),
|
||||||
|
Bridge.stringConcat,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"concat",
|
||||||
|
TypeCompile.fromTypeExpressionExn("[any]=>[any]=>[any]", reducer),
|
||||||
|
Bridge.arrayConcat,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"plot",
|
||||||
|
TypeCompile.fromTypeExpressionExn(
|
||||||
|
// Nested complex types are available
|
||||||
|
// records {property: type}
|
||||||
|
// arrays [type]
|
||||||
|
// tuples [type, type]
|
||||||
|
// <- type contracts are available naturally and they become part of dispatching
|
||||||
|
// Here we are not enumerating the possibilities because type checking has a dedicated test
|
||||||
|
"{title: string, line: {width: number, color: string}}=>string",
|
||||||
|
reducer,
|
||||||
|
),
|
||||||
|
Bridge.plot,
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
//Here we are creating a dispatchChainPiece function that will do the actual dispatch from the jumpTable
|
||||||
|
Reducer_Dispatch_ChainPiece.makeFromTypes(jumpTable)
|
||||||
|
}
|
||||||
|
|
||||||
|
// And finally, let's write a library dispatch for our external library
|
||||||
|
// Exactly the same as the one used in real life
|
||||||
|
let _dispatch = (
|
||||||
|
call: functionCall,
|
||||||
|
environment,
|
||||||
|
reducer: Reducer_Expression_T.reducerFn,
|
||||||
|
chain,
|
||||||
|
): result<internalExpressionValue, 'e> => {
|
||||||
|
let dispatchChainPiece = makeMyDispatchChainPiece(reducer)
|
||||||
|
dispatchChainPiece(call, environment)->E.O2.defaultFn(() => chain(call, environment, reducer))
|
||||||
|
}
|
||||||
|
|
||||||
|
// What is important about this implementation?
|
||||||
|
// A) Exactly the same function jump table can be used to create type guarded lambda functions
|
||||||
|
// Guarded lambda functions will be the basis of the next version of Squiggle
|
||||||
|
// B) Complicated recursive record types are not a problem.
|
||||||
|
|
||||||
|
describe("Type Dispatch", () => {
|
||||||
|
let reducerFn = Expression.reduceExpression
|
||||||
|
let dispatchChainPiece = makeMyDispatchChainPiece(reducerFn)
|
||||||
|
test("stringConcat", () => {
|
||||||
|
let call: functionCall = ("concat", [IEvString("hello"), IEvString("world")])
|
||||||
|
|
||||||
|
let result = dispatchChainPiece(call, defaultEnvironment)
|
||||||
|
expect(result)->toEqual(Some(Ok(IEvString("helloworld"))))
|
||||||
|
})
|
||||||
|
})
|
|
@ -74,6 +74,7 @@ describe("eval on distribution functions", () => {
|
||||||
testEval("truncateLeft(normal(5,2), 3)", "Ok(Point Set Distribution)")
|
testEval("truncateLeft(normal(5,2), 3)", "Ok(Point Set Distribution)")
|
||||||
testEval("truncateRight(normal(5,2), 3)", "Ok(Point Set Distribution)")
|
testEval("truncateRight(normal(5,2), 3)", "Ok(Point Set Distribution)")
|
||||||
testEval("truncate(normal(5,2), 3, 8)", "Ok(Point Set Distribution)")
|
testEval("truncate(normal(5,2), 3, 8)", "Ok(Point Set Distribution)")
|
||||||
|
testEval("truncate(normal(5,2) |> SampleSet.fromDist, 3, 8)", "Ok(Sample Set Distribution)")
|
||||||
testEval("isNormalized(truncate(normal(5,2), 3, 8))", "Ok(true)")
|
testEval("isNormalized(truncate(normal(5,2), 3, 8))", "Ok(true)")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,9 @@ describe("FunctionRegistry Library", () => {
|
||||||
testEvalToBe("SampleSet.fromList([3,5,2,3,5,2,3,5,2,3,3,5])", "Ok(Sample Set Distribution)")
|
testEvalToBe("SampleSet.fromList([3,5,2,3,5,2,3,5,2,3,3,5])", "Ok(Sample Set Distribution)")
|
||||||
testEvalToBe("SampleSet.fromList([3,5,2,3,5,2,3,5,2,3,3,5])", "Ok(Sample Set Distribution)")
|
testEvalToBe("SampleSet.fromList([3,5,2,3,5,2,3,5,2,3,3,5])", "Ok(Sample Set Distribution)")
|
||||||
testEvalToBe("SampleSet.fromFn({|| sample(normal(5,2))})", "Ok(Sample Set Distribution)")
|
testEvalToBe("SampleSet.fromFn({|| sample(normal(5,2))})", "Ok(Sample Set Distribution)")
|
||||||
|
testEvalToBe("SampleSet.min(SampleSet.fromDist(normal(50,2)), 2)", "Ok(Sample Set Distribution)")
|
||||||
|
testEvalToBe("mean(SampleSet.min(SampleSet.fromDist(normal(50,2)), 2))", "Ok(2)")
|
||||||
|
testEvalToBe("SampleSet.max(SampleSet.fromDist(normal(50,2)), 10)", "Ok(Sample Set Distribution)")
|
||||||
testEvalToBe(
|
testEvalToBe(
|
||||||
"addOne(t)=t+1; SampleSet.toList(SampleSet.map(SampleSet.fromList([1,2,3,4,5,6]), addOne))",
|
"addOne(t)=t+1; SampleSet.toList(SampleSet.map(SampleSet.fromList([1,2,3,4,5,6]), addOne))",
|
||||||
"Ok([2,3,4,5,6,7])",
|
"Ok([2,3,4,5,6,7])",
|
||||||
|
|
20
packages/squiggle-lang/__tests__/Stdlib_test.res
Normal file
20
packages/squiggle-lang/__tests__/Stdlib_test.res
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
open Jest
|
||||||
|
open Expect
|
||||||
|
|
||||||
|
let makeTest = (~only=false, str, item1, item2) =>
|
||||||
|
only
|
||||||
|
? Only.test(str, () => expect(item1)->toEqual(item2))
|
||||||
|
: test(str, () => expect(item1)->toEqual(item2))
|
||||||
|
|
||||||
|
describe("Stdlib", () => {
|
||||||
|
makeTest(
|
||||||
|
"Length of Random.sample",
|
||||||
|
Stdlib.Random.sample([1.0, 2.0], {probs: [0.5, 0.5], size: 10})->E.A.length,
|
||||||
|
10,
|
||||||
|
)
|
||||||
|
makeTest(
|
||||||
|
"Random.sample returns elements from input array (will fail with very slim probability)",
|
||||||
|
Stdlib.Random.sample([1.0, 2.0], {probs: [0.5, 0.5], size: 10})->E.A.uniq->E.A.Floats.sort,
|
||||||
|
[1.0, 2.0],
|
||||||
|
)
|
||||||
|
})
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@quri/squiggle-lang",
|
"name": "@quri/squiggle-lang",
|
||||||
"version": "0.2.11",
|
"version": "0.3.1",
|
||||||
"homepage": "https://squiggle-language.com",
|
"homepage": "https://squiggle-language.com",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -18,6 +18,7 @@
|
||||||
"benchmark": "ts-node benchmark/conversion_tests.ts",
|
"benchmark": "ts-node benchmark/conversion_tests.ts",
|
||||||
"test": "jest",
|
"test": "jest",
|
||||||
"test:ts": "jest __tests__/TS/",
|
"test:ts": "jest __tests__/TS/",
|
||||||
|
"test:stdlib": "jest __tests__/Stdlib_test.bs.js",
|
||||||
"test:rescript": "jest --modulePathIgnorePatterns=__tests__/TS/*",
|
"test:rescript": "jest --modulePathIgnorePatterns=__tests__/TS/*",
|
||||||
"test:watch": "jest --watchAll",
|
"test:watch": "jest --watchAll",
|
||||||
"test:fnRegistry": "jest __tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.bs.js",
|
"test:fnRegistry": "jest __tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.bs.js",
|
||||||
|
@ -44,18 +45,18 @@
|
||||||
"@stdlib/stats": "^0.0.13",
|
"@stdlib/stats": "^0.0.13",
|
||||||
"jstat": "^1.9.5",
|
"jstat": "^1.9.5",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"mathjs": "^11.0.1",
|
"mathjs": "^11.1.0",
|
||||||
"pdfast": "^0.2.0"
|
"pdfast": "^0.2.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@glennsl/rescript-jest": "^0.9.0",
|
"@glennsl/rescript-jest": "^0.9.2",
|
||||||
"@istanbuljs/nyc-config-typescript": "^1.0.2",
|
"@istanbuljs/nyc-config-typescript": "^1.0.2",
|
||||||
"@types/jest": "^27.5.0",
|
"@types/jest": "^27.5.0",
|
||||||
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.2",
|
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.2",
|
||||||
"bisect_ppx": "^2.7.1",
|
"bisect_ppx": "^2.7.1",
|
||||||
"chalk": "^5.0.1",
|
"chalk": "^5.0.1",
|
||||||
"codecov": "^3.8.3",
|
"codecov": "^3.8.3",
|
||||||
"fast-check": "^3.1.1",
|
"fast-check": "^3.1.2",
|
||||||
"gentype": "^4.5.0",
|
"gentype": "^4.5.0",
|
||||||
"jest": "^27.5.1",
|
"jest": "^27.5.1",
|
||||||
"moduleserve": "^0.9.1",
|
"moduleserve": "^0.9.1",
|
||||||
|
@ -68,7 +69,7 @@
|
||||||
"ts-jest": "^27.1.4",
|
"ts-jest": "^27.1.4",
|
||||||
"ts-loader": "^9.3.0",
|
"ts-loader": "^9.3.0",
|
||||||
"ts-node": "^10.9.1",
|
"ts-node": "^10.9.1",
|
||||||
"typescript": "^4.7.4",
|
"typescript": "^4.8.2",
|
||||||
"webpack": "^5.74.0",
|
"webpack": "^5.74.0",
|
||||||
"webpack-cli": "^4.10.0"
|
"webpack-cli": "^4.10.0"
|
||||||
},
|
},
|
||||||
|
|
|
@ -40,8 +40,8 @@ export type { result, shape, environment, lambdaValue, squiggleExpression };
|
||||||
export { parse } from "./parse";
|
export { parse } from "./parse";
|
||||||
|
|
||||||
export let defaultSamplingInputs: environment = {
|
export let defaultSamplingInputs: environment = {
|
||||||
sampleCount: 10000,
|
sampleCount: 1000,
|
||||||
xyPointLength: 10000,
|
xyPointLength: 1000,
|
||||||
};
|
};
|
||||||
|
|
||||||
export function run(
|
export function run(
|
||||||
|
|
|
@ -216,7 +216,7 @@ let rec run = (~env: env, functionCallInfo: functionCallInfo): outputType => {
|
||||||
| FromFloat(subFnName, x) => reCall(~functionCallInfo=FromFloat(subFnName, x), ())
|
| FromFloat(subFnName, x) => reCall(~functionCallInfo=FromFloat(subFnName, x), ())
|
||||||
| Mixture(dists) =>
|
| Mixture(dists) =>
|
||||||
dists
|
dists
|
||||||
->GenericDist.mixture(~scaleMultiplyFn=scaleMultiply, ~pointwiseAddFn=pointwiseAdd)
|
->GenericDist.mixture(~scaleMultiplyFn=scaleMultiply, ~pointwiseAddFn=pointwiseAdd, ~env)
|
||||||
->E.R2.fmap(r => Dist(r))
|
->E.R2.fmap(r => Dist(r))
|
||||||
->OutputLocal.fromResult
|
->OutputLocal.fromResult
|
||||||
| FromSamples(xs) =>
|
| FromSamples(xs) =>
|
||||||
|
|
|
@ -242,6 +242,13 @@ module Truncate = {
|
||||||
switch trySymbolicSimplification(leftCutoff, rightCutoff, t) {
|
switch trySymbolicSimplification(leftCutoff, rightCutoff, t) {
|
||||||
| Some(r) => Ok(r)
|
| Some(r) => Ok(r)
|
||||||
| None =>
|
| None =>
|
||||||
|
switch t {
|
||||||
|
| SampleSet(t) =>
|
||||||
|
switch SampleSetDist.truncate(t, ~leftCutoff, ~rightCutoff) {
|
||||||
|
| Ok(r) => Ok(SampleSet(r))
|
||||||
|
| Error(err) => Error(DistributionTypes.SampleSetError(err))
|
||||||
|
}
|
||||||
|
| _ =>
|
||||||
toPointSetFn(t)->E.R2.fmap(t => {
|
toPointSetFn(t)->E.R2.fmap(t => {
|
||||||
DistributionTypes.PointSet(
|
DistributionTypes.PointSet(
|
||||||
PointSetDist.T.truncate(leftCutoff, rightCutoff, t)->PointSetDist.T.normalize,
|
PointSetDist.T.truncate(leftCutoff, rightCutoff, t)->PointSetDist.T.normalize,
|
||||||
|
@ -250,6 +257,7 @@ module Truncate = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let truncate = Truncate.run
|
let truncate = Truncate.run
|
||||||
|
@ -491,15 +499,30 @@ let pointwiseCombinationFloat = (
|
||||||
m->E.R2.fmap(r => DistributionTypes.PointSet(r))
|
m->E.R2.fmap(r => DistributionTypes.PointSet(r))
|
||||||
}
|
}
|
||||||
|
|
||||||
//Note: The result should always cumulatively sum to 1. This would be good to test.
|
//TODO: The result should always cumulatively sum to 1. This would be good to test.
|
||||||
//Note: If the inputs are not normalized, this will return poor results. The weights probably refer to the post-normalized forms. It would be good to apply a catch to this.
|
//TODO: If the inputs are not normalized, this will return poor results. The weights probably refer to the post-normalized forms. It would be good to apply a catch to this.
|
||||||
let mixture = (
|
let mixture = (
|
||||||
values: array<(t, float)>,
|
values: array<(t, float)>,
|
||||||
~scaleMultiplyFn: scaleMultiplyFn,
|
~scaleMultiplyFn: scaleMultiplyFn,
|
||||||
~pointwiseAddFn: pointwiseAddFn,
|
~pointwiseAddFn: pointwiseAddFn,
|
||||||
|
~env: env,
|
||||||
) => {
|
) => {
|
||||||
if E.A.length(values) == 0 {
|
let allValuesAreSampleSet = v => E.A.all(((t, _)) => isSampleSetSet(t), v)
|
||||||
|
|
||||||
|
if E.A.isEmpty(values) {
|
||||||
Error(DistributionTypes.OtherError("Mixture error: mixture must have at least 1 element"))
|
Error(DistributionTypes.OtherError("Mixture error: mixture must have at least 1 element"))
|
||||||
|
} else if allValuesAreSampleSet(values) {
|
||||||
|
let withSampleSetValues = values->E.A2.fmap(((value, weight)) =>
|
||||||
|
switch value {
|
||||||
|
| SampleSet(sampleSet) => Ok((sampleSet, weight))
|
||||||
|
| _ => Error("Unreachable")
|
||||||
|
}->E.R2.toExn("Mixture coding error: SampleSet expected. This should be inaccessible.")
|
||||||
|
)
|
||||||
|
let sampleSetMixture = SampleSetDist.mixture(withSampleSetValues, env.sampleCount)
|
||||||
|
switch sampleSetMixture {
|
||||||
|
| Ok(sampleSet) => Ok(DistributionTypes.SampleSet(sampleSet))
|
||||||
|
| Error(err) => Error(DistributionTypes.Error.sampleErrorToDistErr(err))
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
let totalWeight = values->E.A2.fmap(E.Tuple2.second)->E.A.Floats.sum
|
let totalWeight = values->E.A2.fmap(E.Tuple2.second)->E.A.Floats.sum
|
||||||
let properlyWeightedValues =
|
let properlyWeightedValues =
|
||||||
|
|
|
@ -81,6 +81,7 @@ let mixture: (
|
||||||
array<(t, float)>,
|
array<(t, float)>,
|
||||||
~scaleMultiplyFn: scaleMultiplyFn,
|
~scaleMultiplyFn: scaleMultiplyFn,
|
||||||
~pointwiseAddFn: pointwiseAddFn,
|
~pointwiseAddFn: pointwiseAddFn,
|
||||||
|
~env: env,
|
||||||
) => result<t, error>
|
) => result<t, error>
|
||||||
|
|
||||||
let isSymbolic: t => bool
|
let isSymbolic: t => bool
|
||||||
|
|
|
@ -224,3 +224,8 @@ module T = Dist({
|
||||||
XYShape.Analysis.getVarianceDangerously(t, mean, getMeanOfSquares)
|
XYShape.Analysis.getVarianceDangerously(t, mean, getMeanOfSquares)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
let sampleN = (t: t, n): array<float> => {
|
||||||
|
let normalized = t->T.normalize->getShape
|
||||||
|
Stdlib.Random.sample(normalized.xs, {probs: normalized.ys, size: n})
|
||||||
|
}
|
||||||
|
|
|
@ -257,3 +257,7 @@ let toSparkline = (t: t, bucketCount): result<string, PointSetTypes.sparklineErr
|
||||||
->E.O2.fmap(Continuous.downsampleEquallyOverX(bucketCount))
|
->E.O2.fmap(Continuous.downsampleEquallyOverX(bucketCount))
|
||||||
->E.O2.toResult(PointSetTypes.CannotSparklineDiscrete)
|
->E.O2.toResult(PointSetTypes.CannotSparklineDiscrete)
|
||||||
->E.R2.fmap(r => Continuous.getShape(r).ys->Sparklines.create())
|
->E.R2.fmap(r => Continuous.getShape(r).ys->Sparklines.create())
|
||||||
|
|
||||||
|
let makeDiscrete = (d): t => Discrete(d)
|
||||||
|
let makeContinuous = (d): t => Continuous(d)
|
||||||
|
let makeMixed = (d): t => Mixed(d)
|
||||||
|
|
|
@ -131,3 +131,37 @@ let max = t => T.get(t)->E.A.Floats.max
|
||||||
let stdev = t => T.get(t)->E.A.Floats.stdev
|
let stdev = t => T.get(t)->E.A.Floats.stdev
|
||||||
let variance = t => T.get(t)->E.A.Floats.variance
|
let variance = t => T.get(t)->E.A.Floats.variance
|
||||||
let percentile = (t, f) => T.get(t)->E.A.Floats.percentile(f)
|
let percentile = (t, f) => T.get(t)->E.A.Floats.percentile(f)
|
||||||
|
|
||||||
|
let mixture = (values: array<(t, float)>, intendedLength: int) => {
|
||||||
|
let totalWeight = values->E.A2.fmap(E.Tuple2.second)->E.A.Floats.sum
|
||||||
|
let discreteSamples =
|
||||||
|
values
|
||||||
|
->Belt.Array.mapWithIndex((i, (_, weight)) => (E.I.toFloat(i), weight /. totalWeight))
|
||||||
|
->XYShape.T.fromZippedArray
|
||||||
|
->Discrete.make
|
||||||
|
->Discrete.sampleN(intendedLength)
|
||||||
|
let dists = values->E.A2.fmap(E.Tuple2.first)->E.A2.fmap(T.get)
|
||||||
|
let samples =
|
||||||
|
discreteSamples
|
||||||
|
->Belt.Array.mapWithIndex((index, distIndexToChoose) => {
|
||||||
|
let chosenDist = E.A.get(dists, E.Float.toInt(distIndexToChoose))
|
||||||
|
chosenDist->E.O.bind(E.A.get(_, index))
|
||||||
|
})
|
||||||
|
->E.A.O.openIfAllSome
|
||||||
|
samples->E.O2.toExn("Mixture unreachable error")->T.make
|
||||||
|
}
|
||||||
|
|
||||||
|
let truncateLeft = (t, f) => T.get(t)->E.A2.filter(x => x >= f)->T.make
|
||||||
|
let truncateRight = (t, f) => T.get(t)->E.A2.filter(x => x <= f)->T.make
|
||||||
|
|
||||||
|
let truncate = (t, ~leftCutoff: option<float>, ~rightCutoff: option<float>) => {
|
||||||
|
let withTruncatedLeft = t => leftCutoff |> E.O.dimap(left => truncateLeft(t, left), _ => Ok(t))
|
||||||
|
let withTruncatedRight = t => rightCutoff |> E.O.dimap(left => truncateRight(t, left), _ => Ok(t))
|
||||||
|
t->withTruncatedLeft |> E.R2.bind(withTruncatedRight)
|
||||||
|
}
|
||||||
|
|
||||||
|
let minOfTwo = (t1: t, t2: t) => map2(~fn=(a, b) => Ok(Js.Math.min_float(a, b)), ~t1, ~t2)
|
||||||
|
let maxOfTwo = (t1: t, t2: t) => map2(~fn=(a, b) => Ok(Js.Math.max_float(a, b)), ~t1, ~t2)
|
||||||
|
|
||||||
|
let minOfFloat = (t: t, f: float) => samplesMap(~fn=a => Ok(Js.Math.min_float(a, f)), t)
|
||||||
|
let maxOfFloat = (t: t, f: float) => samplesMap(~fn=a => Ok(Js.Math.max_float(a, f)), t)
|
||||||
|
|
|
@ -23,6 +23,30 @@ let inputsTodist = (inputs: array<FunctionRegistry_Core.frValue>, makeDist) => {
|
||||||
expressionValue
|
expressionValue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module Internal = {
|
||||||
|
type t = PointSetDist.t
|
||||||
|
|
||||||
|
let toType = (r): result<
|
||||||
|
ReducerInterface_InternalExpressionValue.t,
|
||||||
|
Reducer_ErrorValue.errorValue,
|
||||||
|
> =>
|
||||||
|
switch r {
|
||||||
|
| Ok(r) => Ok(Wrappers.evDistribution(PointSet(r)))
|
||||||
|
| Error(err) => Error(REOperationError(err))
|
||||||
|
}
|
||||||
|
|
||||||
|
let doLambdaCall = (aLambdaValue, list, environment, reducer) =>
|
||||||
|
switch Reducer_Expression_Lambda.doLambdaCall(aLambdaValue, list, environment, reducer) {
|
||||||
|
| Ok(IEvNumber(f)) => Ok(f)
|
||||||
|
| _ => Error(Operation.SampleMapNeedsNtoNFunction)
|
||||||
|
}
|
||||||
|
|
||||||
|
let mapY = (pointSetDist: t, aLambdaValue, env, reducer) => {
|
||||||
|
let fn = r => doLambdaCall(aLambdaValue, list{IEvNumber(r)}, env, reducer)
|
||||||
|
PointSetDist.T.mapYResult(~fn, pointSetDist)->toType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let library = [
|
let library = [
|
||||||
Function.make(
|
Function.make(
|
||||||
~name="fromDist",
|
~name="fromDist",
|
||||||
|
@ -53,6 +77,27 @@ let library = [
|
||||||
],
|
],
|
||||||
(),
|
(),
|
||||||
),
|
),
|
||||||
|
Function.make(
|
||||||
|
~name="mapY",
|
||||||
|
~nameSpace,
|
||||||
|
~requiresNamespace=true,
|
||||||
|
~examples=[`PointSet.mapY(mx(normal(5,2)), {|x| x + 1})`],
|
||||||
|
~output=ReducerInterface_InternalExpressionValue.EvtDistribution,
|
||||||
|
~definitions=[
|
||||||
|
FnDefinition.make(
|
||||||
|
~name="mapY",
|
||||||
|
~inputs=[FRTypeDist, FRTypeLambda],
|
||||||
|
~run=(inputs, _, env, reducer) =>
|
||||||
|
switch inputs {
|
||||||
|
| [IEvDistribution(PointSet(dist)), IEvLambda(lambda)] =>
|
||||||
|
Internal.mapY(dist, lambda, env, reducer)->E.R2.errMap(Reducer_ErrorValue.errorToString)
|
||||||
|
| _ => Error(impossibleError)
|
||||||
|
},
|
||||||
|
(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
(),
|
||||||
|
),
|
||||||
Function.make(
|
Function.make(
|
||||||
~name="makeContinuous",
|
~name="makeContinuous",
|
||||||
~nameSpace,
|
~nameSpace,
|
||||||
|
|
|
@ -75,7 +75,7 @@ module Internal = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let library = [
|
let libaryBase = [
|
||||||
Function.make(
|
Function.make(
|
||||||
~name="fromDist",
|
~name="fromDist",
|
||||||
~nameSpace,
|
~nameSpace,
|
||||||
|
@ -92,7 +92,7 @@ let library = [
|
||||||
GenericDist.toSampleSetDist(dist, env.sampleCount)
|
GenericDist.toSampleSetDist(dist, env.sampleCount)
|
||||||
->E.R2.fmap(Wrappers.sampleSet)
|
->E.R2.fmap(Wrappers.sampleSet)
|
||||||
->E.R2.fmap(Wrappers.evDistribution)
|
->E.R2.fmap(Wrappers.evDistribution)
|
||||||
->E.R2.errMap(_ => "")
|
->E.R2.errMap(DistributionTypes.Error.toString)
|
||||||
| _ => Error(impossibleError)
|
| _ => Error(impossibleError)
|
||||||
},
|
},
|
||||||
(),
|
(),
|
||||||
|
@ -158,7 +158,7 @@ let library = [
|
||||||
| [IEvLambda(lambda)] =>
|
| [IEvLambda(lambda)] =>
|
||||||
switch Internal.fromFn(lambda, env, reducer) {
|
switch Internal.fromFn(lambda, env, reducer) {
|
||||||
| Ok(r) => Ok(r->Wrappers.sampleSet->Wrappers.evDistribution)
|
| Ok(r) => Ok(r->Wrappers.sampleSet->Wrappers.evDistribution)
|
||||||
| Error(_) => Error("issue")
|
| Error(e) => Error(Operation.Error.toString(e))
|
||||||
}
|
}
|
||||||
| _ => Error(impossibleError)
|
| _ => Error(impossibleError)
|
||||||
},
|
},
|
||||||
|
@ -180,7 +180,7 @@ let library = [
|
||||||
~run=(inputs, _, env, reducer) =>
|
~run=(inputs, _, env, reducer) =>
|
||||||
switch inputs {
|
switch inputs {
|
||||||
| [IEvDistribution(SampleSet(dist)), IEvLambda(lambda)] =>
|
| [IEvDistribution(SampleSet(dist)), IEvLambda(lambda)] =>
|
||||||
Internal.map1(dist, lambda, env, reducer)->E.R2.errMap(_ => "")
|
Internal.map1(dist, lambda, env, reducer)->E.R2.errMap(Reducer_ErrorValue.errorToString)
|
||||||
| _ => Error(impossibleError)
|
| _ => Error(impossibleError)
|
||||||
},
|
},
|
||||||
(),
|
(),
|
||||||
|
@ -207,7 +207,9 @@ let library = [
|
||||||
IEvDistribution(SampleSet(dist2)),
|
IEvDistribution(SampleSet(dist2)),
|
||||||
IEvLambda(lambda),
|
IEvLambda(lambda),
|
||||||
] =>
|
] =>
|
||||||
Internal.map2(dist1, dist2, lambda, env, reducer)->E.R2.errMap(_ => "")
|
Internal.map2(dist1, dist2, lambda, env, reducer)->E.R2.errMap(
|
||||||
|
Reducer_ErrorValue.errorToString,
|
||||||
|
)
|
||||||
| _ => Error(impossibleError)
|
| _ => Error(impossibleError)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -236,7 +238,9 @@ let library = [
|
||||||
IEvDistribution(SampleSet(dist3)),
|
IEvDistribution(SampleSet(dist3)),
|
||||||
IEvLambda(lambda),
|
IEvLambda(lambda),
|
||||||
] =>
|
] =>
|
||||||
Internal.map3(dist1, dist2, dist3, lambda, env, reducer)->E.R2.errMap(_ => "")
|
Internal.map3(dist1, dist2, dist3, lambda, env, reducer)->E.R2.errMap(
|
||||||
|
Reducer_ErrorValue.errorToString,
|
||||||
|
)
|
||||||
| _ => Error(impossibleError)
|
| _ => Error(impossibleError)
|
||||||
},
|
},
|
||||||
(),
|
(),
|
||||||
|
@ -259,9 +263,9 @@ let library = [
|
||||||
~run=(inputs, _, env, reducer) =>
|
~run=(inputs, _, env, reducer) =>
|
||||||
switch inputs {
|
switch inputs {
|
||||||
| [IEvArray(dists), IEvLambda(lambda)] =>
|
| [IEvArray(dists), IEvLambda(lambda)] =>
|
||||||
Internal.mapN(dists, lambda, env, reducer)->E.R2.errMap(_e => {
|
Internal.mapN(dists, lambda, env, reducer)->E.R2.errMap(
|
||||||
"AHHH doesn't work"
|
Reducer_ErrorValue.errorToString,
|
||||||
})
|
)
|
||||||
| _ => Error(impossibleError)
|
| _ => Error(impossibleError)
|
||||||
},
|
},
|
||||||
(),
|
(),
|
||||||
|
@ -270,3 +274,63 @@ let library = [
|
||||||
(),
|
(),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
module Comparison = {
|
||||||
|
let template = (name, inputs, run) => {
|
||||||
|
FnDefinition.make(
|
||||||
|
~name,
|
||||||
|
~inputs,
|
||||||
|
~run=(inputs, _, _, _) => {
|
||||||
|
run(inputs)
|
||||||
|
},
|
||||||
|
(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
let wrapper = r =>
|
||||||
|
r
|
||||||
|
->E.R2.fmap(r => r->Wrappers.sampleSet->Wrappers.evDistribution)
|
||||||
|
->E.R2.errMap(SampleSetDist.Error.toString)
|
||||||
|
|
||||||
|
let mkBig = (name, withDist, withFloat) =>
|
||||||
|
Function.make(
|
||||||
|
~name,
|
||||||
|
~nameSpace,
|
||||||
|
~requiresNamespace=false,
|
||||||
|
~examples=[
|
||||||
|
`SampleSet.${name}(SampleSet.fromDist(normal(5,2)), SampleSet.fromDist(normal(6,2)))`,
|
||||||
|
`SampleSet.${name}(SampleSet.fromDist(normal(5,2)), 3.0)`,
|
||||||
|
`SampleSet.${name}(4.0, SampleSet.fromDist(normal(6,2)))`,
|
||||||
|
],
|
||||||
|
~output=ReducerInterface_InternalExpressionValue.EvtDistribution,
|
||||||
|
~definitions=[
|
||||||
|
template(name, [FRTypeDist, FRTypeDist], inputs => {
|
||||||
|
switch inputs {
|
||||||
|
| [IEvDistribution(SampleSet(dist1)), IEvDistribution(SampleSet(dist2))] =>
|
||||||
|
withDist(dist1, dist2)->wrapper
|
||||||
|
| _ => Error(impossibleError)
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
template(name, [FRTypeDist, FRTypeNumber], inputs => {
|
||||||
|
switch inputs {
|
||||||
|
| [IEvDistribution(SampleSet(dist)), IEvNumber(f)] => withFloat(dist, f)->wrapper
|
||||||
|
| _ => Error(impossibleError)
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
template(name, [FRTypeNumber, FRTypeDist], inputs => {
|
||||||
|
switch inputs {
|
||||||
|
| [IEvNumber(f), IEvDistribution(SampleSet(dist))] => withFloat(dist, f)->wrapper
|
||||||
|
| _ => Error(impossibleError)
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
(),
|
||||||
|
)
|
||||||
|
|
||||||
|
let library = [
|
||||||
|
mkBig("min", SampleSetDist.minOfTwo, SampleSetDist.minOfFloat),
|
||||||
|
mkBig("max", SampleSetDist.maxOfTwo, SampleSetDist.maxOfFloat),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
let library = E.A.append(libaryBase, Comparison.library)
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
module TypeChecker = Reducer_Type_TypeChecker
|
||||||
|
module T = Reducer_Dispatch_T
|
||||||
|
open ReducerInterface_InternalExpressionValue
|
||||||
|
|
||||||
|
type errorValue = Reducer_ErrorValue.errorValue
|
||||||
|
|
||||||
|
let makeFromTypes = jumpTable => {
|
||||||
|
let dispatchChainPiece: T.dispatchChainPiece = ((fnName, fnArgs): functionCall, environment) => {
|
||||||
|
let jumpTableEntry = jumpTable->Js.Array2.find(elem => {
|
||||||
|
let (candidName, candidType, _) = elem
|
||||||
|
candidName == fnName && TypeChecker.checkITypeArgumentsBool(candidType, fnArgs)
|
||||||
|
})
|
||||||
|
switch jumpTableEntry {
|
||||||
|
| Some((_, _, bridgeFn)) => bridgeFn(fnArgs, environment)->Some
|
||||||
|
| _ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dispatchChainPiece
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
module InternalExpressionValue = ReducerInterface_InternalExpressionValue
|
||||||
|
module ExpressionT = Reducer_Expression_T
|
||||||
|
|
||||||
|
// Each piece of the dispatch chain computes the result or returns None so that the chain can continue
|
||||||
|
type dispatchChainPiece = (
|
||||||
|
InternalExpressionValue.functionCall,
|
||||||
|
InternalExpressionValue.environment,
|
||||||
|
) => option<result<InternalExpressionValue.t, Reducer_ErrorValue.errorValue>>
|
||||||
|
|
||||||
|
type dispatchChainPieceWithReducer = (
|
||||||
|
InternalExpressionValue.functionCall,
|
||||||
|
InternalExpressionValue.environment,
|
||||||
|
ExpressionT.reducerFn,
|
||||||
|
) => option<result<InternalExpressionValue.t, Reducer_ErrorValue.errorValue>>
|
||||||
|
|
||||||
|
// This is a switch statement case implementation: get the arguments and compute the result
|
||||||
|
type genericIEvFunction = (
|
||||||
|
array<InternalExpressionValue.t>,
|
||||||
|
InternalExpressionValue.environment,
|
||||||
|
) => result<InternalExpressionValue.t, Reducer_ErrorValue.errorValue>
|
|
@ -250,7 +250,7 @@ float 'float'
|
||||||
d = [0-9]
|
d = [0-9]
|
||||||
|
|
||||||
boolean 'boolean'
|
boolean 'boolean'
|
||||||
= ('true'/'false')
|
= ('true'/'false') ! [a-z]i ! [_$]
|
||||||
{ return h.nodeBoolean(text() === 'true')}
|
{ return h.nodeBoolean(text() === 'true')}
|
||||||
|
|
||||||
valueConstructor
|
valueConstructor
|
||||||
|
|
|
@ -38,3 +38,12 @@ let fromTypeExpression = (
|
||||||
(reducerFn: ExpressionT.reducerFn),
|
(reducerFn: ExpressionT.reducerFn),
|
||||||
)->Belt.Result.map(T.fromIEvValue)
|
)->Belt.Result.map(T.fromIEvValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let fromTypeExpressionExn = (
|
||||||
|
typeExpressionSourceCode: string,
|
||||||
|
reducerFn: ExpressionT.reducerFn,
|
||||||
|
): T.t =>
|
||||||
|
switch fromTypeExpression(typeExpressionSourceCode, reducerFn) {
|
||||||
|
| Ok(value) => value
|
||||||
|
| _ => `Cannot compile ${typeExpressionSourceCode}`->Reducer_Exception.ImpossibleException->raise
|
||||||
|
}
|
||||||
|
|
|
@ -7,12 +7,17 @@ open InternalExpressionValue
|
||||||
let rec isITypeOf = (anIType: T.iType, aValue): result<bool, T.typeErrorValue> => {
|
let rec isITypeOf = (anIType: T.iType, aValue): result<bool, T.typeErrorValue> => {
|
||||||
let caseTypeIdentifier = (anUpperTypeName, aValue) => {
|
let caseTypeIdentifier = (anUpperTypeName, aValue) => {
|
||||||
let aTypeName = anUpperTypeName->Js.String2.toLowerCase
|
let aTypeName = anUpperTypeName->Js.String2.toLowerCase
|
||||||
|
switch aTypeName {
|
||||||
|
| "any" => Ok(true)
|
||||||
|
| _ => {
|
||||||
let valueTypeName = aValue->valueToValueType->valueTypeToString->Js.String2.toLowerCase
|
let valueTypeName = aValue->valueToValueType->valueTypeToString->Js.String2.toLowerCase
|
||||||
switch aTypeName == valueTypeName {
|
switch aTypeName == valueTypeName {
|
||||||
| true => Ok(true)
|
| true => Ok(true)
|
||||||
| false => T.TypeMismatch(anIType, aValue)->Error
|
| false => T.TypeMismatch(anIType, aValue)->Error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let caseRecord = (anIType, propertyMap: Belt.Map.String.t<T.iType>, evValue) =>
|
let caseRecord = (anIType, propertyMap: Belt.Map.String.t<T.iType>, evValue) =>
|
||||||
switch evValue {
|
switch evValue {
|
||||||
|
@ -149,6 +154,13 @@ let checkITypeArguments = (anIType: T.iType, args: array<InternalExpressionValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let checkITypeArgumentsBool = (anIType: T.iType, args: array<InternalExpressionValue.t>): bool => {
|
||||||
|
switch checkITypeArguments(anIType, args) {
|
||||||
|
| Ok(_) => true
|
||||||
|
| _ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let checkArguments = (
|
let checkArguments = (
|
||||||
typeExpressionSourceCode: string,
|
typeExpressionSourceCode: string,
|
||||||
args: array<InternalExpressionValue.t>,
|
args: array<InternalExpressionValue.t>,
|
||||||
|
|
|
@ -2,7 +2,7 @@ module Bindings = Reducer_Bindings
|
||||||
|
|
||||||
let bindings: Bindings.t =
|
let bindings: Bindings.t =
|
||||||
[
|
[
|
||||||
("System.version", ReducerInterface_InternalExpressionValue.IEvString("0.3.0")),
|
("System.version", ReducerInterface_InternalExpressionValue.IEvString("0.3.1")),
|
||||||
]->Bindings.fromArray
|
]->Bindings.fromArray
|
||||||
|
|
||||||
let makeBindings = (previousBindings: Bindings.t): Bindings.t =>
|
let makeBindings = (previousBindings: Bindings.t): Bindings.t =>
|
||||||
|
|
|
@ -220,6 +220,7 @@ module I = {
|
||||||
let increment = n => n + 1
|
let increment = n => n + 1
|
||||||
let decrement = n => n - 1
|
let decrement = n => n - 1
|
||||||
let toString = Js.Int.toString
|
let toString = Js.Int.toString
|
||||||
|
let toFloat = Js.Int.toFloat
|
||||||
}
|
}
|
||||||
|
|
||||||
exception Assertion(string)
|
exception Assertion(string)
|
||||||
|
@ -572,10 +573,20 @@ module A = {
|
||||||
|> (x => Ok(x))
|
|> (x => Ok(x))
|
||||||
}
|
}
|
||||||
|
|
||||||
let getByOpen = (a, op, bin) =>
|
let getByFmap = (a, fn, boolCondition) => {
|
||||||
switch getBy(a, r => bin(op(r))) {
|
let i = ref(0)
|
||||||
| Some(r) => Some(op(r))
|
let finalFunctionValue = ref(None)
|
||||||
| None => None
|
let length = Belt.Array.length(a)
|
||||||
|
|
||||||
|
while i.contents < length && finalFunctionValue.contents == None {
|
||||||
|
let itemWithFnApplied = Belt.Array.getUnsafe(a, i.contents) |> fn
|
||||||
|
if boolCondition(itemWithFnApplied) {
|
||||||
|
finalFunctionValue := Some(itemWithFnApplied)
|
||||||
|
}
|
||||||
|
i := i.contents + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
finalFunctionValue.contents
|
||||||
}
|
}
|
||||||
|
|
||||||
let tail = Belt.Array.sliceToEnd(_, 1)
|
let tail = Belt.Array.sliceToEnd(_, 1)
|
||||||
|
@ -680,7 +691,7 @@ module A = {
|
||||||
let firstSome = x => Belt.Array.getBy(x, O.isSome)
|
let firstSome = x => Belt.Array.getBy(x, O.isSome)
|
||||||
|
|
||||||
let firstSomeFn = (r: array<unit => option<'a>>): option<'a> =>
|
let firstSomeFn = (r: array<unit => option<'a>>): option<'a> =>
|
||||||
O.flatten(getByOpen(r, l => l(), O.isSome))
|
O.flatten(getByFmap(r, l => l(), O.isSome))
|
||||||
|
|
||||||
let firstSomeFnWithDefault = (r, default) => firstSomeFn(r)->O2.default(default)
|
let firstSomeFnWithDefault = (r, default) => firstSomeFn(r)->O2.default(default)
|
||||||
|
|
||||||
|
|
|
@ -38,3 +38,12 @@ module Logistic = {
|
||||||
@module external variance: (float, float) => float = "@stdlib/stats/base/dists/logistic/variance"
|
@module external variance: (float, float) => float = "@stdlib/stats/base/dists/logistic/variance"
|
||||||
let variance = variance
|
let variance = variance
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module Random = {
|
||||||
|
type sampleArgs = {
|
||||||
|
probs: array<float>,
|
||||||
|
size: int,
|
||||||
|
}
|
||||||
|
@module external sample: (array<float>, sampleArgs) => array<float> = "@stdlib/random/sample"
|
||||||
|
let sample = sample
|
||||||
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ module.exports = {
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
extensions: [".tsx", ".ts", ".js"],
|
extensions: [".tsx", ".ts", ".js"],
|
||||||
|
fallback: { buffer: ["@stdlib/buffer"] },
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
filename: "bundle.js",
|
filename: "bundle.js",
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
{
|
|
||||||
"root": true,
|
|
||||||
"parser": "@typescript-eslint/parser",
|
|
||||||
"parserOptions": {
|
|
||||||
"ecmaVersion": 6,
|
|
||||||
"sourceType": "module"
|
|
||||||
},
|
|
||||||
"plugins": ["@typescript-eslint"],
|
|
||||||
"rules": {
|
|
||||||
"@typescript-eslint/naming-convention": "warn",
|
|
||||||
"@typescript-eslint/semi": "warn",
|
|
||||||
"curly": "warn",
|
|
||||||
"eqeqeq": "warn",
|
|
||||||
"no-throw-literal": "warn",
|
|
||||||
"semi": "off"
|
|
||||||
},
|
|
||||||
"ignorePatterns": ["out", "dist", "**/*.d.ts"]
|
|
||||||
}
|
|
3
packages/vscode-ext/.prettierignore
Normal file
3
packages/vscode-ext/.prettierignore
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
out
|
||||||
|
dist
|
||||||
|
media/vendor
|
|
@ -7,7 +7,7 @@
|
||||||
"publisher": "QURI",
|
"publisher": "QURI",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/quantified-uncertainty/squiggle.git"
|
"url": "https://github.com/quantified-uncertainty/squiggle.git"
|
||||||
},
|
},
|
||||||
"icon": "media/vendor/icon.png",
|
"icon": "media/vendor/icon.png",
|
||||||
"engines": {
|
"engines": {
|
||||||
|
@ -121,20 +121,17 @@
|
||||||
"compile": "yarn run compile:vendor && yarn run compile:grammar && yarn run compile:tsc",
|
"compile": "yarn run compile:vendor && yarn run compile:grammar && yarn run compile:tsc",
|
||||||
"watch": "tsc -b -watch",
|
"watch": "tsc -b -watch",
|
||||||
"pretest": "yarn run compile && yarn run lint",
|
"pretest": "yarn run compile && yarn run lint",
|
||||||
"lint": "eslint client/src server/src --ext ts",
|
"lint": "prettier --check .",
|
||||||
"format": "eslint client/src server/src --ext ts --fix",
|
"format": "prettier --write .",
|
||||||
"package": "npx vsce package --yarn"
|
"package": "npx vsce package --yarn"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/glob": "^7.2.0",
|
"@types/glob": "^7.2.0",
|
||||||
"@types/node": "18.x",
|
"@types/node": "18.x",
|
||||||
"@types/vscode": "^1.70.0",
|
"@types/vscode": "^1.70.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.32.0",
|
|
||||||
"@typescript-eslint/parser": "^5.32.0",
|
|
||||||
"eslint": "^8.21.0",
|
|
||||||
"glob": "^8.0.3",
|
"glob": "^8.0.3",
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
"typescript": "^4.7.4",
|
"typescript": "^4.8.2",
|
||||||
"vsce-yarn-patch": "^1.66.2"
|
"vsce-yarn-patch": "^1.66.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
|
@ -290,12 +290,29 @@ quantile: (distribution, number) => number
|
||||||
quantile(normal(5, 2), 0.5);
|
quantile(normal(5, 2), 0.5);
|
||||||
```
|
```
|
||||||
|
|
||||||
### truncateLeft
|
### truncate
|
||||||
|
|
||||||
Truncates the left side of a distribution. Returns either a pointSet distribution or a symbolic distribution.
|
Truncates both the left side and the right side of a distribution.
|
||||||
|
|
||||||
```
|
```
|
||||||
truncateLeft: (distribution, l => number) => distribution
|
truncate: (distribution, left: number, right: number) => distribution
|
||||||
|
```
|
||||||
|
|
||||||
|
<Admonition type="note" title="Implementation Details">
|
||||||
|
<p>
|
||||||
|
Sample set distributions are truncated by filtering samples, but point set
|
||||||
|
distributions are truncated using direct geometric manipulation. Uniform
|
||||||
|
distributions are truncated symbolically. Symbolic but non-uniform
|
||||||
|
distributions get converted to Point Set distributions.
|
||||||
|
</p>
|
||||||
|
</Admonition>
|
||||||
|
|
||||||
|
### truncateLeft
|
||||||
|
|
||||||
|
Truncates the left side of a distribution.
|
||||||
|
|
||||||
|
```
|
||||||
|
truncateLeft: (distribution, left: number) => distribution
|
||||||
```
|
```
|
||||||
|
|
||||||
**Examples**
|
**Examples**
|
||||||
|
@ -306,10 +323,10 @@ truncateLeft(normal(5, 2), 3);
|
||||||
|
|
||||||
### truncateRight
|
### truncateRight
|
||||||
|
|
||||||
Truncates the right side of a distribution. Returns either a pointSet distribution or a symbolic distribution.
|
Truncates the right side of a distribution.
|
||||||
|
|
||||||
```
|
```
|
||||||
truncateRight: (distribution, r => number) => distribution
|
truncateRight: (distribution, right: number) => distribution
|
||||||
```
|
```
|
||||||
|
|
||||||
**Examples**
|
**Examples**
|
||||||
|
@ -388,7 +405,7 @@ The only functions that do not return normalized distributions are the pointwise
|
||||||
|
|
||||||
### normalize
|
### normalize
|
||||||
|
|
||||||
Normalize a distribution. This means scaling it appropriately so that it's cumulative sum is equal to 1. This only impacts Pointset distributions, because those are the only ones that can be non-normlized.
|
Normalize a distribution. This means scaling it appropriately so that it's cumulative sum is equal to 1. This only impacts Point Set distributions, because those are the only ones that can be non-normlized.
|
||||||
|
|
||||||
```
|
```
|
||||||
normalize: (distribution) => distribution
|
normalize: (distribution) => distribution
|
||||||
|
|
|
@ -46,3 +46,13 @@ PointSet.makeDiscrete([
|
||||||
{ x: 3, y: 0.1 },
|
{ x: 3, y: 0.1 },
|
||||||
]);
|
]);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### mapY
|
||||||
|
|
||||||
|
```
|
||||||
|
PointSet.mapY: (pointSetDist, (number => number)) => pointSetDist
|
||||||
|
```
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
normal(5,3) |> PointSet.fromDist |> PointSet.mapY({|x| x ^ 2}) |> normalize
|
||||||
|
```
|
||||||
|
|
|
@ -52,6 +52,29 @@ const config = {
|
||||||
themeConfig:
|
themeConfig:
|
||||||
/** @type {import('@docusaurus/preset-classic').ThemeConfig} */
|
/** @type {import('@docusaurus/preset-classic').ThemeConfig} */
|
||||||
({
|
({
|
||||||
|
algolia: {
|
||||||
|
// The application ID provided by Algolia
|
||||||
|
appId: "KBED3M1CMD",
|
||||||
|
|
||||||
|
// Public API key: it is safe to commit it
|
||||||
|
apiKey: "c61bc7603893cf287ed6971983af8bad",
|
||||||
|
|
||||||
|
indexName: "squiggle_docs",
|
||||||
|
|
||||||
|
// Optional: see doc section below
|
||||||
|
contextualSearch: true,
|
||||||
|
|
||||||
|
// Optional: Specify domains where the navigation should occur through window.location instead on history.push. Useful when our Algolia config crawls multiple documentation sites and we want to navigate with window.location.href to them.
|
||||||
|
// externalUrlRegex: 'external\\.com|domain\\.com',
|
||||||
|
|
||||||
|
// Optional: Algolia search parameters
|
||||||
|
searchParameters: {},
|
||||||
|
|
||||||
|
// Optional: path for search page that enabled by default (`false` to disable it)
|
||||||
|
searchPagePath: "search",
|
||||||
|
|
||||||
|
//... other Algolia params
|
||||||
|
},
|
||||||
navbar: {
|
navbar: {
|
||||||
title: "Squiggle",
|
title: "Squiggle",
|
||||||
hideOnScroll: true,
|
hideOnScroll: true,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "squiggle-website",
|
"name": "squiggle-website",
|
||||||
"version": "0.2.1",
|
"version": "0.3.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -15,7 +15,7 @@
|
||||||
"@docusaurus/core": "2.0.1",
|
"@docusaurus/core": "2.0.1",
|
||||||
"@docusaurus/preset-classic": "2.0.1",
|
"@docusaurus/preset-classic": "2.0.1",
|
||||||
"@heroicons/react": "^1.0.6",
|
"@heroicons/react": "^1.0.6",
|
||||||
"@quri/squiggle-components": "^0.2.23",
|
"@quri/squiggle-components": "^0.3",
|
||||||
"base64-js": "^1.5.1",
|
"base64-js": "^1.5.1",
|
||||||
"clsx": "^1.2.1",
|
"clsx": "^1.2.1",
|
||||||
"hast-util-is-element": "2.1.2",
|
"hast-util-is-element": "2.1.2",
|
||||||
|
|
Loading…
Reference in New Issue
Block a user