Commit 3dc5a63c authored by Nico Mack's avatar Nico Mack

Major overhaul of parameter setting and result retrieval. Variables are

no longer passed directly but are wrapped in a Declaration object,
allowing to specifiy EQUATE, INDEX and FIELD attributes.
parent c2ab505d
...@@ -14,6 +14,9 @@ EQUATIONS_ELEMENT=equations ...@@ -14,6 +14,9 @@ EQUATIONS_ELEMENT=equations
EQUATION_ELEMENT=equation EQUATION_ELEMENT=equation
MODE_ATTRIBUTE=mode MODE_ATTRIBUTE=mode
INVOKE_ELEMENT=invoke INVOKE_ELEMENT=invoke
INDEX_ATTRIBUTE=index
FIELD_ATTRIBUTE=field
INVOKE_ELEMENT=invoke
EPSILON_ATTRIBUTE=epsilon EPSILON_ATTRIBUTE=epsilon
EXECUTOR_ATTRIBUTE=executor EXECUTOR_ATTRIBUTE=executor
NAME_ATTRIBUTE=name NAME_ATTRIBUTE=name
......
/Spatial$py.class /Spatial$py.class
/Text$py.class /Text$py.class
/Map$py.class /Map$py.class
/Vector$py.class
'''
Created on Jan 8, 2018
@author: mack
'''
def ManipulateVector (V):
R = V
R[3] = 2
return R
\ No newline at end of file
...@@ -22,10 +22,13 @@ package lu.list.itis.dkd.tui.cps; ...@@ -22,10 +22,13 @@ package lu.list.itis.dkd.tui.cps;
import lu.list.itis.dkd.dbc.annotation.NonNullByDefault; import lu.list.itis.dkd.dbc.annotation.NonNullByDefault;
import lu.list.itis.dkd.dbc.annotation.Nullable; import lu.list.itis.dkd.dbc.annotation.Nullable;
import lu.list.itis.dkd.tui.cps.system.Declaration;
import lu.list.itis.dkd.tui.cps.system.System; import lu.list.itis.dkd.tui.cps.system.System;
import lu.list.itis.dkd.tui.cps.variable.Variable; import lu.list.itis.dkd.tui.cps.variable.Variable;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
/** /**
...@@ -41,9 +44,9 @@ public class Phenomenon { ...@@ -41,9 +44,9 @@ public class Phenomenon {
/** The clock which may dictate the sampling rate and advancement of the phenomenon. */ /** The clock which may dictate the sampling rate and advancement of the phenomenon. */
private Clock clock; private Clock clock;
/** The independent variables characterising the system. */ /** The independent variables characterising the system. */
private ConcurrentHashMap<String, Variable<?>> independentVariables; private ConcurrentHashMap<String, Declaration> independentVariables;
/** The variables depending on the system and its inputs. */ /** The variables depending on the system and its inputs. */
private ConcurrentHashMap<String, Variable<?>> dependentVariables; private ConcurrentHashMap<String, Declaration> dependentVariables;
/** The system computing dependent variables from input independent variables. */ /** The system computing dependent variables from input independent variables. */
private lu.list.itis.dkd.tui.cps.system.System system; private lu.list.itis.dkd.tui.cps.system.System system;
/** Field indicating whether the observation is to be driven by a clock. */ /** Field indicating whether the observation is to be driven by a clock. */
...@@ -59,11 +62,11 @@ public class Phenomenon { ...@@ -59,11 +62,11 @@ public class Phenomenon {
* @param system * @param system
* The system computing dependent variables from input independent variables. * The system computing dependent variables from input independent variables.
* @param clockDriven * @param clockDriven
* Indication whether the observation of the phenomenon is to be driven by the ticking of * Indication whether the observation of the phenomenon is to be driven by the ticking of a
* a clock or is synchronous. * clock or is synchronous.
*/ */
public Phenomenon(ConcurrentHashMap<String, Variable<?>> independentVariables, public Phenomenon(ConcurrentHashMap<String, Declaration> independentVariables,
ConcurrentHashMap<String, Variable<?>> dependentVariables, ConcurrentHashMap<String, Declaration> dependentVariables,
lu.list.itis.dkd.tui.cps.system.System system, boolean clockDriven) { lu.list.itis.dkd.tui.cps.system.System system, boolean clockDriven) {
clock = new Clock(); clock = new Clock();
this.independentVariables = independentVariables; this.independentVariables = independentVariables;
...@@ -74,12 +77,12 @@ public class Phenomenon { ...@@ -74,12 +77,12 @@ public class Phenomenon {
if (clockDriven) { if (clockDriven) {
clock.addListener(system); clock.addListener(system);
} else { } else {
for (Variable variable : independentVariables.values()) { for (Declaration declaration : independentVariables.values()) {
variable.addListener(system); declaration.getVariable().addListener(system);
} }
for (Variable variable : dependentVariables.values()) { for (Declaration declaration : dependentVariables.values()) {
variable.addListener(system); declaration.getVariable().addListener(system);
} }
} }
} }
...@@ -104,7 +107,12 @@ public class Phenomenon { ...@@ -104,7 +107,12 @@ public class Phenomenon {
* @return The {@link Collection} of dependent variables. * @return The {@link Collection} of dependent variables.
*/ */
public Collection<Variable<?>> getOutputs() { public Collection<Variable<?>> getOutputs() {
return dependentVariables.values(); List<Variable<?>> outputs = new ArrayList<>();
for (Declaration declaration : dependentVariables.values()) {
outputs.add(declaration.getVariable());
}
return outputs;
} }
/** /**
...@@ -112,11 +120,12 @@ public class Phenomenon { ...@@ -112,11 +120,12 @@ public class Phenomenon {
* *
* @param variableName * @param variableName
* The name of the {@link Variable} to retrieve. * The name of the {@link Variable} to retrieve.
* @return The instance of the {@link Variable} or <code>null</code> if no such {@link Variable} * @return The instance of the {@link Variable} or <code>null</code> if no such {@link Variable} was
* was defined. * defined.
*/ */
public @Nullable Variable<?> getOutput(String variableName) { public @Nullable Variable<?> getOutput(String variableName) {
return dependentVariables.get(variableName); Declaration declaration = dependentVariables.get(variableName);
return (declaration != null) ? declaration.getVariable() : null;
} }
/** /**
...@@ -125,7 +134,12 @@ public class Phenomenon { ...@@ -125,7 +134,12 @@ public class Phenomenon {
* @return The value of independentVariables. * @return The value of independentVariables.
*/ */
public Collection<Variable<?>> getInputs() { public Collection<Variable<?>> getInputs() {
return independentVariables.values(); List<Variable<?>> inputs = new ArrayList<>();
for (Declaration declaration : independentVariables.values()) {
inputs.add(declaration.getVariable());
}
return inputs;
} }
/** /**
......
/**
* Copyright Luxembourg Institute of Science and Technology, 2018. All rights reserved. If you wish
* to use this code for any purpose, please contact the author(s).
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package lu.list.itis.dkd.tui.cps.system;
import lu.list.itis.dkd.tui.cps.variable.MapVariable;
import lu.list.itis.dkd.tui.cps.variable.Variable;
import lu.list.itis.dkd.tui.cps.variable.VectorVariable;
import lu.list.itis.dkd.tui.utility.StringUtils;
import com.jgoodies.common.base.Preconditions;
/**
* Class modeling the fundamental properties for declaring variables in the context of equations.
*
* @author Nico Mack [nico.mack@list.lu]
* @since 1.5
* @version 1.0.0
*/
// ***************************************************************************
// * Class Definition *
// ***************************************************************************
public class Declaration implements Cloneable {
protected String field;
protected String equate;
protected int index;
protected Variable<?> variable;
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Constructor(s) *
// ***************************************************************************
// ---------------------------------------------------------------------------
public Declaration(Variable<?> variable) {
this.variable = variable;
this.index = -1;
}
// ---------------------------------------------------------------------------
public Declaration(Variable<?> variable, String field) {
Preconditions.checkArgument((variable instanceof MapVariable), StringUtils.build("Variable {} is not a MapVariable!", variable.getName())); //$NON-NLS-1$
this.variable = variable;
this.field = field;
this.index = -1;
}
// ---------------------------------------------------------------------------
public Declaration(Variable<?> variable, int index) {
Preconditions.checkArgument((variable instanceof VectorVariable), StringUtils.build("Variable {} is not a VectorVariable!", variable.getName())); //$NON-NLS-1$
this.variable = variable;
this.index = index;
}
// ---------------------------------------------------------------------------
public Declaration(Declaration other) {
this.variable = other.variable.clone();
this.field = other.field;
this.equate = other.equate;
this.index = other.index;
}
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Class Body *
// ***************************************************************************
// ---------------------------------------------------------------------------
public void setEquate(String equate) {
this.equate = equate;
}
// ---------------------------------------------------------------------------
public String getIdentifier() {
return (this.variable != null) ? this.variable.getName() : null;
}
// ---------------------------------------------------------------------------
/**
* Simple getter method for equate.
*
* @return The value of equate.
*/
// ---------------------------------------------------------------------------
public String getEquate() {
return equate;
}
// ---------------------------------------------------------------------------
/**
* Simple getter method for field.
*
* @return The value of field.
*/
// ---------------------------------------------------------------------------
public String getField() {
return field;
}
// ---------------------------------------------------------------------------
/**
* Simple getter method for index.
*
* @return The value of index.
*/
// ---------------------------------------------------------------------------
public int getIndex() {
return index;
}
// ---------------------------------------------------------------------------
/**
* Simple getter method for variable.
*
* @return The value of variable.
*/
// ---------------------------------------------------------------------------
public Variable<?> getVariable() {
return variable;
}
// ---------------------------------------------------------------------------
@Override
public Declaration clone() {
return new Declaration(this);
}
// ---------------------------------------------------------------------------
@SuppressWarnings("nls")
@Override
public String toString() {
StringBuilder renderer = new StringBuilder();
renderer.append(variable.getName());
if ((field != null) && (!field.isEmpty())) {
renderer.append("{").append(field).append("}");
} else if (index >= 0) {
renderer.append("[").append(index).append("]");
}
return renderer.toString();
}
// ---------------------------------------------------------------------------
// ***************************************************************************
// * End of Class
// ***************************************************************************
// ---------------------------------------------------------------------------
}
...@@ -62,9 +62,8 @@ public class Equation { ...@@ -62,9 +62,8 @@ public class Equation {
* @param mapping * @param mapping
* The mapping of variables to take into account for the equation. * The mapping of variables to take into account for the equation.
* @param script * @param script
* The mathematical representation of the equation in string form. Note that the names of * The mathematical representation of the equation in string form. Note that the names of the
* the variables in the script must coincide with the names of the variables in the * variables in the script must coincide with the names of the variables in the mapping.
* mapping.
*/ */
public Equation(String name, Mapping mapping, String script) { public Equation(String name, Mapping mapping, String script) {
this.name = name; this.name = name;
...@@ -84,8 +83,8 @@ public class Equation { ...@@ -84,8 +83,8 @@ public class Equation {
} }
/** /**
* Allows to isolate this equation. An isolated equation will not notify dependent equations * Allows to isolate this equation. An isolated equation will not notify dependent equations when
* when evaluation entailed changes in results. * evaluation entailed changes in results.
* *
* @param isolateIt * @param isolateIt
*/ */
...@@ -98,11 +97,10 @@ public class Equation { ...@@ -98,11 +97,10 @@ public class Equation {
} }
/** /**
* Method called to evaluate the script of the equation with the variables provided by the * Method called to evaluate the script of the equation with the variables provided by the mapping.
* mapping.
*/ */
public synchronized void evaluate() { public synchronized void evaluate() {
LinkedHashSet<Variable<?>> dependentVariables; LinkedHashSet<Declaration> dependentVariables;
String evaluationErrors; String evaluationErrors;
Preconditions.checkState(scriptExecutor != null); Preconditions.checkState(scriptExecutor != null);
...@@ -110,8 +108,8 @@ public class Equation { ...@@ -110,8 +108,8 @@ public class Equation {
try { try {
scriptExecutor.resetExecutionErrors(); scriptExecutor.resetExecutionErrors();
for (Variable<?> variable : lockedMapping.getIndependentVariables()) { for (Declaration declaration : lockedMapping.getIndependentVariables()) {
scriptExecutor.set(variable); scriptExecutor.set(declaration);
} }
scriptExecutor.eval(this.script); scriptExecutor.eval(this.script);
...@@ -126,12 +124,13 @@ public class Equation { ...@@ -126,12 +124,13 @@ public class Equation {
if (consolidated) if (consolidated)
consolidatedListeners = new HashMap<>(); consolidatedListeners = new HashMap<>();
for (Variable<?> variable : dependentVariables) { for (Declaration declaration : dependentVariables) {
Variable<?> variable = declaration.getVariable();
variable.suspendListenerNotification(consolidated); variable.suspendListenerNotification(consolidated);
if (consolidated) if (consolidated)
consolidatedListeners = variable.consolidateListeners(consolidatedListeners); consolidatedListeners = variable.consolidateListeners(consolidatedListeners);
try { try {
variable = scriptExecutor.get(variable); variable = scriptExecutor.get(declaration);
} catch (Exception exception) { } catch (Exception exception) {
LOGGER.error("Error while retrieving variable {}", variable.getName(), exception); //$NON-NLS-1$ LOGGER.error("Error while retrieving variable {}", variable.getName(), exception); //$NON-NLS-1$
} }
...@@ -154,9 +153,9 @@ public class Equation { ...@@ -154,9 +153,9 @@ public class Equation {
if (evaluationErrors.length() > 0) { if (evaluationErrors.length() > 0) {
LOGGER.warn("Error while evaluating equation : {}", evaluationErrors); //$NON-NLS-1$ LOGGER.warn("Error while evaluating equation : {}", evaluationErrors); //$NON-NLS-1$
LOGGER.warn("Script = {}", this.script); //$NON-NLS-1$ LOGGER.warn("Script = {}", this.script); //$NON-NLS-1$
LinkedHashSet<Variable<?>> independentVariables = mapping.getIndependentVariables(); LinkedHashSet<Declaration> independentVariables = mapping.getIndependentVariables();
for (Variable<?> variable : independentVariables) { for (Declaration declaration : independentVariables) {
LOGGER.trace("{} = {}", variable.getName(), variable.getValue()); //$NON-NLS-1$ LOGGER.trace("{} = {}", declaration, declaration.getVariable().getValue()); //$NON-NLS-1$
} }
} }
} }
......
...@@ -30,14 +30,15 @@ import java.util.LinkedHashSet; ...@@ -30,14 +30,15 @@ import java.util.LinkedHashSet;
* Class describing the mapping between a set of input variables and an output variable. The order * Class describing the mapping between a set of input variables and an output variable. The order
* of input variables is preserved and essential when defining the equation. * of input variables is preserved and essential when defining the equation.
* *
* @author Nico Mack [nico.mack@list.lu]
* @author Eric Tobias [eric.tobias@list.lu] * @author Eric Tobias [eric.tobias@list.lu]
* @since 1.0 * @since 1.0
* @version 1.3.1 * @version 1.5.0
*/ */
@NonNullByDefault @NonNullByDefault
public class Mapping { public class Mapping {
private LinkedHashSet<Variable<?>> independentVariables; private LinkedHashSet<Declaration> independentVariables;
private LinkedHashSet<Variable<?>> dependentVariables; private LinkedHashSet<Declaration> dependentVariables;
/** /**
* Constructor initialising the mapping. * Constructor initialising the mapping.
...@@ -47,7 +48,7 @@ public class Mapping { ...@@ -47,7 +48,7 @@ public class Mapping {
* @param dependentVariable * @param dependentVariable
* The dependent variable of the mapping. * The dependent variable of the mapping.
*/ */
public Mapping(LinkedHashSet<Variable<?>> independentVariables, LinkedHashSet<Variable<?>> dependentVariables) { public Mapping(LinkedHashSet<Declaration> independentVariables, LinkedHashSet<Declaration> dependentVariables) {
// Preconditions.checkArgument(!independentVariables.isEmpty(), "The set of input variables // Preconditions.checkArgument(!independentVariables.isEmpty(), "The set of input variables
// cannot be empty."); //$NON-NLS-1$ // cannot be empty."); //$NON-NLS-1$
this.independentVariables = independentVariables; this.independentVariables = independentVariables;
...@@ -59,7 +60,7 @@ public class Mapping { ...@@ -59,7 +60,7 @@ public class Mapping {
* *
* @return The value of independentVariables. * @return The value of independentVariables.
*/ */
public LinkedHashSet<Variable<?>> getIndependentVariables() { public LinkedHashSet<Declaration> getIndependentVariables() {
return independentVariables; return independentVariables;
} }
...@@ -68,7 +69,7 @@ public class Mapping { ...@@ -68,7 +69,7 @@ public class Mapping {
* *
* @return The value of dependentVariables. * @return The value of dependentVariables.
*/ */
public LinkedHashSet<Variable<?>> getDependentVariables() { public LinkedHashSet<Declaration> getDependentVariables() {
return dependentVariables; return dependentVariables;
} }
...@@ -79,8 +80,8 @@ public class Mapping { ...@@ -79,8 +80,8 @@ public class Mapping {
StringBuilder renderer = new StringBuilder(); StringBuilder renderer = new StringBuilder();
if (independentVariables != null) { if (independentVariables != null) {
for (Variable<?> variable : independentVariables) { for (Declaration declaration : independentVariables) {
renderer.append(separator).append(variable.getName()); renderer.append(separator).append(declaration);
separator = ", "; //$NON-NLS-1$ separator = ", "; //$NON-NLS-1$
} }
} else { } else {
...@@ -91,8 +92,8 @@ public class Mapping { ...@@ -91,8 +92,8 @@ public class Mapping {
separator = ""; //$NON-NLS-1$ separator = ""; //$NON-NLS-1$
if (dependentVariables != null) { if (dependentVariables != null) {
for (Variable<?> variable : dependentVariables) { for (Declaration declaration : dependentVariables) {
renderer.append(separator).append(variable.getName()); renderer.append(separator).append(declaration);
separator = ", "; //$NON-NLS-1$ separator = ", "; //$NON-NLS-1$
} }
} else { } else {
...@@ -133,61 +134,41 @@ public class Mapping { ...@@ -133,61 +134,41 @@ public class Mapping {
} }
/** /**
* Method querying whether the {@link Mapping} instance holds the {@link Variable} instance * Method querying whether the {@link Mapping} instance holds the {@link Variable} instance given as
* given as a parameter as an independent {@link Variable} instance. * a parameter as an independent {@link Variable} instance.
* *
* @param variable * @param variable
* The variable to look up. * The variable to look up.
* @return <code>True</code> if the {@link Variable} instance is an independent variable managed * @return <code>True</code> if the {@link Variable} instance is an independent variable managed by
* by this {@link Mapping} instance. * this {@link Mapping} instance.
*/ */
public boolean catersTo(Variable<?> variable) { public boolean catersTo(Variable<?> variable) {
for (Variable<?> _variable : independentVariables) { for (Declaration declaration : independentVariables) {
if (_variable.equals(variable)) { if (variable.equals(declaration.getVariable())) {
return true; return true;
} }
} }
return (independentVariables.contains(variable)); return false;
} }
/** /**
* Method for locking the mapping; cloning all variables such that they may not be influenced by * Method for locking the mapping; cloning all variables such that they may not be influenced by the
* the evaluation of the equation. * evaluation of the equation.
* *
* @return A deep copy of the {@link Mapping}. * @return A deep copy of the {@link Mapping}.
*/ */
public Mapping lock() { public Mapping lock() {
LinkedHashSet<Variable<?>> clonedIndependentVariables = new LinkedHashSet<>(); LinkedHashSet<Declaration> clonedIndependentVariables = new LinkedHashSet<>();
for (Variable<?> variable : independentVariables) { for (Declaration declaration : independentVariables) {
clonedIndependentVariables.add(variable.clone()); clonedIndependentVariables.add(declaration.clone());
} }
LinkedHashSet<Variable<?>> clonedDependentVariables = new LinkedHashSet<>(); LinkedHashSet<Declaration> clonedDependentVariables = new LinkedHashSet<>();
if (dependentVariables != null) { if (dependentVariables != null) {
for (Variable<?> variable : dependentVariables) { for (Declaration declaration : dependentVariables) {
clonedDependentVariables.add(variable.clone()); clonedDependentVariables.add(declaration.clone());
} }
} }
return new Mapping(clonedIndependentVariables, clonedDependentVariables); return new Mapping(clonedIndependentVariables, clonedDependentVariables);
} }