diff --git a/showcase/Entries.re b/showcase/Entries.re index d907299a..51f2f9b1 100644 --- a/showcase/Entries.re +++ b/showcase/Entries.re @@ -1 +1 @@ -let entries = EntryTypes.[ExpressionTreeExamples.entry]; \ No newline at end of file +let entries = []; \ No newline at end of file diff --git a/showcase/entries/Continuous2.re b/showcase/entries/Continuous2.re deleted file mode 100644 index 988ba39b..00000000 --- a/showcase/entries/Continuous2.re +++ /dev/null @@ -1,88 +0,0 @@ -// Examples: -// mm(floor(uniform(30,35)), normal(50,20), [.25,.5]) -// mm(floor(normal(28,4)), normal(32,2), uniform(20,24), [.5,.2,.1]) -// mm(5 to 20, floor(normal(20,2)), [.5, .5])" -// floor(3 to 4) -// uniform(0,1) > 0.3 ? lognormal(6.652, -0.41): 0 - -// let timeDist ={ -// let ingredients = DistPlusRenderer.Inputs.Ingredients.make( -// ~guesstimatorString="(floor(10 to 15))", -// ~domain=RightLimited({xPoint: 50.0, excludingProbabilityMass: 0.3}), -// ~unit= -// DistTypes.TimeDistribution({zero: MomentRe.momentNow(), unit: `years}), -// ()); -// let inputs = DistPlusRenderer.Inputs.make(~distPlusIngredients=ingredients,()) -// inputs |> DistPlusRenderer.run -// } - -// let setup = dist => -// DistPlusRenderer.Inputs.make(~distPlusIngredients=dist,()) -// |> DistPlusRenderer.run -// |> E.R.fmap(distPlus => ) -// |> E.R.toOption -// |> E.O.toExn("") - -// let simpleExample = (name, guesstimatorString) => -// <> -//

-// {name |> ReasonReact.string} -//

-// {setup(DistPlusRenderer.Inputs.Ingredients.make(~guesstimatorString, ()))} -// ; - -// let timeExample = (name, guesstimatorString) => -// <> -//

-// {name |> ReasonReact.string} -//

-// {setup( -// DistPlusRenderer.Inputs.Ingredients.make( -// ~guesstimatorString, -// ~unit=TimeDistribution({zero: MomentRe.momentNow(), unit: `years}), -// (), -// ), -// )} -// ; - -// let distributions = () => -//
-//
-//

-// {"Initial Section" |> ReasonReact.string} -//

-// {simpleExample("Continuous", "5 to 20")} -// {simpleExample("Continuous, wide range", "1 to 1000000")} -// {simpleExample("Continuous, tiny values", "0.000000001 to 0.00000001")} -// {simpleExample( -// "Continuous large values", -// "50000000000000 to 200000000000000000", -// )} -// {simpleExample("Discrete", "floor(10 to 20)")} -// {simpleExample( -// "Discrete and below 0, normal(10,30)", -// "floor(normal(10,30))", -// )} -// {simpleExample("Discrete, wide range", "floor(10 to 200000)")} -// {simpleExample("Mixed", "mm(5 to 20, floor(20 to 30), [.5,.5])")} -// {simpleExample("Mixed, Early-Discrete Point", "mm(1, 5 to 20, [.5,.5])")} -// {simpleExample( -// "Mixed, Two-Discrete Points", -// "mm(0,10, 5 to 20, [.5,.5,.5])", -// )} -//

-// {"Over Time" |> ReasonReact.string} -//

-// {timeExample("Continuous", "5 to 20")} -// {timeExample("Continuous Over Long Period", "500 to 200000")} -// {timeExample("Continuous Over Short Period", "0.0001 to 0.001")} -// {timeExample( -// "Continuous Over Very Long Period", -// "500 to 20000000000000", -// )} -// {timeExample("Discrete", "floor(5 to 20)")} -// {timeExample("Mixed", "mm(5 to 20, floor(5 to 20), [.5,.5])")} -//
-//
; - -// let entry = EntryTypes.(entry(~title="Mixed Distributions", ~render=distributions)); \ No newline at end of file diff --git a/showcase/entries/ExpressionTreeExamples.re b/showcase/entries/ExpressionTreeExamples.re deleted file mode 100644 index 3ab84403..00000000 --- a/showcase/entries/ExpressionTreeExamples.re +++ /dev/null @@ -1,72 +0,0 @@ -// let setup = dist => -// DistPlusRenderer.Inputs.make(~distPlusIngredients=dist, ()) -// |> DistPlusRenderer.run -// |> E.R.fmap(distPlus => ) -// |> E.R.toOption -// |> E.O.toExn("") - -// let simpleExample = (guesstimatorString, ~problem="", ()) => -// <> -//

