Merge remote-tracking branch 'origin/develop' into sampleset-mixture

This commit is contained in:
Quinn Dougherty 2022-09-01 12:39:55 +08:00
commit 729fc2c59d
36 changed files with 2396 additions and 2118 deletions

87
.github/workflows/ci-cachix.yml vendored Normal file
View 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

View File

@ -10,6 +10,7 @@ on:
- master
- develop
- reducer-dev
- epic-reducer-project
jobs:
pre_check:
@ -48,26 +49,26 @@ jobs:
with:
paths: '["packages/cli/**"]'
lang-lint:
name: Language lint
runs-on: ubuntu-latest
needs: pre_check
if: ${{ needs.pre_check.outputs.should_skip_lang != 'true' }}
defaults:
run:
shell: bash
working-directory: packages/squiggle-lang
steps:
- uses: actions/checkout@v3
- name: Install Dependencies
run: cd ../../ && yarn
- name: Check rescript lint
run: yarn lint:rescript
- name: Check javascript, typescript, and markdown lint
uses: creyD/prettier_action@v4.2
with:
dry: true
prettier_options: --check packages/squiggle-lang
# lang-lint:
# name: Language lint
# runs-on: ubuntu-latest
# needs: pre_check
# if: ${{ needs.pre_check.outputs.should_skip_lang != 'true' }}
# defaults:
# run:
# shell: bash
# working-directory: packages/squiggle-lang
# steps:
# - uses: actions/checkout@v3
# - name: Install Dependencies
# run: cd ../../ && yarn
# - name: Check rescript lint
# run: yarn lint:rescript
# - name: Check javascript, typescript, and markdown lint
# uses: creyD/prettier_action@v4.2
# with:
# dry: true
# prettier_options: --check packages/squiggle-lang
lang-build-test-bundle:
name: Language build, test, and bundle
@ -97,95 +98,96 @@ jobs:
- name: Upload typescript coverage report
run: yarn coverage:ts:ci
components-lint:
name: Components lint
runs-on: ubuntu-latest
needs: pre_check
if: ${{ needs.pre_check.outputs.should_skip_components != 'true' }}
defaults:
run:
shell: bash
working-directory: packages/components
steps:
- uses: actions/checkout@v3
- name: Check javascript, typescript, and markdown lint
uses: creyD/prettier_action@v4.2
with:
dry: true
prettier_options: --check packages/components --ignore-path packages/components/.prettierignore
# components-lint:
# name: Components lint
# runs-on: ubuntu-latest
# needs: pre_check
# if: ${{ needs.pre_check.outputs.should_skip_components != 'true' }}
# defaults:
# run:
# shell: bash
# working-directory: packages/components
# steps:
# - uses: actions/checkout@v3
# - name: Check javascript, typescript, and markdown lint
# uses: creyD/prettier_action@v4.2
# with:
# dry: true
# 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:
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
website-lint:
name: Website lint
runs-on: ubuntu-latest
needs: pre_check
if: ${{ needs.pre_check.outputs.should_skip_website != 'true' }}
defaults:
run:
shell: bash
working-directory: packages/website
steps:
- uses: actions/checkout@v3
- name: Check javascript, typescript, and markdown lint
uses: creyD/prettier_action@v4.2
with:
dry: true
prettier_options: --check packages/website
website-build:
name: Website build
runs-on: ubuntu-latest
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') }}
defaults:
run:
shell: bash
working-directory: packages/website
steps:
- uses: actions/checkout@v3
- name: Install dependencies from monorepo level
run: cd ../../ && yarn
- name: Build rescript in squiggle-lang
run: cd ../squiggle-lang && yarn build
- name: Build components
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
# website-lint:
# name: Website lint
# runs-on: ubuntu-latest
# needs: pre_check
# if: ${{ needs.pre_check.outputs.should_skip_website != 'true' }}
# defaults:
# run:
# shell: bash
# working-directory: packages/website
# steps:
# - uses: actions/checkout@v3
# - name: Check javascript, typescript, and markdown lint
# uses: creyD/prettier_action@v4.2
# with:
# dry: true
# prettier_options: --check packages/website
#
# website-build:
# name: Website build
# runs-on: ubuntu-latest
# 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') }}
# defaults:
# run:
# shell: bash
# working-directory: packages/website
# steps:
# - uses: actions/checkout@v3
# - name: Install dependencies from monorepo level
# run: cd ../../ && yarn
# - name: Build rescript in squiggle-lang
# run: cd ../squiggle-lang && yarn build
# - name: Build components
# 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: Check javascript, typescript, and markdown lint
# uses: creyD/prettier_action@v4.2
# with:
# dry: true
# prettier_options: --check packages/vscode-ext
vscode-ext-build:
name: VS Code extension build
@ -203,19 +205,19 @@ jobs:
- name: Build
run: yarn compile
cli-lint:
name: CLI lint
runs-on: ubuntu-latest
needs: pre_check
if: ${{ needs.pre_check.outputs.should_skip_cli != 'true' }}
defaults:
run:
shell: bash
working-directory: packages/cli
steps:
- uses: actions/checkout@v3
- name: Check javascript, typescript, and markdown lint
uses: creyD/prettier_action@v4.2
with:
dry: true
prettier_options: --check packages/cli
# cli-lint:
# name: CLI lint
# runs-on: ubuntu-latest
# needs: pre_check
# if: ${{ needs.pre_check.outputs.should_skip_cli != 'true' }}
# defaults:
# run:
# shell: bash
# working-directory: packages/cli
# steps:
# - uses: actions/checkout@v3
# - name: Check javascript, typescript, and markdown lint
# uses: creyD/prettier_action@v4.2
# with:
# dry: true
# prettier_options: --check packages/cli

