diff --git a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/LibraryFunctionFactory.java b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/LibraryFunctionFactory.java index e0f708f41..4f41aca30 100644 --- a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/LibraryFunctionFactory.java +++ b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/LibraryFunctionFactory.java @@ -1,6 +1,6 @@ /******************************************************************************* * SysML 2 Pilot Implementation - * Copyright (c) 2025 Model Driven Solutions, Inc. + * Copyright (c) 2025, 2026 Model Driven Solutions, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -21,7 +21,11 @@ package org.omg.sysml.execution.expressions; -import org.omg.sysml.execution.expressions.functions.*; +import org.omg.sysml.execution.expressions.functions.data.*; +import org.omg.sysml.execution.expressions.functions.control.*; +import org.omg.sysml.execution.expressions.functions.numerical.*; +import org.omg.sysml.execution.expressions.functions.sequence.*; +import org.omg.sysml.execution.expressions.functions.string.*; public class LibraryFunctionFactory extends org.omg.sysml.expressions.ModelLevelLibraryFunctionFactory { @@ -31,15 +35,44 @@ public class LibraryFunctionFactory extends org.omg.sysml.expressions.ModelLevel protected void initializeFunctionMap() { super.initializeFunctionMap(); - put(new SizeFunction()); - put(new IsEmptyFunction()); - put(new NotEmptyFunction()); - put(new IncludesFunction()); - put(new ExcludesFunction()); + // ControlFunctions + put(new ExistsFunction()); + put(new ForAllFunction()); + put(new MinimizeFunction()); + put(new MaximizeFunction()); + put(new ReduceFunction()); + put(new RejectFunction()); + put(new SelectOneFunction()); + + // DataFunctions + put(new MaxFunction()); + put(new MinFunction()); + // NumericalFunctions put(new SumFunction()); put(new ProdFunction()); + // SequenceFunctions + put(new ExcludesFunction()); + put(new ExcludingAtFunction()); + put(new ExcludingFunction()); + put(new HeadFunction()); + put(new IncludesFunction()); + put(new IncludesOnlyFunction()); + put(new IncludingAtFunction()); + put(new IncludingFunction()); + put(new IntersectionFunction()); + put(new IsEmptyFunction()); + put(new LastFunction()); + put(new NotEmptyFunction()); + put(new SequenceEqualsFunction()); + put(new SequenceSameFunction()); + put(new SizeFunction()); + put(new SubsequenceFunction()); + put(new TailFunction()); + put(new UnionFunction()); + + // StringFunctions put(new StringLengthFunction()); put(new StringSubstringFunction()); } diff --git a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/control/ExistsFunction.java b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/control/ExistsFunction.java new file mode 100644 index 000000000..40dac91a8 --- /dev/null +++ b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/control/ExistsFunction.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * SysML 2 Pilot Implementation + * Copyright (c) 2026 Model Driven Solutions, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * @license LGPL-3.0-or-later + * + *******************************************************************************/ +package org.omg.sysml.execution.expressions.functions.control; + +import org.eclipse.emf.common.util.EList; +import org.omg.sysml.expressions.ModelLevelExpressionEvaluator; +import org.omg.sysml.lang.sysml.Element; +import org.omg.sysml.lang.sysml.InvocationExpression; +import org.omg.sysml.util.EvaluationUtil; + +public class ExistsFunction extends ForAllFunction { + + @Override + public String getOperatorName() { + return "exists"; + } + + @Override + public EList invoke(InvocationExpression invocation, Element target, + ModelLevelExpressionEvaluator evaluator) { + Boolean result = forAll(invocation, target, evaluator, false); + return result == null? EvaluationUtil.singletonList(invocation): EvaluationUtil.booleanResult(!result); + } + +} diff --git a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/control/ForAllFunction.java b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/control/ForAllFunction.java new file mode 100644 index 000000000..979f50cbc --- /dev/null +++ b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/control/ForAllFunction.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * SysML 2 Pilot Implementation + * Copyright (c) 2026 Model Driven Solutions, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * @license LGPL-3.0-or-later + * + *******************************************************************************/ +package org.omg.sysml.execution.expressions.functions.control; + +import org.eclipse.emf.common.util.EList; +import org.omg.sysml.expressions.ModelLevelExpressionEvaluator; +import org.omg.sysml.expressions.functions.control.ControlFunction; +import org.omg.sysml.lang.sysml.Element; +import org.omg.sysml.lang.sysml.Expression; +import org.omg.sysml.lang.sysml.InvocationExpression; +import org.omg.sysml.util.EvaluationUtil; + +public class ForAllFunction extends ControlFunction { + + @Override + public String getOperatorName() { + return "forAll"; + } + + public Boolean forAll(InvocationExpression invocation, Element target, + ModelLevelExpressionEvaluator evaluator, Boolean test) { + EList list = evaluator.evaluateArgument(invocation, 0, target); + Element expr = evaluator.argumentValue(invocation, 1, target); + if (list == null || !(expr instanceof Expression)) { + return null; + } else { + for (Element value: list) { + if (value == null) { + return null; + } else { + EList exprValue = evaluator.evaluateExpression((Expression)expr, target, value); + if (exprValue == null || exprValue.size() != 1) { + return null; + } else if (!test.equals(EvaluationUtil.valueOf(exprValue.get(0)))) { + return false; + } + } + } + return true; + } + } + + @Override + public EList invoke(InvocationExpression invocation, Element target, + ModelLevelExpressionEvaluator evaluator) { + Boolean result = forAll(invocation, target, evaluator, true); + return result == null? EvaluationUtil.singletonList(invocation): EvaluationUtil.booleanResult(result); + } + +} diff --git a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/control/MaximizeFunction.java b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/control/MaximizeFunction.java new file mode 100644 index 000000000..79114d34d --- /dev/null +++ b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/control/MaximizeFunction.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * SysML 2 Pilot Implementation + * Copyright (c) 2026 Model Driven Solutions, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * @license LGPL-3.0-or-later + * + *******************************************************************************/ +package org.omg.sysml.execution.expressions.functions.control; + +import java.util.function.BiFunction; + +import org.eclipse.emf.common.util.EList; +import org.omg.sysml.expressions.ModelLevelExpressionEvaluator; +import org.omg.sysml.lang.sysml.Element; +import org.omg.sysml.lang.sysml.Expression; +import org.omg.sysml.lang.sysml.InvocationExpression; +import org.omg.sysml.lang.sysml.Type; +import org.omg.sysml.lang.sysml.util.SysMLLibraryUtil; +import org.omg.sysml.util.EvaluationUtil; + +public class MaximizeFunction extends ReduceFunction { + private static final String MAX_FUNCTION = "DataFunctions::max"; + + @Override + public String getOperatorName() { + return "maximize"; + } + + @Override + public EList invoke(InvocationExpression invocation, Element target, + ModelLevelExpressionEvaluator evaluator) { + EList list = evaluator.evaluateArgument(invocation, 0, target); + Element expr = evaluator.argumentValue(invocation, 1, target); + if (list == null || !(expr instanceof Expression)) { + return EvaluationUtil.singletonList(invocation); + } else if (list.isEmpty()) { + return EvaluationUtil.nullList(); + } else { + return reduce(invocation, list, new BiFunction<>() { + @Override + public Element apply(Element result, Element value) { + EList exprValue = evaluator.evaluateExpression((Expression)expr, target, value); + if (exprValue == null || exprValue.size() != 1) { + return null; + } else if (result == null) { + return exprValue.get(0); + } else { + Type maxFunction = SysMLLibraryUtil.getLibraryType(expr, MAX_FUNCTION); + InvocationExpression maxInvocation = EvaluationUtil.createInvocationOf(maxFunction, result, exprValue.get(0)); + EList newResult = evaluator.evaluateInvocation(maxInvocation, target); + return newResult == null || newResult.size() != 1? null: newResult.get(0); + } + } + }); + } + } + +} diff --git a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/control/MinimizeFunction.java b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/control/MinimizeFunction.java new file mode 100644 index 000000000..215e3641c --- /dev/null +++ b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/control/MinimizeFunction.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * SysML 2 Pilot Implementation + * Copyright (c) 2026 Model Driven Solutions, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * @license LGPL-3.0-or-later + * + *******************************************************************************/ +package org.omg.sysml.execution.expressions.functions.control; + +import java.util.function.BiFunction; + +import org.eclipse.emf.common.util.EList; +import org.omg.sysml.expressions.ModelLevelExpressionEvaluator; +import org.omg.sysml.lang.sysml.Element; +import org.omg.sysml.lang.sysml.Expression; +import org.omg.sysml.lang.sysml.InvocationExpression; +import org.omg.sysml.lang.sysml.Type; +import org.omg.sysml.lang.sysml.util.SysMLLibraryUtil; +import org.omg.sysml.util.EvaluationUtil; + +public class MinimizeFunction extends ReduceFunction { + private static final String MIN_FUNCTION = "DataFunctions::min"; + + @Override + public String getOperatorName() { + return "minimize"; + } + + @Override + public EList invoke(InvocationExpression invocation, Element target, + ModelLevelExpressionEvaluator evaluator) { + EList list = evaluator.evaluateArgument(invocation, 0, target); + Element expr = evaluator.argumentValue(invocation, 1, target); + if (list == null || !(expr instanceof Expression)) { + return EvaluationUtil.singletonList(invocation); + } else if (list.isEmpty()) { + return EvaluationUtil.nullList(); + } else { + return reduce(invocation, list, new BiFunction<>() { + @Override + public Element apply(Element result, Element value) { + EList exprValue = evaluator.evaluateExpression((Expression)expr, target, value); + if (exprValue == null || exprValue.size() != 1) { + return null; + } else if (result == null) { + return exprValue.get(0); + } else { + Type minFunction = SysMLLibraryUtil.getLibraryType(expr, MIN_FUNCTION); + InvocationExpression minInvocation = EvaluationUtil.createInvocationOf(minFunction, result, exprValue.get(0)); + EList newResult = evaluator.evaluateInvocation(minInvocation, target); + return newResult == null || newResult.size() != 1? null: newResult.get(0); + } + } + }); + } + } + +} diff --git a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/control/ReduceFunction.java b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/control/ReduceFunction.java new file mode 100644 index 000000000..c14f36ca7 --- /dev/null +++ b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/control/ReduceFunction.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * SysML 2 Pilot Implementation + * Copyright (c) 2026 Model Driven Solutions, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * @license LGPL-3.0-or-later + * + *******************************************************************************/ +package org.omg.sysml.execution.expressions.functions.control; + +import java.util.function.BiFunction; + +import org.eclipse.emf.common.util.EList; +import org.omg.sysml.expressions.ModelLevelExpressionEvaluator; +import org.omg.sysml.expressions.functions.control.ControlFunction; +import org.omg.sysml.lang.sysml.Element; +import org.omg.sysml.lang.sysml.Expression; +import org.omg.sysml.lang.sysml.InvocationExpression; +import org.omg.sysml.util.EvaluationUtil; + +public class ReduceFunction extends ControlFunction { + + @Override + public String getOperatorName() { + return "reduce"; + } + + protected EList reduce(InvocationExpression invocation, EList list, + BiFunction compute) { + Element result = null; + for (Element value: list) { + if (value == null) { + return EvaluationUtil.singletonList(invocation); + } else { + result = compute.apply(result, value); + if (result == null) { + return EvaluationUtil.singletonList(invocation); + } + } + } + return EvaluationUtil.singletonList(result); + } + + @Override + public EList invoke(InvocationExpression invocation, Element target, + ModelLevelExpressionEvaluator evaluator) { + EList list = evaluator.evaluateArgument(invocation, 0, target); + Element expr = evaluator.argumentValue(invocation, 1, target); + if (list == null || !(expr instanceof Expression)) { + return EvaluationUtil.singletonList(invocation); + } else if (list.isEmpty()) { + return EvaluationUtil.nullList(); + } else { + return reduce(invocation, list, new BiFunction<>() { + @Override + public Element apply(Element result, Element value) { + if (result == null) { + return value; + } else { + EList exprValue = evaluator.evaluateExpression((Expression)expr, target, result, value); + return exprValue == null || exprValue.size() != 1? null: exprValue.get(0); + } + } + }); + } + } + +} diff --git a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/control/RejectFunction.java b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/control/RejectFunction.java new file mode 100644 index 000000000..9ede5eeec --- /dev/null +++ b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/control/RejectFunction.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * SysML 2 Pilot Implementation + * Copyright (c) 2026 Model Driven Solutions, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * @license LGPL-3.0-or-later + * + *******************************************************************************/ +package org.omg.sysml.execution.expressions.functions.control; + +import java.util.function.BiFunction; + +import org.eclipse.emf.common.util.EList; +import org.omg.sysml.expressions.ModelLevelExpressionEvaluator; +import org.omg.sysml.expressions.functions.control.ControlFunction; +import org.omg.sysml.lang.sysml.Element; +import org.omg.sysml.lang.sysml.InvocationExpression; +import org.omg.sysml.util.EvaluationUtil; + +public class RejectFunction extends ControlFunction { + + @Override + public String getOperatorName() { + return "reject"; + } + + @Override + public EList invoke(InvocationExpression invocation, Element target, + ModelLevelExpressionEvaluator evaluator) { + return collectSelected(invocation, target, evaluator, new BiFunction<>() { + @Override + public EList apply(Element value, EList exprValue) { + return exprValue != null && exprValue.size() == 1 && Boolean.FALSE.equals(EvaluationUtil.valueOf(exprValue.get(0)))? + EvaluationUtil.singletonList(value): + EvaluationUtil.nullList(); + } + }); + } + +} diff --git a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/control/SelectOneFunction.java b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/control/SelectOneFunction.java new file mode 100644 index 000000000..d14e20340 --- /dev/null +++ b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/control/SelectOneFunction.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * SysML 2 Pilot Implementation + * Copyright (c) 2026 Model Driven Solutions, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * @license LGPL-3.0-or-later + * + *******************************************************************************/ +package org.omg.sysml.execution.expressions.functions.control; + +import org.eclipse.emf.common.util.EList; +import org.omg.sysml.expressions.ModelLevelExpressionEvaluator; +import org.omg.sysml.expressions.functions.control.SelectFunction; +import org.omg.sysml.lang.sysml.Element; +import org.omg.sysml.lang.sysml.InvocationExpression; +import org.omg.sysml.util.EvaluationUtil; + +public class SelectOneFunction extends SelectFunction { + + @Override + public String getOperatorName() { + return "selectOne"; + } + + @Override + public EList invoke(InvocationExpression invocation, Element target, + ModelLevelExpressionEvaluator evaluator) { + EList list = super.invoke(invocation, target, evaluator); + return list.isEmpty()? EvaluationUtil.nullList(): + EvaluationUtil.singletonList(list.get(0)); + } + +} diff --git a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/data/MaxFunction.java b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/data/MaxFunction.java new file mode 100644 index 000000000..61749a695 --- /dev/null +++ b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/data/MaxFunction.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * SysML 2 Pilot Implementation + * Copyright (c) 2026 Model Driven Solutions, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of theGNU Lesser General Public License + * along with this program. If not, see . + * + * @license LGPL-3.0-or-later + * + *******************************************************************************/ + +package org.omg.sysml.execution.expressions.functions.data; + +import org.eclipse.emf.common.util.EList; +import org.omg.sysml.expressions.functions.data.ArithmeticFunction; +import org.omg.sysml.lang.sysml.Element; +import org.omg.sysml.util.EvaluationUtil; + +public class MaxFunction extends ArithmeticFunction { + + @Override + public String getOperatorName() { + return "max"; + } + + @Override + protected EList binaryIntegerOp(int x, int y) { + return x > y? EvaluationUtil.integerResult(x): EvaluationUtil.integerResult(y); + } + + @Override + protected EList binaryRealOp(double x, double y) { + return x > y? EvaluationUtil.realResult(x): EvaluationUtil.realResult(y); + } + + @Override + protected EList binaryStringOp(String x, String y) { + return x.compareTo(y) > 0? EvaluationUtil.stringResult(x): EvaluationUtil.stringResult(y); + } + +} diff --git a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/data/MinFunction.java b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/data/MinFunction.java new file mode 100644 index 000000000..fd447c90d --- /dev/null +++ b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/data/MinFunction.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * SysML 2 Pilot Implementation + * Copyright (c) 2026 Model Driven Solutions, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of theGNU Lesser General Public License + * along with this program. If not, see . + * + * @license LGPL-3.0-or-later + * + *******************************************************************************/ + +package org.omg.sysml.execution.expressions.functions.data; + +import org.eclipse.emf.common.util.EList; +import org.omg.sysml.expressions.functions.data.ArithmeticFunction; +import org.omg.sysml.lang.sysml.Element; +import org.omg.sysml.util.EvaluationUtil; + +public class MinFunction extends ArithmeticFunction { + + @Override + public String getOperatorName() { + return "min"; + } + + @Override + protected EList binaryIntegerOp(int x, int y) { + return x < y? EvaluationUtil.integerResult(x): EvaluationUtil.integerResult(y); + } + + @Override + protected EList binaryRealOp(double x, double y) { + return x < y? EvaluationUtil.realResult(x): EvaluationUtil.realResult(y); + } + + @Override + protected EList binaryStringOp(String x, String y) { + return x.compareTo(y) < 0? EvaluationUtil.stringResult(x): EvaluationUtil.stringResult(y); + } + +} diff --git a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/NumericalFunction.java b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/numerical/NumericalFunction.java similarity index 94% rename from org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/NumericalFunction.java rename to org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/numerical/NumericalFunction.java index 82e521deb..aeec71f17 100644 --- a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/NumericalFunction.java +++ b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/numerical/NumericalFunction.java @@ -19,7 +19,7 @@ * *******************************************************************************/ -package org.omg.sysml.execution.expressions.functions; +package org.omg.sysml.execution.expressions.functions.numerical; import org.omg.sysml.expressions.functions.LibraryFunction; diff --git a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/ProdFunction.java b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/numerical/ProdFunction.java similarity index 97% rename from org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/ProdFunction.java rename to org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/numerical/ProdFunction.java index d1cd38955..26191a9da 100644 --- a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/ProdFunction.java +++ b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/numerical/ProdFunction.java @@ -19,7 +19,7 @@ * *******************************************************************************/ -package org.omg.sysml.execution.expressions.functions; +package org.omg.sysml.execution.expressions.functions.numerical; import org.eclipse.emf.common.util.EList; import org.omg.sysml.expressions.ModelLevelExpressionEvaluator; diff --git a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/SumFunction.java b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/numerical/SumFunction.java similarity index 97% rename from org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/SumFunction.java rename to org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/numerical/SumFunction.java index d19470a0c..52336023f 100644 --- a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/SumFunction.java +++ b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/numerical/SumFunction.java @@ -19,7 +19,7 @@ * *******************************************************************************/ -package org.omg.sysml.execution.expressions.functions; +package org.omg.sysml.execution.expressions.functions.numerical; import org.eclipse.emf.common.util.EList; import org.omg.sysml.expressions.ModelLevelExpressionEvaluator; diff --git a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/ExcludesFunction.java b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/ExcludesFunction.java similarity index 78% rename from org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/ExcludesFunction.java rename to org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/ExcludesFunction.java index 028c20e8c..09fecb814 100644 --- a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/ExcludesFunction.java +++ b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/ExcludesFunction.java @@ -18,7 +18,7 @@ * @license LGPL-3.0-or-later * *******************************************************************************/ -package org.omg.sysml.execution.expressions.functions; +package org.omg.sysml.execution.expressions.functions.sequence; import org.eclipse.emf.common.util.EList; import org.omg.sysml.expressions.ModelLevelExpressionEvaluator; @@ -35,11 +35,10 @@ public String getOperatorName() { @Override public EList invoke(InvocationExpression invocation, Element target, ModelLevelExpressionEvaluator evaluator) { - EList list = evaluator.evaluateArgument(invocation, 0, target); - Element value = evaluator.argumentValue(invocation, 1, target); - Boolean result = list == null && value == null? null: list.stream().noneMatch(x->EvaluationUtil.equal(x, value)); - return result == null? EvaluationUtil.singletonList(invocation): - EvaluationUtil.booleanResult(result); + EList list1 = evaluator.evaluateArgument(invocation, 0, target); + EList list2 = evaluator.evaluateArgument(invocation, 1, target); + return list1 == null || list2 == null? EvaluationUtil.singletonList(invocation): + EvaluationUtil.booleanResult(list2.stream().allMatch(e2->list1.stream().noneMatch(e1->EvaluationUtil.equal(e1, e2)))); } } diff --git a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/ExcludingAtFunction.java b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/ExcludingAtFunction.java new file mode 100644 index 000000000..3e097cc27 --- /dev/null +++ b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/ExcludingAtFunction.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * SysML 2 Pilot Implementation + * Copyright (c) 2025 Model Driven Solutions, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of theGNU Lesser General Public License + * along with this program. If not, see . + * + * @license LGPL-3.0-or-later + * + *******************************************************************************/ +package org.omg.sysml.execution.expressions.functions.sequence; + +import org.eclipse.emf.common.util.BasicEList; +import org.eclipse.emf.common.util.EList; +import org.omg.sysml.expressions.ModelLevelExpressionEvaluator; +import org.omg.sysml.lang.sysml.Element; +import org.omg.sysml.lang.sysml.InvocationExpression; +import org.omg.sysml.util.EvaluationUtil; + +public class ExcludingAtFunction extends SequenceFunction { + + @Override + public String getOperatorName() { + return "excludingAt"; + } + + @Override + public EList invoke(InvocationExpression invocation, Element target, ModelLevelExpressionEvaluator evaluator) { + EList seq = evaluator.evaluateArgument(invocation, 0, target); + Element startIndex = evaluator.argumentValue(invocation, 1, target); + Element endIndex = evaluator.argumentValue(invocation, 2, target); + if (seq == null || startIndex == null) { + return EvaluationUtil.singletonList(invocation); + } else { + if (endIndex == null) { + endIndex = startIndex; + } + Object startIndexValue = EvaluationUtil.valueOf(startIndex); + Object endIndexValue = EvaluationUtil.valueOf(endIndex); + if (!(startIndexValue == null || startIndexValue instanceof Integer && + endIndexValue == null || endIndexValue instanceof Integer)) { + return EvaluationUtil.singletonList(invocation); + } else if (startIndexValue == null) { + return seq; + } else { + int i = ((Integer)startIndexValue) - 1; + if (i < 0) { + i = 0; + } + int j = endIndexValue == null? seq.size(): ((Integer)endIndexValue); + if (j < 0) { + j = 0; + } + if (j < i) { + return seq; + } else { + EList result = new BasicEList<>(seq.subList(0, i)); + result.addAll(seq.subList(j, seq.size())); + return result; + } + } + } + } + +} diff --git a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/ExcludingFunction.java b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/ExcludingFunction.java new file mode 100644 index 000000000..bf637afd2 --- /dev/null +++ b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/ExcludingFunction.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * SysML 2 Pilot Implementation + * Copyright (c) 2025 Model Driven Solutions, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of theGNU Lesser General Public License + * along with this program. If not, see . + * + * @license LGPL-3.0-or-later + * + *******************************************************************************/ +package org.omg.sysml.execution.expressions.functions.sequence; + +import org.eclipse.emf.common.util.BasicEList; +import org.eclipse.emf.common.util.EList; +import org.omg.sysml.expressions.ModelLevelExpressionEvaluator; +import org.omg.sysml.lang.sysml.Element; +import org.omg.sysml.lang.sysml.InvocationExpression; +import org.omg.sysml.util.EvaluationUtil; + +public class ExcludingFunction extends SequenceFunction { + + @Override + public String getOperatorName() { + return "excluding"; + } + + @Override + public EList invoke(InvocationExpression invocation, Element target, ModelLevelExpressionEvaluator evaluator) { + EList list1 = evaluator.evaluateArgument(invocation, 0, target); + EList list2 = evaluator.evaluateArgument(invocation, 1, target); + if (list1 == null || list2 == null) { + return EvaluationUtil.singletonList(invocation); + } else { + EList result = new BasicEList<>(list1); + result.removeIf(e1->list2.stream().anyMatch(e2->EvaluationUtil.equal(e1, e2))); + return result; + } + } + +} diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/functions/EqualsFunction.java b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/HeadFunction.java similarity index 73% rename from org.omg.sysml/src/org/omg/sysml/expressions/functions/EqualsFunction.java rename to org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/HeadFunction.java index 814553cde..8a879b134 100644 --- a/org.omg.sysml/src/org/omg/sysml/expressions/functions/EqualsFunction.java +++ b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/HeadFunction.java @@ -1,6 +1,6 @@ /******************************************************************************* * SysML 2 Pilot Implementation - * Copyright (c) 2021 Model Driven Solutions, Inc. + * Copyright (c) 2025 Model Driven Solutions, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -18,8 +18,7 @@ * @license LGPL-3.0-or-later * *******************************************************************************/ - -package org.omg.sysml.expressions.functions; +package org.omg.sysml.execution.expressions.functions.sequence; import org.eclipse.emf.common.util.EList; import org.omg.sysml.expressions.ModelLevelExpressionEvaluator; @@ -27,19 +26,19 @@ import org.omg.sysml.lang.sysml.InvocationExpression; import org.omg.sysml.util.EvaluationUtil; -public class EqualsFunction extends BaseFunction { +public class HeadFunction extends SequenceFunction { @Override public String getOperatorName() { - return "'=='"; + return "head"; } - + @Override public EList invoke(InvocationExpression invocation, Element target, ModelLevelExpressionEvaluator evaluator) { - EList x = evaluator.evaluateArgument(invocation, 0, target); - EList y = evaluator.evaluateArgument(invocation, 1, target); - Boolean result = x == null || y == null? null: EvaluationUtil.equal(x, y); - return result == null? EvaluationUtil.singletonList(invocation): EvaluationUtil.booleanResult(result); + EList seq = evaluator.evaluateArgument(invocation, 0, target); + return seq == null? EvaluationUtil.singletonList(invocation): + seq.isEmpty()? EvaluationUtil.nullList(): + EvaluationUtil.singletonList(seq.getFirst()); } } diff --git a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/IncludesFunction.java b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/IncludesFunction.java new file mode 100644 index 000000000..f4b0f5dae --- /dev/null +++ b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/IncludesFunction.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * SysML 2 Pilot Implementation + * Copyright (c) 2021, 2025 Model Driven Solutions, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of theGNU Lesser General Public License + * along with this program. If not, see . + * + * @license LGPL-3.0-or-later + * + *******************************************************************************/ +package org.omg.sysml.execution.expressions.functions.sequence; + +import org.eclipse.emf.common.util.EList; +import org.omg.sysml.expressions.ModelLevelExpressionEvaluator; +import org.omg.sysml.lang.sysml.Element; +import org.omg.sysml.lang.sysml.InvocationExpression; +import org.omg.sysml.util.EvaluationUtil; + +public class IncludesFunction extends SequenceFunction { + + @Override + public String getOperatorName() { + return "includes"; + } + + @Override + public EList invoke(InvocationExpression invocation, Element target, ModelLevelExpressionEvaluator evaluator) { + EList list1 = evaluator.evaluateArgument(invocation, 0, target); + EList list2 = evaluator.evaluateArgument(invocation, 1, target); + return list1 == null || list2 == null? EvaluationUtil.singletonList(invocation): + list2.isEmpty()? EvaluationUtil.booleanResult(true): + list1.isEmpty()? EvaluationUtil.booleanResult(false): + EvaluationUtil.booleanResult(includes(list1, list2)); + } + + protected static boolean includes(EList list1, EList list2) { + return list2.stream().allMatch(x->list1.stream().anyMatch(y->EvaluationUtil.equal(x, y))); + } + +} diff --git a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/IncludesOnlyFunction.java b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/IncludesOnlyFunction.java new file mode 100644 index 000000000..013e52264 --- /dev/null +++ b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/IncludesOnlyFunction.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * SysML 2 Pilot Implementation + * Copyright (c) 2025 Model Driven Solutions, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of theGNU Lesser General Public License + * along with this program. If not, see . + * + * @license LGPL-3.0-or-later + * + *******************************************************************************/ +package org.omg.sysml.execution.expressions.functions.sequence; + +import org.eclipse.emf.common.util.EList; +import org.omg.sysml.expressions.ModelLevelExpressionEvaluator; +import org.omg.sysml.lang.sysml.Element; +import org.omg.sysml.lang.sysml.InvocationExpression; +import org.omg.sysml.util.EvaluationUtil; + +public class IncludesOnlyFunction extends IncludesFunction { + + @Override + public String getOperatorName() { + return "includesOnly"; + } + + @Override + public EList invoke(InvocationExpression invocation, Element target, ModelLevelExpressionEvaluator evaluator) { + EList list1 = evaluator.evaluateArgument(invocation, 0, target); + EList list2 = evaluator.evaluateArgument(invocation, 1, target); + return list1 == null || list2 == null? EvaluationUtil.singletonList(invocation): + list2.isEmpty()? EvaluationUtil.booleanResult(list1.isEmpty()): + list1.isEmpty()? EvaluationUtil.booleanResult(false): + EvaluationUtil.booleanResult(includes(list1, list2) && includes(list2, list1)); + } + +} diff --git a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/IncludingAtFunction.java b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/IncludingAtFunction.java new file mode 100644 index 000000000..9685dcd1e --- /dev/null +++ b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/IncludingAtFunction.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * SysML 2 Pilot Implementation + * Copyright (c) 2025 Model Driven Solutions, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of theGNU Lesser General Public License + * along with this program. If not, see . + * + * @license LGPL-3.0-or-later + * + *******************************************************************************/ +package org.omg.sysml.execution.expressions.functions.sequence; + +import org.eclipse.emf.common.util.BasicEList; +import org.eclipse.emf.common.util.EList; +import org.omg.sysml.expressions.ModelLevelExpressionEvaluator; +import org.omg.sysml.lang.sysml.Element; +import org.omg.sysml.lang.sysml.InvocationExpression; +import org.omg.sysml.util.EvaluationUtil; + +public class IncludingAtFunction extends SequenceFunction { + + @Override + public String getOperatorName() { + return "includingAt"; + } + + @Override + public EList invoke(InvocationExpression invocation, Element target, ModelLevelExpressionEvaluator evaluator) { + EList seq = evaluator.evaluateArgument(invocation, 0, target); + EList values = evaluator.evaluateArgument(invocation, 1, target); + Element index = evaluator.argumentValue(invocation, 2, target); + if (seq == null || values == null || index == null) { + return EvaluationUtil.singletonList(invocation); + } else { + Object indexValue = EvaluationUtil.valueOf(index); + if (!(indexValue == null || indexValue instanceof Integer)) { + return EvaluationUtil.singletonList(invocation); + } else { + int i = indexValue == null? seq.size(): ((Integer)indexValue) - 1; + if (i < 0) { + i = 0; + } + EList result = new BasicEList<>(seq.subList(0, i)); + result.addAll(values); + result.addAll(seq.subList(i, seq.size())); + return result; + } + } + } + +} diff --git a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/IncludingFunction.java b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/IncludingFunction.java new file mode 100644 index 000000000..d986472d8 --- /dev/null +++ b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/IncludingFunction.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * SysML 2 Pilot Implementation + * Copyright (c) 2025 Model Driven Solutions, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of theGNU Lesser General Public License + * along with this program. If not, see . + * + * @license LGPL-3.0-or-later + * + *******************************************************************************/ +package org.omg.sysml.execution.expressions.functions.sequence; + +public class IncludingFunction extends UnionFunction { + + @Override + public String getOperatorName() { + return "including"; + } + +} diff --git a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/IntersectionFunction.java b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/IntersectionFunction.java new file mode 100644 index 000000000..b532d1b60 --- /dev/null +++ b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/IntersectionFunction.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * SysML 2 Pilot Implementation + * Copyright (c) 2025 Model Driven Solutions, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of theGNU Lesser General Public License + * along with this program. If not, see . + * + * @license LGPL-3.0-or-later + * + *******************************************************************************/ +package org.omg.sysml.execution.expressions.functions.sequence; + +import org.eclipse.emf.common.util.BasicEList; +import org.eclipse.emf.common.util.EList; +import org.omg.sysml.expressions.ModelLevelExpressionEvaluator; +import org.omg.sysml.lang.sysml.Element; +import org.omg.sysml.lang.sysml.InvocationExpression; +import org.omg.sysml.util.EvaluationUtil; + +public class IntersectionFunction extends SequenceFunction { + + @Override + public String getOperatorName() { + return "intersection"; + } + + @Override + public EList invoke(InvocationExpression invocation, Element target, ModelLevelExpressionEvaluator evaluator) { + EList list1 = evaluator.evaluateArgument(invocation, 0, target); + EList list2 = evaluator.evaluateArgument(invocation, 1, target); + if (list1 == null || list2 == null) { + return EvaluationUtil.singletonList(invocation); + } else { + EList result = new BasicEList<>(list1); + result.removeIf(e1->list2.stream().noneMatch(e2->EvaluationUtil.equal(e1, e2))); + return result; + } + } + +} diff --git a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/IsEmptyFunction.java b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/IsEmptyFunction.java similarity index 96% rename from org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/IsEmptyFunction.java rename to org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/IsEmptyFunction.java index 80559352d..07c4555f6 100644 --- a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/IsEmptyFunction.java +++ b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/IsEmptyFunction.java @@ -18,7 +18,7 @@ * @license LGPL-3.0-or-later * *******************************************************************************/ -package org.omg.sysml.execution.expressions.functions; +package org.omg.sysml.execution.expressions.functions.sequence; import org.eclipse.emf.common.util.EList; import org.omg.sysml.expressions.ModelLevelExpressionEvaluator; diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/functions/NotEqualsFunction.java b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/LastFunction.java similarity index 73% rename from org.omg.sysml/src/org/omg/sysml/expressions/functions/NotEqualsFunction.java rename to org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/LastFunction.java index 73e1ffbef..d6b05655f 100644 --- a/org.omg.sysml/src/org/omg/sysml/expressions/functions/NotEqualsFunction.java +++ b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/LastFunction.java @@ -1,6 +1,6 @@ /******************************************************************************* * SysML 2 Pilot Implementation - * Copyright (c) 2021 Model Driven Solutions, Inc. + * Copyright (c) 2025 Model Driven Solutions, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -18,8 +18,7 @@ * @license LGPL-3.0-or-later * *******************************************************************************/ - -package org.omg.sysml.expressions.functions; +package org.omg.sysml.execution.expressions.functions.sequence; import org.eclipse.emf.common.util.EList; import org.omg.sysml.expressions.ModelLevelExpressionEvaluator; @@ -27,19 +26,19 @@ import org.omg.sysml.lang.sysml.InvocationExpression; import org.omg.sysml.util.EvaluationUtil; -public class NotEqualsFunction extends BaseFunction { +public class LastFunction extends SequenceFunction { @Override public String getOperatorName() { - return "'!='"; + return "last"; } - + @Override public EList invoke(InvocationExpression invocation, Element target, ModelLevelExpressionEvaluator evaluator) { - EList x = evaluator.evaluateArgument(invocation, 0, target); - EList y = evaluator.evaluateArgument(invocation, 1, target); - Boolean result = x == null || y == null? null: !EvaluationUtil.equal(x, y); - return result == null? EvaluationUtil.singletonList(invocation): EvaluationUtil.booleanResult(result); + EList seq = evaluator.evaluateArgument(invocation, 0, target); + return seq == null? EvaluationUtil.singletonList(invocation): + seq.isEmpty()? EvaluationUtil.nullList(): + EvaluationUtil.singletonList(seq.getLast()); } } diff --git a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/NotEmptyFunction.java b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/NotEmptyFunction.java similarity index 96% rename from org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/NotEmptyFunction.java rename to org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/NotEmptyFunction.java index 037f6a986..45f58e3bf 100644 --- a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/NotEmptyFunction.java +++ b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/NotEmptyFunction.java @@ -18,7 +18,7 @@ * @license LGPL-3.0-or-later * *******************************************************************************/ -package org.omg.sysml.execution.expressions.functions; +package org.omg.sysml.execution.expressions.functions.sequence; import org.eclipse.emf.common.util.EList; import org.omg.sysml.expressions.ModelLevelExpressionEvaluator; diff --git a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/SequenceEqualsFunction.java b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/SequenceEqualsFunction.java new file mode 100644 index 000000000..8a634e46f --- /dev/null +++ b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/SequenceEqualsFunction.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * SysML 2 Pilot Implementation + * Copyright (c) 2025 Model Driven Solutions, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of theGNU Lesser General Public License + * along with this program. If not, see . + * + * @license LGPL-3.0-or-later + * + *******************************************************************************/ + +package org.omg.sysml.execution.expressions.functions.sequence; + +import org.eclipse.emf.common.util.EList; +import org.omg.sysml.expressions.ModelLevelExpressionEvaluator; +import org.omg.sysml.lang.sysml.Element; +import org.omg.sysml.lang.sysml.InvocationExpression; +import org.omg.sysml.util.EvaluationUtil; + +public class SequenceEqualsFunction extends SequenceFunction { + + @Override + public String getOperatorName() { + return "equals"; + } + + @Override + public EList invoke(InvocationExpression invocation, Element target, + ModelLevelExpressionEvaluator evaluator) { + EList list1 = evaluator.evaluateArgument(invocation, 0, target); + EList list2 = evaluator.evaluateArgument(invocation, 1, target); + return list1 == null || list2 == null? EvaluationUtil.singletonList(invocation): + EvaluationUtil.booleanResult(EvaluationUtil.equal(list1, list2)); + } + +} diff --git a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/SequenceFunction.java b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/SequenceFunction.java similarity index 95% rename from org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/SequenceFunction.java rename to org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/SequenceFunction.java index 2d54a94cd..6d949cadd 100644 --- a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/SequenceFunction.java +++ b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/SequenceFunction.java @@ -19,7 +19,7 @@ * *******************************************************************************/ -package org.omg.sysml.execution.expressions.functions; +package org.omg.sysml.execution.expressions.functions.sequence; import org.omg.sysml.expressions.functions.LibraryFunction; diff --git a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/SequenceSameFunction.java b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/SequenceSameFunction.java new file mode 100644 index 000000000..75eef547a --- /dev/null +++ b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/SequenceSameFunction.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * SysML 2 Pilot Implementation + * Copyright (c) 2025 Model Driven Solutions, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of theGNU Lesser General Public License + * along with this program. If not, see . + * + * @license LGPL-3.0-or-later + * + *******************************************************************************/ + +package org.omg.sysml.execution.expressions.functions.sequence; + +import org.eclipse.emf.common.util.EList; +import org.omg.sysml.expressions.ModelLevelExpressionEvaluator; +import org.omg.sysml.lang.sysml.Element; +import org.omg.sysml.lang.sysml.InvocationExpression; +import org.omg.sysml.util.EvaluationUtil; + +public class SequenceSameFunction extends SequenceEqualsFunction { + + @Override + public String getOperatorName() { + return "same"; + } + + @Override + public EList invoke(InvocationExpression invocation, Element target, + ModelLevelExpressionEvaluator evaluator) { + EList list1 = evaluator.evaluateArgument(invocation, 0, target); + EList list2 = evaluator.evaluateArgument(invocation, 1, target); + return list1 == null || list2 == null? EvaluationUtil.singletonList(invocation): + EvaluationUtil.booleanResult(EvaluationUtil.equal(list1, list2)); + } + +} diff --git a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/SizeFunction.java b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/SizeFunction.java similarity index 96% rename from org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/SizeFunction.java rename to org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/SizeFunction.java index 7f1edc0e9..c38e91de4 100644 --- a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/SizeFunction.java +++ b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/SizeFunction.java @@ -18,7 +18,7 @@ * @license LGPL-3.0-or-later * *******************************************************************************/ -package org.omg.sysml.execution.expressions.functions; +package org.omg.sysml.execution.expressions.functions.sequence; import org.eclipse.emf.common.util.EList; import org.omg.sysml.expressions.ModelLevelExpressionEvaluator; diff --git a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/SubsequenceFunction.java b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/SubsequenceFunction.java new file mode 100644 index 000000000..eaa4e19cb --- /dev/null +++ b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/SubsequenceFunction.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * SysML 2 Pilot Implementation + * Copyright (c) 2025 Model Driven Solutions, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of theGNU Lesser General Public License + * along with this program. If not, see . + * + * @license LGPL-3.0-or-later + * + *******************************************************************************/ +package org.omg.sysml.execution.expressions.functions.sequence; + +import org.eclipse.emf.common.util.BasicEList; +import org.eclipse.emf.common.util.EList; +import org.omg.sysml.expressions.ModelLevelExpressionEvaluator; +import org.omg.sysml.lang.sysml.Element; +import org.omg.sysml.lang.sysml.InvocationExpression; +import org.omg.sysml.util.EvaluationUtil; + +public class SubsequenceFunction extends SequenceFunction { + + @Override + public String getOperatorName() { + return "subsequence"; + } + + @Override + public EList invoke(InvocationExpression invocation, Element target, ModelLevelExpressionEvaluator evaluator) { + EList seq = evaluator.evaluateArgument(invocation, 0, target); + Element startIndex = evaluator.argumentValue(invocation, 1, target); + Element endIndex = evaluator.argumentValue(invocation, 2, target); + if (seq == null || startIndex == null) { + return EvaluationUtil.singletonList(invocation); + } else { + Object startIndexValue = EvaluationUtil.valueOf(startIndex); + Object endIndexValue = endIndex == null? null: EvaluationUtil.valueOf(endIndex); + if (!((startIndexValue == null || startIndexValue instanceof Integer) && + (endIndexValue == null || endIndexValue instanceof Integer))) { + return EvaluationUtil.singletonList(invocation); + } else if (startIndexValue == null) { + return EvaluationUtil.nullList(); + } else { + int i = ((Integer)startIndexValue) - 1; + if (i < 0) { + i = 0; + } + int j = endIndexValue == null? seq.size(): ((Integer)endIndexValue); + if (j < 0) { + j = 0; + } + if (j < i) { + return EvaluationUtil.nullList(); + } else { + return new BasicEList<>(seq.subList(i, j)); + } + } + } + } + +} diff --git a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/IncludesFunction.java b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/TailFunction.java similarity index 71% rename from org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/IncludesFunction.java rename to org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/TailFunction.java index e5fc1e0ed..777bf95e6 100644 --- a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/IncludesFunction.java +++ b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/TailFunction.java @@ -1,6 +1,6 @@ /******************************************************************************* * SysML 2 Pilot Implementation - * Copyright (c) 2021, 2025 Model Driven Solutions, Inc. + * Copyright (c) 2025 Model Driven Solutions, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -18,28 +18,28 @@ * @license LGPL-3.0-or-later * *******************************************************************************/ -package org.omg.sysml.execution.expressions.functions; +package org.omg.sysml.execution.expressions.functions.sequence; +import org.eclipse.emf.common.util.BasicEList; import org.eclipse.emf.common.util.EList; import org.omg.sysml.expressions.ModelLevelExpressionEvaluator; import org.omg.sysml.lang.sysml.Element; import org.omg.sysml.lang.sysml.InvocationExpression; import org.omg.sysml.util.EvaluationUtil; -public class IncludesFunction extends SequenceFunction { +public class TailFunction extends SequenceFunction { @Override public String getOperatorName() { - return "includes"; + return "tail"; } @Override public EList invoke(InvocationExpression invocation, Element target, ModelLevelExpressionEvaluator evaluator) { - EList list = evaluator.evaluateArgument(invocation, 0, target); - Element value = evaluator.argumentValue(invocation, 1, target); - Boolean result = list == null && value == null? null: list.stream().anyMatch(x->EvaluationUtil.equal(x, value)); - return result == null? EvaluationUtil.singletonList(invocation): - EvaluationUtil.booleanResult(result); + EList seq = evaluator.evaluateArgument(invocation, 0, target); + return seq == null? EvaluationUtil.singletonList(invocation): + seq.size() <= 1? EvaluationUtil.nullList(): + new BasicEList<>(seq.subList(1, seq.size())); } } diff --git a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/UnionFunction.java b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/UnionFunction.java new file mode 100644 index 000000000..8ba9843b8 --- /dev/null +++ b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/sequence/UnionFunction.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * SysML 2 Pilot Implementation + * Copyright (c) 2025 Model Driven Solutions, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of theGNU Lesser General Public License + * along with this program. If not, see . + * + * @license LGPL-3.0-or-later + * + *******************************************************************************/ +package org.omg.sysml.execution.expressions.functions.sequence; + +import org.omg.sysml.expressions.functions.base.ListConcatFunction; + +public class UnionFunction extends ListConcatFunction { + + @Override + public String getPackageName() { + return "SequenceFunctions"; + } + + @Override + public String getOperatorName() { + return "union"; + } + +} diff --git a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/StringFunction.java b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/string/StringFunction.java similarity index 95% rename from org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/StringFunction.java rename to org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/string/StringFunction.java index 0eae736b8..34b43bdfe 100644 --- a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/StringFunction.java +++ b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/string/StringFunction.java @@ -19,7 +19,7 @@ * *******************************************************************************/ -package org.omg.sysml.execution.expressions.functions; +package org.omg.sysml.execution.expressions.functions.string; import org.omg.sysml.expressions.functions.LibraryFunction; diff --git a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/StringLengthFunction.java b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/string/StringLengthFunction.java similarity index 96% rename from org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/StringLengthFunction.java rename to org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/string/StringLengthFunction.java index 44030a165..85d38ca65 100644 --- a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/StringLengthFunction.java +++ b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/string/StringLengthFunction.java @@ -19,7 +19,7 @@ * *******************************************************************************/ -package org.omg.sysml.execution.expressions.functions; +package org.omg.sysml.execution.expressions.functions.string; import org.eclipse.emf.common.util.EList; import org.omg.sysml.expressions.ModelLevelExpressionEvaluator; diff --git a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/StringSubstringFunction.java b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/string/StringSubstringFunction.java similarity index 97% rename from org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/StringSubstringFunction.java rename to org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/string/StringSubstringFunction.java index c97a98fea..7b7cf7004 100644 --- a/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/StringSubstringFunction.java +++ b/org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/functions/string/StringSubstringFunction.java @@ -19,7 +19,7 @@ * *******************************************************************************/ -package org.omg.sysml.execution.expressions.functions; +package org.omg.sysml.execution.expressions.functions.string; import org.eclipse.emf.common.util.EList; import org.omg.sysml.expressions.ModelLevelExpressionEvaluator; diff --git a/org.omg.sysml.interactive.tests/src/org/omg/sysml/interactive/tests/ExpressionEvaluationTest.java b/org.omg.sysml.interactive.tests/src/org/omg/sysml/interactive/tests/ExpressionEvaluationTest.java index e63a7708e..fdb4da91b 100644 --- a/org.omg.sysml.interactive.tests/src/org/omg/sysml/interactive/tests/ExpressionEvaluationTest.java +++ b/org.omg.sysml.interactive.tests/src/org/omg/sysml/interactive/tests/ExpressionEvaluationTest.java @@ -1,7 +1,7 @@ /******************************************************************************* * SysML 2 Pilot Implementation * Copyright (c) 2022 Mgnite, Inc. - * Copyright (c) 2022, 2023 Model Driven Solutions, Inc. + * Copyright (c) 2022, 2023, 2025-2026 Model Driven Solutions, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -125,7 +125,7 @@ public void testEvaluation3() throws Exception { assertElement("LiteralInteger 15", instance.eval("p12.a2", "EvalTest3")); } - // Tests inherited context with a redefined (bound) outer features. + // Tests inherited context with redefined (bound) outer features. public final String evalTest4 = "package EvalTest4 {\n" + " part p1 {\n" @@ -355,8 +355,8 @@ public void testIndexOperator() throws Exception { public void testInvocationEvaluation() throws Exception { SysMLInteractive instance = getSysMLInteractiveInstance(); process(instance, invocationTest); -// assertElement("LiteralInteger 1", instance.eval("Test(1, 2)", "InvocationTest")); -// assertElement("LiteralInteger 1", instance.eval("Test(x = 1, y = 2)", "InvocationTest")); + assertElement("LiteralInteger 1", instance.eval("Test(1, 2)", "InvocationTest")); + assertElement("LiteralInteger 1", instance.eval("Test(x = 1, y = 2)", "InvocationTest")); assertElement("LiteralInteger 1", instance.eval("Test(y = 2, x = 1)", "InvocationTest")); } @@ -378,32 +378,191 @@ public void testListOpsExpression() throws Exception { assertList(new String[] {}, instance.eval("()", null)); assertList(new String[]{"LiteralInteger 1", "LiteralInteger 2", "LiteralInteger 3"}, instance.eval("(1, 2, 3)", null)); assertList(new String[]{"LiteralInteger 1", "LiteralInteger 2", "LiteralInteger 3"}, instance.eval("1..3", null)); + } + + + @Test + public void testControlOpEvaluation() throws Exception { + SysMLInteractive instance = getSysMLInteractiveInstance(); + assertList(new String[] {"LiteralInteger 2", "LiteralInteger 4", "LiteralInteger 6"}, instance.eval("(1,2,3).{in x : ScalarValues::Integer; x * 2}", null)); + assertList(new String[] {"LiteralInteger 1", "LiteralInteger 2"}, instance.eval("(1,2,3).?{in x : ScalarValues::Integer; x < 3}", null)); + } + + @Test + public void testDataFunctionEvaluation() throws Exception { + SysMLInteractive instance = getSysMLInteractiveInstance(); + + assertElement("LiteralInteger 2", instance.eval("DataFunctions::max(1,2)", null)); + assertElement("LiteralInteger 2", instance.eval("DataFunctions::max(2,1)", null)); + assertElement("LiteralInteger 2", instance.eval("DataFunctions::max(2,2)", null)); + assertElement("LiteralRational 2.0", instance.eval("DataFunctions::max(1,2.0)", null)); + assertElement("LiteralRational 2.0", instance.eval("DataFunctions::max(2,1.0)", null)); + assertElement("LiteralRational 2.0", instance.eval("DataFunctions::max(2.0,2.0)", null)); + assertElement("LiteralString b", instance.eval("DataFunctions::max(\"a\", \"b\")", null)); + assertElement("LiteralString b", instance.eval("DataFunctions::max(\"b\", \"a\")", null)); + assertElement("LiteralString b", instance.eval("DataFunctions::max(\"b\", \"b\")", null)); + + assertElement("LiteralInteger 1", instance.eval("DataFunctions::min(1,2)", null)); + assertElement("LiteralInteger 1", instance.eval("DataFunctions::min(2,1)", null)); + assertElement("LiteralInteger 1", instance.eval("DataFunctions::min(1,1)", null)); + assertElement("LiteralRational 1.0", instance.eval("DataFunctions::min(1,2.0)", null)); + assertElement("LiteralRational 1.0", instance.eval("DataFunctions::min(2,1.0)", null)); + assertElement("LiteralRational 1.0", instance.eval("DataFunctions::min(1.0,1.0)", null)); + assertElement("LiteralString a", instance.eval("DataFunctions::min(\"a\", \"b\")", null)); + assertElement("LiteralString a", instance.eval("DataFunctions::min(\"b\", \"a\")", null)); + assertElement("LiteralString a", instance.eval("DataFunctions::min(\"a\", \"a\")", null)); + } + + @Test + public void testNumericalFunctionEvaluation() throws Exception { + SysMLInteractive instance = getSysMLInteractiveInstance(); + assertElement("LiteralInteger 6", instance.eval("NumericalFunctions::sum((1,2,3))", null)); + assertElement("LiteralInteger 6", instance.eval("NumericalFunctions::product((1,2,3))", null)); + } + + @Test + public void testSequenceFunctionEvaluation() throws Exception { + SysMLInteractive instance = getSysMLInteractiveInstance(); assertElement("LiteralInteger 3", instance.eval("SequenceFunctions::size((1, 2, 3))", null)); + assertElement("LiteralBoolean true", instance.eval("SequenceFunctions::includes((1, 2, 3), 1)", null)); assertElement("LiteralBoolean false", instance.eval("SequenceFunctions::includes((1, 2, 3), 5)", null)); + assertElement("LiteralBoolean true", instance.eval("SequenceFunctions::includes((1, 2, 3), (1, 3))", null)); + assertElement("LiteralBoolean false", instance.eval("SequenceFunctions::includes((1, 2, 3), (1, 5))", null)); + + assertElement("LiteralBoolean true", instance.eval("SequenceFunctions::includesOnly((1, 2, 3), (3, 2, 1))", null)); + assertElement("LiteralBoolean false", instance.eval("SequenceFunctions::includesOnly((1, 2, 3), (1, 5))", null)); + assertElement("LiteralBoolean false", instance.eval("SequenceFunctions::excludes((1, 2, 3), 1)", null)); assertElement("LiteralBoolean true", instance.eval("SequenceFunctions::excludes((1, 2, 3), 5)", null)); + assertElement("LiteralBoolean true", instance.eval("SequenceFunctions::isEmpty(null)", null)); assertElement("LiteralBoolean false", instance.eval("SequenceFunctions::isEmpty(1)", null)); assertElement("LiteralBoolean false", instance.eval("SequenceFunctions::isEmpty((1,2,3))", null)); + assertElement("LiteralBoolean false", instance.eval("SequenceFunctions::notEmpty(null)", null)); assertElement("LiteralBoolean true", instance.eval("SequenceFunctions::notEmpty(1)", null)); assertElement("LiteralBoolean true", instance.eval("SequenceFunctions::notEmpty((1,2,3))", null)); + + assertElement("LiteralBoolean true", instance.eval("SequenceFunctions::equals((1, 2, 3), (1, 2, 3))", null)); + assertElement("LiteralBoolean false", instance.eval("SequenceFunctions::equals((1, 2, 3), (2, 1, 3))", null)); + assertElement("LiteralBoolean false", instance.eval("SequenceFunctions::equals((1, 2, 3), (1, 5))", null)); + + assertElement("LiteralBoolean true", instance.eval("SequenceFunctions::same((1, 2, 3), (1, 2, 3))", null)); + assertElement("LiteralBoolean false", instance.eval("SequenceFunctions::same((1, 2, 3), (2, 1, 3))", null)); + assertElement("LiteralBoolean false", instance.eval("SequenceFunctions::same((1, 2, 3), (1, 5))", null)); + + assertList(new String[]{"LiteralInteger 1", "LiteralInteger 2", "LiteralInteger 3", "LiteralInteger 4"}, instance.eval("SequenceFunctions::including((1, 2, 3), 4)", null)); + assertList(new String[]{"LiteralInteger 1", "LiteralInteger 2", "LiteralInteger 3", "LiteralInteger 4", "LiteralInteger 5"}, instance.eval("SequenceFunctions::including((1, 2, 3), (4,5))", null)); + assertList(new String[]{"LiteralInteger 1", "LiteralInteger 2", "LiteralInteger 3"}, instance.eval("SequenceFunctions::including((1, 2, 3), ())", null)); + + assertList(new String[]{"LiteralInteger 4", "LiteralInteger 1", "LiteralInteger 2", "LiteralInteger 3"}, instance.eval("SequenceFunctions::includingAt((1, 2, 3), 4, 1)", null)); + assertList(new String[]{"LiteralInteger 1", "LiteralInteger 4", "LiteralInteger 5", "LiteralInteger 2", "LiteralInteger 3"}, instance.eval("SequenceFunctions::includingAt((1, 2, 3), (4,5), 2)", null)); + assertList(new String[]{"LiteralInteger 1", "LiteralInteger 2", "LiteralInteger 3", "LiteralInteger 4"}, instance.eval("SequenceFunctions::includingAt((1, 2, 3), 4, *)", null)); + + assertList(new String[]{"LiteralInteger 2", "LiteralInteger 3"}, instance.eval("SequenceFunctions::excluding((1, 2, 3), 1)", null)); + assertList(new String[]{"LiteralInteger 2"}, instance.eval("SequenceFunctions::excluding((1, 2, 3), (1,3))", null)); + assertList(new String[]{"LiteralInteger 1", "LiteralInteger 2", "LiteralInteger 3"}, instance.eval("SequenceFunctions::excluding((1, 2, 3), ())", null)); + + assertList(new String[]{"LiteralInteger 2", "LiteralInteger 3"}, instance.eval("SequenceFunctions::excludingAt((1, 2, 3), 1)", null)); + assertList(new String[]{"LiteralInteger 1", "LiteralInteger 4"}, instance.eval("SequenceFunctions::excludingAt((1, 2, 3, 4), 2, 3)", null)); + assertList(new String[]{"LiteralInteger 1"}, instance.eval("SequenceFunctions::excludingAt((1, 2, 3), 2, *)", null)); + + assertList(new String[]{"LiteralInteger 1", "LiteralInteger 2", "LiteralInteger 3"}, instance.eval("SequenceFunctions::subsequence((1, 2, 3), 1)", null)); + assertList(new String[]{"LiteralInteger 2", "LiteralInteger 3"}, instance.eval("SequenceFunctions::subsequence((1, 2, 3), 2)", null)); + assertList(new String[]{"LiteralInteger 2", "LiteralInteger 3"}, instance.eval("SequenceFunctions::subsequence((1, 2, 3, 4), 2, 3)", null)); + assertList(new String[]{"LiteralInteger 2", "LiteralInteger 3"}, instance.eval("SequenceFunctions::subsequence((1, 2, 3), 2, *)", null)); + + assertList(new String[]{"LiteralInteger 1"}, instance.eval("SequenceFunctions::head((1, 2, 3))", null)); + assertList(new String[]{}, instance.eval("SequenceFunctions::head(())", null)); + assertList(new String[]{"LiteralInteger 2", "LiteralInteger 3"}, instance.eval("SequenceFunctions::tail((1, 2, 3))", null)); + assertList(new String[]{}, instance.eval("SequenceFunctions::tail(())", null)); + assertList(new String[]{"LiteralInteger 3"}, instance.eval("SequenceFunctions::last((1, 2, 3))", null)); + assertList(new String[]{}, instance.eval("SequenceFunctions::last(())", null)); + + assertList(new String[]{"LiteralInteger 1", "LiteralInteger 2", "LiteralInteger 3"}, instance.eval("SequenceFunctions::union((1, 2, 3), ())", null)); + assertList(new String[]{"LiteralInteger 1", "LiteralInteger 2", "LiteralInteger 3", "LiteralInteger 4", "LiteralInteger 5"}, instance.eval("SequenceFunctions::union((1, 2, 3), (4, 5))", null)); + assertList(new String[]{"LiteralInteger 4", "LiteralInteger 5"}, instance.eval("SequenceFunctions::union((), (4, 5))", null)); + + assertList(new String[]{}, instance.eval("SequenceFunctions::intersection((1, 2, 3), ())", null)); + assertList(new String[]{}, instance.eval("SequenceFunctions::intersection((1, 2, 3), (4, 5))", null)); + assertList(new String[]{"LiteralInteger 1", "LiteralInteger 3"}, instance.eval("SequenceFunctions::intersection((1, 2, 3), (1, 3, 4))", null)); + assertList(new String[]{}, instance.eval("SequenceFunctions::intersection((), (4, 5))", null)); } + public final String collectionTest = + "package CollectionTest {\n" + + " private import Collections::*;\n" + + " attribute empty = new OrderedCollection(elements = null);\n" + + " attribute collection1 = new OrderedCollection(elements = 1);\n" + + " attribute collection5 = new OrderedCollection(elements = 5);\n" + + " attribute collection15 = new OrderedCollection(elements = (1, 5));\n" + + " attribute collection123 = new OrderedCollection(elements = (1, 2, 3));\n" + + " attribute collection123a = new OrderedCollection(elements = (1, 2, 3));\n" + + " attribute collection321 = new OrderedCollection(elements = (3, 2, 1));\n" + + "}"; + @Test - public void testNumericalFunctionEvaluation() throws Exception { + public void testCollectionFunctionEvaluation() throws Exception { SysMLInteractive instance = getSysMLInteractiveInstance(); - assertElement("LiteralInteger 6", instance.eval("NumericalFunctions::sum((1,2,3))", null)); - assertElement("LiteralInteger 6", instance.eval("NumericalFunctions::product((1,2,3))", null)); + process(instance, collectionTest); + + assertElement("LiteralInteger 3", instance.eval("CollectionFunctions::size(collection123)", "CollectionTest")); + + assertElement("LiteralBoolean true", instance.eval("CollectionFunctions::contains(collection123, 1)", "CollectionTest")); + assertElement("LiteralBoolean false", instance.eval("CollectionFunctions::contains(collection123, 5)", "CollectionTest")); + assertElement("LiteralBoolean true", instance.eval("CollectionFunctions::contains(collection123, (1, 3))", "CollectionTest")); + assertElement("LiteralBoolean false", instance.eval("CollectionFunctions::contains(collection123, (1, 5))", "CollectionTest")); + + assertElement("LiteralBoolean true", instance.eval("CollectionFunctions::containsAll(collection123, collection321)", "CollectionTest")); + assertElement("LiteralBoolean false", instance.eval("CollectionFunctions::containsAll(collection123, collection15)", "CollectionTest")); + + assertElement("LiteralBoolean true", instance.eval("CollectionFunctions::isEmpty(empty)", "CollectionTest")); + assertElement("LiteralBoolean false", instance.eval("CollectionFunctions::isEmpty(collection1)", "CollectionTest")); + assertElement("LiteralBoolean false", instance.eval("CollectionFunctions::isEmpty(collection123)", "CollectionTest")); + + assertElement("LiteralBoolean false", instance.eval("CollectionFunctions::notEmpty(empty)", "CollectionTest")); + assertElement("LiteralBoolean true", instance.eval("CollectionFunctions::notEmpty(collection1)", "CollectionTest")); + assertElement("LiteralBoolean true", instance.eval("CollectionFunctions::notEmpty(collection123)", "CollectionTest")); + + assertElement("LiteralBoolean true", instance.eval("CollectionFunctions::'=='(collection123, collection123a)", "CollectionTest")); + assertElement("LiteralBoolean false", instance.eval("CollectionFunctions::'=='(collection123, collection321)", "CollectionTest")); + assertElement("LiteralBoolean false", instance.eval("CollectionFunctions::'=='(collection123, collection15)", "CollectionTest")); + + assertElement("LiteralInteger 2", instance.eval("CollectionFunctions::'#'(collection123, 2)", "CollectionTest")); + assertList(new String[]{}, instance.eval("CollectionFunctions::'#'(collection123, 4)", "CollectionTest")); + + assertList(new String[]{"LiteralInteger 1"}, instance.eval("CollectionFunctions::head(collection123)", "CollectionTest")); + assertList(new String[]{}, instance.eval("CollectionFunctions::head(empty)", "CollectionTest")); + assertList(new String[]{"LiteralInteger 2", "LiteralInteger 3"}, instance.eval("CollectionFunctions::tail(collection123)", "CollectionTest")); + assertList(new String[]{}, instance.eval("CollectionFunctions::tail(empty)", "CollectionTest")); + assertList(new String[]{"LiteralInteger 3"}, instance.eval("CollectionFunctions::last(collection123)", "CollectionTest")); + assertList(new String[]{}, instance.eval("CollectionFunctions::last(empty)", "CollectionTest")); } @Test - public void testControlOpEvaluation() throws Exception { + public void testControlFunctionEvaluation() throws Exception { SysMLInteractive instance = getSysMLInteractiveInstance(); - assertList(new String[] {"LiteralInteger 2", "LiteralInteger 4", "LiteralInteger 6"}, instance.eval("(1,2,3).{in x : ScalarValues::Integer; x * 2}", null)); - assertList(new String[] {"LiteralInteger 1", "LiteralInteger 2"}, instance.eval("(1,2,3).?{in x : ScalarValues::Integer; x < 3}", null)); assertList(new String[] {"LiteralInteger 2", "LiteralInteger 4", "LiteralInteger 6"}, instance.eval("(1,2,3)->ControlFunctions::collect{in x : ScalarValues::Integer; x * 2}", null)); assertList(new String[] {"LiteralInteger 1", "LiteralInteger 2"}, instance.eval("(1,2,3)->ControlFunctions::select{in x : ScalarValues::Integer; x < 3}", null)); + assertList(new String[] {"LiteralInteger 1"}, instance.eval("(1,2,3)->ControlFunctions::selectOne{in x : ScalarValues::Integer; x < 3}", null)); + assertList(new String[] {"LiteralInteger 3"}, instance.eval("(1,2,3)->ControlFunctions::reject{in x : ScalarValues::Integer; x < 3}", null)); + assertList(new String[] {"LiteralInteger 6"}, instance.eval("(1,2,3)->ControlFunctions::reduce{in x : ScalarValues::Integer; in y : ScalarValues::Integer; x * y}", null)); + assertList(new String[] {"LiteralInteger 6"}, instance.eval("(1,2,3)->ControlFunctions::reduce DataFunctions::'*'", null)); + assertList(new String[] {}, instance.eval("()->ControlFunctions::reduce DataFunctions::'*'", null)); + assertList(new String[] {"LiteralBoolean false"}, instance.eval("(1,2,3)->ControlFunctions::forAll{in x : ScalarValues::Integer; x < 3}", null)); + assertList(new String[] {"LiteralBoolean true"}, instance.eval("(1,2,3)->ControlFunctions::forAll{in x : ScalarValues::Integer; x < 4}", null)); + assertList(new String[] {"LiteralBoolean false"}, instance.eval("(1,2,3)->ControlFunctions::exists{in x : ScalarValues::Integer; x < 0}", null)); + assertList(new String[] {"LiteralBoolean true"}, instance.eval("(1,2,3)->ControlFunctions::exists{in x : ScalarValues::Integer; x < 3}", null)); + assertList(new String[] {"LiteralBoolean false"}, instance.eval("(false,false,false)->ControlFunctions::allTrue()", null)); + assertList(new String[] {"LiteralBoolean false"}, instance.eval("(true,false,true)->ControlFunctions::allTrue()", null)); + assertList(new String[] {"LiteralBoolean true"}, instance.eval("(true,true,true)->ControlFunctions::allTrue()", null)); + assertList(new String[] {"LiteralBoolean false"}, instance.eval("(false,false,false)->ControlFunctions::anyTrue()", null)); + assertList(new String[] {"LiteralBoolean true"}, instance.eval("(false,true,false)->ControlFunctions::anyTrue()", null)); + assertList(new String[] {"LiteralBoolean true"}, instance.eval("(true,true,true)->ControlFunctions::anyTrue()", null)); + assertList(new String[] {"LiteralInteger 6"}, instance.eval("(1,2,3)->ControlFunctions::maximize{in x : ScalarValues::Integer; x * 2}", null)); + assertList(new String[] {}, instance.eval("()->ControlFunctions::maximize{in x : ScalarValues::Integer; x * 2}", null)); + assertList(new String[] {"LiteralInteger 2"}, instance.eval("(1,2,3)->ControlFunctions::minimize{in x : ScalarValues::Integer; x * 2}", null)); + assertList(new String[] {}, instance.eval("()->ControlFunctions::minimize{in x : ScalarValues::Integer; x * 2}", null)); } } diff --git a/org.omg.sysml.interactive.tests/src/org/omg/sysml/interactive/tests/ModelLevelEvaluationTest.java b/org.omg.sysml.interactive.tests/src/org/omg/sysml/interactive/tests/ModelLevelEvaluationTest.java index 1b8fe687e..4ef55d79f 100644 --- a/org.omg.sysml.interactive.tests/src/org/omg/sysml/interactive/tests/ModelLevelEvaluationTest.java +++ b/org.omg.sysml.interactive.tests/src/org/omg/sysml/interactive/tests/ModelLevelEvaluationTest.java @@ -1,6 +1,6 @@ /******************************************************************************* * SysML 2 Pilot Implementation - * Copyright (c) 2021-2022, 2025 Model Driven Solutions, Inc. + * Copyright (c) 2021-2022, 2025-2026 Model Driven Solutions, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -302,6 +302,10 @@ public void testListEvaluation() throws Exception { assertArrayEquals(new Object[] {1, 2, 3}, evaluateListValue(null, null, "1..3")); assertArrayEquals(new Object[] {-1, 0, 1, 2}, evaluateListValue(null, null, "-1..2")); assertArrayEquals(new Object[] {}, evaluateListValue(null, null, "5..3")); + + assertEquals(2, evaluateIntegerValue(null, null, "(1, 2, 3)#(2)")); + assertArrayEquals(new Object[] {}, evaluateListValue(null, null, "(1, 2, 3)#(4)")); + // assertEquals(3, evaluateIntegerValue(null, null, "SequenceFunctions::size((1, 2, 3))")); // assertEquals(true, evaluateBooleanValue(null, null, "SequenceFunctions::includes((1, 2, 3), 1)")); // assertEquals(false, evaluateBooleanValue(null, null, "SequenceFunctions::includes((1, 2, 3), 5)")); @@ -315,6 +319,24 @@ public void testListEvaluation() throws Exception { // assertEquals(true, evaluateBooleanValue(null, null, "SequenceFunctions::notEmpty((1,2,3))")); } + @Test + public void testCollectionEvaluation() throws Exception { + SysMLInteractive instance = getSysMLInteractiveInstance(); + process(instance, + "attribute collection15 = new Collections::OrderedCollection(elements = (1, 5));\n" + + "attribute collection123 = new Collections::OrderedCollection(elements = (1, 2, 3));\n" + + "attribute collection123a = new Collections::OrderedCollection(elements = (1, 2, 3));\n" + + "attribute collection321 = new Collections::OrderedCollection(elements = (3, 2, 1));"); + assertEquals(true, evaluateBooleanValue(instance, null, "collection123 == collection123a")); + assertEquals(false, evaluateBooleanValue(instance, null, "collection123 == collection321")); + assertEquals(false, evaluateBooleanValue(instance, null, "collection123 == collection15")); + assertEquals(false, evaluateBooleanValue(instance, null, "collection123 != collection123a")); + assertEquals(true, evaluateBooleanValue(instance, null, "collection123 != collection321")); + assertEquals(true, evaluateBooleanValue(instance, null, "collection123 != collection15")); + assertEquals(2, evaluateIntegerValue(instance, null, "collection123#(2)")); + assertArrayEquals(new Object[] {}, evaluateListValue(instance, null, "collection123#(4)")); + } + // Note: These collect and select expressions are currently not model-level evaluable, because the feature references // to parameters of the body expressions are considered non-model-level evaluable (currently per the specification). // @Test diff --git a/org.omg.sysml/META-INF/MANIFEST.MF b/org.omg.sysml/META-INF/MANIFEST.MF index ef1d9266b..99286db32 100644 --- a/org.omg.sysml/META-INF/MANIFEST.MF +++ b/org.omg.sysml/META-INF/MANIFEST.MF @@ -32,6 +32,9 @@ Export-Package: org.omg.sysml, org.omg.sysml.delegate.setting, org.omg.sysml.expressions, org.omg.sysml.expressions.functions, + org.omg.sysml.expressions.functions.base, + org.omg.sysml.expressions.functions.control, + org.omg.sysml.expressions.functions.data, org.omg.sysml.lang.sysml, org.omg.sysml.lang.sysml.impl, org.omg.sysml.lang.sysml.util, diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/ModelLevelExpressionEvaluator.java b/org.omg.sysml/src/org/omg/sysml/expressions/ModelLevelExpressionEvaluator.java index e697611bb..ea46c4ac7 100644 --- a/org.omg.sysml/src/org/omg/sysml/expressions/ModelLevelExpressionEvaluator.java +++ b/org.omg.sysml/src/org/omg/sysml/expressions/ModelLevelExpressionEvaluator.java @@ -1,6 +1,6 @@ /******************************************************************************* * SysML 2 Pilot Implementation - * Copyright (c) 2022, 2025 Model Driven Solutions, Inc. + * Copyright (c) 2022, 2025-2026 Model Driven Solutions, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -118,14 +118,19 @@ public EList evaluateConstructor(ConstructorExpression expression, Elem } public EList evaluateExpression(Expression expression, Element target, Element... arguments) { - Expression resultExpression = EvaluationUtil.getResultExpressionFor(expression); - if (resultExpression == null) { - return EvaluationUtil.singletonList(expression); + InvocationExpression invocation = EvaluationUtil.createInvocationOf(expression, arguments); + LibraryFunction libraryFunction = libraryFunctionFactory.getLibraryFunction(expression.getFunction()); + if (libraryFunction != null) { + return libraryFunction.invoke(invocation, target, this); } else { - Feature targetFeature = EvaluationUtil.getTargetFeatureFor(target); - Expression invocation = EvaluationUtil.createInvocationOf(expression, arguments); - EList results = evaluate(resultExpression, FeatureUtil.chainFeatures(targetFeature, invocation)); - return results == null? EvaluationUtil.singletonList(resultExpression): results; + Expression resultExpression = EvaluationUtil.getResultExpressionFor(expression); + if (resultExpression == null) { + return EvaluationUtil.singletonList(expression); + } else { + Feature targetFeature = EvaluationUtil.getTargetFeatureFor(target); + EList results = evaluate(resultExpression, FeatureUtil.chainFeatures(targetFeature, invocation)); + return results == null? EvaluationUtil.singletonList(resultExpression): results; + } } } diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/ModelLevelLibraryFunctionFactory.java b/org.omg.sysml/src/org/omg/sysml/expressions/ModelLevelLibraryFunctionFactory.java index 6d6e41232..7d0d0095a 100644 --- a/org.omg.sysml/src/org/omg/sysml/expressions/ModelLevelLibraryFunctionFactory.java +++ b/org.omg.sysml/src/org/omg/sysml/expressions/ModelLevelLibraryFunctionFactory.java @@ -24,7 +24,11 @@ import java.util.HashMap; import java.util.Map; -import org.omg.sysml.expressions.functions.*; +import org.omg.sysml.expressions.functions.LibraryFunction; +import org.omg.sysml.expressions.functions.base.*; +import org.omg.sysml.expressions.functions.bool.*; +import org.omg.sysml.expressions.functions.control.*; +import org.omg.sysml.expressions.functions.data.*; import org.omg.sysml.lang.sysml.Function; public class ModelLevelLibraryFunctionFactory { @@ -36,47 +40,46 @@ public class ModelLevelLibraryFunctionFactory { protected void initializeFunctionMap() { functionMap = new HashMap<>(); + // BaseFunctions put(new EqualsFunction()); put(new NotEqualsFunction()); put(new SameFunction()); put(new NotSameFunction()); - - put(new ListConcatFunction()); - put(new ListRangeFunction()); - put(new IndexFunction()); - put(new IsTypeFunction()); put(new HasTypeFunction()); put(new AtFunction()); put(new AtAtFunction()); - put(new AsFunction()); put(new MetaFunction()); - + put(new ListConcatFunction()); + put(new IndexFunction()); + + // DataFunctions + put(new ListRangeFunction()); put(new PlusFunction()); put(new MinusFunction()); put(new TimesFunction()); put(new DivideFunction()); put(new PowerFunction()); put(new RemainderFunction()); + put(new LessThanFunction()); + put(new LessThanOrEqualFunction()); + put(new GreaterThanFunction()); + put(new GreaterThanOrEqualFunction()); + // BooleanFunctions put(new NotFunction()); put(new OrFunction()); put(new XorFunction()); put(new AndFunction()); - put(new LessThanFunction()); - put(new LessThanOrEqualFunction()); - put(new GreaterThanFunction()); - put(new GreaterThanOrEqualFunction()); - + // ControlFunctions put(new DotFunction()); put(new ConditionalFunction()); put(new ConditionalAndFunction()); put(new ConditionalOrFunction()); put(new ConditionalImpliesFunction()); - put(new NullCoalescingFunction()); - + put(new NullCoalescingFunction()); put(new CollectFunction()); put(new SelectFunction()); } diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/functions/AsFunction.java b/org.omg.sysml/src/org/omg/sysml/expressions/functions/base/AsFunction.java similarity index 97% rename from org.omg.sysml/src/org/omg/sysml/expressions/functions/AsFunction.java rename to org.omg.sysml/src/org/omg/sysml/expressions/functions/base/AsFunction.java index acaa41c2e..f6c5c7328 100644 --- a/org.omg.sysml/src/org/omg/sysml/expressions/functions/AsFunction.java +++ b/org.omg.sysml/src/org/omg/sysml/expressions/functions/base/AsFunction.java @@ -19,7 +19,7 @@ * *******************************************************************************/ -package org.omg.sysml.expressions.functions; +package org.omg.sysml.expressions.functions.base; import org.eclipse.emf.common.util.BasicEList; import org.eclipse.emf.common.util.EList; diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/functions/AtAtFunction.java b/org.omg.sysml/src/org/omg/sysml/expressions/functions/base/AtAtFunction.java similarity index 95% rename from org.omg.sysml/src/org/omg/sysml/expressions/functions/AtAtFunction.java rename to org.omg.sysml/src/org/omg/sysml/expressions/functions/base/AtAtFunction.java index 2623ee871..c267e058d 100644 --- a/org.omg.sysml/src/org/omg/sysml/expressions/functions/AtAtFunction.java +++ b/org.omg.sysml/src/org/omg/sysml/expressions/functions/base/AtAtFunction.java @@ -19,7 +19,7 @@ * *******************************************************************************/ -package org.omg.sysml.expressions.functions; +package org.omg.sysml.expressions.functions.base; public class AtAtFunction extends AtFunction { diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/functions/AtFunction.java b/org.omg.sysml/src/org/omg/sysml/expressions/functions/base/AtFunction.java similarity index 97% rename from org.omg.sysml/src/org/omg/sysml/expressions/functions/AtFunction.java rename to org.omg.sysml/src/org/omg/sysml/expressions/functions/base/AtFunction.java index 60b94d0a7..059a2bddb 100644 --- a/org.omg.sysml/src/org/omg/sysml/expressions/functions/AtFunction.java +++ b/org.omg.sysml/src/org/omg/sysml/expressions/functions/base/AtFunction.java @@ -19,7 +19,7 @@ * *******************************************************************************/ -package org.omg.sysml.expressions.functions; +package org.omg.sysml.expressions.functions.base; import org.eclipse.emf.common.util.EList; import org.omg.sysml.expressions.ModelLevelExpressionEvaluator; diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/functions/BaseFunction.java b/org.omg.sysml/src/org/omg/sysml/expressions/functions/base/BaseFunction.java similarity index 91% rename from org.omg.sysml/src/org/omg/sysml/expressions/functions/BaseFunction.java rename to org.omg.sysml/src/org/omg/sysml/expressions/functions/base/BaseFunction.java index 85a4d5242..579b55dd0 100644 --- a/org.omg.sysml/src/org/omg/sysml/expressions/functions/BaseFunction.java +++ b/org.omg.sysml/src/org/omg/sysml/expressions/functions/base/BaseFunction.java @@ -19,7 +19,9 @@ * *******************************************************************************/ -package org.omg.sysml.expressions.functions; +package org.omg.sysml.expressions.functions.base; + +import org.omg.sysml.expressions.functions.LibraryFunction; public abstract class BaseFunction implements LibraryFunction { diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/functions/base/EqualsFunction.java b/org.omg.sysml/src/org/omg/sysml/expressions/functions/base/EqualsFunction.java new file mode 100644 index 000000000..eaa31f9ed --- /dev/null +++ b/org.omg.sysml/src/org/omg/sysml/expressions/functions/base/EqualsFunction.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * SysML 2 Pilot Implementation + * Copyright (c) 2021, 2026 Model Driven Solutions, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of theGNU Lesser General Public License + * along with this program. If not, see . + * + * @license LGPL-3.0-or-later + * + *******************************************************************************/ + +package org.omg.sysml.expressions.functions.base; + +import org.eclipse.emf.common.util.EList; +import org.omg.sysml.expressions.ModelLevelExpressionEvaluator; +import org.omg.sysml.lang.sysml.Element; +import org.omg.sysml.lang.sysml.Feature; +import org.omg.sysml.lang.sysml.InvocationExpression; +import org.omg.sysml.lang.sysml.Type; +import org.omg.sysml.util.EvaluationUtil; +import org.omg.sysml.util.ExpressionUtil; +import org.omg.sysml.util.TypeUtil; + +public class EqualsFunction extends BaseFunction { + + @Override + public String getOperatorName() { + return "'=='"; + } + + protected boolean isCollection(InvocationExpression invocation, EList values) { + Type collectionType = ExpressionUtil.getCollectionDataType(invocation); + return values != null && values.size() == 1 && values.get(0) instanceof Type && + TypeUtil.specializes((Type)values.get(0), collectionType); + } + + protected boolean compare(EList x, EList y) { + // Note: This allows comparison of arbitrary lists, even though the '==' function args have multiplicity 0..1. + return EvaluationUtil.equal(x, y); + } + + @Override + public EList invoke(InvocationExpression invocation, Element target, ModelLevelExpressionEvaluator evaluator) { + EList x = evaluator.evaluateArgument(invocation, 0, target); + EList y = evaluator.evaluateArgument(invocation, 1, target); + if (isCollection(invocation, x) && isCollection(invocation, y)) { + x = EvaluationUtil.getElementsOf((Feature)x.get(0)); + y = EvaluationUtil.getElementsOf((Feature)y.get(0)); + } + return x == null || y == null? EvaluationUtil.singletonList(invocation): + EvaluationUtil.booleanResult(compare(x, y)); + } + +} diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/functions/HasTypeFunction.java b/org.omg.sysml/src/org/omg/sysml/expressions/functions/base/HasTypeFunction.java similarity index 97% rename from org.omg.sysml/src/org/omg/sysml/expressions/functions/HasTypeFunction.java rename to org.omg.sysml/src/org/omg/sysml/expressions/functions/base/HasTypeFunction.java index 9c6b0006e..12c8b17a5 100644 --- a/org.omg.sysml/src/org/omg/sysml/expressions/functions/HasTypeFunction.java +++ b/org.omg.sysml/src/org/omg/sysml/expressions/functions/base/HasTypeFunction.java @@ -18,7 +18,7 @@ * @license LGPL-3.0-or-later * *******************************************************************************/ -package org.omg.sysml.expressions.functions; +package org.omg.sysml.expressions.functions.base; import org.eclipse.emf.common.util.EList; import org.omg.sysml.expressions.ModelLevelExpressionEvaluator; diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/functions/IndexFunction.java b/org.omg.sysml/src/org/omg/sysml/expressions/functions/base/IndexFunction.java similarity index 92% rename from org.omg.sysml/src/org/omg/sysml/expressions/functions/IndexFunction.java rename to org.omg.sysml/src/org/omg/sysml/expressions/functions/base/IndexFunction.java index bfbffd08b..ed598819a 100644 --- a/org.omg.sysml/src/org/omg/sysml/expressions/functions/IndexFunction.java +++ b/org.omg.sysml/src/org/omg/sysml/expressions/functions/base/IndexFunction.java @@ -1,6 +1,6 @@ /******************************************************************************* * SysML 2 Pilot Implementation - * Copyright (c) 2021, 2023 Model Driven Solutions, Inc. + * Copyright (c) 2021, 2023, 2026 Model Driven Solutions, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -19,7 +19,7 @@ * *******************************************************************************/ -package org.omg.sysml.expressions.functions; +package org.omg.sysml.expressions.functions.base; import java.util.ArrayList; import java.util.List; @@ -86,10 +86,7 @@ protected boolean isOrderedCollection(InvocationExpression invocation, EList indexCollection(InvocationExpression invocation, Feature collection, int index, ModelLevelExpressionEvaluator evaluator) { - List elementsChain = new ArrayList<>(); - elementsChain.add(collection); - elementsChain.add(ExpressionUtil.getCollectionElementsFeature(collection)); - EList elements = evaluator.evaluateFeatureChain(elementsChain, collection); + EList elements = EvaluationUtil.getElementsOf(collection); return elements == null? EvaluationUtil.singletonList(invocation): indexSequence(elements, index); } diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/functions/IsTypeFunction.java b/org.omg.sysml/src/org/omg/sysml/expressions/functions/base/IsTypeFunction.java similarity index 97% rename from org.omg.sysml/src/org/omg/sysml/expressions/functions/IsTypeFunction.java rename to org.omg.sysml/src/org/omg/sysml/expressions/functions/base/IsTypeFunction.java index 0e0c62f9c..ed71e0c73 100644 --- a/org.omg.sysml/src/org/omg/sysml/expressions/functions/IsTypeFunction.java +++ b/org.omg.sysml/src/org/omg/sysml/expressions/functions/base/IsTypeFunction.java @@ -18,7 +18,7 @@ * @license LGPL-3.0-or-later * *******************************************************************************/ -package org.omg.sysml.expressions.functions; +package org.omg.sysml.expressions.functions.base; import org.eclipse.emf.common.util.EList; import org.omg.sysml.expressions.ModelLevelExpressionEvaluator; diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/functions/ListConcatFunction.java b/org.omg.sysml/src/org/omg/sysml/expressions/functions/base/ListConcatFunction.java similarity index 97% rename from org.omg.sysml/src/org/omg/sysml/expressions/functions/ListConcatFunction.java rename to org.omg.sysml/src/org/omg/sysml/expressions/functions/base/ListConcatFunction.java index f70e12acc..27cef48ce 100644 --- a/org.omg.sysml/src/org/omg/sysml/expressions/functions/ListConcatFunction.java +++ b/org.omg.sysml/src/org/omg/sysml/expressions/functions/base/ListConcatFunction.java @@ -19,7 +19,7 @@ * *******************************************************************************/ -package org.omg.sysml.expressions.functions; +package org.omg.sysml.expressions.functions.base; import org.eclipse.emf.common.util.BasicEList; import org.eclipse.emf.common.util.EList; diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/functions/MetaFunction.java b/org.omg.sysml/src/org/omg/sysml/expressions/functions/base/MetaFunction.java similarity index 95% rename from org.omg.sysml/src/org/omg/sysml/expressions/functions/MetaFunction.java rename to org.omg.sysml/src/org/omg/sysml/expressions/functions/base/MetaFunction.java index 530487248..ebffe9b0f 100644 --- a/org.omg.sysml/src/org/omg/sysml/expressions/functions/MetaFunction.java +++ b/org.omg.sysml/src/org/omg/sysml/expressions/functions/base/MetaFunction.java @@ -19,7 +19,7 @@ * *******************************************************************************/ -package org.omg.sysml.expressions.functions; +package org.omg.sysml.expressions.functions.base; public class MetaFunction extends AsFunction { diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/functions/base/NotEqualsFunction.java b/org.omg.sysml/src/org/omg/sysml/expressions/functions/base/NotEqualsFunction.java new file mode 100644 index 000000000..d21975b94 --- /dev/null +++ b/org.omg.sysml/src/org/omg/sysml/expressions/functions/base/NotEqualsFunction.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * SysML 2 Pilot Implementation + * Copyright (c) 2021, 2026 Model Driven Solutions, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of theGNU Lesser General Public License + * along with this program. If not, see . + * + * @license LGPL-3.0-or-later + * + *******************************************************************************/ + +package org.omg.sysml.expressions.functions.base; + +import org.eclipse.emf.common.util.EList; +import org.omg.sysml.lang.sysml.Element; +import org.omg.sysml.util.EvaluationUtil; + +public class NotEqualsFunction extends EqualsFunction { + + @Override + public String getOperatorName() { + return "'!='"; + } + + @Override + protected boolean compare(EList x, EList y) { + // Note: This allows comparison of arbitrary lists, even though the !==' function args have multiplicity 0..1. + return !EvaluationUtil.equal(x, y); + } + + +} diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/functions/NotSameFunction.java b/org.omg.sysml/src/org/omg/sysml/expressions/functions/base/NotSameFunction.java similarity index 95% rename from org.omg.sysml/src/org/omg/sysml/expressions/functions/NotSameFunction.java rename to org.omg.sysml/src/org/omg/sysml/expressions/functions/base/NotSameFunction.java index f8378d469..abf120649 100644 --- a/org.omg.sysml/src/org/omg/sysml/expressions/functions/NotSameFunction.java +++ b/org.omg.sysml/src/org/omg/sysml/expressions/functions/base/NotSameFunction.java @@ -19,7 +19,7 @@ * *******************************************************************************/ -package org.omg.sysml.expressions.functions; +package org.omg.sysml.expressions.functions.base; public class NotSameFunction extends NotEqualsFunction { diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/functions/SameFunction.java b/org.omg.sysml/src/org/omg/sysml/expressions/functions/base/SameFunction.java similarity index 95% rename from org.omg.sysml/src/org/omg/sysml/expressions/functions/SameFunction.java rename to org.omg.sysml/src/org/omg/sysml/expressions/functions/base/SameFunction.java index 26efd360b..652defff9 100644 --- a/org.omg.sysml/src/org/omg/sysml/expressions/functions/SameFunction.java +++ b/org.omg.sysml/src/org/omg/sysml/expressions/functions/base/SameFunction.java @@ -19,7 +19,7 @@ * *******************************************************************************/ -package org.omg.sysml.expressions.functions; +package org.omg.sysml.expressions.functions.base; public class SameFunction extends EqualsFunction { diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/functions/AndFunction.java b/org.omg.sysml/src/org/omg/sysml/expressions/functions/bool/AndFunction.java similarity index 96% rename from org.omg.sysml/src/org/omg/sysml/expressions/functions/AndFunction.java rename to org.omg.sysml/src/org/omg/sysml/expressions/functions/bool/AndFunction.java index 77f51f698..9e7883567 100644 --- a/org.omg.sysml/src/org/omg/sysml/expressions/functions/AndFunction.java +++ b/org.omg.sysml/src/org/omg/sysml/expressions/functions/bool/AndFunction.java @@ -19,7 +19,7 @@ * *******************************************************************************/ -package org.omg.sysml.expressions.functions; +package org.omg.sysml.expressions.functions.bool; import org.eclipse.emf.common.util.EList; import org.omg.sysml.lang.sysml.Element; diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/functions/BooleanFunction.java b/org.omg.sysml/src/org/omg/sysml/expressions/functions/bool/BooleanFunction.java similarity index 94% rename from org.omg.sysml/src/org/omg/sysml/expressions/functions/BooleanFunction.java rename to org.omg.sysml/src/org/omg/sysml/expressions/functions/bool/BooleanFunction.java index 9a76f2090..097762b13 100644 --- a/org.omg.sysml/src/org/omg/sysml/expressions/functions/BooleanFunction.java +++ b/org.omg.sysml/src/org/omg/sysml/expressions/functions/bool/BooleanFunction.java @@ -19,10 +19,11 @@ * *******************************************************************************/ -package org.omg.sysml.expressions.functions; +package org.omg.sysml.expressions.functions.bool; import org.eclipse.emf.common.util.EList; import org.omg.sysml.expressions.ModelLevelExpressionEvaluator; +import org.omg.sysml.expressions.functions.LibraryFunction; import org.omg.sysml.lang.sysml.Element; import org.omg.sysml.lang.sysml.InvocationExpression; import org.omg.sysml.util.EvaluationUtil; diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/functions/NotFunction.java b/org.omg.sysml/src/org/omg/sysml/expressions/functions/bool/NotFunction.java similarity index 96% rename from org.omg.sysml/src/org/omg/sysml/expressions/functions/NotFunction.java rename to org.omg.sysml/src/org/omg/sysml/expressions/functions/bool/NotFunction.java index 44fd441ae..bd4ed4112 100644 --- a/org.omg.sysml/src/org/omg/sysml/expressions/functions/NotFunction.java +++ b/org.omg.sysml/src/org/omg/sysml/expressions/functions/bool/NotFunction.java @@ -19,7 +19,7 @@ * *******************************************************************************/ -package org.omg.sysml.expressions.functions; +package org.omg.sysml.expressions.functions.bool; import org.eclipse.emf.common.util.EList; import org.omg.sysml.lang.sysml.Element; diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/functions/OrFunction.java b/org.omg.sysml/src/org/omg/sysml/expressions/functions/bool/OrFunction.java similarity index 96% rename from org.omg.sysml/src/org/omg/sysml/expressions/functions/OrFunction.java rename to org.omg.sysml/src/org/omg/sysml/expressions/functions/bool/OrFunction.java index 1ef2259fa..69f746aae 100644 --- a/org.omg.sysml/src/org/omg/sysml/expressions/functions/OrFunction.java +++ b/org.omg.sysml/src/org/omg/sysml/expressions/functions/bool/OrFunction.java @@ -19,7 +19,7 @@ * *******************************************************************************/ -package org.omg.sysml.expressions.functions; +package org.omg.sysml.expressions.functions.bool; import org.eclipse.emf.common.util.EList; import org.omg.sysml.lang.sysml.Element; diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/functions/XorFunction.java b/org.omg.sysml/src/org/omg/sysml/expressions/functions/bool/XorFunction.java similarity index 96% rename from org.omg.sysml/src/org/omg/sysml/expressions/functions/XorFunction.java rename to org.omg.sysml/src/org/omg/sysml/expressions/functions/bool/XorFunction.java index 1d0ef34e5..6e2553ffa 100644 --- a/org.omg.sysml/src/org/omg/sysml/expressions/functions/XorFunction.java +++ b/org.omg.sysml/src/org/omg/sysml/expressions/functions/bool/XorFunction.java @@ -19,7 +19,7 @@ * *******************************************************************************/ -package org.omg.sysml.expressions.functions; +package org.omg.sysml.expressions.functions.bool; import org.eclipse.emf.common.util.EList; import org.omg.sysml.lang.sysml.Element; diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/functions/CollectFunction.java b/org.omg.sysml/src/org/omg/sysml/expressions/functions/control/CollectFunction.java similarity index 97% rename from org.omg.sysml/src/org/omg/sysml/expressions/functions/CollectFunction.java rename to org.omg.sysml/src/org/omg/sysml/expressions/functions/control/CollectFunction.java index 35e661b53..c3bab5a88 100644 --- a/org.omg.sysml/src/org/omg/sysml/expressions/functions/CollectFunction.java +++ b/org.omg.sysml/src/org/omg/sysml/expressions/functions/control/CollectFunction.java @@ -18,7 +18,7 @@ * @license LGPL-3.0-or-later * *******************************************************************************/ -package org.omg.sysml.expressions.functions; +package org.omg.sysml.expressions.functions.control; import java.util.function.BiFunction; diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/functions/ConditionalAndFunction.java b/org.omg.sysml/src/org/omg/sysml/expressions/functions/control/ConditionalAndFunction.java similarity index 96% rename from org.omg.sysml/src/org/omg/sysml/expressions/functions/ConditionalAndFunction.java rename to org.omg.sysml/src/org/omg/sysml/expressions/functions/control/ConditionalAndFunction.java index f19524a42..60b5c8948 100644 --- a/org.omg.sysml/src/org/omg/sysml/expressions/functions/ConditionalAndFunction.java +++ b/org.omg.sysml/src/org/omg/sysml/expressions/functions/control/ConditionalAndFunction.java @@ -18,7 +18,7 @@ * @license LGPL-3.0-or-later * *******************************************************************************/ -package org.omg.sysml.expressions.functions; +package org.omg.sysml.expressions.functions.control; public class ConditionalAndFunction extends ConditionalLogicalFunction { diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/functions/ConditionalFunction.java b/org.omg.sysml/src/org/omg/sysml/expressions/functions/control/ConditionalFunction.java similarity index 97% rename from org.omg.sysml/src/org/omg/sysml/expressions/functions/ConditionalFunction.java rename to org.omg.sysml/src/org/omg/sysml/expressions/functions/control/ConditionalFunction.java index 0569914dd..d0d477a6a 100644 --- a/org.omg.sysml/src/org/omg/sysml/expressions/functions/ConditionalFunction.java +++ b/org.omg.sysml/src/org/omg/sysml/expressions/functions/control/ConditionalFunction.java @@ -18,7 +18,7 @@ * @license LGPL-3.0-or-later * *******************************************************************************/ -package org.omg.sysml.expressions.functions; +package org.omg.sysml.expressions.functions.control; import org.eclipse.emf.common.util.EList; import org.omg.sysml.expressions.ModelLevelExpressionEvaluator; diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/functions/ConditionalImpliesFunction.java b/org.omg.sysml/src/org/omg/sysml/expressions/functions/control/ConditionalImpliesFunction.java similarity index 96% rename from org.omg.sysml/src/org/omg/sysml/expressions/functions/ConditionalImpliesFunction.java rename to org.omg.sysml/src/org/omg/sysml/expressions/functions/control/ConditionalImpliesFunction.java index 32b65d228..299a2d351 100644 --- a/org.omg.sysml/src/org/omg/sysml/expressions/functions/ConditionalImpliesFunction.java +++ b/org.omg.sysml/src/org/omg/sysml/expressions/functions/control/ConditionalImpliesFunction.java @@ -18,7 +18,7 @@ * @license LGPL-3.0-or-later * *******************************************************************************/ -package org.omg.sysml.expressions.functions; +package org.omg.sysml.expressions.functions.control; public class ConditionalImpliesFunction extends ConditionalLogicalFunction { diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/functions/ConditionalLogicalFunction.java b/org.omg.sysml/src/org/omg/sysml/expressions/functions/control/ConditionalLogicalFunction.java similarity index 97% rename from org.omg.sysml/src/org/omg/sysml/expressions/functions/ConditionalLogicalFunction.java rename to org.omg.sysml/src/org/omg/sysml/expressions/functions/control/ConditionalLogicalFunction.java index aa94acbbe..00a1f6f4e 100644 --- a/org.omg.sysml/src/org/omg/sysml/expressions/functions/ConditionalLogicalFunction.java +++ b/org.omg.sysml/src/org/omg/sysml/expressions/functions/control/ConditionalLogicalFunction.java @@ -18,7 +18,7 @@ * @license LGPL-3.0-or-later * *******************************************************************************/ -package org.omg.sysml.expressions.functions; +package org.omg.sysml.expressions.functions.control; import org.eclipse.emf.common.util.EList; import org.omg.sysml.expressions.ModelLevelExpressionEvaluator; diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/functions/ConditionalOrFunction.java b/org.omg.sysml/src/org/omg/sysml/expressions/functions/control/ConditionalOrFunction.java similarity index 96% rename from org.omg.sysml/src/org/omg/sysml/expressions/functions/ConditionalOrFunction.java rename to org.omg.sysml/src/org/omg/sysml/expressions/functions/control/ConditionalOrFunction.java index c20d6dba8..9840382fd 100644 --- a/org.omg.sysml/src/org/omg/sysml/expressions/functions/ConditionalOrFunction.java +++ b/org.omg.sysml/src/org/omg/sysml/expressions/functions/control/ConditionalOrFunction.java @@ -18,7 +18,7 @@ * @license LGPL-3.0-or-later * *******************************************************************************/ -package org.omg.sysml.expressions.functions; +package org.omg.sysml.expressions.functions.control; public class ConditionalOrFunction extends ConditionalLogicalFunction { diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/functions/ControlFunction.java b/org.omg.sysml/src/org/omg/sysml/expressions/functions/control/ControlFunction.java similarity index 95% rename from org.omg.sysml/src/org/omg/sysml/expressions/functions/ControlFunction.java rename to org.omg.sysml/src/org/omg/sysml/expressions/functions/control/ControlFunction.java index 1e7e49c4f..19a8cb375 100644 --- a/org.omg.sysml/src/org/omg/sysml/expressions/functions/ControlFunction.java +++ b/org.omg.sysml/src/org/omg/sysml/expressions/functions/control/ControlFunction.java @@ -19,13 +19,14 @@ * *******************************************************************************/ -package org.omg.sysml.expressions.functions; +package org.omg.sysml.expressions.functions.control; import java.util.function.BiFunction; import org.eclipse.emf.common.util.BasicEList; import org.eclipse.emf.common.util.EList; import org.omg.sysml.expressions.ModelLevelExpressionEvaluator; +import org.omg.sysml.expressions.functions.LibraryFunction; import org.omg.sysml.lang.sysml.Element; import org.omg.sysml.lang.sysml.Expression; import org.omg.sysml.lang.sysml.InvocationExpression; diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/functions/DotFunction.java b/org.omg.sysml/src/org/omg/sysml/expressions/functions/control/DotFunction.java similarity index 98% rename from org.omg.sysml/src/org/omg/sysml/expressions/functions/DotFunction.java rename to org.omg.sysml/src/org/omg/sysml/expressions/functions/control/DotFunction.java index 168ca3308..c237f55cf 100644 --- a/org.omg.sysml/src/org/omg/sysml/expressions/functions/DotFunction.java +++ b/org.omg.sysml/src/org/omg/sysml/expressions/functions/control/DotFunction.java @@ -19,7 +19,7 @@ * *******************************************************************************/ -package org.omg.sysml.expressions.functions; +package org.omg.sysml.expressions.functions.control; import org.eclipse.emf.common.util.BasicEList; import org.eclipse.emf.common.util.EList; diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/functions/NullCoalescingFunction.java b/org.omg.sysml/src/org/omg/sysml/expressions/functions/control/NullCoalescingFunction.java similarity index 97% rename from org.omg.sysml/src/org/omg/sysml/expressions/functions/NullCoalescingFunction.java rename to org.omg.sysml/src/org/omg/sysml/expressions/functions/control/NullCoalescingFunction.java index fa4faeb8e..b7c5dcbed 100644 --- a/org.omg.sysml/src/org/omg/sysml/expressions/functions/NullCoalescingFunction.java +++ b/org.omg.sysml/src/org/omg/sysml/expressions/functions/control/NullCoalescingFunction.java @@ -18,7 +18,7 @@ * @license LGPL-3.0-or-later * *******************************************************************************/ -package org.omg.sysml.expressions.functions; +package org.omg.sysml.expressions.functions.control; import org.eclipse.emf.common.util.EList; import org.omg.sysml.expressions.ModelLevelExpressionEvaluator; diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/functions/SelectFunction.java b/org.omg.sysml/src/org/omg/sysml/expressions/functions/control/SelectFunction.java similarity index 97% rename from org.omg.sysml/src/org/omg/sysml/expressions/functions/SelectFunction.java rename to org.omg.sysml/src/org/omg/sysml/expressions/functions/control/SelectFunction.java index 22f5e9ff4..9e94fabb8 100644 --- a/org.omg.sysml/src/org/omg/sysml/expressions/functions/SelectFunction.java +++ b/org.omg.sysml/src/org/omg/sysml/expressions/functions/control/SelectFunction.java @@ -18,7 +18,7 @@ * @license LGPL-3.0-or-later * *******************************************************************************/ -package org.omg.sysml.expressions.functions; +package org.omg.sysml.expressions.functions.control; import java.util.function.BiFunction; diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/functions/ArithmeticFunction.java b/org.omg.sysml/src/org/omg/sysml/expressions/functions/data/ArithmeticFunction.java similarity index 98% rename from org.omg.sysml/src/org/omg/sysml/expressions/functions/ArithmeticFunction.java rename to org.omg.sysml/src/org/omg/sysml/expressions/functions/data/ArithmeticFunction.java index 235a1eb67..9dc440f13 100644 --- a/org.omg.sysml/src/org/omg/sysml/expressions/functions/ArithmeticFunction.java +++ b/org.omg.sysml/src/org/omg/sysml/expressions/functions/data/ArithmeticFunction.java @@ -19,7 +19,7 @@ * *******************************************************************************/ -package org.omg.sysml.expressions.functions; +package org.omg.sysml.expressions.functions.data; import org.eclipse.emf.common.util.EList; import org.omg.sysml.expressions.ModelLevelExpressionEvaluator; diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/functions/DataFunction.java b/org.omg.sysml/src/org/omg/sysml/expressions/functions/data/DataFunction.java similarity index 91% rename from org.omg.sysml/src/org/omg/sysml/expressions/functions/DataFunction.java rename to org.omg.sysml/src/org/omg/sysml/expressions/functions/data/DataFunction.java index 35d99a52e..dc0a13a51 100644 --- a/org.omg.sysml/src/org/omg/sysml/expressions/functions/DataFunction.java +++ b/org.omg.sysml/src/org/omg/sysml/expressions/functions/data/DataFunction.java @@ -19,7 +19,9 @@ * *******************************************************************************/ -package org.omg.sysml.expressions.functions; +package org.omg.sysml.expressions.functions.data; + +import org.omg.sysml.expressions.functions.LibraryFunction; public abstract class DataFunction implements LibraryFunction { diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/functions/DivideFunction.java b/org.omg.sysml/src/org/omg/sysml/expressions/functions/data/DivideFunction.java similarity index 96% rename from org.omg.sysml/src/org/omg/sysml/expressions/functions/DivideFunction.java rename to org.omg.sysml/src/org/omg/sysml/expressions/functions/data/DivideFunction.java index c4bbddd27..a5029efe6 100644 --- a/org.omg.sysml/src/org/omg/sysml/expressions/functions/DivideFunction.java +++ b/org.omg.sysml/src/org/omg/sysml/expressions/functions/data/DivideFunction.java @@ -19,7 +19,7 @@ * *******************************************************************************/ -package org.omg.sysml.expressions.functions; +package org.omg.sysml.expressions.functions.data; import org.eclipse.emf.common.util.EList; import org.omg.sysml.lang.sysml.Element; diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/functions/GreaterThanFunction.java b/org.omg.sysml/src/org/omg/sysml/expressions/functions/data/GreaterThanFunction.java similarity index 97% rename from org.omg.sysml/src/org/omg/sysml/expressions/functions/GreaterThanFunction.java rename to org.omg.sysml/src/org/omg/sysml/expressions/functions/data/GreaterThanFunction.java index 69dbedb86..c89cb1caf 100644 --- a/org.omg.sysml/src/org/omg/sysml/expressions/functions/GreaterThanFunction.java +++ b/org.omg.sysml/src/org/omg/sysml/expressions/functions/data/GreaterThanFunction.java @@ -19,7 +19,7 @@ * *******************************************************************************/ -package org.omg.sysml.expressions.functions; +package org.omg.sysml.expressions.functions.data; import org.eclipse.emf.common.util.EList; import org.omg.sysml.lang.sysml.Element; diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/functions/GreaterThanOrEqualFunction.java b/org.omg.sysml/src/org/omg/sysml/expressions/functions/data/GreaterThanOrEqualFunction.java similarity index 97% rename from org.omg.sysml/src/org/omg/sysml/expressions/functions/GreaterThanOrEqualFunction.java rename to org.omg.sysml/src/org/omg/sysml/expressions/functions/data/GreaterThanOrEqualFunction.java index 4391916c6..dba382bf2 100644 --- a/org.omg.sysml/src/org/omg/sysml/expressions/functions/GreaterThanOrEqualFunction.java +++ b/org.omg.sysml/src/org/omg/sysml/expressions/functions/data/GreaterThanOrEqualFunction.java @@ -19,7 +19,7 @@ * *******************************************************************************/ -package org.omg.sysml.expressions.functions; +package org.omg.sysml.expressions.functions.data; import org.eclipse.emf.common.util.EList; import org.omg.sysml.lang.sysml.Element; diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/functions/LessThanFunction.java b/org.omg.sysml/src/org/omg/sysml/expressions/functions/data/LessThanFunction.java similarity index 97% rename from org.omg.sysml/src/org/omg/sysml/expressions/functions/LessThanFunction.java rename to org.omg.sysml/src/org/omg/sysml/expressions/functions/data/LessThanFunction.java index 5d83015cf..4dde70f6a 100644 --- a/org.omg.sysml/src/org/omg/sysml/expressions/functions/LessThanFunction.java +++ b/org.omg.sysml/src/org/omg/sysml/expressions/functions/data/LessThanFunction.java @@ -19,7 +19,7 @@ * *******************************************************************************/ -package org.omg.sysml.expressions.functions; +package org.omg.sysml.expressions.functions.data; import org.eclipse.emf.common.util.EList; import org.omg.sysml.lang.sysml.Element; diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/functions/LessThanOrEqualFunction.java b/org.omg.sysml/src/org/omg/sysml/expressions/functions/data/LessThanOrEqualFunction.java similarity index 97% rename from org.omg.sysml/src/org/omg/sysml/expressions/functions/LessThanOrEqualFunction.java rename to org.omg.sysml/src/org/omg/sysml/expressions/functions/data/LessThanOrEqualFunction.java index 0ced745d0..17b955fe0 100644 --- a/org.omg.sysml/src/org/omg/sysml/expressions/functions/LessThanOrEqualFunction.java +++ b/org.omg.sysml/src/org/omg/sysml/expressions/functions/data/LessThanOrEqualFunction.java @@ -19,7 +19,7 @@ * *******************************************************************************/ -package org.omg.sysml.expressions.functions; +package org.omg.sysml.expressions.functions.data; import org.eclipse.emf.common.util.EList; import org.omg.sysml.lang.sysml.Element; diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/functions/ListRangeFunction.java b/org.omg.sysml/src/org/omg/sysml/expressions/functions/data/ListRangeFunction.java similarity index 97% rename from org.omg.sysml/src/org/omg/sysml/expressions/functions/ListRangeFunction.java rename to org.omg.sysml/src/org/omg/sysml/expressions/functions/data/ListRangeFunction.java index 5645434bb..741335c12 100644 --- a/org.omg.sysml/src/org/omg/sysml/expressions/functions/ListRangeFunction.java +++ b/org.omg.sysml/src/org/omg/sysml/expressions/functions/data/ListRangeFunction.java @@ -19,7 +19,7 @@ * *******************************************************************************/ -package org.omg.sysml.expressions.functions; +package org.omg.sysml.expressions.functions.data; import org.eclipse.emf.common.util.BasicEList; import org.eclipse.emf.common.util.EList; diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/functions/MinusFunction.java b/org.omg.sysml/src/org/omg/sysml/expressions/functions/data/MinusFunction.java similarity index 97% rename from org.omg.sysml/src/org/omg/sysml/expressions/functions/MinusFunction.java rename to org.omg.sysml/src/org/omg/sysml/expressions/functions/data/MinusFunction.java index 7d1c51af7..e97cb31ca 100644 --- a/org.omg.sysml/src/org/omg/sysml/expressions/functions/MinusFunction.java +++ b/org.omg.sysml/src/org/omg/sysml/expressions/functions/data/MinusFunction.java @@ -19,7 +19,7 @@ * *******************************************************************************/ -package org.omg.sysml.expressions.functions; +package org.omg.sysml.expressions.functions.data; import org.eclipse.emf.common.util.EList; import org.omg.sysml.lang.sysml.Element; diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/functions/PlusFunction.java b/org.omg.sysml/src/org/omg/sysml/expressions/functions/data/PlusFunction.java similarity index 97% rename from org.omg.sysml/src/org/omg/sysml/expressions/functions/PlusFunction.java rename to org.omg.sysml/src/org/omg/sysml/expressions/functions/data/PlusFunction.java index 0998c0559..f95141516 100644 --- a/org.omg.sysml/src/org/omg/sysml/expressions/functions/PlusFunction.java +++ b/org.omg.sysml/src/org/omg/sysml/expressions/functions/data/PlusFunction.java @@ -19,7 +19,7 @@ * *******************************************************************************/ -package org.omg.sysml.expressions.functions; +package org.omg.sysml.expressions.functions.data; import org.eclipse.emf.common.util.EList; import org.omg.sysml.lang.sysml.Element; diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/functions/PowerFunction.java b/org.omg.sysml/src/org/omg/sysml/expressions/functions/data/PowerFunction.java similarity index 96% rename from org.omg.sysml/src/org/omg/sysml/expressions/functions/PowerFunction.java rename to org.omg.sysml/src/org/omg/sysml/expressions/functions/data/PowerFunction.java index 5b4e15eeb..4cd2d760e 100644 --- a/org.omg.sysml/src/org/omg/sysml/expressions/functions/PowerFunction.java +++ b/org.omg.sysml/src/org/omg/sysml/expressions/functions/data/PowerFunction.java @@ -19,7 +19,7 @@ * *******************************************************************************/ -package org.omg.sysml.expressions.functions; +package org.omg.sysml.expressions.functions.data; import org.eclipse.emf.common.util.EList; import org.omg.sysml.lang.sysml.Element; diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/functions/RemainderFunction.java b/org.omg.sysml/src/org/omg/sysml/expressions/functions/data/RemainderFunction.java similarity index 96% rename from org.omg.sysml/src/org/omg/sysml/expressions/functions/RemainderFunction.java rename to org.omg.sysml/src/org/omg/sysml/expressions/functions/data/RemainderFunction.java index 4d5aa14ac..192e8527f 100644 --- a/org.omg.sysml/src/org/omg/sysml/expressions/functions/RemainderFunction.java +++ b/org.omg.sysml/src/org/omg/sysml/expressions/functions/data/RemainderFunction.java @@ -19,7 +19,7 @@ * *******************************************************************************/ -package org.omg.sysml.expressions.functions; +package org.omg.sysml.expressions.functions.data; import org.eclipse.emf.common.util.EList; import org.omg.sysml.lang.sysml.Element; diff --git a/org.omg.sysml/src/org/omg/sysml/expressions/functions/TimesFunction.java b/org.omg.sysml/src/org/omg/sysml/expressions/functions/data/TimesFunction.java similarity index 96% rename from org.omg.sysml/src/org/omg/sysml/expressions/functions/TimesFunction.java rename to org.omg.sysml/src/org/omg/sysml/expressions/functions/data/TimesFunction.java index 1e157a0eb..3c90fee6f 100644 --- a/org.omg.sysml/src/org/omg/sysml/expressions/functions/TimesFunction.java +++ b/org.omg.sysml/src/org/omg/sysml/expressions/functions/data/TimesFunction.java @@ -19,7 +19,7 @@ * *******************************************************************************/ -package org.omg.sysml.expressions.functions; +package org.omg.sysml.expressions.functions.data; import org.eclipse.emf.common.util.EList; import org.omg.sysml.lang.sysml.Element; diff --git a/org.omg.sysml/src/org/omg/sysml/util/EvaluationUtil.java b/org.omg.sysml/src/org/omg/sysml/util/EvaluationUtil.java index 7fdca0a11..86adc4b5a 100644 --- a/org.omg.sysml/src/org/omg/sysml/util/EvaluationUtil.java +++ b/org.omg.sysml/src/org/omg/sysml/util/EvaluationUtil.java @@ -1,6 +1,6 @@ /******************************************************************************* * SysML 2 Pilot Implementation - * Copyright (c) 2022, 2025 Model Driven Solutions, Inc. + * Copyright (c) 2022, 2025-2026 Model Driven Solutions, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -21,6 +21,7 @@ package org.omg.sysml.util; +import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -44,6 +45,7 @@ import org.omg.sysml.lang.sysml.LiteralString; import org.omg.sysml.lang.sysml.MetadataFeature; import org.omg.sysml.lang.sysml.Redefinition; +import org.omg.sysml.lang.sysml.Specialization; import org.omg.sysml.lang.sysml.SysMLFactory; import org.omg.sysml.lang.sysml.SysMLPackage; import org.omg.sysml.lang.sysml.Type; @@ -98,7 +100,7 @@ public static EList singletonList(Element element) { public static Expression expressionFor(EList results, Element context) { if (!results.stream().allMatch( elm->elm instanceof Feature && - (!(elm instanceof Expression) || elm instanceof LiteralExpression))) { + (!(elm instanceof Expression) || elm instanceof LiteralExpression || elm.eClass() == SysMLPackage.eINSTANCE.getExpression()))) { return null; } else if (results.isEmpty()) { return SysMLFactory.eINSTANCE.createNullExpression(); @@ -107,12 +109,16 @@ public static Expression expressionFor(EList results, Element context) if (results.size() > 1) { Type listOp = SysMLLibraryUtil.getLibraryType(context, ExpressionUtil.getOperatorQualifiedNames(",")); for (int i = 1; i < results.size(); i++) { + InvocationExpression listExpr = SysMLFactory.eINSTANCE.createInvocationExpression(); + TypeUtil.addOwnedParameterTo(listExpr, expression); + TypeUtil.addOwnedParameterTo(listExpr, expressionFor(results.get(i))); + NamespaceUtil.addMemberTo(listExpr, listOp); + FeatureTyping typing = SysMLFactory.eINSTANCE.createFeatureTyping(); typing.setType(listOp); - InvocationExpression listExpr = SysMLFactory.eINSTANCE.createInvocationExpression(); + typing.setTypedFeature(listExpr); listExpr.getOwnedRelationship().add(typing); - TypeUtil.addOwnedParameterTo(listExpr, expression); - TypeUtil.addOwnedParameterTo(listExpr, expressionFor(results.get(i))); + expression = listExpr; } } @@ -220,7 +226,7 @@ public static boolean equal(Element x, Element y) { x_value.equals(y_value); } - public static Boolean equal(List x, List y) { + public static boolean equal(List x, List y) { if (x.size() != y.size()) { return false; } else { @@ -232,6 +238,13 @@ public static Boolean equal(List x, List y) { return true; } } + + public static EList getElementsOf(Feature collection) { + List elementsChain = new ArrayList<>(); + elementsChain.add(collection); + elementsChain.add(ExpressionUtil.getCollectionElementsFeature(collection)); + return ModelLevelExpressionEvaluator.INSTANCE.evaluateFeatureChain(elementsChain, collection); + } public static Feature getTargetFeatureFor(Element target) { if (target instanceof Feature) { @@ -338,11 +351,16 @@ public static void instantiateArguments(Feature target, List parameters } } - public static Expression createInvocationOf(Expression expression, Element... arguments) { - Expression invocation = SysMLFactory.eINSTANCE.createExpression(); - FeatureUtil.addSubsettingTo(invocation).setSubsettedFeature(expression); + public static InvocationExpression createInvocationOf(Type type, Element... arguments) { + InvocationExpression invocation = SysMLFactory.eINSTANCE.createInvocationExpression(); + NamespaceUtil.addMemberTo(invocation, type); + + Specialization specialization = SysMLFactory.eINSTANCE.createSpecialization(); + specialization.setGeneral(type); + specialization.setSpecific(invocation); + invocation.getOwnedRelationship().add(specialization); - List parameters = TypeUtil.getAllParametersOf(expression); + List parameters = TypeUtil.getAllParametersOf(type); instantiateArguments(invocation, parameters, arguments); return invocation; } diff --git a/org.omg.sysml/src/org/omg/sysml/util/ExpressionUtil.java b/org.omg.sysml/src/org/omg/sysml/util/ExpressionUtil.java index d3b65bf24..e6aa33b5d 100644 --- a/org.omg.sysml/src/org/omg/sysml/util/ExpressionUtil.java +++ b/org.omg.sysml/src/org/omg/sysml/util/ExpressionUtil.java @@ -1,6 +1,6 @@ /******************************************************************************* * SysML 2 Pilot Implementation - * Copyright (c) 2021-2023, 2025 Model Driven Solutions, Inc. + * Copyright (c) 2021-2023, 2025-2026 Model Driven Solutions, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -51,6 +51,7 @@ public class ExpressionUtil { private ExpressionUtil() { } + public static final String COLLECTION_DATA_TYPE = "Collections::Collection"; public static final String ORDERED_COLLECTION_DATA_TYPE = "Collections::OrderedCollection"; public static final String ARRAY_DATA_TYPE = "Collections::Array"; @@ -58,6 +59,10 @@ private ExpressionUtil() { public static final String COLLECTION_ELEMENTS_FEATURE = "Collections::Collection::elements"; public static final String ARRAY_DIMENSIONS_FEATURE = "Collections::Array::dimensions"; + public static DataType getCollectionDataType(Element context) { + return (DataType)SysMLLibraryUtil.getLibraryType(context, COLLECTION_DATA_TYPE); + } + public static DataType getOrderedCollectionDataType(Element context) { return (DataType)SysMLLibraryUtil.getLibraryType(context, ORDERED_COLLECTION_DATA_TYPE); } diff --git a/org.omg.sysml/syntax-gen/org/omg/sysml/lang/sysml/impl/ExpressionImpl.java b/org.omg.sysml/syntax-gen/org/omg/sysml/lang/sysml/impl/ExpressionImpl.java index 7d95bfcc1..a79c5e55f 100644 --- a/org.omg.sysml/syntax-gen/org/omg/sysml/lang/sysml/impl/ExpressionImpl.java +++ b/org.omg.sysml/syntax-gen/org/omg/sysml/lang/sysml/impl/ExpressionImpl.java @@ -29,13 +29,11 @@ import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EOperation; import org.eclipse.emf.ecore.EStructuralFeature; -import org.eclipse.emf.ecore.util.BasicInternalEList; import org.eclipse.uml2.common.util.UnionEObjectEList; import org.omg.sysml.lang.sysml.Behavior; import org.omg.sysml.lang.sysml.Element; import org.omg.sysml.lang.sysml.Expression; import org.omg.sysml.lang.sysml.Feature; -import org.omg.sysml.lang.sysml.FeatureDirectionKind; import org.omg.sysml.lang.sysml.Function; import org.omg.sysml.lang.sysml.SysMLPackage; @@ -163,33 +161,7 @@ public EList getBehavior() { public boolean isSetBehavior() { return false; } - - @Override - public EList getInput() { - // Only owned inputs - EList inputs = new BasicInternalEList(Feature.class); - // Note: Using directionOf causes an infinite recursion. - getOwnedFeature().stream(). - filter(feature-> - FeatureDirectionKind.IN == feature.getDirection() || - FeatureDirectionKind.INOUT == feature.getDirection()). - forEachOrdered(inputs::add); - return inputs; - } - - @Override - public EList getOutput() { - // Only owned outputs - EList outputs = new BasicInternalEList(Feature.class); - // Note: Using directionOf causes an infinite recursion. - getOwnedFeature().stream(). - filter(feature-> - FeatureDirectionKind.OUT == feature.getDirection() || - FeatureDirectionKind.INOUT == feature.getDirection()). - forEachOrdered(outputs::add); - return outputs; - } - + /** * *