From 597a1dbeae046924775673e070bc851c4cd0700f Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Mon, 4 Jul 2022 17:14:54 -0400 Subject: [PATCH] Beginning code for mesh --- .../src/rescript/Utility/Declaration.res | 106 +++++++++++++++--- .../squiggle-lang/src/rescript/Utility/E.res | 26 +++-- 2 files changed, 111 insertions(+), 21 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/Utility/Declaration.res b/packages/squiggle-lang/src/rescript/Utility/Declaration.res index 871dd580..1a5d949f 100644 --- a/packages/squiggle-lang/src/rescript/Utility/Declaration.res +++ b/packages/squiggle-lang/src/rescript/Utility/Declaration.res @@ -1,5 +1,11 @@ @genType -type arg = Float({min: float, max: float}) | Date({min: Js.Date.t, max: Js.Date.t}) +type arg = + | Float({min: float, max: float}) + | Date({min: Js.Date.t, max: Js.Date.t}) + | Bool + | String({options: array}) + +type argType = [#Float(float) | #Date(Js.Date.t) | #Bool(bool) | #String(array)] @genType type declaration<'a> = { @@ -7,6 +13,91 @@ type declaration<'a> = { args: array, } +module Float = { + let range = (min, max, i) => E.A.Floats.range(min, max, i) + let random = (min, max) => min +. Js.Math.random() *. (max -. min) +} + +module Date = { + let range = (min: Js.Date.t, max: Js.Date.t, i) => E.JsDate.range(min, max, i) + let random = (min: Js.Date.t, max: Js.Date.t) => + Float.random(Js.Date.valueOf(min), Js.Date.valueOf(max))->Js.Date.fromFloat +} + +module Bool = { + let range = [true, false] + let random = () => E.Int.random(~min=0, ~max=1) |> E.A.unsafe_get([true, false]) +} + +module String = { + let range = (options: array, i) => { + if E.A.length(options) < i { + options + } else { + Belt.Array.makeBy(i, _ => E.Int.random(~min=0, ~max=E.A.length(options) - 1)) + ->E.A.uniq + ->E.A2.fmap(E.A.unsafe_get(options)) + } + } + + let random = (options: array) => { + let i = E.Int.random(~min=0, ~max=E.A.length(options) - 1) + E.A.unsafe_get(options, i) + } +} + +module Arg = { + let range = (arg: arg, i) => + switch arg { + | Float({min, max}) => Float.range(min, max, i)->E.A2.fmap(r => #Float(r)) + | Date({min, max}) => Date.range(min, max, i)->E.A2.fmap(r => #Date(r)) + | Bool => Bool.range->E.A2.fmap(r => #Bool(r)) + | String({options}) => String.range(options, i)->E.A2.fmap(r => #String(r)) + } + + let random = (arg: arg) => + switch arg { + | Float({min, max}) => #Float(Float.random(min, max)) + | Date({min, max}) => #Date(Date.random(min, max)) + | Bool => #Bool(Bool.random()) + | String({options}) => #String(String.random(options)) + } + + let possibleValueNumber = (arg: arg) => + switch arg { + | Float(_) => infinity + | Date(_) => infinity + | Bool => 2.0 + | String({options}) => E.A.length(options)->E.Int.toFloat + } + + let toString = (arg: arg) => { + switch arg { + | Float({min, max}) => + `Float({min: ${E.Float.with2DigitsPrecision(min)}, max: ${E.Float.with2DigitsPrecision( + max, + )}})` + | Date({min, max}) => + `Date({min: ${DateTime.Date.toString(min)}, max: ${DateTime.Date.toString(max)}})` + } + } +} + +let meshFromCount = (args: array, total) => { + let length = E.A.length(args) + let averageCount = + Js.Math.pow_float( + ~base=E.Int.toFloat(total), + ~exp=1.0 /. E.Int.toFloat(length), + )->Js.Math.floor_int + args->E.A2.fmap(Arg.range(_, averageCount))->E.A.cartesianProductMany +} + +let randomFromCount = (args: array, total) => { + let randomItem = () => args |> E.A.fmap(Arg.random) + Belt.Array.makeBy(total, _ => randomItem()) +} + module ContinuousFloatArg = { let make = (min: float, max: float): arg => { Float({min: min, max: max}) @@ -19,19 +110,6 @@ module ContinuousTimeArg = { } } -module Arg = { - let toString = (arg: arg) => { - switch arg { - | Float({min, max}) => - `Float({min: ${E.Float.with2DigitsPrecision(min)}, max: ${E.Float.with2DigitsPrecision( - max, - )}})` - | Date({min, max}) => - `Date({min: ${DateTime.Date.toString(min)}, max: ${DateTime.Date.toString(max)}})` - } - } -} - let make = (fn: 'a, args: array): declaration<'a> => { {fn: fn, args: args} } diff --git a/packages/squiggle-lang/src/rescript/Utility/E.res b/packages/squiggle-lang/src/rescript/Utility/E.res index 70ca4994..1102f0c3 100644 --- a/packages/squiggle-lang/src/rescript/Utility/E.res +++ b/packages/squiggle-lang/src/rescript/Utility/E.res @@ -35,6 +35,7 @@ module FloatFloatMap = { module Int = { let max = (i1: int, i2: int) => i1 > i2 ? i1 : i2 let random = (~min, ~max) => Js.Math.random_int(min, max) + let toFloat = Belt.Int.toFloat } /* Utils */ module U = { @@ -362,13 +363,6 @@ module J = { } } -module JsDate = { - let fromString = Js.Date.fromString - let now = Js.Date.now - let make = Js.Date.make - let valueOf = Js.Date.valueOf -} - /* List */ module L = { module Util = { @@ -634,6 +628,15 @@ module A = { let all = (p: 'a => bool, xs: array<'a>): bool => length(filter(p, xs)) == length(xs) let any = (p: 'a => bool, xs: array<'a>): bool => length(filter(p, xs)) > 0 + let cartesianProductMany = (combinations: array>) => { + let appendCombination = (l: array>, l': array<'a>): array> => + l |> fmap(lEl => l' |> fmap(l'El => concat(lEl, [l'El]))) |> concatMany + let laterCombinations = Belt.Array.sliceToEnd(combinations, 1) + let startArray = combinations->unsafe_get(0) |> fmap(r => [r]) + let results = reduce(laterCombinations, startArray, appendCombination) + results + } + module O = { let concatSomes = (optionals: array>): array<'a> => optionals @@ -882,3 +885,12 @@ module Dict = { let concat = (a, b) => A.concat(toArray(a), toArray(b))->fromArray let concatMany = ts => ts->A2.fmap(toArray)->A.concatMany->fromArray } + +module JsDate = { + let fromString = Js.Date.fromString + let now = Js.Date.now + let make = Js.Date.make + let valueOf = Js.Date.valueOf + let fromFloat = Js.Date.fromFloat + let range = (min, max, n) => A.Floats.range(valueOf(min), valueOf(max), n) |> A.fmap(fromFloat) +}