Skip to content
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

Canonical way to process and/or present complex expressions with nested subexpressions #32

Open
mvpeterson opened this issue Feb 7, 2024 · 4 comments
Labels
tutorial Tutorial question

Comments

@mvpeterson
Copy link

It’s not clear how to process (or present) complex expressions like
(a (c b1 b2) (c b3 b4)
with nested subexpressions using metta. For example, there are expressions that specify line segments

(seg (point 1 1) (point 1 2))
(seg (point 1 1) (point 2 1))

I would like to have a function that would return all vertical lines
(_vertical $x)
Here we need to match segments with the same X coordinate at the points. It is not clear then how to proceed to matching two points if one argument is supplied to (_vertical $x).
One can write
(= (_vertical $x $y) (match &self (seg $x $y) ($x $y)))
and points will be returned
[((point 1 1) (point 1 2)), ((point 1 1) (point 2 1))]
But then it is not clear how to match them, since they are specified in the subexpression (seg . .)

Of course, we can write this manually

(= (_vertical $x $y1 $x $y2) (match &self (seg (point $x $y1) (point $x $y2)) (seg (point $x $y1) (point $x $y2)) ))
!(_vertical $x $y1 $x $y2)

It seems to work like this, but what if there are many more such subexpressions?

@Necr0x0Der
Copy link
Contributor

A few questions:

  • do you keep segments in the space as separate expressions?
  • do your line segments always contain two points?
  • do you want your (_vertical $x) function to return all vertical lines with the specified abscissa?

If all the answers are 'yes', then, would it work for you:

(seg (point 1 1) (point 1 2))
(seg (point 1 1) (point 2 1))
(= (_vertical $x)
   (match &self
          (seg (point $x $y1) (point $x $y2))
          (seg (point $x $y1) (point $x $y2))
   )
)
!(_vertical 1)

?
It is similar to what you described as "manual" version expect it doesn't require four arguments for _vertical.
However, you have this part "but what if there are many more such subexpressions?", and maybe your core concern remained underdescribed.

@mvpeterson
Copy link
Author

mvpeterson commented Feb 7, 2024

do you keep segments in the space as separate expressions?

Let's suppose yes. But what other options might there be?

do you want your (_vertical $x) function to return all vertical lines with the specified abscissa?

Yes, and here you describe the rule directly for the X coordinate. And now it's pretty obvious, but I didn't think that way, I tried to match first (seg $q $z), and get points out of it, but then I got stuck on extracting the coordinates of the points.

do your line segments always contain two points?

Not necessarily, what if it is an expression for a 100-dimensional line? In this case, the name “vertical” maybe not very appropriate, but anyway.

@Necr0x0Der
Copy link
Contributor

Necr0x0Der commented Feb 7, 2024

Not necessarily, what if it is an expression for a 100-dimensional line? In this case, the name “vertical” maybe not very appropriate, but anyway.

OK, if we suppose an extension to N-dimensional case, I'd propose to either wrap coordinates into the List-like data structure or to pass a tuple with coordinates and use car-atom / cdr-atom primitives. In both cases, I don't see a way to avoid using recursion and to represent this function via pure pattern matching. Well, I can imagine a complex pattern matching language which says that N-th element of the pattern 1 is the same variable as in the pattern 2, but I don't think it makes sense to move this functionality from Turing-complete language to pattern matching, which is not supposed to be Turing-complete in any case, and there will always be some computational pattern which are not covered by it.

@Necr0x0Der
Copy link
Contributor

An interesting option would be the possibility to be able to construct a pattern like (seg (point $x1 $x2 ... $x ... $xn) (point $y1 $y2 ... $x ... $yn)) programmatically in MeTTa. We have parse operation in Python stdlib (although I'm not sure if its implementation suffices), and such the pattern could it principle be constructed. But I'm still not sure if using pattern matching here instead of recursion makes sense, since either we will have to construct this pattern by a recursive function as well, or we goes back to making the pattern matching language much richer and possibly even Turing-complete

@Necr0x0Der Necr0x0Der added the tutorial Tutorial question label Mar 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
tutorial Tutorial question
Projects
None yet
Development

No branches or pull requests

2 participants