{guesstimatorString |> ReasonReact.string}

-//

{problem |> (e => "problem: " ++ e) |> ReasonReact.string}

-// {setup( -// DistPlusRenderer.Inputs.Ingredients.make(~guesstimatorString, ()), -// )} -// ; - -let distributions = () => -
-
-

- {"Initial Section" |> ReasonReact.string} -

- // {simpleExample( - // "normal(-1, 1) + normal(5, 2)", - // ~problem="Tails look too flat", - // (), - // )} - // {simpleExample( - // "mm(normal(4,2), normal(10,1))", - // ~problem="Tails look too flat", - // (), - // )} - // {simpleExample( - // "normal(-1, 1) * normal(5, 2)", - // ~problem="This looks really weird", - // (), - // )} - // {simpleExample( - // "normal(1,2) * normal(2,2) * normal(3,1)", - // ~problem="Seems like important parts are cut off", - // (), - // )} - // {simpleExample( - // "mm(uniform(0, 1) , normal(3,2))", - // ~problem="Uniform distribution seems to break multimodal", - // (), - // )} - // {simpleExample( - // "truncate(mm(1 to 10, 10 to 30), 10, 20)", - // ~problem="Truncate seems to have no effect", - // (), - // )} - // {simpleExample( - // "normal(5,2)*(10^3)", - // ~problem="Multiplied items should be evaluated.", - // (), - // )} - // {simpleExample( - // "normal(5,10*3)", - // ~problem="At least simple operations in the distributions should be evaluated.", - // (), - // )} - // {simpleExample( - // "normal(5,10)^3", - // ~problem="Exponentiation not yet supported", - // (), - // )} -
-
; - -let entry = - EntryTypes.(entry(~title="ExpressionTree", ~render=distributions)); diff --git a/src/App.re b/src/App.re index 1744d9b8..482d27fe 100644 --- a/src/App.re +++ b/src/App.re @@ -1,26 +1,15 @@ type route = - | Model(string) | DistBuilder | Home | NotFound; let routeToPath = route => switch (route) { - | Model(modelId) => "/m/" ++ modelId | DistBuilder => "/dist-builder" | Home => "/" | _ => "/" }; -module Models = { - let all = [| - EAFunds.Interface.model, - GlobalCatastrophe.Interface.model, - Human.Interface.model, - |]; - let getById = id => E.A.getBy(all, r => r.id == id); -}; - module Menu = { module Styles = { open Css; @@ -82,7 +71,6 @@ let make = () => { let routing = switch (url.path) { - | ["m", modelId] => Model(modelId) | ["dist-builder"] => DistBuilder | [] => Home | _ => NotFound @@ -91,14 +79,6 @@ let make = () => { <> {switch (routing) { - | Model(id) => - ( - switch (Models.getById(id)) { - | Some(model) => - | None =>
{"Page is not found" |> R.ste}
- } - ) - |> fixedLength | DistBuilder => | Home => | _ => fixedLength({"Page is not found" |> R.ste}) diff --git a/src/components/CodeEditor.js b/src/components/CodeEditor.js index 87a6b8d4..626a2461 100644 --- a/src/components/CodeEditor.js +++ b/src/components/CodeEditor.js @@ -21,7 +21,6 @@ export class CodeEditor extends React.Component { mode="golang" height="400px" width="100%" - keyboardHandler="vim" theme="github" showGutter={false} highlightActiveLine={false} diff --git a/src/index.html b/src/index.html index d5ce2e8b..bd9e0959 100644 --- a/src/index.html +++ b/src/index.html @@ -3,7 +3,7 @@ - Highly Speculative Forecasts + Squiggle Language diff --git a/src/interface/FormBuilder.re b/src/interface/FormBuilder.re deleted file mode 100644 index 428d5556..00000000 --- a/src/interface/FormBuilder.re +++ /dev/null @@ -1,104 +0,0 @@ -open Prop; - -type formState = { - combo: Combo.t, - setCombo: (Combo.t => Combo.t) => unit, - setInputValue: (Combo.t, string, option(Value.t)) => unit, -}; - -let makeHelpers = (combo): formState => { - let (combo, setCombo) = React.useState(() => combo); - let setInputValue = (combo, id, newValue) => - setCombo(_ => Combo.updateInputValue(combo, id, newValue)); - {combo, setCombo, setInputValue}; -}; - -let propValue = (t: Prop.Value.t) => { - switch (t) { - | SelectSingle(r) => r |> ReasonReact.string - | ConditionalArray(r) => "Array" |> ReasonReact.string - | DistPlusIngredients((r: DistPlusRenderer.Inputs.ingredients)) => - let newDistribution = - DistPlusRenderer.Inputs.make( - ~distPlusIngredients=r, - (), - ) - |> DistPlusRenderer.run; - switch (newDistribution) { - | Ok(distribution) =>
- // - // - //
- // {"30 to infinity, 80% mass" |> ReasonReact.string} - //
- | Error(e) => e |> ReasonReact.string - }; - | FloatCdf(_) =>
- | Probability(r) => - (r *. 100. |> Js.Float.toFixed) ++ "%" |> ReasonReact.string - | DateTime(r) => r |> MomentRe.Moment.defaultFormat |> ReasonReact.string - | FloatPoint(r) => r |> Js.Float.toFixed |> ReasonReact.string - }; -}; - -module ModelForm = { - let handleChange = (handleChange, event) => - handleChange(ReactEvent.Form.target(event)##value); - - [@react.component] - let make = (~model: Model.t) => { - let formState = makeHelpers(Combo.fromModel(model)); -
-
-

- {model.name |> ReasonReact.string} -

-

{model.description |> ReasonReact.string}

-

{model.author |> ReasonReact.string}

- - {"Model Code" |> ReasonReact.string} - - {Combo.inputTypeValuePairs(formState.combo) - |> E.A.fmap(((type_: TypeWithMetadata.t, value)) => -
- - - formState.setInputValue( - formState.combo, - type_.id, - newValue, - ) - } - /> -
- ) - |> ReasonReact.array} -
- {model.run(Prop.Combo.InputValues.toValueArray(formState.combo)) - |> R.O.fmapOrNull(propValue)} -
-
-
; - }; -}; diff --git a/src/interface/Prop.re b/src/interface/Prop.re deleted file mode 100644 index e20a1f8c..00000000 --- a/src/interface/Prop.re +++ /dev/null @@ -1,329 +0,0 @@ -module Value = { - type conditional = { - name: string, - truthValue: bool, - }; - - type t = - | SelectSingle(string) - | DateTime(MomentRe.Moment.t) - | FloatPoint(float) - | Probability(float) - | DistPlusIngredients(DistPlusRenderer.Inputs.ingredients) - | ConditionalArray(array(conditional)) - | FloatCdf(string); - - module ConditionalArray = { - let get = (conditionals: array(conditional), name: string) => - Belt.Array.getBy(conditionals, (c: conditional) => c.name == name); - }; -}; - -module ValueCombination = { - type pointsToEvenlySample = int; - - type dateTimeRange = { - startTime: MomentRe.Moment.t, - endTime: MomentRe.Moment.t, - pointsWithin: int, - }; - - type floatPointRange = { - startTime: float, - endTime: float, - pointsWithin: int, - }; - - type range('a) = { - beginning: 'a, - ending: 'a, - pointsToEvenlySample, - }; - - type t = - | SelectSingle - | DateTime(range(MomentRe.Moment.t)) - | FloatPoint(range(MomentRe.Moment.t)) - | Probability(pointsToEvenlySample); -}; - -module ValueCluster = { - type conditional = { - name: string, - truthValue: bool, - }; - - type pointsToEvenlySample = int; - - type dateTimeRange = { - startTime: MomentRe.Moment.t, - endTime: MomentRe.Moment.t, - pointsWithin: int, - }; - - type floatPointRange = { - startTime: float, - endTime: float, - pointsWithin: int, - }; - - type range('a) = { - beginning: 'a, - ending: 'a, - pointsToEvenlySample, - }; - - type t = - | SelectSingle([ | `combination | `item(string)]) - | DateTime( - [ - | `combination(range(MomentRe.Moment.t)) - | `item(MomentRe.Moment.t) - ], - ) - | FloatPoint( - [ | `combination(range(MomentRe.Moment.t)) | `item(string)], - ) - | Probability([ | `item(string)]) - | DistPlusIngredients([ | `item(DistPlusRenderer.Inputs.ingredients)]) - | ConditionalArray([ | `item(array(conditional))]) - | FloatCdf([ | `item(string)]); -}; - -module Type = { - type selectOption = { - id: string, - name: string, - }; - - type selectSingle = { - options: list(selectOption), - default: option(string), - }; - - type conditionals = { - defaults: array(Value.conditional), - options: array(string), - }; - - let makeConditionals = (defaults, options): conditionals => { - defaults, - options, - }; - - type floatPoint = {validatations: list(float => bool)}; - - type withDefaultMinMax('a) = { - default: option('a), - min: option('a), - max: option('a), - }; - - type withDefault('a) = {default: option('a)}; - - type t = - | SelectSingle(selectSingle) - | FloatPoint(withDefaultMinMax(float)) - | Probability(withDefault(float)) - | DateTime(withDefaultMinMax(MomentRe.Moment.t)) - | Year(withDefaultMinMax(float)) - | Conditionals(conditionals) - | FloatCdf; - - let default = (t: t) => - switch (t) { - | Conditionals(s) => Some(Value.ConditionalArray(s.defaults)) - | Year(r) => r.default->Belt.Option.map(p => Value.FloatPoint(p)) - | FloatPoint(r) => r.default->Belt.Option.map(p => Value.FloatPoint(p)) - | Probability(r) => r.default->Belt.Option.map(p => Value.Probability(p)) - | DateTime(r) => r.default->Belt.Option.map(p => Value.DateTime(p)) - | SelectSingle(r) => - r.default->Belt.Option.map(p => Value.SelectSingle(p)) - | FloatCdf => None - }; -}; - -module ValueMap = { - module MS = Belt.Map.String; - type t = MS.t(Value.t); - let get = (t: t, s) => MS.get(t, s); - let keys = MS.keysToArray; - let map = MS.map; - let fromArray = (r): t => MS.fromArray(r); - let values = (t: t) => t |> MS.valuesToArray; - let update = (t, k, v) => MS.update(t, k, _ => v); - let toArray = MS.toArray; - let fromOptionalMap = (t: MS.t(option(Value.t))): t => - MS.keep(t, (_, d) => E.O.isSome(d)) - ->MS.map(d => E.O.toExn("This should not have happened", d)); - let fromOptionalArray = (r): t => MS.fromArray(r) |> fromOptionalMap; -}; - -module ValueClusterMap = { - module MS = Belt.Map.String; - type t = MS.t(ValueCluster.t); - let get = (t: t, s) => MS.get(t, s); - let keys = MS.keysToArray; - let map = MS.map; - let fromArray = (r): t => MS.fromArray(r); - let values = (t: t) => t |> MS.valuesToArray; - let update = (t, k, v) => MS.update(t, k, _ => v); - let toArray = MS.toArray; - let fromOptionalMap = (t: MS.t(option(ValueCluster.t))): t => - MS.keep(t, (_, d) => E.O.isSome(d)) - ->MS.map(d => E.O.toExn("This should not have happened", d)); - let fromOptionalArray = (r): t => MS.fromArray(r) |> fromOptionalMap; -}; - -module TypeWithMetadata = { - // TODO: Figure out a better name for assumptionType - type assumptionType = - | PRIMARY_INPUT - | ASSUMPTION; - - type t = { - id: string, - name: string, - description: option(string), - type_: Type.t, - assumptionType, - }; - - type ts = array(t); - - let make = - ( - ~name, - ~type_, - ~id=name, - ~description=None, - ~assumptionType=PRIMARY_INPUT, - (), - ) => { - id, - name, - type_, - description, - assumptionType, - }; - - let currentYear = - make( - ~id="currentYear", - ~name="Current Day", - ~description=None, - ~type_= - DateTime({ - default: Some(MomentRe.momentNow()), - min: Some(MomentRe.momentNow()), - max: Some(MomentRe.momentNow()), - }), - ~assumptionType=ASSUMPTION, - (), - ); - - let age = - make( - ~id="age", - ~name="Current Age", - ~description=None, - ~type_= - FloatPoint({ - default: Some(40.0), - min: Some(0.0), - max: Some(100.0), - }), - ~assumptionType=PRIMARY_INPUT, - (), - ); - - let sex = - make( - ~id="sex", - ~name="Sex", - ~description=None, - ~type_= - SelectSingle({ - options: [ - {id: "male", name: "Male"}, - {id: "female", name: "Female"}, - ], - default: Some("female"), - }), - ~assumptionType=PRIMARY_INPUT, - (), - ); -}; - -module Model = { - type t = { - name: string, - id: string, - fileName: string, - description: string, - author: string, - version: string, - inputTypes: array(TypeWithMetadata.t), - outputTypes: array(TypeWithMetadata.t), - run: array(option(Value.t)) => option(Value.t), - } - and combo = { - model: t, - inputValues: ValueMap.t, - outputValues: ValueMap.t, - }; - - module InputTypes = { - let keys = (t: t) => - t.inputTypes |> E.A.fmap((r: TypeWithMetadata.t) => r.id); - - let getBy = (t: t, fn) => t.inputTypes |> E.A.getBy(_, fn); - }; -}; - -module Combo = { - type t = Model.combo; - type valueArray = array(option(Value.t)); - - module InputValues = { - let defaults = (t: Model.t) => - t.inputTypes - |> E.A.fmap((o: TypeWithMetadata.t) => (o.id, Type.default(o.type_))) - |> ValueMap.fromOptionalArray; - - let isValid = (t: t) => - t.model - |> Model.InputTypes.keys - |> E.A.fmap(ValueMap.get(t.inputValues)) - |> Belt.Array.some(_, E.O.isNone); - - let update = (t: t, key: string, onUpdate: option(Value.t)) => - ValueMap.update(t.inputValues, key, onUpdate); - - let toValueArray = (t: t): valueArray => { - t.model.inputTypes - |> E.A.fmap((r: TypeWithMetadata.t) => - t.inputValues->ValueMap.get(r.id) - ); - }; - }; - - let updateInputValue = (t: t, k, u) => { - ...t, - inputValues: InputValues.update(t, k, u), - }; - - let inputTypeValuePairs = (t: t) => - t.model.inputTypes - |> E.A.fmap((i: TypeWithMetadata.t) => - (i, ValueMap.get(t.inputValues, i.id)) - ); - - let fromModel = (t: Model.t): t => { - model: t, - inputValues: InputValues.defaults(t), - outputValues: InputValues.defaults(t), - }; - - let run = (t: t, f): ValueMap.t => f(t.inputValues); -}; \ No newline at end of file diff --git a/src/interface/ValueForm.re b/src/interface/ValueForm.re deleted file mode 100644 index 2d746a20..00000000 --- a/src/interface/ValueForm.re +++ /dev/null @@ -1,157 +0,0 @@ -open Prop; -let handleChange = (handleChange, event) => - handleChange(ReactEvent.Form.target(event)##value); -type onChange = option(Value.t) => unit; - -module ConditionalReducer = { - type action = - | ADD_OR_UPDATE_CONDITIONAL(Value.conditional) - | REMOVE_CONDITIONAL(Value.conditional); - - let reducer = (items: array(Value.conditional), action: action) => - switch (action) { - | ADD_OR_UPDATE_CONDITIONAL(conditional) => - items->E.A.hasBy(c => c.name == conditional.name) - ? items - |> E.A.fmap((r: Value.conditional) => - r.name == conditional.name ? conditional : r - ) - : E.A.append(items, [|conditional|]) - | REMOVE_CONDITIONAL(conditional) => - items - |> E.A.filter((c: Value.conditional) => c.name != conditional.name) - }; -}; - -[@react.component] -let make = - ( - ~type_: TypeWithMetadata.t, - ~value: option(Value.t), - ~onChange: onChange, - ) => { - switch (type_.type_, value) { - | (Conditionals(l), Some(ConditionalArray(n))) => -
- {n - |> E.A.fmap((r: Value.conditional) => -
- onChange( - Some( - Value.ConditionalArray( - ConditionalReducer.reducer( - n, - REMOVE_CONDITIONAL({name: r.name, truthValue: true}), - ), - ), - ), - ) - }> - {r.name |> ReasonReact.string} - {(r.truthValue ? " = True" : " = False") |> ReasonReact.string} -
- ) - |> ReasonReact.array} - {l.options - |> E.A.fmap(r => -
- {r |> ReasonReact.string} - - -
- ) - |> ReasonReact.array} -
- | (Conditionals(l), _) => - l.options |> E.A.fmap(r => r |> ReasonReact.string) |> ReasonReact.array - | (Year(_), Some(FloatPoint(r))) => - Js.Float.toString} - onChange={handleChange(r => - switch (Js.Float.fromString(r)) { - | r => onChange(Some(Value.FloatPoint(r))) - } - )} - /> - | (FloatPoint(_), Some(FloatPoint(r))) => - Js.Float.toString} - onChange={handleChange(r => - switch (Js.Float.fromString(r)) { - | r => onChange(Some(Value.FloatPoint(r))) - } - )} - /> - | (Year(_), _) - | (FloatPoint(_), _) => - | (SelectSingle(t), Some(SelectSingle(r))) => - - | (DateTime(_), Some(DateTime((d: MomentRe.Moment.t)))) => - - onChange( - Some(Value.DateTime(MomentRe.momentWithFormat(r, "YYYY-MM-DD"))), - ) - )} - /> - }; -}; \ No newline at end of file diff --git a/src/models/EAFunds.re b/src/models/EAFunds.re deleted file mode 100644 index c4dd6dd1..00000000 --- a/src/models/EAFunds.re +++ /dev/null @@ -1,306 +0,0 @@ -module Data = { - type fund = - | ANIMAL_WELFARE - | GLOBAL_HEALTH - | LONG_TERM_FUTURE - | META; - - type group = - | Fund(fund) - | All; - - type output = - | DONATIONS - | CHANCE_OF_EXISTENCE - | PAYOUTS; - - type conditionals = - | WORLD_CATASTROPHE; - - type fundWithInfo = { - group, - name: string, - existingDonations: option(float), - existingPayouts: option(float), - }; - - let makeFundWithInfo = (name, group, existingDonations, existingPayouts) => { - group, - name, - existingDonations, - existingPayouts, - }; - - let funds = [| - makeFundWithInfo( - "Animal Welfare Fund", - Fund(ANIMAL_WELFARE), - Some(400000.0), - Some(100000.0), - ), - makeFundWithInfo( - "Global Health Fund", - Fund(GLOBAL_HEALTH), - Some(400000.0), - Some(100000.0), - ), - makeFundWithInfo( - "Long Term Future Fund", - Fund(LONG_TERM_FUTURE), - Some(400000.0), - Some(100000.0), - ), - makeFundWithInfo( - "Meta Fund", - Fund(ANIMAL_WELFARE), - Some(400000.0), - Some(100000.0), - ), - makeFundWithInfo("All", All, None, None), - |]; -}; - -module Model = { - open Data; - let currentYear = 2020.; - let firstYearStdDev = 400000.; - type yearlyNumericDiff = { - meanDiff: float, - stdDiff: float, - }; - - let yearlyMeanGrowthRateIfNotClosed = (group: group): yearlyNumericDiff => { - {meanDiff: 1.1, stdDiff: 1.2}; - }; - - let calculateDifference = - (currentValue, dateTime, currentDateTime, y: yearlyNumericDiff) => { - let yearDiff = MomentRe.diff(dateTime, currentDateTime, `days) /. 365.; - let meanDiff = Js.Math.pow_float(~base=y.meanDiff, ~exp=yearDiff); - let stdDevDiff = Js.Math.pow_float(~base=y.stdDiff, ~exp=yearDiff); - GuesstimatorDist.logNormal( - currentValue *. meanDiff, - firstYearStdDev *. stdDevDiff, - ); - }; - - let rec currentValue = (group: group, output) => { - let sum = (): float => - currentValue(Fund(ANIMAL_WELFARE), output) - +. currentValue(Fund(GLOBAL_HEALTH), output) - +. currentValue(Fund(LONG_TERM_FUTURE), output) - +. currentValue(Fund(META), output); - switch (group, output) { - | (Fund(ANIMAL_WELFARE), DONATIONS) => 300000.0 - | (Fund(ANIMAL_WELFARE), PAYOUTS) => 2300000.0 - | (Fund(GLOBAL_HEALTH), DONATIONS) => 1000000.0 - | (Fund(GLOBAL_HEALTH), PAYOUTS) => 500000.0 - | (Fund(LONG_TERM_FUTURE), DONATIONS) => 600000.0 - | (Fund(LONG_TERM_FUTURE), PAYOUTS) => 120000.0 - | (Fund(META), DONATIONS) => 9300000.0 - | (Fund(META), PAYOUTS) => 830000.0 - | (All, _) => sum() - | (_, CHANCE_OF_EXISTENCE) => 0.0 - }; - }; - - let xRisk = conditionals => - Prop.Value.ConditionalArray.get(conditionals, "Global Existential Event"); - - // TODO: Fixe number that integral is calculated for - let getGlobalCatastropheChance = dateTime => { - GlobalCatastrophe.makeI(MomentRe.momentNow()) - |> DistPlusRenderer.Inputs.make(~distPlusIngredients=_, ()) - |> DistPlusRenderer.run - |> E.R.bind(_, r => - r - |> DistPlusTime.Integral.xToY(Time(dateTime)) - |> E.O.toResult("error") - ) - |> E.R.toOption; - }; - - let make = - ( - group: group, - dateTime: MomentRe.Moment.t, - currentDateTime: MomentRe.Moment.t, - output: output, - conditionals: array(Prop.Value.conditional), - ) => { - let xRisk = xRisk(conditionals); - switch (output) { - | DONATIONS - | PAYOUTS => - let difference = - calculateDifference( - currentValue(group, output), - dateTime, - currentDateTime, - yearlyMeanGrowthRateIfNotClosed(group), - ); - - let str = - switch (xRisk) { - | Some({truthValue: true}) => "0" - | Some({truthValue: false}) => difference - | None => - let foo = - getGlobalCatastropheChance(dateTime) - |> E.O.fmap(r => { - let chance = r; - let opposite = 1.0 -. r; - let reg = difference; - {j|mm(0, $reg, [$chance, $opposite])|j}; - }); - foo |> E.O.default(""); - }; - - let distPlusIngredients = - DistPlusRenderer.Inputs.Ingredients.make( - ~guesstimatorString=str, - ~domain=Complete, - ~unit=UnspecifiedDistribution, - (), - ); - Prop.Value.DistPlusIngredients(distPlusIngredients); - - | CHANCE_OF_EXISTENCE => - Prop.Value.DistPlusIngredients( - DistPlusRenderer.Inputs.Ingredients.make( - ~guesstimatorString= - GuesstimatorDist.min( - GlobalCatastrophe.guesstimatorString, - GuesstimatorDist.logNormal(20., 2.), - ), - ~unit=TimeDistribution({zero: currentDateTime, unit: `years}), - ~domain=RightLimited({xPoint: 100., excludingProbabilityMass: 0.3}), - (), - ), - ) - }; - }; -}; - -module Interface = { - open Data; - - let fundKey = "Fund"; - let dayKey = "Day"; - let outputKey = "Output"; - - let choiceFromString = (s: string) => - funds |> E.A.getBy(_, r => r.name == s); - - let outputFromString = (s: string) => - switch (s) { - | "donations" => DONATIONS - | "exists" => CHANCE_OF_EXISTENCE - | _ => PAYOUTS - }; - - let run = (p: array(option(Prop.Value.t))) => { - switch (p) { - | [| - Some(SelectSingle(fund)), - Some(DateTime(intendedYear)), - Some(DateTime(currentYear)), - Some(SelectSingle(output)), - Some(ConditionalArray(conditionals)), - |] => - choiceFromString(fund) - |> E.O.fmap(fund => - Model.make( - fund.group, - intendedYear, - currentYear, - outputFromString(output), - conditionals, - ) - ) - | _ => None - }; - }; - - let model: Prop.Model.t = - Prop.{ - id: "ea-funds", - name: "EA Funds: Donations & Payouts", - description: "Calculate the payments and payouts of CEA Funds based on existing data.", - version: "1.0.0", - fileName: "EAFunds.re", - author: "Ozzie Gooen", - inputTypes: [| - TypeWithMetadata.make( - ~name=fundKey, - ~type_= - SelectSingle({ - default: Some(Array.unsafe_get(Data.funds, 0).name), - options: - Data.funds - |> E.A.fmap((r) => - ({name: r.name, id: r.name}: Prop.Type.selectOption) - ) - |> Array.to_list, - }), - (), - ), - TypeWithMetadata.make( - ~name=dayKey, - ~type_= - DateTime({ - default: - Some( - MomentRe.Moment.add( - ~duration=MomentRe.duration(5., `years), - MomentRe.momentNow(), - ), - ), - min: - Some( - MomentRe.Moment.subtract( - ~duration=MomentRe.duration(20., `years), - MomentRe.momentNow(), - ), - ), - max: - Some( - MomentRe.Moment.add( - ~duration=MomentRe.duration(20., `years), - MomentRe.momentNow(), - ), - ), - }), - (), - ), - TypeWithMetadata.currentYear, - TypeWithMetadata.make( - ~name=outputKey, - ~type_= - SelectSingle({ - default: Some("Output"), - options: [ - {name: "Donations", id: "donations"}, - {name: "Funding", id: "funding"}, - {name: "Closing", id: "exists"}, - ], - }), - (), - ), - TypeWithMetadata.make( - ~name="Conditionals", - ~id="conditionals", - ~type_= - Conditionals( - Prop.Type.makeConditionals( - [||], - [|"Global Existential Event"|], - ), - ), - (), - ), - |], - outputTypes: [||], - run, - }; -}; diff --git a/src/models/GlobalCatastrophe.re b/src/models/GlobalCatastrophe.re deleted file mode 100644 index 9f675267..00000000 --- a/src/models/GlobalCatastrophe.re +++ /dev/null @@ -1,39 +0,0 @@ -let guesstimatorString = "uniform(1, 100)"; - -let makeI = (currentDateTime: MomentRe.Moment.t) => { - DistPlusRenderer.Inputs.Ingredients.make( - ~guesstimatorString, - ~unit=TimeDistribution({zero: currentDateTime, unit: `years}), - ~domain=RightLimited({xPoint: 300.0, excludingProbabilityMass: 0.3}), - (), - ); -}; -module Model = { - let make = (currentDateTime: MomentRe.Moment.t) => { - Prop.Value.DistPlusIngredients(makeI(currentDateTime)); - }; -}; - -module Interface = { - let dayKey = "Day"; - - let run = (p: array(option(Prop.Value.t))) => { - switch (p) { - | [|Some(DateTime(currentYear))|] => Some(Model.make(currentYear)) - | _ => None - }; - }; - - let model: Prop.Model.t = - Prop.{ - name: "Global Catastrophe", - id: "global-catastrophe", - fileName: "GlobalCatastrophe.re", - description: "The chances of having at least one catastrophe per year in the future, assuming no other catastrophe until then.", - version: "1.0.0", - author: "Ozzie Gooen", - inputTypes: [|TypeWithMetadata.currentYear|], - outputTypes: [||], - run, - }; -}; \ No newline at end of file diff --git a/src/models/Human.re b/src/models/Human.re deleted file mode 100644 index 2439adcc..00000000 --- a/src/models/Human.re +++ /dev/null @@ -1,42 +0,0 @@ -let guesstimatorString = age => - GuesstimatorDist.normal(72.0 -. age, 5.0 -. age *. 0.01); - -let makeI = (age: float) => { - DistPlusRenderer.Inputs.Ingredients.make( - ~guesstimatorString=guesstimatorString(age), - ~unit=TimeDistribution({zero: MomentRe.momentNow(), unit: `years}), - ~domain=RightLimited({xPoint: 300.0, excludingProbabilityMass: 0.3}), - (), - ); -}; - -module Model = { - let make = (age: float) => { - Prop.Value.DistPlusIngredients(makeI(age)); - }; -}; - -module Interface = { - let ageKey = "age"; - - let run = (p: array(option(Prop.Value.t))) => { - switch (p) { - | [|Some(FloatPoint(age)), Some(SelectSingle(sex))|] => - Some(Model.make(age)) - | _ => None - }; - }; - - let model: Prop.Model.t = - Prop.{ - name: "Death Time", - id: "human-lifespan", - fileName: "Human.re", - description: "When will you die?", - version: "1.0.0", - author: "Ozzie Gooen", - inputTypes: [|TypeWithMetadata.age, TypeWithMetadata.sex|], - outputTypes: [||], - run, - }; -}; \ No newline at end of file diff --git a/src/pages/Home.re b/src/pages/Home.re index 1773e1ee..e824e9e0 100644 --- a/src/pages/Home.re +++ b/src/pages/Home.re @@ -1,20 +1,3 @@ -type route = - | Model(string); - -let routeToPath = route => - switch (route) { - | Model(modelId) => "/m/" ++ modelId - }; - -module Models = { - let all = [| - EAFunds.Interface.model, - GlobalCatastrophe.Interface.model, - Human.Interface.model, - |]; - let getById = id => E.A.getBy(all, r => r.id == id); -}; - module Styles = { open Css; let h3 = style([fontSize(`em(1.5)), marginBottom(`em(1.5))]); @@ -30,51 +13,9 @@ module Table = { }; }; - module Item = { - [@react.component] - let make = (~model: Prop.Model.t, ~children) => { - ; - }; - }; - - module ColumnsTitles = { - [@react.component] - let make = () => { -
-
{"Name" |> R.ste}
-
- {"Description" |> R.ste} -
-
{"Author" |> R.ste}
-
; - }; - }; - [@react.component] let make = () => { <> -

{"Probability Models" |> R.ste}

- - {Models.all - |> E.A.fmap((model: Prop.Model.t) => { - {model.name |> R.ste} - }) - |> ReasonReact.array} ; }; };