View File

@ -3,7 +3,7 @@ name: Run Release Please
on:
push:
branches:
- develop
- master
jobs:
pre_check:
@ -55,21 +55,22 @@ jobs:
token: ${{secrets.GITHUB_TOKEN}}
command: manifest-pr
path: packages/squiggle-lang
bump-patch-for-minor-pre-major: true
# bump-patch-for-minor-pre-major: true
skip-github-release: true
# - name: Publish: Checkout source
# uses: actions/checkout@v2
# # these if statements ensure that a publication only occurs when
# # a new release is created:
# if: ${{ steps.release.outputs.release_created }}
# - name: Publish: Install dependencies
# run: yarn
# if: ${{ steps.release.outputs.release_created }}
# - name: Publish
# run: cd packages/squiggle-lang && yarn publish
# env:
# NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
# if: ${{ steps.release.outputs.release_created }}
- name: Publish- Checkout source
uses: actions/checkout@v3
# these if statements ensure that a publication only occurs when
# a new release is created:
if: ${{ steps.release.outputs.release_created }}
- name: Publish- Install dependencies
run: yarn
if: ${{ steps.release.outputs.release_created }}
- name: Publish
run: cd packages/squiggle-lang && yarn publish
env:
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
if: ${{ steps.release.outputs.release_created }}
relplz-components:
name: for components
runs-on: ubuntu-latest
@ -82,20 +83,20 @@ jobs:
token: ${{secrets.GITHUB_TOKEN}}
command: manifest-pr
path: packages/components
bump-patch-for-minor-pre-major: true
# bump-patch-for-minor-pre-major: true
skip-github-release: true
# - name: Publish: Checkout source
# uses: actions/checkout@v2
# # these if statements ensure that a publication only occurs when
# # a new release is created:
# if: ${{ steps.release.outputs.release_created }}
# - name: Publish: Install dependencies
# run: yarn
# if: ${{ steps.release.outputs.release_created }}
# - name: Publish
# run: cd packages/components && yarn publish
# env:
# NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
- name: Publish- Checkout source
uses: actions/checkout@v3
# these if statements ensure that a publication only occurs when
# a new release is created:
if: ${{ steps.release.outputs.release_created }}
- name: Publish- Install dependencies
run: yarn
if: ${{ steps.release.outputs.release_created }}
- name: Publish
run: cd packages/components && yarn publish
env:
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
relplz-website:
name: for website
runs-on: ubuntu-latest
@ -108,7 +109,7 @@ jobs:
token: ${{secrets.GITHUB_TOKEN}}
command: manifest-pr
path: packages/website
bump-patch-for-minor-pre-major: true
# bump-patch-for-minor-pre-major: true
skip-github-release: true
relplz-vscodeext:
name: for vscode-ext
@ -122,7 +123,7 @@ jobs:
token: ${{secrets.GITHUB_TOKEN}}
command: manifest-pr
path: packages/vscode-ext
bump-patch-for-minor-pre-major: true
# bump-patch-for-minor-pre-major: true
skip-github-release: true
relplz-cl:
name: for cli

