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 + ")";
}