Skip to content

ST6RI-842: Support shorthand notations (PlantUML) #647

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

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open

Conversation

himi
Copy link
Member

@himi himi commented May 5, 2025

This PR renders shorthand notations for PerformActionUsage, ExhibitStateUsage, EventOccurrenceUsage, and IncludeUsecase. In the example below, we can use just an arrow with <<perform>> label from p1 to a0 to render PerformActionUsage without rendering a distinct node for it.

part p1 {
   perform a0;
}
action a0;

However, we cannot use this notation if PerformActionUsage is referred to by others or if it has its own members, because we cannot properly render this information without a distinct node. We render a cumbersome notation with a distinct node in such cases.

himi added 2 commits May 5, 2025 00:26
* VDefault (casePerformActionUsage, caseExhibitStateUsage,
  caseExhibitStateUsage, caseIncludeUseCaseUsage): Use shorthand
  notation if possible
* VStructure (caseSatisfyRequirementUsage): if
  hasRefSubsettingWithoutDeclaredName(), render a node for the
  SatisfyRequirementUsage.
* SysML2PlantUMLStyle (StyleRelDefaultSwitch): Added arrow styles for
  shorthand notations.
(isEmptyObjective, isEmpty): Added
(addShorthandRelation): Use isEmpty().
* VCompartment (caseObjectiveMembership): Do not render empty objectives.
* VTree (caseObjectiveMembership): Likewise
@himi
Copy link
Member Author

himi commented May 5, 2025

We can use shorthand notations with the simple cases:

package TestSimple {
		part p0 {
			perform a0;
			perform p1.a11;
			exhibit s0;
			exhibit p1.s11;
			event oc0;
			event p1.oc11;
			use case uc1 {
				include uc0;
				include p1.uc11;
			}
		}
		action a0;
		state s0;
		occurrence oc0;
		use case uc0;	
		
		part p1 {
			action a11;
			state s11;
			occurrence oc11;
			use case uc11;
		}
	}

image

@himi
Copy link
Member Author

himi commented May 5, 2025

If such features are referred by others, the visualizer does not use shorthand notations:

package TestReferred {
		part p0 {
			perform a0;
			perform action a01 :> a0;
			perform p1.a11;
			perform action a02 :> a11;
			exhibit s0;
			exhibit state s01 :> s0;
			exhibit p1.s11;
			exhibit state s02 :> s11;
			event oc0;
			event occurrence oc1 :> oc0;
			event p1.oc11;
			use case uc1 {
				include uc0;
				include p1.uc11;
			}
		}
		use case uc01 :> p0.uc1.uc0;
		action a0;
		state s0;
		occurrence oc0;
		use case uc0;	
		
		part p1 {
			action a11;
			state s11;
			occurrence oc11;
			use case uc11;
		}
	}

image

Opps.. I found ExhibitStateUsage edge notation was wrong, I will fix it.

Fixed. The updated rendering result is (I used ortholine style to show edges) :
image

@himi
Copy link
Member Author

himi commented May 5, 2025

If such features owns any meaningful (excluding empty subjects or objectives) members, shorthand notations are not used:

package TestWithFeature {
		part p0 {
			perform a0 {
				action a00;
			}
			perform p1.a11 {
				action a00;
			}
			exhibit s0 {
				state s00;
			}
			exhibit p1.s11 {
				state s00;
			}
			event oc0 {
				attribute attr0;
			}
			event p1.oc11 {
				attribute attr0;
			}
			use case uc1 {
				include uc0 {
					use case uc00;
				}
				include p1.uc11 {
					use case uc00;
				}
			}
		}
		action a0;
		state s0;
		occurrence oc0;
		use case uc0;	
		
		part p1 {
			action a11;
			state s11;
			occurrence oc11;
			use case uc11;
		}
	}

image

@himi
Copy link
Member Author

himi commented May 5, 2025

I also fixed an issue on SatisfyRequirementUsage. Previously, the visualizer did not render
satisfy requirement r1 by p1; (it could render satisfy r1 by p1; requirement r1;). This is fixed as below

package TestSatisfyRequirement {
		part p1;
		satisfy requirement r1 by p1;
		requirement r2;
		satisfy r2 by p1;
	}

image

@himi
Copy link
Member Author

himi commented May 5, 2025

BTW, I found a weird behaviour on event occurrence. Unlike PerformActionUsage or likewise, EventOccurrenceUsage does not have an effective name. Is it an intended behaviour? Actually, it's not so useful I think.

