G3Kappa / Ergo

Other
4 stars 0 forks source link

Merge BuiltIn resolution and KnowledgeBase match steps into a single step #52

Closed G3Kappa closed 8 months ago

G3Kappa commented 1 year ago

The Evaluations produced by built-ins are similar to the KBMatches produced by knowledge bases.

They are both IAsyncEnumerables that produce objects containing a SubstutionMap.

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 or false. 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 the Rhs is a stubbed version of the built-in that simply returns true.

G3Kappa commented 1 year ago

This isn't as easy as I thought, but exploring the problem is yielding some optimizations already.

G3Kappa commented 1 year ago

It turns out that the semantics of builtins are kinda similar to lambdas. Further investigation warranted

G3Kappa commented 8 months ago

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.