1
.gitignore vendored
View File

@ -7,3 +7,4 @@ yarn-error.log
**/.sync.ffs_db
.direnv
.log
result

View File

@ -1,15 +1,16 @@
.direnv
*.bs.js
*.gen.tsx
packages/*/dist
packages/components/storybook-static
node_modules
packages/*/node_modules
packages/website/.docusaurus
packages/squiggle-lang/lib
packages/squiggle-lang/.nyc_output/
packages/squiggle-lang/coverage/
packages/squiggle-lang/.cache/
packages/website/build/
packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_GeneratedParser.js
packages/vscode-ext/media/vendor/
packages/squiggle-lang/.nyc_output/
packages/*/dist
result

79
flake.lock Normal file
View 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
View 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
View 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
View 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
View 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";
};
}

View 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
View 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
View 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
View 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";
};
}

View File

@ -5,14 +5,14 @@
# We need to patchelf rescript executables. https://github.com/NixOS/nixpkgs/issues/107375
set -x
fhsShellName="squiggle-development"
fhsShellDotNix="{pkgs ? import <nixpkgs> {} }: (pkgs.buildFHSUserEnv { name = \"${fhsShellName}\"; targetPkgs = pkgs: [pkgs.yarn]; runScript = \"yarn\"; }).env"
fhsShellName="squiggle-fhs-development"
fhsShellDotNix="{pkgs ? import <nixpkgs> {} }: (pkgs.buildFHSUserEnv { name = \"${fhsShellName}\"; targetPkgs = pkgs: [pkgs.yarn pkgs.glibc]; runScript = \"yarn\"; }).env"
nix-shell - <<<"$fhsShellDotNix"
theLd=$(patchelf --print-interpreter $(which mkdir))
patchelf --set-interpreter $theLd ./node_modules/gentype/gentype.exe
patchelf --set-interpreter $theLd ./node_modules/rescript/linux/*.exe
patchelf --set-interpreter $theLd ./node_modules/bisect_ppx/ppx
patchelf --set-interpreter $theLd ./node_moduels/bisect_ppx/bisect-ppx-report
theSo=$(find /nix/store/*$fhsShellName*/lib64 -name libstdc++.so.6 | grep $fhsShellName | head -n 1)
patchelf --set-interpreter $theLd ./node_modules/bisect_ppx/bisect-ppx-report
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

View File

@ -4,23 +4,23 @@
"license": "MIT",
"dependencies": {
"@floating-ui/react-dom": "^1.0.0",
"@floating-ui/react-dom-interactions": "^0.9.2",
"@floating-ui/react-dom-interactions": "^0.9.3",
"@headlessui/react": "^1.6.6",
"@heroicons/react": "^1.0.6",
"@hookform/resolvers": "^2.9.7",
"@quri/squiggle-lang": "^0.3.0",
"@react-hook/size": "^2.1.2",
"clsx": "^1.2.1",
"framer-motion": "^7.1.1",
"framer-motion": "^7.2.1",
"lodash": "^4.17.21",
"react": "^18.1.0",
"react-ace": "^10.1.0",
"react-hook-form": "^7.34.1",
"react-hook-form": "^7.34.2",
"react-use": "^17.4.0",
"react-vega": "^7.6.0",
"vega": "^5.22.1",
"vega-embed": "^6.21.0",
"vega-lite": "^5.4.0",
"vega-lite": "^5.5.0",
"vscode-uri": "^3.0.3",
"yup": "^0.32.11"
},
@ -38,8 +38,8 @@
"@testing-library/react": "^13.3.0",
"@testing-library/user-event": "^14.4.3",
"@types/jest": "^27.5.0",
"@types/lodash": "^4.14.182",
"@types/node": "^18.7.4",
"@types/lodash": "^4.14.184",
"@types/node": "^18.7.13",
"@types/react": "^18.0.9",
"@types/styled-components": "^5.1.26",
"@types/webpack": "^5.28.0",
@ -54,8 +54,8 @@
"tailwindcss": "^3.1.8",
"ts-loader": "^9.3.0",
"tsconfig-paths-webpack-plugin": "^4.0.0",
"typescript": "^4.7.4",
"web-vitals": "^2.1.4",
"typescript": "^4.8.2",
"web-vitals": "^3.0.0",
"webpack": "^5.74.0",
"webpack-cli": "^4.10.0",
"webpack-dev-server": "^4.10.0"

