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 0393e0df authored by Eric Tobias's avatar Eric Tobias

Initial forke of CPS

parents
*.metadata
*.classpath
CPS/target
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>cps</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
</natures>
</projectDescription>
This diff is collapsed.
This diff is collapsed.
activeProfiles=
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1
<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>
<name>Complex Problem Solving library</name>
<build>
<sourceDirectory>src</sourceDirectory>
<testSourceDirectory>test</testSourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>lu.list.itis.dkd</groupId>
<artifactId>dbc-annotation</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>19.0</version>
</dependency>
<dependency>
<groupId>dk.ange</groupId>
<artifactId>javaoctave</artifactId>
<version>0.6.4</version>
</dependency>
<dependency>
<groupId>lu.list.itis.dkd.tui</groupId>
<artifactId>tulip</artifactId>
<version>2.2.0</version>
</dependency>
</dependencies>
</project>
\ 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.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
/**
* 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.logging.Level;
import java.util.logging.Logger;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
import com.google.common.base.Preconditions;
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 24 Feb 2014
* @version 1
*/
@NonNullByDefault
public class Equation
{
private Mapping mapping, lockedMapping;
@Nullable
private ScriptEngine scriptEngine;
private String script;
/**
* Constructor
* @param mapping
* The mapping of variables to take into account for the equation.
* @param script
* The mathematical representation of the equation in string form.
* Note that the names of the variables in the script must coincide with
* the names of the variables in the mapping.
*/
public Equation(Mapping mapping, String script)
{
this.mapping = mapping;
this.lockedMapping = mapping;
this.script = script;
}
/**
* Simple getter method for mapping.
* @return The value of mapping.
*/
public Mapping getMapping()
{
return mapping;
}
/**
* Method called to evaluate the script of the equation with
* the variables provided by the mapping.
*/
@SuppressWarnings("null")
public void evaluate()
{
Preconditions.checkState(scriptEngine != null);
try{
mapping.getDependentVariable().setValue(scriptEngine.eval(replaceVariables()));
} catch (ScriptException e) {
Logger.getLogger(Equation.class.getSimpleName()).log(Level.SEVERE, "", e);
}
}
/**
* Method used to replace variables with their actual values in the formula.
* @return
* The formula with variables replaced by their values, ready for evaluation.
*/
private String replaceVariables()
{
String result = new String(script);
for(Variable variable : lockedMapping.getIndependentVariables())
{
result = result.replaceAll(variable.getName(), variable.getValue().toString());
}
result = result.replaceAll(lockedMapping.getDependentVariable().getName(), lockedMapping.getDependentVariable().getValue().toString());
assert result != null;
return result;
}
/**
* Method for setting the script engine to use.
* @param engine
* The {@link ScriptEngine} instance to use for
* evaluating the scripted formulas.
*/
public void setScriptEngine(ScriptEngine engine)
{
scriptEngine = engine;
}
/**
* Method querying whether the {@link Equation} instance is
* affected by a change of the {@link Variable} instance and
* would need to recompute.
* @param variable
* The variable to look up.
* @return
* <code>True</code> if the {@link Variable} instance is
* an independent variable that is part of this
* {@link Equation} isntance's computation.
*/
public boolean catersTo(Variable variable)
{
return mapping.catersTo(variable);
}
/**
* Method used to make a local copy of all variables to lock
* down the state for asynchronous, clock-driven computation.
*/
public void saveState()
{
lockedMapping = mapping.lock();
}
}
\ No newline at end of file
This diff is collapsed.
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
/**
* 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.concurrent.ConcurrentHashMap;
import com.google.common.base.Preconditions;
import lu.list.itis.dkd.cps.InputEvent;
import lu.list.itis.dkd.cps.variable.Variable;
import lu.list.itis.dkd.dbc.annotation.NonNullByDefault;
/**
* Class implementing a system of linear equations. The class
* holds a number of equations and defines the engine that
* evaluates the equations. The class may be driven by a clock
* react to input changes synchronously.
* @author Eric TOBIAS [eric.tobias@tudor.lu]
* @since 21 Feb 2014
* @version 1
*/
@NonNullByDefault
public class LinearEquationSystem extends System
{
private ConcurrentHashMap<Mapping, Equation> equations;
// private ScriptEngine scriptEngine;
// private static OctaveEngine scriptEngine;
// static {
// OctaveEngineFactory l_Factory = new OctaveEngineFactory();
// l_Factory.setOctaveProgram(new File ("/opt/local/bin/octave"));
// l_Factory.setWorkingDir(new File("./octave"));
// scriptEngine = l_Factory.getScriptEngine();
// }
/**
* Constructor issuing a super call and initialising the map of
* equations.
* @param lockToNesting
* Boolean indicating whether nested systems will have their
* inputs locked during computation. Doing so will result
* in a synchronous behaviour of the system while choosing
* <code>false</code> will have the nested systems evaluate
* their equations first, possibly propagating results to
* systems higher up in the nesting tree.
*/
@SuppressWarnings("null")
public LinearEquationSystem(boolean lockToNesting)
{
super();
equations = new ConcurrentHashMap<>();
// scriptEngine = new ScriptEngineManager().getEngineByName("js");
this.lockSystemForNesting = lockToNesting;
// assert scriptEngine != null : "Script engine cannot be null;";
}
/**
* Method used for adding an {@link Equation} instance to the system.
* @param equation
* The {@link Equation} instance to add.
* @return
* An instance of the equation map for chain-calling.
*/
public ConcurrentHashMap<Mapping, Equation> addEquation(Equation equation)
{
// ((OctaveEquation)equation).setScriptEngine(scriptEngine);
// equation.setScriptEngine(scriptEngine);
equations.put(equation.getMapping(), equation);
return equations;
}
/** {@inheritDoc} */
@Override
public synchronized void clockTicked(long tick)
{
super.clockTicked(tick);
for(Equation equation : equations.values())
{
equation.evaluate();
}
}
/** {@inheritDoc} */
@SuppressWarnings("null")
@Override
public synchronized void inputChanged(InputEvent input)
{
Preconditions.checkArgument(input != null && input.getSource() != null,
"Neither the input nor the input source may be null.");
/** Invoke super method dealing with nested systems. */
super.inputChanged(input);
for(Equation equation : equations.values())
{
if(equation.catersTo((Variable) input.getSource()))
{
equation.evaluate();
}
}
}
/** {@inheritDoc} */
@Override
public void saveState()
{
for(Equation equation : equations.values())
{
equation.saveState();
}
}
}
\ No newline at end of file