eclipse-viatra / org.eclipse.viatra

Main components of the VIATRA framework
https://eclipse.dev/viatra
Eclipse Public License 2.0
0 stars 1 forks source link

Support embedded subpatterns #8

Open eclipse-viatra-bot opened 6 months ago

eclipse-viatra-bot commented 6 months ago

| --- | --- | | Bugzilla Link | 398787 | | Status | NEW | | Importance | P3 enhancement | | Reported | Jan 22, 2013 12:11 EDT | | Modified | Apr 16, 2019 08:03 EDT | | Version | oldinquery | | Reporter | Zoltan Ujhelyi |

Description

Cloned from: 92: Embedded NAC\ http://github.com/ujhelyiz/EMF-IncQuery/issues/issue/92

Add support for embedded NAC's, in a simplified VTCL style.

eclipse-viatra-bot commented 6 months ago

By Istvan Rath on May 20, 2013 04:51

Postponing non-essential features to the 0.8.x series.

eclipse-viatra-bot commented 6 months ago

By Eric Lépicier on Dec 23, 2013 09:38

Please consider extending embedded patterns also for count and transitive closure...

In a general way (even without neg or count), embedded sub patterns might also serve explicit optimization of patterns, allowing check clauses to be focused on a subset of pattern constraints ?

pattern aPattern(A, B, C) {\ {\ ClassA.b(A, B);\ check(B.name.startsWith("...");\ }\ ClassB.x.y.z.c(B, C);\ }

eclipse-viatra-bot commented 6 months ago

By Zoltan Ujhelyi on Dec 23, 2013 10:01

(In reply to Eric Lépicier from comment #2)

Please consider extending embedded patterns also for count and transitive closure...

Basically, when embedded patterns will be available, it makes sense to do the whole package, as you asked for. However, thanks for pointing it out, and updated the summary as well. But sadly we have no estimate when it will be developed yet.

In a general way (even without neg or count), embedded sub patterns might also serve explicit optimization of patterns, allowing check clauses to be focused on a subset of pattern constraints ?

pattern aPattern(A, B, C) { { ClassA.b(A, B); check(B.name.startsWith("..."); } ClassB.x.y.z.c(B, C); }

To tell the truth, I am sceptical about creating subpatterns for optimization, as this might reduce the readability of the patterns greatly. In your case, this description makes it unclear whether the check expressions are applied to all B elements, or just those that have the mentioned x.y.z.c path.

Additionally, I might be wrong here, but if I recall correctly, the Rete optimizer might already execute the 'B.name.startsWith' expression before checking the path between variables B and C.

I am not entirely against such things, however if such optimizations are really required, I would try to put them into named blocks (or named patterns) instead. This would help to group the elements semantically, that would make th pattern definitions more maintainable.

eclipse-viatra-bot commented 6 months ago

By Eric Lépicier on Dec 23, 2013 11:34

(In reply to Zoltan Ujhelyi from comment #3)

(In reply to Eric Lépicier from comment #2)

Please consider extending embedded patterns also for count and transitive closure... Basically, when embedded patterns will be available, it makes sense to do the whole package, as you asked for. However, thanks for pointing it out, and updated the summary as well. But sadly we have no estimate when it will be developed yet. In a general way (even without neg or count), embedded sub patterns might also serve explicit optimization of patterns, allowing check clauses to be focused on a subset of pattern constraints ?

pattern aPattern(A, B, C) { { ClassA.b(A, B); check(B.name.startsWith("..."); } ClassB.x.y.z.c(B, C); }

To tell the truth, I am sceptical about creating subpatterns for optimization, as this might reduce the readability of the patterns greatly. In your case, this description makes it unclear whether the check expressions are applied to all B elements, or just those that have the mentioned x.y.z.c path.

Additionally, I might be wrong here, but if I recall correctly, the Rete optimizer might already execute the 'B.name.startsWith' expression before checking the path between variables B and C.

I am not entirely against such things, however if such optimizations are really required, I would try to put them into named blocks (or named patterns) instead. This would help to group the elements semantically, that would make th pattern definitions more maintainable.

I agree, I'm no longer convinced myself about my demand, and even less by my example ... I might have clicked 'submit' too fast ...

Not to charge Istvan, but my suggestion was inspired by his answer, which I might have mixed with check efficiency:\ EL: Is a “find” clause as effective as classic patterns?\ IR: the superficial answer to this is a “yes”. Finds make the most sense if you maximize reuse, and it is also useful for advanced, manual optimization (as it affects the Rete layout, which can make a difference in certain corner cases).\ I'm fully aware that algorithm efficiency is often better than manual optimization !

Please ignore my last suggestion, as I clearly prefer the readability and reusability to be promoted. \ To be more precise, my initial demand (before I knew this bug) was mostly concerning the negation of very simple direct "one-line" constraints. For these, a subpattern is duplicating the feature and is not justified for reuse. For more complicated negations, I think the "neg find" is the most appropriate.

eclipse-viatra-bot commented 6 months ago

By Istvan Rath on Dec 23, 2013 16:22

(In reply to Eric Lépicier from comment #4)

Not to charge Istvan, but my suggestion was inspired by his answer, which I might have mixed with check efficiency: EL: Is a “find” clause as effective as classic patterns? IR: the superficial answer to this is a “yes”. Finds make the most sense if you maximize reuse, and it is also useful for advanced, manual optimization (as it affects the Rete layout, which can make a difference in certain corner cases). I'm fully aware that algorithm efficiency is often better than manual optimization !

Subpatterns can make sense for some purposes, e.g. factoring out common parts in the case of "or" patterns (https://bugs.eclipse.org/bugs/show_bug.cgi?id=398751), or just to simplify large pattern bodies by using inline named blocks (to e.g. avoid variable name clashes due to scoping).

I agree with Zoltán that such a technique should not introduce ambiguity in terms of the interpretation of the language.

Please ignore my last suggestion, as I clearly prefer the readability and reusability to be promoted. To be more precise, my initial demand (before I knew this bug) was mostly concerning the negation of very simple direct "one-line" constraints. For these, a subpattern is duplicating the feature and is not justified for reuse. For more complicated negations, I think the "neg find" is the most appropriate.

We should also support embedded negs, e.g.

pattern notnotA(A)\ {\ neg pattern notA(A) {\ neg pattern A(A) {\ SomeType(A);\ }\ }\ }

eclipse-viatra-bot commented 6 months ago

By Eric Lépicier on Dec 24, 2013 04:52

(In reply to Istvan Rath from comment #5)

Subpatterns can make sense for some purposes, e.g. factoring out common parts in the case of "or" patterns (https://bugs.eclipse.org/bugs/show_bug.cgi?id=398751), or just to simplify large pattern bodies by using inline named blocks (to e.g. avoid variable name clashes due to scoping).

It seems that you're planing to add full support for assembling subpatterns with logical operators (NEG, OR ... and AND) ...\ The latter makes patterns look like classical expressions: just replace braces with parenthesis, write AND between constraints (where it was implicit by constraint juxtaposition), and you'll got a classical expression language.\ Many of my users would be more familiar with this kind of expressions. \ My own advice is that it may make disappear the descriptive form of a graph pattern that I was really liking ...

We should also support embedded negs, e.g.

pattern notnotA(A) { neg pattern notA(A) { neg pattern A(A) { SomeType(A); } } }

Wow, this one gave me a momentaneous headache, A should decide quickly who he is !\ More seriously, I find this "named embedded pattern" syntax quite complicated. \ As an ancient developper, I expect a distinction between prototype parameters (those specified in the pattern header) and call parameters (those written in the find clause). In your examples, naming is unique, so I can't see the gain for name clashes ? However, I agree on readability improvement, even if anonymous commented subpatterns could be sufficient.

Merry Christmas!

eclipse-viatra-bot commented 6 months ago

By Zoltan Ujhelyi on Dec 24, 2013 07:04

(In reply to Eric Lépicier from comment #6)

(In reply to Istvan Rath from comment #5)

Subpatterns can make sense for some purposes, e.g. factoring out common parts in the case of "or" patterns (https://bugs.eclipse.org/bugs/show_bug.cgi?id=398751), or just to simplify large pattern bodies by using inline named blocks (to e.g. avoid variable name clashes due to scoping).

It seems that you're planing to add full support for assembling subpatterns with logical operators (NEG, OR ... and AND) ... The latter makes patterns look like classical expressions: just replace braces with parenthesis, write AND between constraints (where it was implicit by constraint juxtaposition), and you'll got a classical expression language. Many of my users would be more familiar with this kind of expressions. My own advice is that it may make disappear the descriptive form of a graph pattern that I was really liking ...

I agree, such things should be added only very carefully, as this is quite a big change. However, bug 398751 asks just a small part of this: add a single common block for all or patterns.

It is a good question how these issues relate to each other - having subpatterns would make the other easier to solve; however, it may lead to a "classical expression language" (that may or may not be what we are looking for).

We should also support embedded negs, e.g.

pattern notnotA(A) { neg pattern notA(A) { neg pattern A(A) { SomeType(A); } } }

Wow, this one gave me a momentaneous headache, A should decide quickly who he is ! More seriously, I find this "named embedded pattern" syntax quite complicated. As an ancient developper, I expect a distinction between prototype parameters (those specified in the pattern header) and call parameters (those written in the find clause). In your examples, naming is unique, so I can't see the gain for name clashes ? However, I agree on readability improvement, even if anonymous commented subpatterns could be sufficient.

I also believe, if we support embedded subpatterns, we should not blindly copy the old VTCL syntax (as Istvan has presented here). E.g., it makes sense to me for subpatterns to see the variables of its container pattern (at least for the syntax; for the runtime, these embedded patterns could become the same patterns as before), and that would make parameter passing either optional (or even unnecessary).

On the other hand, naming the subpatterns would help with readability so I would like to support that (at least as an option).\

Merry Christmas!

Thanks, and same to you!

eclipse-viatra-bot commented 6 months ago

By Istvan Rath on Apr 08, 2014 18:02

Moving this feature to post-0.8.

eclipse-viatra-bot commented 6 months ago

By Istvan Rath on Apr 24, 2014 04:22

I'm expecting this to be addressed for 0.9.

eclipse-viatra-bot commented 6 months ago

By Abel Hegedus on Apr 19, 2016 05:25

Updating to correct milestone.

eclipse-viatra-bot commented 6 months ago

By Zoltan Ujhelyi on Oct 04, 2017 05:26

Moving potential tasks from future to 2.0.

eclipse-viatra-bot commented 6 months ago

By Gabor Bergmann on Apr 05, 2018 12:22

Note: this issue is related to Bug 530883. Unlike the other issue, the focus here is a syntax for multi-line, multi-constraint embedded subpatterns.

Several syntax options have been discussed recently. Not that there are a few pitfalls: (i) determining which variables are shared between the outer and inner pattern bodies; (ii) determining how such patterns are quantified / aggregated / transitively closed by the outer pattern; (iii) how to "lift" constraints that should appear in both bodies.

Here is a NON_SOLUTION:

pattern uniqueName(elem : NamedElement, name: java String) {\ NamedElement.name(elem, name);\ neg { // no NamedElement 'other' such that\ NamedElement.name(other, name);\ other != elem;\ }\ }

Clearly, the embedded pattern is invalid without an enumerable 'elem'. Automatic lifting of the type constraint is possible, but I would advise against it (due to extreme performance cost). So we either duplicate the constraint NamedElement.name(elem, name); or need a syntax that indicates common parts.

NON-FINAL PROPOSAL (concrete syntax subject to change, the point is the abstract structure)

pattern uniqueName(elem : NamedElement, name: java String) {\ with { // part of the positive pattern, but also part of the negative condition\ NamedElement.name(elem, name);\ } unless { // this will be the negative condition, with the common part added\ NamedElement.name(other, name);\ other != elem; \ }\ }

Trivial problems with this: (i) ugly, does not fit the rest of the language; (ii) only works for 'neg', different syntax would be needed for e.g. an aggregation.

However, such a path for introducing syntactic sugar could be extended further, e.g. we could use a "forall"-like syntax (for all matches of this, that other thing also holds), or simply to be able to indicate a common parts of a disjunction (equivalently, an embedded 'or').

Finally, István Ráth's proposal featuring with-unless and embedded transitive closure:

NON-FINAL PROPOSAL

/*

eclipse-viatra-bot commented 6 months ago

By Zoltan Ujhelyi on Apr 16, 2019 08:03

A limited version of this feature was introduced in bug 530883 in VIATRA 2.0 that allows negating and aggregating simple type constraints and path expressions.

Providing a more feature-complete version requires significant planning to make sure it's behavior is still understandable, thus postponing it into an unspecified future milestone.