View File

@ -231,7 +231,7 @@ export const PlaygroundContext = React.createContext<PlaygroundContextShape>({
export const SquigglePlayground: FC<PlaygroundProps> = ({
defaultCode = "",
height = 500,
showSummary = false,
showSummary = true,
logX = false,
expY = false,
title,

View File

@ -1,8 +1,8 @@
import clsx from "clsx";
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,
label,
register,

View File

@ -1,7 +1,7 @@
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,
label,
type,

View 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),
)
})

View File

@ -74,6 +74,7 @@ describe("eval on distribution functions", () => {
testEval("truncateLeft(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) |> SampleSet.fromDist, 3, 8)", "Ok(Sample Set Distribution)")
testEval("isNormalized(truncate(normal(5,2), 3, 8))", "Ok(true)")
})

View File

@ -45,18 +45,18 @@
"@stdlib/stats": "^0.0.13",
"jstat": "^1.9.5",
"lodash": "^4.17.21",
"mathjs": "^11.0.1",
"mathjs": "^11.1.0",
"pdfast": "^0.2.0"
},
"devDependencies": {
"@glennsl/rescript-jest": "^0.9.0",
"@glennsl/rescript-jest": "^0.9.2",
"@istanbuljs/nyc-config-typescript": "^1.0.2",
"@types/jest": "^27.5.0",
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.2",
"bisect_ppx": "^2.7.1",
"chalk": "^5.0.1",
"codecov": "^3.8.3",
"fast-check": "^3.1.1",
"fast-check": "^3.1.2",
"gentype": "^4.5.0",
"jest": "^27.5.1",
"moduleserve": "^0.9.1",
@ -69,7 +69,7 @@
"ts-jest": "^27.1.4",
"ts-loader": "^9.3.0",
"ts-node": "^10.9.1",
"typescript": "^4.7.4",
"typescript": "^4.8.2",
"webpack": "^5.74.0",
"webpack-cli": "^4.10.0"
},

View File