package TestEventEffectiveName {
		part p1 {
			event oc1 {
				attribute attr1;
			}
			perform a1 {
				action a0;
			}
		}
		
		occurrence oc1;
		action a1;
	}

In MIXED view, it's rendered as:
image

@himi himi requested a review from seidewitz May 5, 2025 16:44
  relationship
* VDefault (isEmptySubject, isEmptyObjective): Check if the name is
  null.
@seidewitz seidewitz added this to the 2025-04 milestone May 6, 2025
@seidewitz seidewitz self-assigned this May 6, 2025
@seidewitz
Copy link
Member

Unlike PerformActionUsage or likewise, EventOccurrenceUsage does not have an effective name. Is it an intended behaviour?

Yes, this is the intended behavior. It is because one intended style of event occurrence usages is to have them refer to the source and target events of messages (e.g., event msg.sourceEvent), but, if the event occurrence usages had the referenced names as their effective names, this could result in multiple usages in the same scope with the names sourceEvent or targetEvent.

@seidewitz
Copy link
Member

In your TestSimple model, if I try to just render part p0, the result is

image

That is, none of the event occurrence usages, perform action usages or exhibit usages appear. I think this is misleading. I would expect some form of "cumbersome" notation to be used to show them. For example, if I change perform a0 in p0 to perform action aa0 ::> a0;, then this renders as

image

However, if I remove the name aa0, the perform action usage disappears from the diagram again. But it is displayed if regular subsetting is used instead of reference subsetting:

image

@himi
Copy link
Member Author

himi commented May 6, 2025

@seidewitz thank you for the feedback. I agree. I will fix it tonight.

Update: I could fix it but I need to add explanations because it's complicated than what I had expected. I will write them tomorrow.

@seidewitz
Copy link
Member

seidewitz commented May 6, 2025

If a perform action usage (or similar) has additional specializations (e.g., perform a0 :> p1.a11;), then it is seemingly still rendered using the shorthand notation. It should be rendered using "cumbersome" notation in order to show these extra relationships.

Also, there actually is a specific graphical notation for reference subsetting. From 8.2.3.6 Definition and Usage Graphical Notation:

image

Can this be used in the "cumbersome" notation to make it clear what the referenced feature is? This is particularly relevant when the perform action usage has other kinds of subsettings, too.

@himi
Copy link
Member Author

himi commented May 6, 2025

If a perform action usage (or similar) has additional specializations (e.g., perform a0 :> p1.a11;), then it is seemingly still rendered using the shorthand notation. It should be rendered using "cumbersome" notation in order to show these extra relationships.

Agreed. I want to fix it as well.

Also, there actually is a specific graphical notation for reference subsetting. From 8.2.3.6 Definition and Usage Graphical Notation:

image

Can this be used in the "cumbersome" notation to make it clear what the referenced feature is. This is particularly relevant when the perform action usage has other kinds of subsettings, too.

Unfortunately, this requires the update to PlantUML itself. So I plan to support such new symbols in a different schedule.

himi added 3 commits May 6, 2025 19:43
  not exist in the rendering result, we render a distinct
  node (cumbersome notation).
* VDefault (isEmpty): Check Specialization except for
  ReferenceSubsetting
  (addShorthandRelation): Use toBeRendered() to check if the target is rendered.
@himi
Copy link
Member Author

himi commented May 7, 2025

Finally, I could implement to make the visualizer use a cumbersome notation when the target feature is not rendered. However, this is not so straightforward. Let's consider the following example.

package TestFeatureChain1 {
		part p0 {
			perform p2.a0;
			part p1 {
				action a0;
			}
		}
		part p2 :> p0.p1;
	}

The visualizer renders if we render the entire package:
image
If we choose part p0 only, it renders as below:
image
In this case, even though a0 is (indirectly) owned by p0, still the feature chain of p2.p1.a0 is not rendered and the visualizer could not use a shorthand notation.

The next example would be more tricky:

package TestFeatureChain2 {
		part p0 {
			perform p1.p11.a0;
			part p1 {
                part p11 :> p2;
			}
		}
		part p2 {
            action a0;
        }
}

The visualizer renders the entire package as below:
image

And it renders p0 as below:
image

In this case, a0 is not owned by p0 even indirectly but it is rendered by inheritance. So the visualizer can use a shorthand notation.

@seidewitz
Copy link
Member

seidewitz commented May 7, 2025

