Fixed major bug for module functions

This commit is contained in:
Ozzie Gooen 2022-07-19 23:06:10 -07:00
parent 90d3f89c0a
commit 9173b103f5
7 changed files with 94 additions and 50 deletions

View File

@ -59,6 +59,7 @@ describe("FunctionRegistry Library", () => {
)
testEvalToBe("Dist.logScore({estimate: normal(5,2), answer: 4.5})", "Ok(1.6433360626394853)")
testEvalToBe("Dist.klDivergence(normal(5,2), normal(5,1.5))", "Ok(0.06874342818671068)")
testEvalToBe("Sampleset.fromList([3,5,2,3,5,2,3,5,2,3,3,5])", "Ok(Sample Set Distribution)")
})
describe("Fn auto-testing", () => {

View File

@ -15,6 +15,7 @@
"start": "rescript build -w -with-deps",
"clean": "rescript clean && rm -rf dist",
"test:reducer": "jest __tests__/Reducer*/",
"test:current": "jest __tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.bs.js",
"benchmark": "ts-node benchmark/conversion_tests.ts",
"test": "jest",
"test:ts": "jest __tests__/TS/",

View File

@ -170,6 +170,7 @@ module FRType = {
inputs: array<t>,
args: array<internalExpressionValue>,
): option<array<frValue>> => {
// Js.log3("Matching", inputs, args)
let isSameLength = E.A.length(inputs) == E.A.length(args)
if !isSameLength {
None
@ -240,53 +241,82 @@ module Matcher = {
type definitionId = int
type match = Match.t<array<definitionId>, definitionId>
let match = (f: function, fnName: string, args: array<internalExpressionValue>): match => {
let matchedDefinition = () =>
E.A.getIndexBy(f.definitions, r =>
MatchSimple.isFullMatch(FnDefinition.match(r, fnName, args))
) |> E.O.fmap(r => Match.FullMatch(r))
let getMatchedNameOnlyDefinition = () => {
let nameMatchIndexes =
f.definitions
->E.A2.fmapi((index, r) =>
MatchSimple.isNameMatchOnly(FnDefinition.match(r, fnName, args)) ? Some(index) : None
let match = (
f: function,
namespace: option<string>,
fnName: string,
args: array<internalExpressionValue>,
): match => {
switch namespace {
| Some(ns) if ns !== f.nameSpace => Match.DifferentName
| _ => {
let matchedDefinition = () =>
E.A.getIndexBy(f.definitions, r =>
MatchSimple.isFullMatch(FnDefinition.match(r, fnName, args))
) |> E.O.fmap(r => Match.FullMatch(r))
let getMatchedNameOnlyDefinition = () => {
let nameMatchIndexes =
f.definitions
->E.A2.fmapi((index, r) =>
MatchSimple.isNameMatchOnly(FnDefinition.match(r, fnName, args))
? Some(index)
: None
)
->E.A.O.concatSomes
switch nameMatchIndexes {
| [] => None
| elements => Some(Match.SameNameDifferentArguments(elements))
}
}
E.A.O.firstSomeFnWithDefault(
[matchedDefinition, getMatchedNameOnlyDefinition],
Match.DifferentName,
)
->E.A.O.concatSomes
switch nameMatchIndexes {
| [] => None
| elements => Some(Match.SameNameDifferentArguments(elements))
}
}
E.A.O.firstSomeFnWithDefault(
[matchedDefinition, getMatchedNameOnlyDefinition],
Match.DifferentName,
)
}
}
module RegistryMatch = {
type match = {
namespace: option<string>,
fnName: string,
inputIndex: int,
}
let makeMatch = (fnName: string, inputIndex: int) => {fnName: fnName, inputIndex: inputIndex}
let makeMatch = (namespace: option<string>, fnName: string, inputIndex: int) => {
namespace: namespace,
fnName: fnName,
inputIndex: inputIndex,
}
}
module Registry = {
let _findExactMatches = (r: registry, fnName: string, args: array<internalExpressionValue>) => {
let functionMatchPairs = r.functions->E.A2.fmap(l => (l, Function.match(l, fnName, args)))
let _findExactMatches = (
r: registry,
namespace: option<string>,
fnName: string,
args: array<internalExpressionValue>,
) => {
let functionMatchPairs =
r.functions->E.A2.fmap(l => (l, Function.match(l, namespace, fnName, args)))
let fullMatch = functionMatchPairs->E.A.getBy(((_, match)) => Match.isFullMatch(match))
fullMatch->E.O.bind(((fn, match)) =>
switch match {
| FullMatch(index) => Some(RegistryMatch.makeMatch(fn.name, index))
| FullMatch(index) => Some(RegistryMatch.makeMatch(namespace, fn.name, index))
| _ => None
}
)
}
let _findNameMatches = (r: registry, fnName: string, args: array<internalExpressionValue>) => {
let functionMatchPairs = r.functions->E.A2.fmap(l => (l, Function.match(l, fnName, args)))
let _findNameMatches = (
r: registry,
namespace: option<string>,
fnName: string,
args: array<internalExpressionValue>,
) => {
let functionMatchPairs =
r.functions->E.A2.fmap(l => (l, Function.match(l, namespace, fnName, args)))
let getNameMatches =
functionMatchPairs
->E.A2.fmap(((fn, match)) => Match.isNameMatchOnly(match) ? Some((fn, match)) : None)
@ -296,7 +326,7 @@ module Matcher = {
->E.A2.fmap(((fn, match)) =>
switch match {
| SameNameDifferentArguments(indexes) =>
indexes->E.A2.fmap(index => RegistryMatch.makeMatch(fn.name, index))
indexes->E.A2.fmap(index => RegistryMatch.makeMatch(namespace, fn.name, index))
| _ => []
}
)
@ -307,22 +337,29 @@ module Matcher = {
let findMatches = (r: registry, fnName: string, args: array<internalExpressionValue>) => {
let fnNameInParts = Js.String.split(".", fnName)
let fnToSearch = E.A.get(fnNameInParts, 1) |> E.O.default(fnNameInParts[0])
let nameSpace = E.A.length(fnNameInParts) > 1 ? Some(fnNameInParts[0]) : None
switch _findExactMatches(r, fnToSearch, args) {
switch _findExactMatches(r, nameSpace, fnToSearch, args) {
| Some(r) => Match.FullMatch(r)
| None =>
switch _findNameMatches(r, fnToSearch, args) {
switch _findNameMatches(r, nameSpace, fnToSearch, args) {
| Some(r) => Match.SameNameDifferentArguments(r)
| None => Match.DifferentName
}
}
}
let matchToDef = (registry: registry, {fnName, inputIndex}: RegistryMatch.match): option<
fnDefinition,
> =>
let matchToDef = (
registry: registry,
{namespace, fnName, inputIndex}: RegistryMatch.match,
): option<fnDefinition> =>
registry.functions
->E.A.getBy(fn => fn.name === fnName)
->E.A.getBy(fn => {
switch namespace {
| Some(ns) => ns === fn.nameSpace && fnName === fn.name
| _ => fnName === fn.name
}
})
->E.O.bind(fn => E.A.get(fn.definitions, inputIndex))
}
}
@ -474,6 +511,8 @@ module Registry = {
`There are function matches for ${fnName}(), but with different arguments: ${defs}`
}
let match = Matcher.Registry.findMatches(modified, fnName, args)
switch Matcher.Registry.findMatches(modified, fnName, args) {
| Matcher.Match.FullMatch(match) =>
match->matchToDef->E.O2.fmap(FnDefinition.run(_, args, env, reducer))

View File

@ -2,10 +2,10 @@ let fnList = Belt.Array.concatMany([
FR_Dict.library,
FR_Dist.library,
FR_Fn.library,
FR_Sampleset.library,
FR_List.library,
FR_Number.library,
FR_Pointset.library,
FR_Sampleset.library,
FR_Scoring.library,
])

View File

@ -156,11 +156,12 @@ let library = [
FnDefinition.make(
~name="fromList",
~inputs=[FRTypeArray(FRTypeArray(FRTypeAny))],
~run=(inputs, _, _, _) =>
~run=(inputs, _, _, _) =>{
switch inputs {
| [IEvArray(items)] => Internals.fromList(items)
| _ => Error(impossibleError)
},
}
},
(),
),
],

View File

@ -74,7 +74,7 @@ let library = [
~name="fromDist",
~nameSpace,
~requiresNamespace=true,
~examples=[`PointSet.fromDist(normal(5,2))`],
~examples=[`Pointset.fromDist(normal(5,2))`],
~output=ReducerInterface_InternalExpressionValue.EvtDistribution,
~definitions=[
FnDefinition.make(

View File

@ -90,19 +90,19 @@ let library = [
(),
),
Function.make(
~name="fromLlist",
~name="fromList",
~nameSpace,
~requiresNamespace=true,
~examples=[`Sampleset.fromLlist([3,5,2,3,5,2,3,5,2,3,3,5,3,2,3,1,1,3])`],
~examples=[`Sampleset.fromList([3,5,2,3,5,2,3,5,2,3,3,5,3,2,3,1,1,3])`],
~output=ReducerInterface_InternalExpressionValue.EvtDistribution,
~definitions=[
FnDefinition.make(
~name="fromLlist",
~name="fromList",
~inputs=[FRTypeArray(FRTypeNumber)],
~run=(_, inputs, _, _) => {
let sampleSet =
Prepare.ToTypedArray.numbers(inputs) |> E.R2.bind(r =>
SampleSetDist.make(r)->E.R2.errMap(_ => "")
SampleSetDist.make(r)->E.R2.errMap(_ => "AM I HERE? WHYERE AMI??")
)
sampleSet->E.R2.fmap(Wrappers.sampleSet)->E.R2.fmap(Wrappers.evDistribution)
},
@ -112,14 +112,14 @@ let library = [
(),
),
Function.make(
~name="toLlist",
~name="toList",
~nameSpace,
~requiresNamespace=false,
~examples=[`Sampleset.toLlist(Sampleset.maker(normal(5,2))`],
~examples=[`Sampleset.toList(Sampleset.fromDist(normal(5,2)))`],
~output=ReducerInterface_InternalExpressionValue.EvtArray,
~definitions=[
FnDefinition.make(
~name="toLlist",
~name="toList",
~inputs=[FRTypeDist],
~run=(inputs, _, _, _) =>
switch inputs {
@ -133,14 +133,14 @@ let library = [
(),
),
Function.make(
~name="mapp",
~name="map",
~nameSpace,
~requiresNamespace,
~examples=[`Sampleset.mapp(Sampleset.maker(normal(5,2)), {|x| x + 1})`],
~examples=[`Sampleset.map(Sampleset.fromDist(normal(5,2)), {|x| x + 1})`],
~output=ReducerInterface_InternalExpressionValue.EvtDistribution,
~definitions=[
FnDefinition.make(
~name="mapp",
~name="map",
~inputs=[FRTypeDist, FRTypeLambda],
~run=(inputs, _, env, reducer) =>
switch inputs {
@ -158,7 +158,7 @@ let library = [
~nameSpace,
~requiresNamespace,
~examples=[
`Sampleset.map2(Sampleset.maker(normal(5,2)), Sampleset.maker(normal(5,2)), {|x, y| x + y})`,
`Sampleset.map2(Sampleset.fromDist(normal(5,2)), Sampleset.fromDist(normal(5,2)), {|x, y| x + y})`,
],
~output=ReducerInterface_InternalExpressionValue.EvtDistribution,
~definitions=[
@ -186,7 +186,7 @@ let library = [
~nameSpace,
~requiresNamespace,
~examples=[
`Sampleset.map3(Sampleset.maker(normal(5,2)), Sampleset.maker(normal(5,2)), Sampleset.maker(normal(5,2)), {|x, y, z| max([x,y,z]))`,
`Sampleset.map3(Sampleset.fromDist(normal(5,2)), Sampleset.fromDist(normal(5,2)), Sampleset.fromDist(normal(5,2)), {|x, y, z| max([x,y,z])})`,
],
~output=ReducerInterface_InternalExpressionValue.EvtDistribution,
~definitions=[
@ -214,7 +214,7 @@ let library = [
~nameSpace,
~requiresNamespace,
~examples=[
`Sampleset.mapN([Sampleset.maker(normal(5,2)), Sampleset.maker(normal(5,2)), Sampleset.maker(normal(5,2))], {|x| max(x)})`,
`Sampleset.mapN([Sampleset.fromDist(normal(5,2)), Sampleset.fromDist(normal(5,2)), Sampleset.fromDist(normal(5,2))], {|x| max(x)})`,
],
~output=ReducerInterface_InternalExpressionValue.EvtDistribution,
~definitions=[
@ -224,7 +224,9 @@ let library = [
~run=(inputs, _, env, reducer) =>
switch inputs {
| [IEvArray(dists), IEvLambda(lambda)] =>
Internal.mapN(dists, lambda, env, reducer)->E.R2.errMap(e => {Js.log2("HI", e); "AHHH doesn't work"})
Internal.mapN(dists, lambda, env, reducer)->E.R2.errMap(e => {
"AHHH doesn't work"
})
| _ => Error(impossibleError)
},
(),