Closed G3Kappa closed 8 months ago
This isn't as easy as I thought, but exploring the problem is yielding some optimizations already.
It turns out that the semantics of builtins are kinda similar to lambdas. Further investigation warranted
In the end I ended up adding a Maybe<BuiltIn>
to predicates, so that they can be stored in the knowledge base as usual.
This somewhat broke one use case for libraries, which was to provide a different set of builtins depending on the interpreter scope. Now the builtins are baked into the knowledge base and some hoops need to be jumped through to update it dynamically after creation, especially because the static analyzer needs to be notified of these changes. This leads to #75.
But aside from that, this effectively solves the issue and removes the ambiguity between builtins and regular predicates, with the exception that builtins have extremely granular control over how they are compiled.
The
Evaluation
s produced by built-ins are similar to theKBMatch
es produced by knowledge bases.They are both
IAsyncEnumerables
that produce objects containing aSubstutionMap
.However the semantics are a bit different. Built-ins can return a different value than what was passed in, as opposed to pure predicates that always return
true
orfalse
. For instance,math:eval(3.14)
is effectively replaced by the result of the evaluation,3.14
.As of now, built-ins are evaluated recursively. So, as long as the evaluation of a built-in is another built-in call, the evaluation will be performed immediately and the result will be passed on. But as it turns out, this isn't needed by anything. After all, built-ins are supposed to behave like regular predicates in most scenarios.
When eliminating this recursive resolution, it becomes evident that evaluations are pretty much the same thing as matches where the
Lhs
is mutable instead of immutable, and where theRhs
is a stubbed version of the built-in that simply returnstrue
.