Dear users, Please note that, from Monday, August 16, 2019, RSA keys shorter than 2048bit will no longer be accepted for security reasons. Please update your keys as needed before this date. If you need assistance with regard to this process, please contact sia@list.lu

Thank you for your understanding.

Commit 269db096 authored by Eric Tobias's avatar Eric Tobias

Changed namespace and added dual-license header

parent bafc4a67
Pipeline #106 skipped
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>lu.list.itis.dkd.tui</groupId>
<artifactId>cps</artifactId>
<version>1.0.0</version>
<artifactId>tulip-cps</artifactId>
<version>1.3.0</version>
<name>Complex Problem Solving library</name>
<build>
......
/**
* Copyright CRP Henri Tudor, 2014.
* All rights reserved. If you wish to use this code for any purpose,
* please contact CRP Henri Tudor's Technology Transfer Office : tto@tudor.lu
*/
package lu.list.itis.dkd.cps;
import java.util.Vector;
import lu.list.itis.dkd.dbc.annotation.NonNullByDefault;
/**
* Class implementing a clock holding a value representing
* an abstract turn.
* @author Eric TOBIAS [eric.tobias@tudor.lu]
* @since 21 Feb 2014
* @version 1
*/
@NonNullByDefault
public class Clock
{
/** Field holding the current turn value. */
private long tick = 0;
/** Field holding a {@link Vector} of listeners to turn churns. */
private Vector<InputDriver> tickListeners = new Vector<>();
/**
* Getter method returning the current turn count.
* @return
* The current turn value.
* @invariant tick >= 0
*/
public long getTick()
{
return tick;
}
/**
* Method resetting the turn value.
* @post tick = 0
*/
public void reset()
{
tick = 0;
}
/**
* Advances the turn count by one. Should the count be the
* maximum value of the counter it will wrap to 0. The
* method also notifies all listeners of the change.
* @return
* The value of the new turn count.
* @post tick = old(tick) + 1 || tick = Long.MAX_VALUE => tick = 0
*/
public long tick()
{
if(tick == Long.MAX_VALUE)
{
reset();
} else {
tick++;
}
for(InputDriver listener : tickListeners)
{
listener.clockTicked(tick);
}
return tick;
}
/**
* Method invoked to add a {@link InputDriver} to the {@link Vector} of
* listeners to notify on tick.
* @param listener
* The {@link InputDriver} to add.
*/
public void addListener(InputDriver listener)
{
tickListeners.add(listener);
}
}
\ No newline at end of file
/**
* Copyright CRP Henri Tudor, 2014.
* All rights reserved. If you wish to use this code for any purpose,
* please contact CRP Henri Tudor's Technology Transfer Office : tto@tudor.lu
*/
package lu.list.itis.dkd.cps;
import java.util.EventListener;
import lu.list.itis.dkd.dbc.annotation.NonNullByDefault;
/**
* Interface defining method for listeners to input change.
* @author Eric TOBIAS [eric.tobias@tudor.lu]
* @since 21 Feb 2014
* @version 1
*/
@NonNullByDefault
public interface InputChangeListener extends EventListener
{
/**
* Method invoked by any observed instances when an input has changed.
* @param input
* The {@link InputEvent} holding the source as well as turn
* count, variable name, and value of the input.
*/
public void inputChanged(InputEvent input);
}
\ No newline at end of file
/**
* Copyright CRP Henri Tudor, 2014.
* All rights reserved. If you wish to use this code for any purpose,
* please contact CRP Henri Tudor's Technology Transfer Office : tto@tudor.lu
*/
package lu.list.itis.dkd.cps;
import lu.list.itis.dkd.dbc.annotation.NonNullByDefault;
/**
* Interface specifying the methods for driving the collection or
* forwarding of input values.
* @author Eric TOBIAS [eric.tobias@tudor.lu]
* @since 21 Feb 2014
* @version 1
*/
@NonNullByDefault
public interface InputDriver
{
/**
* Method invoked when the clock advanced a turn.
* @param tick
* The turn count the clock advanced to.
*/
public void clockTicked(long tick);
}
\ No newline at end of file
/**
* Copyright CRP Henri Tudor, 2014.
* All rights reserved. If you wish to use this code for any purpose,
* please contact CRP Henri Tudor's Technology Transfer Office : tto@tudor.lu
*/
package lu.list.itis.dkd.cps;
import java.util.EventObject;
import lu.list.itis.dkd.cps.variable.Variable;
import lu.list.itis.dkd.dbc.annotation.NonNullByDefault;
/**
* Class implementing an event holding all necessary information
* to change {@link Variable} instances synchronously with the change
* of an external input.
* @author Eric TOBIAS [eric.tobias@tudor.lu]
* @since 21 Feb 2014
* @version 1
*/
@NonNullByDefault
public class InputEvent extends EventObject
{
private static final long serialVersionUID = 2884355501325896122L;
/** The turn index the event was triggered at. */
private long tick;
/**
* Constructor initialising the source and all other fields.
* @param source
* The source of the event.
* @param tick
* The turn index the event was triggered at.
*/
public InputEvent(Variable source, long tick)
{
super(source);
this.tick = tick;
}
/**
* Constructor initialising the source field and
* setting the tick field to -1.
* @param source
* The source of the event.
*/
public InputEvent(Variable source)
{
super(source);
this.tick = -1;
}
/**
* Simple getter method for tick.
* @return The value of tick.
*/
public long getTick()
{
return tick;
}
}
\ No newline at end of file
/**
* Copyright CRP Henri Tudor, 2014.
* All rights reserved. If you wish to use this code for any purpose,
* please contact CRP Henri Tudor's Technology Transfer Office : tto@tudor.lu
*/
package lu.list.itis.dkd.cps;
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import lu.list.itis.dkd.cps.variable.Variable;
import lu.list.itis.dkd.dbc.annotation.NonNullByDefault;
import lu.list.itis.dkd.dbc.annotation.Nullable;
/**
*
* @author Eric TOBIAS [eric.tobias@tudor.lu]
* @since 21 Feb 2014
* @version 1
*/
@NonNullByDefault
public class Phenomenon
{
/** The clock which may dictate the sampling rate and advancement of the phenomenon. */
private Clock clock;
/** The independent variables characterising the system. */
private ConcurrentHashMap<String, Variable> independentVariables;
/** The variables depending on the system and its inputs. */
private ConcurrentHashMap<String, Variable> dependentVariables;
/** The system computing dependent variables from input independent variables. */
private lu.list.itis.dkd.cps.system.System system;
/** Field indicating whether the observation is to be driven by a clock. */
private boolean clockDriven;
/**
* Constructor initialising all fields.
* @param independentVariables
* The independent variables characterising the system.
* @param dependentVariables
* The variables depending on the system and its inputs.
* @param system
* The system computing dependent variables from input independent variables.
* @param clockDriven
* Indication whether the observation of the phenomenon is to be driven
* by the ticking of a clock or is synchronous.
*/
public Phenomenon(ConcurrentHashMap<String, Variable> independentVariables,
ConcurrentHashMap<String, Variable> dependentVariables,
lu.list.itis.dkd.cps.system.System system, boolean clockDriven)
{
clock = new Clock();
this.independentVariables = independentVariables;
this.dependentVariables = dependentVariables;
this.system = system;
this.clockDriven = clockDriven;
if(clockDriven)
{
clock.addListener(system);
} else {
for(Variable variable : independentVariables.values())
{
variable.addListener(system);
}
for(Variable variable : dependentVariables.values())
{
variable.addListener(system);
}
}
}
/**
* Method used to advance the observation by one turn or period.
* @return
* The turn of the observation or <code>-1</code> if the phenomenon
* is observed synchronously with the modification of the input
* parameters.
* @invariant result >= -1
*/
public long churn()
{
if(clockDriven)
{
return clock.tick();
}
return -1;
}
/**
* Method for retrieving the output.
* @return
* The {@link Collection} of dependent variables.
*/
@SuppressWarnings("null")
public Collection<Variable> getOutputs()
{
return dependentVariables.values();
}
/**
* Method used to retrieve the output with the given name.
* @param variableName
* The name of the {@link Variable} to retrieve.
* @return
* The instance of the {@link Variable} or <code>null</code>
* if no such {@link Variable} was defined.
*/
public @Nullable Variable getOutput(String variableName)
{
return dependentVariables.get(variableName);
}
/**
* Simple getter method for independentVariables.
* @return The value of independentVariables.
*/
@SuppressWarnings("null")
public Collection<Variable> getInputs()
{
return independentVariables.values();
}
/**
* Simple getter method for system.
* @return The value of system.
*/
public lu.list.itis.dkd.cps.system.System getSystem()
{
return system;
}
}
\ No newline at end of file
package lu.list.itis.dkd.cps.system;
/**
* @author nmack
* @date 07 Apr 2015
*
* <br>$Log: EquationSystemException.java,v $
*/
//***************************************************************************
//* Class Definition and Members *
//***************************************************************************
public class EquationSystemException extends Exception
{
/**
*
*/
private static final long serialVersionUID = 7422560120940501724L;
//***************************************************************************
//* Constants *
//***************************************************************************
//---------------------------------------------------------------------------
//***************************************************************************
//* Constructor(s) *
//***************************************************************************
//---------------------------------------------------------------------------
public EquationSystemException (String reason)
{
super(reason);
}
//---------------------------------------------------------------------------
//***************************************************************************
//* Primitives *
//***************************************************************************
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//***************************************************************************
//* Class Body *
//***************************************************************************
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//***************************************************************************
//* End of Class *
//***************************************************************************
//---------------------------------------------------------------------------
}
\ No newline at end of file
package lu.list.itis.dkd.cps.system;
import java.util.LinkedHashSet;
import com.google.common.base.Preconditions;
import lu.list.itis.dkd.cps.variable.Variable;
/**
* @author nmack
* @date 03 Apr 2015
*
* <br>
* $Log: OctaveMapping.java,v $
*/
// ***************************************************************************
// * Class Definition and Members *
// ***************************************************************************
public class OctaveMapping extends Mapping
{
private LinkedHashSet<Variable> dependentVariables;
// ***************************************************************************
// * Constants *
// ***************************************************************************
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Constructor(s) *
// ***************************************************************************
// ---------------------------------------------------------------------------
public OctaveMapping(LinkedHashSet<Variable> independentVariables, LinkedHashSet<Variable> dependentVariables)
{
super(independentVariables, null);
Preconditions.checkArgument(!dependentVariables.isEmpty(), "The set of output variables cannot be empty.");
this.dependentVariables = dependentVariables;
}
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Primitives *
// ***************************************************************************
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Class Body *
// ***************************************************************************
// ---------------------------------------------------------------------------
/**
* Simple getter method for dependentVariable.
*
* @return The value of dependentVariable.
*/
// ---------------------------------------------------------------------------
public LinkedHashSet<Variable> getDependentVariables()
{
return dependentVariables;
}
// ---------------------------------------------------------------------------
public String toString()
{
String separator = "";
StringBuilder renderer = new StringBuilder();
LinkedHashSet<Variable> independentVariables = super.getIndependentVariables();
for (Variable variable : independentVariables)
{
renderer.append(separator).append(variable.getName());
separator = ", ";
}
renderer.append(" => ");
separator = "";
for (Variable variable : dependentVariables)
{
renderer.append(separator).append(variable.getName());
separator = ", ";
}
return renderer.toString();
}
// ---------------------------------------------------------------------------
/**
* Method for locking the mapping; cloning all variables such that they may
* not be influenced by the evaluation of the equation.
*
* @return A deep copy of the {@link Mapping}.
*/
// ---------------------------------------------------------------------------
public synchronized Mapping lock()
{
LinkedHashSet<Variable> independentVariables = super.getIndependentVariables();
LinkedHashSet<Variable> clonedIndependentVariables = new LinkedHashSet<>();
for (Variable variable : independentVariables)
{
clonedIndependentVariables.add(variable.clone());
}
LinkedHashSet<Variable> clonedDependentVariables = new LinkedHashSet<>();
for (Variable variable : dependentVariables)
{
clonedDependentVariables.add(variable.clone());
}
return new OctaveMapping(clonedIndependentVariables, clonedDependentVariables);
}
// ---------------------------------------------------------------------------
// ***************************************************************************
// * End of Class *
// ***************************************************************************
// ---------------------------------------------------------------------------
}
\ No newline at end of file
/**
* Copyright CRP Henri Tudor, 2014.
* All rights reserved. If you wish to use this code for any purpose,
* please contact CRP Henri Tudor's Technology Transfer Office : tto@tudor.lu
*/
package lu.list.itis.dkd.cps.system;
import java.util.Vector;
import lu.list.itis.dkd.cps.InputChangeListener;
import lu.list.itis.dkd.cps.InputDriver;
import lu.list.itis.dkd.cps.InputEvent;
import lu.list.itis.dkd.dbc.annotation.NonNullByDefault;
/**
* Abstract class serving as a top level hierarchical construct
* for all system instances.
* @author Eric TOBIAS [eric.tobias@tudor.lu]
* @since 21 Feb 2014
* @version 1
*/
@NonNullByDefault
public abstract class System implements InputDriver, InputChangeListener
{
/** Field holding the {@link Vector} of nested {@link System} instances. */
protected Vector<System> nestedSystems;
protected boolean lockSystemForNesting = true;
/**
* Constructor.
*/
public System()
{
nestedSystems = new Vector<>();
}
/**
* Method used to nest a system.
* @param system
* The {@link System} instance to add.
*/
public void nestSystem(System system)
{
nestedSystems.add(system);
}
/**
* {@inheritDoc}<br><br>
*
* The method will issue calls to all nested stated to lock input
* variables after locking variables itself but before forwarding
* the call to them.
*/
@Override
public synchronized void inputChanged(InputEvent input)
{
saveState();
for(System nestedSystem : nestedSystems)
{
if (nestedSystem != null) nestedSystem.saveState();
}
for(System nestedSystem : nestedSystems)
{
if (nestedSystem != null) nestedSystem.inputChanged(input);
}
}
/**
* {@inheritDoc}<br><br>
*
* The method will issue calls to all nested stated to lock input
* variables after locking variables itself but before forwarding
* the call to them.
*/
@Override
public synchronized void clockTicked(long tick)
{
if(lockSystemForNesting) saveState();
for(System nestedSystem : nestedSystems)
{
nestedSystem.saveState();
}
for(System nestedSystem : nestedSystems)
{
nestedSystem.clockTicked(tick);
}
}
/**
* Method used to announce an upcoming tick to
* all computation units and nested systems,
* hence the need to lock all outputs that may
* server as inputs in feedback loops.
*/
public abstract void saveState();
}
\ No newline at end of file
/**
* Copyright CRP Henri Tudor, 2014.
* All rights reserved. If you wish to use this code for any purpose,
* please contact CRP Henri Tudor's Technology Transfer Office : tto@tudor.lu
*/
package lu.list.itis.dkd.cps.variable;
import java.util.Vector;
import lu.list.itis.dkd.cps.InputChangeListener;
import lu.list.itis.dkd.dbc.annotation.NonNullByDefault;
import lu.list.itis.dkd.dbc.annotation.Nullable;
/**
* Abstract class modelling the bases of variables as
* processed by the {@link System}.
* @author Eric TOBIAS [eric.tobias@tudor.lu]
* @since 21 Feb 2014
* @version 1
*/
@NonNullByDefault
public abstract class Variable implements Cloneable
{
/** The name of the variable. */
protected String name;
/** The unit the variable is given in. */
protected String unit;
/** The listeners to notify when the variable changes value. */
protected Vector<InputChangeListener> listeners;
/**
* Constructor initialising the name and unit fields.
* @param name
* The name of the variable.
* @param unit
* The unit the variable is given in.
*/
public Variable(String name, String unit)
{
this.name = name;
this.unit = unit;
listeners = new Vector<>();
}
/**
* Simple getter method for name.
* @return The value of name.
*/
public String getName()
{
return name;
}
/**
* Simple getter method for unit.
* @return The value of unit.
*/
public String getUnit()
{
return unit;
}
/**
* Simple getter method for the value held by the {@link Variable} instance.
* @return
* The value held by the {@link Variable} instance.
*/
public abstract Object getValue();
/**
* Method used to set the value held by the variable.
* @param value
* The new value the variable should have.
*/
public abstract void setValue(Object value);
/** {@inheritDoc} */
@Override
public String toString()
{
return name + " (" + unit + ")";
}
/** {@inheritDoc} */
@Override
public int hashCode()
{
return toString().hashCode();
}