trueagi-io / metta-examples

Discussion of MeTTa programming with examples
MIT License
20 stars 18 forks source link

What is the most idiomatic way for "filtering" tuples in Metta? #52

Open CICS-Oleg opened 2 months ago

CICS-Oleg commented 2 months ago

Suppose we have a tupe of atoms (alpha beta gamma delta delta). How to filter out delta? Now suppose we have a tupe of strings ("alpha" "beta" "gamma" "delta" "delta"). How to filter out 'delta' most effectively in this case? Lets consider nested scenarios: (alpha beta gamma (delta (delta))) and ("alpha" "beta" "gamma" ("delta" ("delta"))). What should be done in this case?

I'm afraid the ways to solve this I could imagine right away are more "functional" and not effective like recursive functions from SICP examples.

I suspect it can be done by a matching technique but don't get how to correctly formulate desired output for match. Needs some sql's 'EXCEPT' analog or whatever.

!(add-atom &self (alpha beta gamma (delta (delta))))
!(add-atom &self ("alpha" "beta" "gamma" ("delta" ("delta"))))
!(match &self (delta) (all the rest elements in tuple besides deltas))
DaddyWesker commented 2 months ago

Unfortunately I can't come with non-functional variant either. Probably @Necr0x0Der or @vsbogd could help out with your question.

vsbogd commented 2 months ago

I suspect it can be done by a matching technique but don't get how to correctly formulate desired output for match . Needs some sql's 'EXCEPT' analog or whatever.

It is not possible to use match to filter out something from the tuple.

I am not sure I understand your question correctly though. Do you mean if (alpha beta gamma delta delta) is given you need to get (alpha beta gamma)? Does order of other atoms inside tuple matters?

Necr0x0Der commented 2 months ago

More context would be appreciated. Maybe, the initial representation is just inconvenient. For example, instead of (Friends-of Alpha Beta Gamma Delta) one could use (Friend-of Alpha Beta), (Friend-of Alpha Gamma), (Friend-of Alpha Delta). However, if one wants a generic way to traverse a hypergraph starting with a certain atom, then the current atomspace for the interpreter is not very suitable for this (since it doesn't do deduplication of atoms).But I don't think it is what you need in any case

CICS-Oleg commented 2 months ago

@vsbogd

Do you mean if (alpha beta gamma delta delta) is given you need to get (alpha beta gamma)?

Yes.

Does order of other atoms inside tuple matters?

Let's suppose that it doesn't matter.

Necr0x0Der commented 2 months ago

Let's suppose that it doesn't matter.

Your usecase is still not clear, but what's about something like this?

(member my-set alpha)
(member my-set beta)
(member my-set gamma)
(member my-set delta)
!(match &self (member $set delta)
   (match &self (member $x $member) $member))
CICS-Oleg commented 1 month ago
(member my-set alpha)
(member my-set beta)
(member my-set gamma)
(member my-set delta)
(member aint-my-set delta)

Taking the example above, how to make a set of entities, which are in my-set, but not in aint-my-set? And speaking about operations on sets, how to get intersection of sets for the example above?

CICS-Oleg commented 1 month ago
(member my-set alpha)
(member my-set beta)
(member my-set gamma)
(member my-set delta)
!(match &self (member $set delta)
   (match &self (member $x $member) $member))

Is it a filtering example? If it's so then it gives the same result as !(match &self (member $x $member) $member)) with no filtering.

Necr0x0Der commented 1 month ago

Is it a filtering example?

there is a typo; it should be

!(match &self (member $set delta)
   (match &self (member $set $member) $member))

Although, if delta is in several sets, then the result will be their union

Necr0x0Der commented 1 month ago

how to make a set of entities, which are in my-set, but not in aint-my-set?

Maybe, this is the right way

!(match &self (member my-set $member)
   (unify (member aint-my-set $member) &self Empty $member))
Necr0x0Der commented 1 month ago

And speaking about operations on sets, how to get intersection of sets for the example above?

!(match &self
    (, (member my-set $member)
       (member aint-my-set $member))
    $member)
DaddyWesker commented 1 month ago

Is it a filtering example?

there is a typo; it should be

!(match &self (member $set delta)
   (match &self (member $set $member) $member))

Although, if delta is in several sets, then the result will be their union

For me this code still gives [gamma, delta, beta, alpha], so all members of set which contains delta if I read this code right.