This is a lot better. But I think event occurrence usages are still not being rendered correctly, probably because of them not having effective names. For example,

        part p0 {
            perform a0;
            perform p1.a11;
            exhibit s0;
            exhibit p1.s11;
            event oc0;
            event p1.oc11;
            use case uc1 {
                include uc0;
                include p1.uc11;
            }

renders as
image
It seems like the event occurrence usages should render similarly to the others, with the keyword «event» and the referenced event (e.g., s0). And shouldn't the include use case usages in this case have the keyword «include», not «include use case»?

…ceUsage,

  caseIncludeUseCaseUsage): Show <<event>> or <<include>> when
  hasRefSubsettingWithoutDeclaredName() is true like perform and exhibit.
@himi
Copy link
Member Author

himi commented May 7, 2025

@seidewitz, thank you for your review. I'd missed it and have just fixed it.

image

@seidewitz
Copy link
Member

The event symbols still show noname, rather than oc0 and oc11.

@himi
Copy link
Member Author

himi commented May 8, 2025

The event symbols still show noname, rather than oc0 and oc11.

It is just printing the result of getName(). I think it is inconsistent if we show the names of referenced names. If we need to do so, does this special rule apply to EventOccrrenceUsage only?

I just come up with an idea. When getName() is null and its reference subsetting exists, how do you think showing ::> referenced? I think it is consistent with the current graphical notation.

@seidewitz
Copy link
Member

I just come up with an idea. When getName() is null and its reference subsetting exists, how do you think showing ::> referenced? I think it is consistent with the current graphical notation.

I guess the graphical notation for this is really not clear in the specification. My understanding was that for symbols using the keywords «event», «perform», etc., the name would always be the name of the referenced feature, consistent with the textual notation. It just happens that, for all the cases other than «event», the effective name is also the name of the referenced feature. But that was not what I had in mind as what was actually being shown.

On the other hand, I agree that it also makes sense to interpret the name compartment of a usage symbol as always showing the (effective) name of that usage. So, I understand your idea of showing ::> referenced if getName() is null. Except then this is then just the same as what could be shown if the keyword was «event occurrence». It is not clear what the point of using «event» is then.

So, I would suggest either using «event» with the name of the referenced event occurrence or using «event occurrence», but showing ::> referenced. The latter wouldn't be entirely consistent with the other cases, but, then, event occurrence usage is different in not having an effective name.

Obviously we should clear this up in the specification in the future, probably when we formalize the mapping from the GBNF to the abstract syntax.

@himi
Copy link
Member Author

himi commented May 8, 2025

I'm getting to understand your point. These nodes representing <<perform>>, <<exhibit>>, <<event>>, and <<include>> are special and its title should print reference rather than its name. I think it's consistent in this sense. I want to change the appearance a bit for example, with some icon implying references like ::>. If you support this special treatment, I will use references instead of name for this nodes. So for example, if we say perform p0.a1, we print p0.a1 instead of just a1, which aligns with the textual notation.

@seidewitz
Copy link
Member

I want to change the appearance a bit for example, with some icon implying references like ::>.

I am not quite sure what you are proposing. As I noted previously, if you include ::> in the graphic for, e.g., «perform», then that would be notationally the same as what you would show for «perform action», so it would not be clear what the point of the shorter form is.

@himi
Copy link
Member Author

himi commented May 8, 2025

My point is that I want to use a special graphical notation for these nodes to specify it is not usual. Anyway, it's much better to use a simple notation and I will use a usual round rentable notation in this PR without further agreement. Do you agree that we use a referencing feature name or feature chain names with <<perform>>, <<exhibit>>, <<event>>, or <<include>>?

@seidewitz
Copy link
Member

My point is that I want to use a special graphical notation for these nodes to specify it is not usual. Anyway, it's much better to use a simple notation and I will use a usual round rentable notation in this PR without further agreement. Do you agree that we use a referencing feature name or feature chain names with <<perform>>, <<exhibit>>, <<event>>, or <<include>>?

Yes, I agree.

  hasRefSubsettingWithoutDeclaredName()
  (addNameWithId): If it's a special reference, use the reference
  name.
  (getNameWithNamespace): Allow enclosingNs to be null.
* VStructure (hasRefSubsettingWithoutDeclaredName): Removed.
(extractTitleName): Use getSpecialReference() instead of
hasRefSubsettingWithoutDeclaredName().
(caseSatisfyRequirementUsage): Ditto.
* SysML2PlantUMLStyle.StyleStereotypeDefaultSwitch: Ditto.
@himi
Copy link
Member Author

himi commented May 8, 2025

Done. Now TestSimple::p0 is rendered as:
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants