-
Notifications
You must be signed in to change notification settings - Fork 59
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
MeTTa should support single sided matching #674
Comments
As a few quick remarks:
I disagree with this reason, because traditional FPLs simply don't support constructions like
I also disagree that this is incorrect. Reducing
produces Apparently, we don't want to change this behavior. In general. I don't see from the "bug description" what the issue really is. I can guess that in some cases we may want to work with expressions with variables as is, avoiding substitution of variables, and we may need to come up with some idiomatic way of doing so. But it would help, if you describe, what you are trying to achieve in your use case. |
I mean, maybe, you can use something like |
I would agree that something like |
I agree.
My use case is to emulate lambda calculus and combinatory logic in MeTTa, and, ideally, to do that elegantly. The solution I have so far is not elegant, I guess that's my issue, other than that it works so it's not that bad. See https://github.com/ngeiswei/hyperon-chaining/blob/23ac2aad8671a19fc6234b9679468fcd429ca977/experimental/hol/calculi-converter.metta#L464-L627 for my solution so far. If I had a one-sided |
But there is a deeper issue: is two-sided reduction too unconstrained to be the default? Two-sided reduction is forcing us to deal with annoying corner cases such as when a variable matches a function as in issues #642 or #242. I wonder whether these issues are not the manifestation of a bigger problem, which is that two-sided reduction, as a default spontaneous reduction behavior, is too unconstrained. I understand that inference control could potentially come to the rescue to constrain reduction, and maybe that's a valid solution (it should then also be a solution for emulating combinatory logic and lambda calculus). Still, I wonder... |
I looked at the example you provided and I believe the issue is that when a combinator expression is generated from lambda expression and something like I am not 100% sure (because I didn't fully read the code) but is it possible using |
Saying this I don't fully deny the idea of a single side matching. For instance single-side |
It should be possible, although I would prefer a more elegant alternative if there is one. But maybe that's the best.
Maybe what could be useful is to have a single-side match built-in operator (called say |
The number of cases where single-sided matching evaluation would be useful is adding up. Here they are
One can write MeTTa code that works around the lack of single-sided matching evaluation, using I don't know exactly what is the correct way to remedy that. Ideally the programmer should have the ability to decide at each function entry point, whether it should be double or single sided evaluated. Let me give an example. Assume
So the following call
would only return
instead of
As
would trigger that entry point, and return I believe that is the level of control we want. How to represent that control? I don't have a clear answer. I suppose one place could be the type signature, but it would only work if one can associate a type to, not just a function, but a function entry point. Thus requiring inline type definitions. Any idea? |
Perhaps a good way would be in the
would be singled-sided evaluated. |
I wonder what combination would convey the idea of single sided. I can think of
An other alternative is to make single-sided the default, and have a new equality for double-sided, such as |
I'd like to provide yet another example where single-sided evaluation would be useful. The following MeTTa code
enters an infinite recursion. If I could define such reduction rule as a single-sided matching, then it would output the correct result, which is Why do I need such reduction rule, you may ask?
is equivalent to |
As we discussed at MeTTa Study Call, this
can be understood differently. One may write a pretty simple grounded function, which replaces all variables in the expression to be evaluated with placeholders like But if we think about implementing this feature in the current MeTTa (either via grounded functions or pure MeTTa, but with the use of unification), the drawback is that we implement a simpler operation by reusing a more complex operation, which is not be the most efficient way. Thus, the question is whether the issue supposes that one-sided pattern matching should be the core operation with its own implementation (and either unification should rely on it, or there should be two different implementations). Thus, I wonder |
I would say it is pretty easy to implement single-sided matching as a separate function inside core library. Current double-side matching implementation basically uses the To me the main question is how to embed this implementation into language naturally. |
I don't know if double-sided unification can be easily derived from single-sided unification. It seems to me they kinda both derive from a more general, more controlled unification. I suppose they mostly differ by the substitution step, double-sided operates substitution over all variables while single-sided operates substitution over variables on one side only. So, maybe if we split unification into two steps
and expose these two steps to MeTTa, then the user can have fuller control over the whole thing, including choosing between "double-sided vs single sided" unification.
My belief is that there is a utility in having single-sided unification across all functions that rely on unification, |
I was thinking of some character, either indicating single-sided if double-sided is the default, or indicating double-sided if single-sided is the default. For instance
|
Actually, that is not true, so the functionality is a little more complicated to break apart. |
Describe the bug
I believe MeTTa should seamlessly offer single sided matching alongside double sided matching. In the sense that the developer should be able to easily specify when reduction should take place, under which conditions, in this case single sided matching.
To Reproduce
Single sided matching is the default in traditional functional programming languages, that should be enough of a reason. Let me nonetheless describe a situation where it is useful. For instance, the following SKI combinaroty logic reduction rule is only correct if MeTTa reduction is single sided
Expected behavior
Try for instance
With single sided MeTTa reduction, it should remain unreduced.
Actual behavior
It reduces to
which is incorrect according to SKI combinator logic.
Additional context
I tried to work around that by adding the following type definitions
which did not work.
I also tried
which did not work either, though this is not surprising since
Combinator
is not a meta type.Also, these workarounds would not address the broader issue of doing only singled sided reduction on demand.
I also tried to write my own reduction function using
case
but sincecase
is double sided, it is not directly possible either. The only alternative I found is to deconstruct the term and use==
here and there to identify the pattern, which sorta defeats the point of having a language based on pattern matching.For instance, for that specific example, the code would be
which is still OK since the pattern to identify is constant, but it becomes far less elegant when the reduction rules involve more sophisticated patterns such as
Also, I think this falls under the broader issue of controlling when and when not to reduce, such as reducing or not reducing the first variable of an expression with a function, such as discussed in issues #642 or #242, or reducing till bindings are ready #659.
The text was updated successfully, but these errors were encountered: