-
Notifications
You must be signed in to change notification settings - Fork 0
#683 Add activity constraints #684
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
base: main
Are you sure you want to change the base?
Changes from 14 commits
12cb8f6
58705a8
6fe4ef6
212a07b
3bb41f9
0fa177a
a468205
19fa69f
6b5dc4d
8a1f8c1
ee430c6
3127da1
5aa521f
ab173a0
549e163
8cd8aac
f689a77
686be24
281f185
1c52cc8
49a6a8e
3312f5d
e623614
0487e95
2f63429
f0ba3f0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1649,17 +1649,26 @@ private List<Invariant> createDisableEventsWhenDoneRequirements() { | |
| } | ||
|
|
||
| /** | ||
| * Translates all UML class constraints that are in context to CIF requirement invariants. | ||
| * Translates all UML class constraints that are in context and all activity's constraints to CIF requirement | ||
| * invariants. | ||
| * | ||
| * @return The translated CIF requirement invariants. | ||
| */ | ||
| private List<Invariant> translateRequirements() { | ||
| List<Invariant> cifInvariants = new ArrayList<>(); | ||
|
|
||
| // Translate class requirements. | ||
| for (Constraint umlConstraint: activity.getContext().getOwnedRules()) { | ||
| cifInvariants.addAll(translateRequirement(umlConstraint)); | ||
| } | ||
|
|
||
| // Translate activity requirements. | ||
| for (Constraint umlConstraint: activity.getOwnedRules()) { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it sufficient to translate the requirements like this? Should we also include all requirements of other activities that we call, etc? (all other 'relevant' activities)
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I did this to be consistent with the occurrence constraints: these are considered only during the activity synthesis, not when an activity is called. Better to have a conversation offline about this. |
||
| if (PokaYokeUmlProfileUtil.isRequirementConstraint(umlConstraint)) { | ||
| cifInvariants.addAll(translateRequirement(umlConstraint)); | ||
| } | ||
| } | ||
|
|
||
| return cifInvariants; | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -82,7 +82,7 @@ public class PokaYokeUmlProfileUtil { | |
|
|
||
| private static final String ST_FORMAL_CONSTRAINT = SynthMLPackage.Literals.FORMAL_CONSTRAINT.getName(); | ||
|
|
||
| public static final String ST_CLASS_REQUIREMENT = SynthMLPackage.Literals.REQUIREMENT.getName(); | ||
| public static final String ST_REQUIREMENT = SynthMLPackage.Literals.REQUIREMENT.getName(); | ||
|
|
||
| public static final String ST_SYNTHESIS_PRECONDITION = SynthMLPackage.Literals.SYNTHESIS_PRECONDITION.getName(); | ||
|
|
||
|
|
@@ -112,8 +112,7 @@ public class PokaYokeUmlProfileUtil { | |
| + ST_FORMAL_CONSTRAINT; | ||
|
|
||
| /** Qualified name for the {@link Requirement} stereotype. */ | ||
| public static final String REQUIREMENT_STEREOTYPE = POKA_YOKE_PROFILE + NamedElement.SEPARATOR | ||
| + ST_CLASS_REQUIREMENT; | ||
| public static final String REQUIREMENT_STEREOTYPE = POKA_YOKE_PROFILE + NamedElement.SEPARATOR + ST_REQUIREMENT; | ||
|
|
||
| /** Qualified name for the {@link SynthesisPrecondition} stereotype. */ | ||
| public static final String SYNTHESIS_PRECONDITION_STEREOTYPE = POKA_YOKE_PROFILE + NamedElement.SEPARATOR | ||
|
|
@@ -528,8 +527,8 @@ public static List<Stereotype> getSupportedConstraintStereotypes(Constraint cons | |
| getStereotype(constraint, ST_USAGE_PRECONDITION)); | ||
| } else if (isPostconditionConstraint(constraint)) { | ||
| return List.of(getStereotype(constraint, ST_POSTCONDITION)); | ||
| } else if (isClassRequirement(constraint)) { | ||
| return List.of(getStereotype(constraint, ST_CLASS_REQUIREMENT)); | ||
| } else if (isClassRequirementConstraint(constraint)) { | ||
| return List.of(getStereotype(constraint, ST_REQUIREMENT)); | ||
| } else { | ||
| return List.of(); | ||
| } | ||
|
|
@@ -564,12 +563,22 @@ public static boolean isUsagePrecondition(Constraint constraint) { | |
| return appliedStereotypes.get(0).getName().equals(ST_USAGE_PRECONDITION); | ||
| } | ||
|
|
||
| public static boolean isRequirementConstraint(Constraint constraint) { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe move
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are three methods for 'where' the constraint is (precondition/postcondition of activity, rule of a class/activity), and three methods about what kind (synthesis pre, usage pre, requirement).
|
||
| List<Stereotype> appliedStereotypes = constraint.getAppliedStereotypes(); | ||
|
|
||
| if (appliedStereotypes.isEmpty()) { | ||
| return false; | ||
| } | ||
|
|
||
| return appliedStereotypes.get(0).getName().equals(ST_REQUIREMENT); | ||
| } | ||
|
|
||
| private static boolean isPostconditionConstraint(Constraint constraint) { | ||
| return (constraint.eContainer() instanceof Activity activity) | ||
| && activity.getPostconditions().contains(constraint); | ||
| } | ||
|
|
||
| private static boolean isClassRequirement(Constraint constraint) { | ||
| private static boolean isClassRequirementConstraint(Constraint constraint) { | ||
| return (constraint.eContainer() instanceof Classifier clazz) && clazz.getOwnedRules().contains(constraint); | ||
| } | ||
|
|
||
|
|
@@ -592,7 +601,7 @@ public static void setConstraintStereotype(Constraint constraint, Stereotype ste | |
| } | ||
|
|
||
| private static String getQualifiedStereotypeName(String stereotypeName) { | ||
| if (ST_CLASS_REQUIREMENT.equals(stereotypeName)) { | ||
| if (ST_REQUIREMENT.equals(stereotypeName)) { | ||
| return REQUIREMENT_STEREOTYPE; | ||
| } else if (ST_SYNTHESIS_PRECONDITION.equals(stereotypeName)) { | ||
| return SYNTHESIS_PRECONDITION_STEREOTYPE; | ||
|
|
@@ -616,7 +625,7 @@ public static void setConstraintExpression(Constraint constraint, String newValu | |
|
|
||
| public static String getStereotypeName(Stereotype st) { | ||
| // Returns a slightly better formatted name for the preconditions. | ||
| if (st.getName().equals(ST_CLASS_REQUIREMENT)) { | ||
| if (st.getName().equals(ST_REQUIREMENT)) { | ||
| return "Requirement"; | ||
| } else if (st.getName().equals(ST_SYNTHESIS_PRECONDITION)) { | ||
| return "Synthesis precondition"; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -22,6 +22,7 @@ | |
| import java.util.Stack; | ||
| import java.util.regex.Pattern; | ||
| import java.util.stream.Collectors; | ||
| import java.util.stream.Stream; | ||
|
|
||
| import org.eclipse.escet.cif.parser.ast.AInvariant; | ||
| import org.eclipse.escet.cif.parser.ast.automata.AAssignmentUpdate; | ||
|
|
@@ -544,8 +545,15 @@ private void checkValidActivity(Activity activity) { | |
| .filter(IntervalConstraint.class::isInstance).map(IntervalConstraint.class::cast) | ||
| .collect(Collectors.toCollection(LinkedHashSet::new)); | ||
|
|
||
| if (!members.equals(Sets.union(preAndPostconditions, intervalConstraints))) { | ||
| error("Activity should contain only precondition, postcondition, and interval constraint members.", | ||
| Set<Constraint> activityRequirements = activity.getOwnedRules().stream() | ||
| .filter(r -> PokaYokeUmlProfileUtil.isRequirementConstraint(r)).map(Constraint.class::cast) | ||
| .collect(Collectors.toCollection(LinkedHashSet::new)); | ||
|
|
||
| Set<Constraint> allowedConstraints = Stream.of(preAndPostconditions, intervalConstraints, activityRequirements) | ||
AndreaPuffo marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| .flatMap(Set::stream).collect(Collectors.toSet()); | ||
|
|
||
| if (!members.equals(allowedConstraints)) { | ||
| error("Activity should contain only precondition, postcondition, constraints and interval constraint members.", | ||
| UMLPackage.Literals.NAMESPACE__MEMBER); | ||
| } | ||
|
|
||
|
|
@@ -1003,8 +1011,10 @@ private void checkValidConstraint(Constraint constraint) { | |
|
|
||
| if (CifContext.isActivityPrePostconditionConstraint(constraint)) { | ||
| checkValidActivityPrePostconditionConstraint(constraint); | ||
| } else if (CifContext.isClassConstraint(constraint)) { | ||
| checkValidClassConstraint(constraint); | ||
| } else if (CifContext.isClassConstraint(constraint) | ||
| || (PokaYokeUmlProfileUtil.isRequirementConstraint(constraint))) | ||
|
||
| { | ||
| checkValidRequirementConstraint(constraint); | ||
| } else if (CifContext.isOccurrenceConstraint(constraint)) { | ||
| checkValidOccurrenceConstraint((IntervalConstraint)constraint); | ||
| } else if (CifContext.isPrimitiveTypeConstraint(constraint)) { | ||
|
|
@@ -1058,7 +1068,7 @@ private void checkValidActivityPrePostconditionConstraint(Constraint constraint) | |
| } | ||
| } | ||
|
|
||
| private void checkValidClassConstraint(Constraint constraint) { | ||
| private void checkValidRequirementConstraint(Constraint constraint) { | ||
| // Check that the constraint has the right stereotype applied. | ||
| List<Stereotype> stereotypes = constraint.getAppliedStereotypes(); | ||
|
|
||
|
|
@@ -1068,7 +1078,7 @@ private void checkValidClassConstraint(Constraint constraint) { | |
| return; | ||
| } | ||
|
|
||
| if (!stereotypes.get(0).getName().equals(PokaYokeUmlProfileUtil.ST_CLASS_REQUIREMENT)) { | ||
| if (!stereotypes.get(0).getName().equals(PokaYokeUmlProfileUtil.ST_REQUIREMENT)) { | ||
| error(String.format("Constraint '%s' must have a requirement stereotype applied.", constraint.getName()), | ||
| UMLPackage.Literals.CONSTRAINT__SPECIFICATION); | ||
| return; | ||
|
|
@@ -1080,7 +1090,7 @@ private void checkValidClassConstraint(Constraint constraint) { | |
| } | ||
|
|
||
| try { | ||
| new CifTypeChecker(getGlobalContext(constraint)).checkInvariant(CifParserHelper.parseInvariant(constraint)); | ||
| new CifTypeChecker(getScopedContext(constraint)).checkInvariant(CifParserHelper.parseInvariant(constraint)); | ||
| } catch (RuntimeException e) { | ||
| error("Invalid invariant: " + e.getLocalizedMessage(), UMLPackage.Literals.CONSTRAINT__SPECIFICATION); | ||
| } | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.