Merge pull request #222 from quantified-uncertainty/quinn-dougherty-patch-1

A couple tiny hotfixes to opsy stuff
This commit is contained in:
Quinn 2022-04-11 19:21:05 -04:00 committed by GitHub
commit 49b9801006
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 269 additions and 224 deletions

18
.github/CODEOWNERS vendored
View File

@ -8,15 +8,23 @@
# IMPORTANT NOTE: in order to actually get pinged, commit access is required. # IMPORTANT NOTE: in order to actually get pinged, commit access is required.
# This also holds true for GitHub teams. # This also holds true for GitHub teams.
# This file # Rescript
/.github/CODEOWNERS @quinn-dougherty
# Any rescript code
*.res @Hazelfire @OAGr @quinn-dougherty *.res @Hazelfire @OAGr @quinn-dougherty
*.resi @Hazelfire @OAGr @quinn-dougherty
# Any typescript code # Typescript
*.tsx @Hazelfire @OAGr *.tsx @Hazelfire @OAGr
*.ts @Hazelfire @OAGr
# Javascript
*.js @Hazelfire
# Any opsy files # Any opsy files
.github/* @quinn-dougherty
*.json @quinn-dougherty @Hazelfire *.json @quinn-dougherty @Hazelfire
*.y*ml @quinn-dougherty *.y*ml @quinn-dougherty
*.config.js @Hazelfire
# Documentation
*.md @quinn-dougherty @OAGr @Hazelfire
*.mdx @quinn-dougherty @OAGr @Hazelfire

View File

@ -1,6 +1,6 @@
--- ---
name: Developer friction when contributing to Squiggle name: Developer friction when contributing to Squiggle
about: Did your yarn scripts fail? Did the CI diverge from a README? Have a testing-related task? Etc. about: Have a testing-related task? Did your yarn scripts fail? Did the CI diverge from a README? Etc.
labels: 'ops & testing' labels: 'ops & testing'
--- ---
# Description: # Description:

View File

@ -1,11 +1,12 @@
name: Squiggle packages check name: Squiggle packages check
on: on:
push: # Delete this line if there becomes a scarcity of build minutes.
pull_request: pull_request:
branches: branches:
- master - master
- production
- staging - staging
- develop
jobs: jobs:
@ -33,8 +34,29 @@ jobs:
with: with:
paths: '["packages/website/**"]' paths: '["packages/website/**"]'
lang-build-test: lang-lint:
name: Language build and test 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@v2
- 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 .
lang-build-test-bundle:
name: Language build, test, and bundle
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' }}
@ -53,11 +75,28 @@ jobs:
- name: Run webpack - name: Run webpack
run: yarn bundle run: yarn bundle
components-build-test: components-lint:
name: Components build and test 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:
run:
shell: bash
working-directory: packages/components
steps:
- uses: actions/checkout@v2
- name: Check javascript, typescript, and markdown lint
uses: creyD/prettier_action@v4.2
with:
dry: true
prettier_options: --check .
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: defaults:
run: run:
shell: bash shell: bash
@ -73,11 +112,28 @@ jobs:
- name: Build storybook - name: Build storybook
run: yarn build 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@v2
- name: Check javascript, typescript, and markdown lint
uses: creyD/prettier_action@v4.2
with:
dry: true
prettier_options: --check .
website-build: website-build:
name: Website build name: Website build
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: pre_check needs: pre_check
if: ${{ needs.pre_check.outputs.should_skip_website != 'true' }} 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: defaults:
run: run:
shell: bash shell: bash

View File

@ -15,12 +15,16 @@ on:
push: push:
branches: branches:
- master - master
- production
- staging - staging
- develop
pull_request: pull_request:
# The branches below must be a subset of the branches above # The branches below must be a subset of the branches above
branches: branches:
- master - master
- production
- staging - staging
- develop
schedule: schedule:
- cron: '42 19 * * 0' - cron: '42 19 * * 0'

View File

@ -1,15 +1,18 @@
# Squiggle # Squiggle
![Packages check](https://github.com/QURIresearch/squiggle/actions/workflows/ci.yaml/badge.svg) ![Packages check](https://github.com/QURIresearch/squiggle/actions/workflows/ci.yml/badge.svg)
[![npm version](https://badge.fury.io/js/@quri%2Fsquiggle-lang.svg)](https://www.npmjs.com/package/@quri/squiggle-lang) [![npm version](https://badge.fury.io/js/@quri%2Fsquiggle-lang.svg)](https://www.npmjs.com/package/@quri/squiggle-lang)
[![npm version](https://badge.fury.io/js/@quri%2Fsquiggle-components.svg)](https://www.npmjs.com/package/@quri/squiggle-components) [![npm version](https://badge.fury.io/js/@quri%2Fsquiggle-components.svg)](https://www.npmjs.com/package/@quri/squiggle-components)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/QURIresearch/squiggle/blob/staging/LICENSE)
This is an experimental DSL/language for making probabilistic estimates. The full story can be found [here](https://www.lesswrong.com/s/rDe8QE5NvXcZYzgZ3). This is an experimental DSL/language for making probabilistic estimates. The full story can be found [here](https://www.lesswrong.com/s/rDe8QE5NvXcZYzgZ3).
## Our deployments ## Our deployments
- **website/docs prod**: https://squiggle-language.com - **website/docs prod**: https://squiggle-language.com [![Netlify Status](https://api.netlify.com/api/v1/badges/2139af5c-671d-473d-a9f6-66c96077d8a1/deploy-status)](https://app.netlify.com/sites/squiggle-documentation/deploys)
- **website/docs staging**: https://staging--squiggle-documentation.netlify.app/ - **website/docs staging**: https://staging--squiggle-documentation.netlify.app/
- **old playground**: https://playground.squiggle-language.com - **components storybook prod**: https://squiggle-components.netlify.app/ [![Netlify Status](https://api.netlify.com/api/v1/badges/b7f724aa-6b20-4d0e-bf86-3fcd1a3e9a70/deploy-status)](https://app.netlify.com/sites/squiggle-components/deploys)
- **components storybook staging**: https://staging--squiggle-components.netlify.app/
- **legacy (2020) playground**: https://playground.squiggle-language.com
## Packages ## Packages
This monorepo has several packages that can be used for various purposes. All This monorepo has several packages that can be used for various purposes. All

View File

@ -4,6 +4,9 @@
"scripts": { "scripts": {
"nodeclean": "rm -r node_modules && rm -r packages/*/node_modules" "nodeclean": "rm -r node_modules && rm -r packages/*/node_modules"
}, },
"devDependencies": {
"prettier": "^2.6.2"
},
"workspaces": [ "workspaces": [
"packages/*" "packages/*"
], ],

View File

@ -32,7 +32,9 @@
"start": "cross-env REACT_APP_FAST_REFRESH=false && start-storybook -p 6006 -s public", "start": "cross-env REACT_APP_FAST_REFRESH=false && start-storybook -p 6006 -s public",
"build": "tsc -b && build-storybook -s public", "build": "tsc -b && build-storybook -s public",
"bundle": "webpack", "bundle": "webpack",
"all": "yarn bundle && yarn build" "all": "yarn bundle && yarn build",
"lint": "prettier --check .",
"format": "prettier --write ."
}, },
"eslintConfig": { "eslintConfig": {
"extends": [ "extends": [
@ -76,7 +78,6 @@
"@storybook/preset-create-react-app": "^4.1.0", "@storybook/preset-create-react-app": "^4.1.0",
"@storybook/react": "^6.4.20", "@storybook/react": "^6.4.20",
"@types/webpack": "^4.41.32", "@types/webpack": "^4.41.32",
"prettier": "^2.6.2",
"react-codejar": "^1.1.2", "react-codejar": "^1.1.2",
"ts-loader": "^9.2.8", "ts-loader": "^9.2.8",
"webpack": "^5.72.0", "webpack": "^5.72.0",

41
packages/squiggle-lang/lint.sh Executable file
View File

@ -0,0 +1,41 @@
#!/bin/bash
# Hat tip to @dfalling
# https://forum.rescript-lang.org/t/rescript-9-1-how-can-we-format-to-standard-out/1590/2?u=quinn-dougherty
errors=false
files=`ls src/rescript/**/**/*.res src/rescript/**/*.res src/rescript/*.res`
for file in $files
do
current=`cat $file`
linted=`echo "${current}" | rescript format -stdin .res`
diff=`diff <(echo $current) <(echo $linted)`
if [ ${#diff} -gt 0 ]
then
echo "ERROR: $file doesn't pass lint"
errors=true
fi
done
files=`ls src/rescript/**/**/*.resi src/rescript/**/*.resi` # src/rescript/*/resi
for file in $files
do
current=`cat $file`
linted=`echo "${current}" | rescript format -stdin .resi`
diff=`diff <(echo $current) <(echo $linted)`
if [ ${#diff} -gt 0 ]
then
echo "ERROR: $file doesn't pass lint"
errors=true
fi
done
if $errors
then
exit 1
else
echo "All files pass lint"
fi

View File

@ -11,6 +11,10 @@
"test": "jest", "test": "jest",
"test:watch": "jest --watchAll", "test:watch": "jest --watchAll",
"coverage": "rm -f *.coverage; yarn clean; BISECT_ENABLE=yes yarn build; yarn test; bisect-ppx-report html", "coverage": "rm -f *.coverage; yarn clean; BISECT_ENABLE=yes yarn build; yarn test; bisect-ppx-report html",
"lint:rescript": "./lint.sh",
"lint:prettier": "prettier --check .",
"lint": "yarn lint:rescript && yarn lint:prettier",
"format": "rescript format -all && prettier --write .",
"all": "yarn build && yarn bundle && yarn test" "all": "yarn build && yarn bundle && yarn test"
}, },
"keywords": [ "keywords": [

View File

@ -213,19 +213,20 @@ module SamplingDistribution = {
let i1 = renderIfIsNotSamplingDistribution(evaluationParams, t1) let i1 = renderIfIsNotSamplingDistribution(evaluationParams, t1)
let i2 = renderIfIsNotSamplingDistribution(evaluationParams, t2) let i2 = renderIfIsNotSamplingDistribution(evaluationParams, t2)
E.R.merge(i1, i2) |> E.R.bind(_, ((a, b)) => { E.R.merge(i1, i2) |> E.R.bind(_, ((a, b)) => {
let samples = getCombinationSamples( let samples =
evaluationParams.samplingInputs.sampleCount, getCombinationSamples(
algebraicOp, evaluationParams.samplingInputs.sampleCount,
a, algebraicOp,
b, a,
) |> E.O.toResult("Could not get samples") b,
) |> E.O.toResult("Could not get samples")
let sampleSetDist = samples -> E.R.bind(SampleSetDist.make) let sampleSetDist = samples->E.R.bind(SampleSetDist.make)
let pointSetDist = let pointSetDist =
sampleSetDist sampleSetDist->E.R.bind(r =>
-> E.R.bind(r => SampleSetDist.toPointSetDist(~samplingInputs=evaluationParams.samplingInputs, ~samples=r)
SampleSetDist.toPointSetDist(~samplingInputs=evaluationParams.samplingInputs, ~samples=r)); )
pointSetDist |> E.R.fmap(r => #Normalize(#RenderedDist(r))) pointSetDist |> E.R.fmap(r => #Normalize(#RenderedDist(r)))
}) })
} }

View File

@ -1,116 +1,87 @@
open PointSetTypes; open PointSetTypes
@genType @genType
type t = PointSetTypes.distPlus; type t = PointSetTypes.distPlus
let pointSetDistIntegral = pointSetDist => PointSetDist.T.Integral.get(pointSetDist); let pointSetDistIntegral = pointSetDist => PointSetDist.T.Integral.get(pointSetDist)
let make = let make = (~pointSetDist, ~squiggleString, ()): t => {
( let integral = pointSetDistIntegral(pointSetDist)
~pointSetDist, {pointSetDist: pointSetDist, integralCache: integral, squiggleString: squiggleString}
~squiggleString, }
(),
)
: t => {
let integral = pointSetDistIntegral(pointSetDist);
{pointSetDist, integralCache: integral, squiggleString};
};
let update = let update = (~pointSetDist=?, ~integralCache=?, ~squiggleString=?, t: t) => {
(
~pointSetDist=?,
~integralCache=?,
~squiggleString=?,
t: t,
) => {
pointSetDist: E.O.default(t.pointSetDist, pointSetDist), pointSetDist: E.O.default(t.pointSetDist, pointSetDist),
integralCache: E.O.default(t.integralCache, integralCache), integralCache: E.O.default(t.integralCache, integralCache),
squiggleString: E.O.default(t.squiggleString, squiggleString), squiggleString: E.O.default(t.squiggleString, squiggleString),
}; }
let updateShape = (pointSetDist, t) => { let updateShape = (pointSetDist, t) => {
let integralCache = pointSetDistIntegral(pointSetDist); let integralCache = pointSetDistIntegral(pointSetDist)
update(~pointSetDist, ~integralCache, t); update(~pointSetDist, ~integralCache, t)
}; }
let toPointSetDist = ({pointSetDist, _}: t) => pointSetDist; let toPointSetDist = ({pointSetDist, _}: t) => pointSetDist
let pointSetDistFn = (fn, {pointSetDist}: t) => fn(pointSetDist); let pointSetDistFn = (fn, {pointSetDist}: t) => fn(pointSetDist)
module T = module T = Distributions.Dist({
Distributions.Dist({ type t = PointSetTypes.distPlus
type t = PointSetTypes.distPlus; type integral = PointSetTypes.distPlus
type integral = PointSetTypes.distPlus; let toPointSetDist = toPointSetDist
let toPointSetDist = toPointSetDist; let toContinuous = pointSetDistFn(PointSetDist.T.toContinuous)
let toContinuous = pointSetDistFn(PointSetDist.T.toContinuous); let toDiscrete = pointSetDistFn(PointSetDist.T.toDiscrete)
let toDiscrete = pointSetDistFn(PointSetDist.T.toDiscrete);
let normalize = (t: t): t => { let normalize = (t: t): t => {
let normalizedShape = t |> toPointSetDist |> PointSetDist.T.normalize; let normalizedShape = t |> toPointSetDist |> PointSetDist.T.normalize
t |> updateShape(normalizedShape); t |> updateShape(normalizedShape)
}; }
let truncate = (leftCutoff, rightCutoff, t: t): t => { let truncate = (leftCutoff, rightCutoff, t: t): t => {
let truncatedShape = let truncatedShape = t |> toPointSetDist |> PointSetDist.T.truncate(leftCutoff, rightCutoff)
t
|> toPointSetDist
|> PointSetDist.T.truncate(leftCutoff, rightCutoff);
t |> updateShape(truncatedShape); t |> updateShape(truncatedShape)
}; }
let xToY = (f, t: t) => let xToY = (f, t: t) => t |> toPointSetDist |> PointSetDist.T.xToY(f)
t
|> toPointSetDist
|> PointSetDist.T.xToY(f);
let minX = pointSetDistFn(PointSetDist.T.minX); let minX = pointSetDistFn(PointSetDist.T.minX)
let maxX = pointSetDistFn(PointSetDist.T.maxX); let maxX = pointSetDistFn(PointSetDist.T.maxX)
let toDiscreteProbabilityMassFraction = let toDiscreteProbabilityMassFraction = pointSetDistFn(
pointSetDistFn(PointSetDist.T.toDiscreteProbabilityMassFraction); PointSetDist.T.toDiscreteProbabilityMassFraction,
)
// This bit is kind of awkward, could probably use rethinking. // This bit is kind of awkward, could probably use rethinking.
let integral = (t: t) => let integral = (t: t) => updateShape(Continuous(t.integralCache), t)
updateShape(Continuous(t.integralCache), t);
let updateIntegralCache = (integralCache: option<PointSetTypes.continuousShape>, t) => let updateIntegralCache = (integralCache: option<PointSetTypes.continuousShape>, t) =>
update(~integralCache=E.O.default(t.integralCache, integralCache), t); update(~integralCache=E.O.default(t.integralCache, integralCache), t)
let downsample = (i, t): t => let downsample = (i, t): t => updateShape(t |> toPointSetDist |> PointSetDist.T.downsample(i), t)
updateShape(t |> toPointSetDist |> PointSetDist.T.downsample(i), t); // todo: adjust for limit, maybe?
// todo: adjust for limit, maybe? let mapY = (
let mapY = ~integralSumCacheFn=previousIntegralSum => None,
( ~integralCacheFn=previousIntegralCache => None,
~integralSumCacheFn=previousIntegralSum => None, ~fn,
~integralCacheFn=previousIntegralCache => None, {pointSetDist, _} as t: t,
~fn, ): t => PointSetDist.T.mapY(~integralSumCacheFn, ~fn, pointSetDist) |> updateShape(_, t)
{pointSetDist, _} as t: t,
)
: t =>
PointSetDist.T.mapY(~integralSumCacheFn, ~fn, pointSetDist)
|> updateShape(_, t);
// get the total of everything // get the total of everything
let integralEndY = (t: t) => { let integralEndY = (t: t) => {
PointSetDist.T.Integral.sum( PointSetDist.T.Integral.sum(toPointSetDist(t))
toPointSetDist(t), }
);
};
// TODO: Fix this below, obviously. Adjust for limits // TODO: Fix this below, obviously. Adjust for limits
let integralXtoY = (f, t: t) => { let integralXtoY = (f, t: t) => {
PointSetDist.T.Integral.xToY( PointSetDist.T.Integral.xToY(f, toPointSetDist(t))
f, }
toPointSetDist(t),
)
};
// TODO: This part is broken when there is a limit, if this is supposed to be taken into account. // TODO: This part is broken when there is a limit, if this is supposed to be taken into account.
let integralYtoX = (f, t: t) => { let integralYtoX = (f, t: t) => {
PointSetDist.T.Integral.yToX(f, toPointSetDist(t)); PointSetDist.T.Integral.yToX(f, toPointSetDist(t))
}; }
let mean = (t: t) => { let mean = (t: t) => {
PointSetDist.T.mean(t.pointSetDist); PointSetDist.T.mean(t.pointSetDist)
}; }
let variance = (t: t) => PointSetDist.T.variance(t.pointSetDist); let variance = (t: t) => PointSetDist.T.variance(t.pointSetDist)
}); })

View File

@ -121,17 +121,14 @@ module MathAdtToDistDst = {
| (_, _, Ok(mu), Ok(sigma)) => Ok(#FunctionCall("lognormal", [mu, sigma])) | (_, _, Ok(mu), Ok(sigma)) => Ok(#FunctionCall("lognormal", [mu, sigma]))
| _ => Error("Lognormal distribution needs either mean and stdev or mu and sigma") | _ => Error("Lognormal distribution needs either mean and stdev or mu and sigma")
} }
| _ => | _ => parseArgs() |> E.R.fmap((args: array<ASTTypes.node>) => #FunctionCall("lognormal", args))
parseArgs() |> E.R.fmap((args: array<ASTTypes.node>) =>
#FunctionCall("lognormal", args)
)
} }
// Error("Dotwise exponentiation needs two operands") // Error("Dotwise exponentiation needs two operands")
let operationParser = ( let operationParser = (name: string, args: result<array<ASTTypes.node>, string>): result<
name: string, ASTTypes.node,
args: result<array<ASTTypes.node>, string>, string,
): result<ASTTypes.node, string> => { > => {
let toOkAlgebraic = r => Ok(#AlgebraicCombination(r)) let toOkAlgebraic = r => Ok(#AlgebraicCombination(r))
let toOkPointwise = r => Ok(#PointwiseCombination(r)) let toOkPointwise = r => Ok(#PointwiseCombination(r))
let toOkTruncate = r => Ok(#Truncate(r)) let toOkTruncate = r => Ok(#Truncate(r))
@ -169,10 +166,7 @@ module MathAdtToDistDst = {
} }
let functionParser = ( let functionParser = (
nodeParser: MathJsonToMathJsAdt.arg => Belt.Result.t< nodeParser: MathJsonToMathJsAdt.arg => Belt.Result.t<ASTTypes.node, string>,
ASTTypes.node,
string,
>,
name: string, name: string,
args: array<MathJsonToMathJsAdt.arg>, args: array<MathJsonToMathJsAdt.arg>,
): result<ASTTypes.node, string> => { ): result<ASTTypes.node, string> => {
@ -224,17 +218,11 @@ module MathAdtToDistDst = {
) )
Ok(hash) Ok(hash)
} }
| name => | name => parseArgs() |> E.R.fmap((args: array<ASTTypes.node>) => #FunctionCall(name, args))
parseArgs() |> E.R.fmap((args: array<ASTTypes.node>) =>
#FunctionCall(name, args)
)
} }
} }
let rec nodeParser: MathJsonToMathJsAdt.arg => result< let rec nodeParser: MathJsonToMathJsAdt.arg => result<ASTTypes.node, string> = x =>
ASTTypes.node,
string,
> = x =>
switch x { switch x {
| Value(f) => Ok(#SymbolicDist(#Float(f))) | Value(f) => Ok(#SymbolicDist(#Float(f)))
| Symbol(sym) => Ok(#Symbol(sym)) | Symbol(sym) => Ok(#Symbol(sym))
@ -267,8 +255,7 @@ module MathAdtToDistDst = {
blocks |> E.A.fmap(b => topLevel(b)) |> E.A.R.firstErrorOrOpen |> E.R.fmap(E.A.concatMany) blocks |> E.A.fmap(b => topLevel(b)) |> E.A.R.firstErrorOrOpen |> E.R.fmap(E.A.concatMany)
} }
let run = (r): result<ASTTypes.program, string> => let run = (r): result<ASTTypes.program, string> => r |> MathAdtCleaner.run |> topLevel
r |> MathAdtCleaner.run |> topLevel
} }
/* The MathJs parser doesn't support '.+' syntax, but we want it because it /* The MathJs parser doesn't support '.+' syntax, but we want it because it

View File

@ -39,17 +39,16 @@ module Inputs = {
type exportDistribution = [ type exportDistribution = [
| #DistPlus(DistPlus.t) | #DistPlus(DistPlus.t)
| #Float(float) | #Float(float)
| #Function((float) => Belt.Result.t<DistPlus.t,string>) | #Function(float => Belt.Result.t<DistPlus.t, string>)
] ]
type exportEnv = array<(string, ASTTypes.node)> type exportEnv = array<(string, ASTTypes.node)>
type exportType = { type exportType = {
environment : exportEnv, environment: exportEnv,
exports: array<exportDistribution> exports: array<exportDistribution>,
} }
module Internals = { module Internals = {
let addVariable = ( let addVariable = (
{samplingInputs, squiggleString, environment}: Inputs.inputs, {samplingInputs, squiggleString, environment}: Inputs.inputs,
@ -58,9 +57,7 @@ module Internals = {
): Inputs.inputs => { ): Inputs.inputs => {
samplingInputs: samplingInputs, samplingInputs: samplingInputs,
squiggleString: squiggleString, squiggleString: squiggleString,
environment: ASTTypes.Environment.update(environment, str, _ => Some( environment: ASTTypes.Environment.update(environment, str, _ => Some(node)),
node,
)),
} }
type outputs = { type outputs = {
@ -76,8 +73,7 @@ module Internals = {
pointSetDistLength: inputs.samplingInputs.pointDistLength |> E.O.default(10000), pointSetDistLength: inputs.samplingInputs.pointDistLength |> E.O.default(10000),
} }
let runNode = (inputs, node) => let runNode = (inputs, node) => AST.toLeaf(makeInputs(inputs), inputs.environment, node)
AST.toLeaf(makeInputs(inputs), inputs.environment, node)
let renderIfNeeded = (inputs: Inputs.inputs, node: ASTTypes.node): result< let renderIfNeeded = (inputs: Inputs.inputs, node: ASTTypes.node): result<
ASTTypes.node, ASTTypes.node,
@ -106,16 +102,14 @@ module Internals = {
let outputToDistPlus = (inputs: Inputs.inputs, pointSetDist: PointSetTypes.pointSetDist) => let outputToDistPlus = (inputs: Inputs.inputs, pointSetDist: PointSetTypes.pointSetDist) =>
DistPlus.make(~pointSetDist, ~squiggleString=Some(inputs.squiggleString), ()) DistPlus.make(~pointSetDist, ~squiggleString=Some(inputs.squiggleString), ())
let rec returnDist = (functionInfo : (array<string>, ASTTypes.node), let rec returnDist = (
inputs : Inputs.inputs, functionInfo: (array<string>, ASTTypes.node),
env : ASTTypes.environment) => { inputs: Inputs.inputs,
(input : float) => { env: ASTTypes.environment,
let foo: Inputs.inputs = {...inputs, environment: env}; ) => {
evaluateFunction( (input: float) => {
foo, let foo: Inputs.inputs = {...inputs, environment: env}
functionInfo, evaluateFunction(foo, functionInfo, [#SymbolicDist(#Float(input))]) |> E.R.bind(_, a =>
[#SymbolicDist(#Float(input))],
) |> E.R.bind(_, a =>
switch a { switch a {
| #DistPlus(d) => Ok(DistPlus.T.normalize(d)) | #DistPlus(d) => Ok(DistPlus.T.normalize(d))
| n => | n =>
@ -126,11 +120,10 @@ module Internals = {
} }
} }
// TODO: Consider using ExpressionTypes.ExpressionTree.getFloat or similar in this function // TODO: Consider using ExpressionTypes.ExpressionTree.getFloat or similar in this function
and coersionToExportedTypes = ( and coersionToExportedTypes = (inputs, env: ASTTypes.environment, ex: ASTTypes.node): result<
inputs, exportDistribution,
env: ASTTypes.environment, string,
ex: ASTTypes.node, > =>
): result<exportDistribution, string> =>
ex ex
|> renderIfNeeded(inputs) |> renderIfNeeded(inputs)
|> E.R.bind(_, x => |> E.R.bind(_, x =>
@ -143,56 +136,45 @@ module Internals = {
} }
) )
and evaluateFunction = ( and evaluateFunction = (inputs: Inputs.inputs, fn: (array<string>, ASTTypes.node), fnInputs) => {
inputs: Inputs.inputs, let output = AST.runFunction(makeInputs(inputs), inputs.environment, fnInputs, fn)
fn: (array<string>, ASTTypes.node),
fnInputs,
) => {
let output = AST.runFunction(
makeInputs(inputs),
inputs.environment,
fnInputs,
fn,
)
output |> E.R.bind(_, coersionToExportedTypes(inputs, inputs.environment)) output |> E.R.bind(_, coersionToExportedTypes(inputs, inputs.environment))
} }
let runProgram = (inputs: Inputs.inputs, p: ASTTypes.program) => { let runProgram = (inputs: Inputs.inputs, p: ASTTypes.program) => {
let ins = ref(inputs) let ins = ref(inputs)
p p
|> E.A.fmap(x => |> E.A.fmap(x =>
switch x { switch x {
| #Assignment(name, node) => | #Assignment(name, node) =>
ins := addVariable(ins.contents, name, node) ins := addVariable(ins.contents, name, node)
None None
| #Expression(node) => | #Expression(node) => Some(runNode(ins.contents, node))
Some(runNode(ins.contents, node)) }
} )
) |> E.A.O.concatSomes
|> E.A.O.concatSomes |> E.A.R.firstErrorOrOpen
|> E.R.bind(_, d =>
d
|> E.A.fmap(x => coersionToExportedTypes(inputs, ins.contents.environment, x))
|> E.A.R.firstErrorOrOpen |> E.A.R.firstErrorOrOpen
|> E.R.bind(_, d => )
d |> E.R.fmap(ex => {
|> E.A.fmap(x => coersionToExportedTypes(inputs, ins.contents.environment, x)) environment: Belt.Map.String.toArray(ins.contents.environment),
|> E.A.R.firstErrorOrOpen exports: ex,
) })
|> E.R.fmap(ex =>
{
environment: Belt.Map.String.toArray(ins.contents.environment),
exports: ex
}
)
} }
let inputsToLeaf = (inputs: Inputs.inputs) => let inputsToLeaf = (inputs: Inputs.inputs) =>
Parser.fromString(inputs.squiggleString) |> E.R.bind(_, g => runProgram(inputs, g)) Parser.fromString(inputs.squiggleString) |> E.R.bind(_, g => runProgram(inputs, g))
} }
@genType @genType
let runAll : (string, Inputs.SamplingInputs.t, exportEnv) => result<exportType,string> = let runAll: (string, Inputs.SamplingInputs.t, exportEnv) => result<exportType, string> = (
(squiggleString, samplingInputs, environment) => { squiggleString,
samplingInputs,
environment,
) => {
let inputs = Inputs.make( let inputs = Inputs.make(
~samplingInputs, ~samplingInputs,
~squiggleString, ~squiggleString,

View File

@ -6,7 +6,9 @@
"start": "docusaurus start", "start": "docusaurus start",
"build": "docusaurus build", "build": "docusaurus build",
"clean": "docusaurus clear", "clean": "docusaurus clear",
"all": "yarn build" "all": "yarn build",
"lint": "prettier --check .",
"format": "prettier --write ."
}, },
"dependencies": { "dependencies": {
"@docusaurus/core": "2.0.0-beta.18", "@docusaurus/core": "2.0.0-beta.18",

View File

@ -4025,7 +4025,7 @@
dependencies: dependencies:
"@types/react" "*" "@types/react" "*"
"@types/react@*": "@types/react@*", "@types/react@^16.9.19", "@types/react@^17.0.43", "@types/react@^18.0.1":
version "17.0.44" version "17.0.44"
resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.44.tgz#c3714bd34dd551ab20b8015d9d0dbec812a51ec7" resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.44.tgz#c3714bd34dd551ab20b8015d9d0dbec812a51ec7"
integrity sha512-Ye0nlw09GeMp2Suh8qoOv0odfgCoowfM/9MG6WeRD60Gq9wS90bdkdRtYbRkNhXOpG4H+YXGvj4wOWhAC0LJ1g== integrity sha512-Ye0nlw09GeMp2Suh8qoOv0odfgCoowfM/9MG6WeRD60Gq9wS90bdkdRtYbRkNhXOpG4H+YXGvj4wOWhAC0LJ1g==
@ -4034,24 +4034,6 @@
"@types/scheduler" "*" "@types/scheduler" "*"
csstype "^3.0.2" csstype "^3.0.2"
"@types/react@^16.9.19":
version "16.14.24"
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.14.24.tgz#f2c5e9fa78f83f769884b83defcf7924b9eb5c82"
integrity sha512-e7U2WC8XQP/xfR7bwhOhNFZKPTfW1ph+MiqtudKb8tSV8RyCsovQx2sNVtKoOryjxFKpHPPC/yNiGfdeVM5Gyw==
dependencies:
"@types/prop-types" "*"
"@types/scheduler" "*"
csstype "^3.0.2"
"@types/react@^18.0.1":
version "18.0.1"
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.1.tgz#1b2e02fb7613212518733946e49fb963dfc66e19"
integrity sha512-VnWlrVgG0dYt+NqlfMI0yUYb8Rdl4XUROyH+c6gq/iFCiZ805Vi//26UW38DHnxQkbDhnrIWTBiy6oKZqL11cw==
dependencies:
"@types/prop-types" "*"
"@types/scheduler" "*"
csstype "^3.0.2"
"@types/resolve@1.17.1": "@types/resolve@1.17.1":
version "1.17.1" version "1.17.1"
resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.17.1.tgz#3afd6ad8967c77e4376c598a82ddd58f46ec45d6" resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.17.1.tgz#3afd6ad8967c77e4376c598a82ddd58f46ec45d6"