@ -40,8 +40,8 @@ export type { result, shape, environment, lambdaValue, squiggleExpression };
export { parse } from "./parse";
export let defaultSamplingInputs: environment = {
sampleCount: 10000,
xyPointLength: 10000,
sampleCount: 1000,
xyPointLength: 1000,
};
export function run(

View File

@ -242,6 +242,13 @@ module Truncate = {
switch trySymbolicSimplification(leftCutoff, rightCutoff, t) {
| Some(r) => Ok(r)
| 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 => {
DistributionTypes.PointSet(
PointSetDist.T.truncate(leftCutoff, rightCutoff, t)->PointSetDist.T.normalize,
@ -250,6 +257,7 @@ module Truncate = {
}
}
}
}
}
let truncate = Truncate.run

View File

@ -150,3 +150,12 @@ let mixture = (values: array<(t, float)>, intendedLength: int) => {
->E.A.O.openIfAllSome
(samples |> E.O.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)
}

View File

@ -23,6 +23,30 @@ let inputsTodist = (inputs: array<FunctionRegistry_Core.frValue>, makeDist) => {
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 = [
Function.make(
~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(
~name="makeContinuous",
~nameSpace,

View File

@ -92,7 +92,7 @@ let library = [
GenericDist.toSampleSetDist(dist, env.sampleCount)
->E.R2.fmap(Wrappers.sampleSet)
->E.R2.fmap(Wrappers.evDistribution)
->E.R2.errMap(_ => "")
->E.R2.errMap(DistributionTypes.Error.toString)
| _ => Error(impossibleError)
},
(),
@ -158,7 +158,7 @@ let library = [
| [IEvLambda(lambda)] =>
switch Internal.fromFn(lambda, env, reducer) {
| Ok(r) => Ok(r->Wrappers.sampleSet->Wrappers.evDistribution)
| Error(_) => Error("issue")
| Error(e) => Error(Operation.Error.toString(e))
}
| _ => Error(impossibleError)
},
@ -180,7 +180,7 @@ let library = [
~run=(inputs, _, env, reducer) =>
switch inputs {
| [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)
},
(),
@ -207,7 +207,9 @@ let library = [
IEvDistribution(SampleSet(dist2)),
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)
}
},
@ -236,7 +238,9 @@ let library = [
IEvDistribution(SampleSet(dist3)),
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)
},
(),
@ -259,9 +263,9 @@ let library = [
~run=(inputs, _, env, reducer) =>
switch inputs {
| [IEvArray(dists), IEvLambda(lambda)] =>
Internal.mapN(dists, lambda, env, reducer)->E.R2.errMap(_e => {
"AHHH doesn't work"
})
Internal.mapN(dists, lambda, env, reducer)->E.R2.errMap(
Reducer_ErrorValue.errorToString,
)
| _ => Error(impossibleError)
},
(),

View File

@ -250,7 +250,7 @@ float 'float'
d = [0-9]
boolean 'boolean'
= ('true'/'false')
= ('true'/'false') ! [a-z]i ! [_$]
{ return h.nodeBoolean(text() === 'true')}
valueConstructor

View File

@ -573,10 +573,20 @@ module A = {
|> (x => Ok(x))
}
let getByOpen = (a, op, bin) =>
switch getBy(a, r => bin(op(r))) {
| Some(r) => Some(op(r))
| None => None
let getByFmap = (a, fn, boolCondition) => {
let i = ref(0)
let finalFunctionValue = ref(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)
@ -681,7 +691,7 @@ module A = {
let firstSome = x => Belt.Array.getBy(x, O.isSome)
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)

View File

@ -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"]
}

View File

@ -0,0 +1,3 @@
out
dist
media/vendor

View File

@ -7,7 +7,7 @@
"publisher": "QURI",
"repository": {
"type": "git",
"url": "git+https://github.com/quantified-uncertainty/squiggle.git"
"url": "https://github.com/quantified-uncertainty/squiggle.git"
},
"icon": "media/vendor/icon.png",
"engines": {
@ -121,20 +121,17 @@
"compile": "yarn run compile:vendor && yarn run compile:grammar && yarn run compile:tsc",
"watch": "tsc -b -watch",
"pretest": "yarn run compile && yarn run lint",
"lint": "eslint client/src server/src --ext ts",
"format": "eslint client/src server/src --ext ts --fix",
"lint": "prettier --check .",
"format": "prettier --write .",
"package": "npx vsce package --yarn"
},
"devDependencies": {
"@types/glob": "^7.2.0",
"@types/node": "18.x",
"@types/vscode": "^1.70.0",
"@typescript-eslint/eslint-plugin": "^5.33.1",
"@typescript-eslint/parser": "^5.33.0",
"eslint": "^8.22.0",
"glob": "^8.0.3",
"js-yaml": "^4.1.0",
"typescript": "^4.7.4",
"typescript": "^4.8.2",
"vsce-yarn-patch": "^1.66.2"
},
"dependencies": {

View File

@ -290,12 +290,29 @@ quantile: (distribution, number) => number
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**
@ -306,10 +323,10 @@ truncateLeft(normal(5, 2), 3);
### 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**
@ -388,7 +405,7 @@ The only functions that do not return normalized distributions are the pointwise
### 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

View File

@ -46,3 +46,13 @@ PointSet.makeDiscrete([
{ x: 3, y: 0.1 },
]);
```
### mapY
```
PointSet.mapY: (pointSetDist, (number => number)) => pointSetDist
```
```javascript
normal(5,3) |> PointSet.fromDist |> PointSet.mapY({|x| x ^ 2}) |> normalize
```

View File

@ -54,10 +54,10 @@ const config = {
({
algolia: {
// The application ID provided by Algolia
appId: "NEUN2KAR5K",
appId: "KBED3M1CMD",
// Public API key: it is safe to commit it
apiKey: "1f5c74a2d72799add24eb7682531a1b0",
apiKey: "c61bc7603893cf287ed6971983af8bad",
indexName: "squiggle_docs",

3380
yarn.lock

File diff suppressed because it is too large Load Diff