InterpreterUtil.java
/**
* Copyright (c) 2004-2025 Carnegie Mellon University and others. (see Contributors file).
* All Rights Reserved.
*
* NO WARRANTY. ALL MATERIAL IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY
* KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE
* OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT
* MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
*
* This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
* SPDX-License-Identifier: EPL-2.0
*
* Created, in part, with funding and support from the United States Government. (see Acknowledgments file).
*
* This program includes and/or can make use of certain third party source code, object code, documentation and other
* files ("Third Party Software"). The Third Party Software that is used by this program is dependent upon your system
* configuration. By using this program, You agree to comply with any and all relevant Third Party Software terms and
* conditions contained in any such Third Party Software or separate license file distributed with such Third Party
* Software. The parties who own the Third Party Software ("Third Party Licensors") are intended third party benefici-
* aries to this license with respect to the terms applicable to their Third Party Software. Third Party Software li-
* censes only apply to the Third Party Software and not any other portion of this program or this program as a whole.
*/
package org.osate.alisa.common.typing;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Iterator;
import org.eclipse.emf.ecore.EObject;
import org.osate.aadl2.Aadl2Factory;
import org.osate.aadl2.IntegerLiteral;
import org.osate.aadl2.NamedElement;
import org.osate.aadl2.NumberValue;
import org.osate.aadl2.RealLiteral;
import org.osate.aadl2.UnitLiteral;
import org.osate.aadl2.instance.InstanceObject;
import org.osate.alisa.common.common.AModelReference;
import org.osate.pluginsupport.ExecuteJavaUtil;
public class InterpreterUtil {
public static UnitLiteral smallerUnit(UnitLiteral unit1, UnitLiteral unit2) {
if (unit1 == null || unit2 == null) {
return null;
} else if (unit1 == unit2) {
return unit1;
} else {
RealLiteral tester = Aadl2Factory.eINSTANCE.createRealLiteral();
tester.setValue(1.0);
tester.setUnit(unit1);
if (tester.getScaledValue(unit2) < 1.0) {
return unit1;
} else {
return unit2;
}
}
}
public static int compareTo(NumberValue v1, NumberValue v2) {
UnitLiteral minUnit = smallerUnit(v1.getUnit(), v2.getUnit());
if (v1 instanceof IntegerLiteral && v2 instanceof IntegerLiteral) {
Long s1 = (v1.getUnit() == null) ? ((IntegerLiteral) v1).getValue()
: Math.round(v1.getScaledValue(minUnit));
Long s2 = (v2.getUnit() == null) ? ((IntegerLiteral) v2).getValue()
: Math.round(v2.getScaledValue(minUnit));
return s1.compareTo(s2);
} else {
Double s1 = (v1.getUnit() == null)
? (v1 instanceof IntegerLiteral) ? ((IntegerLiteral) v1).getValue() : ((RealLiteral) v1).getValue()
: v1.getScaledValue(minUnit);
Double s2 = (v2.getUnit() == null)
? (v2 instanceof IntegerLiteral) ? ((IntegerLiteral) v2).getValue() : ((RealLiteral) v2).getValue()
: v2.getScaledValue(minUnit);
return s1.compareTo(s2);
}
}
public static NumberValue add(NumberValue v1, NumberValue v2) {
UnitLiteral minUnit = smallerUnit(v1.getUnit(), v2.getUnit());
if (v1 instanceof IntegerLiteral && v2 instanceof IntegerLiteral) {
long s1 = (v1.getUnit() == null) ? ((IntegerLiteral) v1).getValue()
: Math.round(v1.getScaledValue(minUnit));
long s2 = (v2.getUnit() == null) ? ((IntegerLiteral) v2).getValue()
: Math.round(v2.getScaledValue(minUnit));
IntegerLiteral result = Aadl2Factory.eINSTANCE.createIntegerLiteral();
result.setValue(s1 + s2);
result.setUnit(minUnit);
return result;
} else {
double s1 = (v1.getUnit() == null)
? (v1 instanceof IntegerLiteral) ? ((IntegerLiteral) v1).getValue() : ((RealLiteral) v1).getValue()
: v1.getScaledValue(minUnit);
double s2 = (v2.getUnit() == null)
? (v2 instanceof IntegerLiteral) ? ((IntegerLiteral) v2).getValue() : ((RealLiteral) v2).getValue()
: v2.getScaledValue(minUnit);
RealLiteral result = Aadl2Factory.eINSTANCE.createRealLiteral();
result.setValue(s1 + s2);
result.setUnit(minUnit);
return result;
}
}
public static NumberValue subtract(NumberValue v1, NumberValue v2) {
if (v2 instanceof IntegerLiteral) {
IntegerLiteral neg = Aadl2Factory.eINSTANCE.createIntegerLiteral();
neg.setValue(-((IntegerLiteral) v2).getValue());
neg.setUnit(v2.getUnit());
return add(v1, neg);
} else {
RealLiteral neg = Aadl2Factory.eINSTANCE.createRealLiteral();
neg.setValue(-((RealLiteral) v2).getValue());
neg.setUnit(v2.getUnit());
return add(v1, neg);
}
}
public static NumberValue multiply(NumberValue v1, NumberValue v2) {
UnitLiteral unit = (v1.getUnit() != null) ? v1.getUnit() : v2.getUnit();
if (v1 instanceof IntegerLiteral && v2 instanceof IntegerLiteral) {
long s1 = ((IntegerLiteral) v1).getValue();
long s2 = ((IntegerLiteral) v2).getValue();
IntegerLiteral result = Aadl2Factory.eINSTANCE.createIntegerLiteral();
result.setValue(s1 * s2);
result.setUnit(unit);
return result;
} else {
double s1 = (v1 instanceof IntegerLiteral) ? ((IntegerLiteral) v1).getValue()
: ((RealLiteral) v1).getValue();
double s2 = (v2 instanceof IntegerLiteral) ? ((IntegerLiteral) v2).getValue()
: ((RealLiteral) v2).getValue();
RealLiteral result = Aadl2Factory.eINSTANCE.createRealLiteral();
result.setValue(s1 * s2);
result.setUnit(unit);
return result;
}
}
public static NumberValue divide(NumberValue v1, NumberValue v2) {
UnitLiteral minUnit = smallerUnit(v1.getUnit(), v2.getUnit());
boolean twoUnits = v1.getUnit() != null && v2.getUnit() != null;
UnitLiteral unit = (v1.getUnit() != null) ? v1.getUnit() : v2.getUnit();
double s1 = (!twoUnits)
? (v1 instanceof IntegerLiteral) ? ((IntegerLiteral) v1).getValue() : ((RealLiteral) v1).getValue()
: v1.getScaledValue(minUnit);
double s2 = (!twoUnits)
? (v2 instanceof IntegerLiteral) ? ((IntegerLiteral) v2).getValue() : ((RealLiteral) v2).getValue()
: v2.getScaledValue(minUnit);
RealLiteral result = Aadl2Factory.eINSTANCE.createRealLiteral();
result.setValue(s1 / s2);
result.setUnit(twoUnits ? null : unit);
return result;
}
public static NumberValue divideInt(IntegerLiteral v1, IntegerLiteral v2) {
UnitLiteral minUnit = smallerUnit(v1.getUnit(), v2.getUnit());
boolean twoUnits = v1.getUnit() != null && v2.getUnit() != null;
UnitLiteral unit = (v1.getUnit() != null) ? v1.getUnit() : v2.getUnit();
long s1 = (!twoUnits) ? v1.getValue() : Math.round(v1.getScaledValue(minUnit));
long s2 = (!twoUnits) ? v2.getValue() : Math.round(v2.getScaledValue(minUnit));
IntegerLiteral result = Aadl2Factory.eINSTANCE.createIntegerLiteral();
result.setValue(s1 / s2);
result.setUnit(twoUnits ? minUnit : unit);
return result;
}
public static NumberValue mod(IntegerLiteral v1, IntegerLiteral v2) {
UnitLiteral minUnit = smallerUnit(v1.getUnit(), v2.getUnit());
boolean twoUnits = v1.getUnit() != null && v2.getUnit() != null;
UnitLiteral unit = (v1.getUnit() != null) ? v1.getUnit() : v2.getUnit();
long s1 = (!twoUnits) ? v1.getValue() : Math.round(v1.getScaledValue(minUnit));
long s2 = (!twoUnits) ? v2.getValue() : Math.round(v2.getScaledValue(minUnit));
IntegerLiteral result = Aadl2Factory.eINSTANCE.createIntegerLiteral();
result.setValue(s1 % s2);
result.setUnit(twoUnits ? minUnit : unit);
return result;
}
public static NumberValue min(Collection<NumberValue> nvals) {
Iterator<NumberValue> it = nvals.iterator();
NumberValue result = it.next();
while (it.hasNext()) {
NumberValue nv = it.next();
if (compareTo(nv, result) < 0) {
result = nv;
}
}
return result;
}
public static NumberValue max(Collection<NumberValue> nvals) {
Iterator<NumberValue> it = nvals.iterator();
NumberValue result = it.next();
while (it.hasNext()) {
NumberValue nv = it.next();
if (compareTo(nv, result) > 0) {
result = nv;
}
}
return result;
}
public static IntegerLiteral round(NumberValue nv) {
if (nv instanceof RealLiteral) {
long iv = Math.round(((RealLiteral) nv).getValue());
IntegerLiteral result = Aadl2Factory.eINSTANCE.createIntegerLiteral();
result.setValue(iv);
result.setUnit(nv.getUnit());
return result;
} else {
return (IntegerLiteral) nv;
}
}
public static IntegerLiteral floor(NumberValue nv) {
if (nv instanceof RealLiteral) {
long iv = Double.valueOf(Math.floor(((RealLiteral) nv).getValue())).longValue();
IntegerLiteral result = Aadl2Factory.eINSTANCE.createIntegerLiteral();
result.setValue(iv);
result.setUnit(nv.getUnit());
return result;
} else {
return (IntegerLiteral) nv;
}
}
public static IntegerLiteral ceil(NumberValue nv) {
if (nv instanceof RealLiteral) {
long iv = Double.valueOf(Math.ceil(((RealLiteral) nv).getValue())).longValue();
IntegerLiteral result = Aadl2Factory.eINSTANCE.createIntegerLiteral();
result.setValue(iv);
result.setUnit(nv.getUnit());
return result;
} else {
return (IntegerLiteral) nv;
}
}
/**
* Resolve a model element reference relative to an instance object
*/
static InstanceObject resolve(AModelReference ref, NamedElement root) {
if (!(root instanceof InstanceObject)) {
return null;
}
if (ref.getPrev() == null) {
return (InstanceObject) root;
} else {
InstanceObject io = resolve(ref.getPrev(), root);
EObject result = io.eContents().stream()
.filter(it -> (it instanceof InstanceObject)
? ((InstanceObject) it).getName().equalsIgnoreCase(ref.getModelElement().getName()) : false)
.findFirst().get();
return (InstanceObject) result;
}
}
public static InterpreterUtil instance = new InterpreterUtil();
// Method returns null if Java class was found.
// Otherwise it returns an error message
public String methodExists(final String javaMethod) {
Method m = ExecuteJavaUtil.getJavaMethod(javaMethod);
if (m != null) {
return null;
} else {
return "Java method " + javaMethod + " not found.";
}
}
}