Bug 514634 General Improvement of Polygraph, MoCC CSDF rate computation


Change-Id: Ic7b9d833ee3fb99cc229d66ec5949d2b4fde5d64
Signed-off-by: Arnault Lapitre <arnault.lapitre@cea.fr>
diff --git a/codegen/org.eclipse.efm.modeling.codegen.xlia.sdf.polygraph/src/org/eclipse/efm/modeling/codegen/xlia/sdf/polygraph/mocc/ast/MoccChannel.java b/codegen/org.eclipse.efm.modeling.codegen.xlia.sdf.polygraph/src/org/eclipse/efm/modeling/codegen/xlia/sdf/polygraph/mocc/ast/MoccChannel.java
index b30b405..3431f87 100644
--- a/codegen/org.eclipse.efm.modeling.codegen.xlia.sdf.polygraph/src/org/eclipse/efm/modeling/codegen/xlia/sdf/polygraph/mocc/ast/MoccChannel.java
+++ b/codegen/org.eclipse.efm.modeling.codegen.xlia.sdf.polygraph/src/org/eclipse/efm/modeling/codegen/xlia/sdf/polygraph/mocc/ast/MoccChannel.java
@@ -167,7 +167,12 @@
 
 		sout.append(' ').append(name).append(" {")
 			.append('\n')
-			.append('\t').append("output<").append(outputPort.strRate()).append("> ")
+			.append('\t').append("output<").append(outputPort.strRate());
+		if( outputPort.cycloStaticRate != null ) {
+			sout.append(" , ");
+			outputPort.strCycloStaticRate(sout);
+		}
+		sout.append("> ")
 			.append(outputPort.getActor().getName())
 			.append("->").append(outputPort.getName())
 			.append('\n');
@@ -184,7 +189,12 @@
 				.append('\n');
 		}
 
-		sout.append('\t').append("input<").append(inputPort.strRate()).append("> ")
+		sout.append('\t').append("input<").append(inputPort.strRate());
+		if( inputPort.cycloStaticRate != null ) {
+			sout.append(" , ");
+			inputPort.strCycloStaticRate(sout);
+		}
+		sout.append("> ")
 			.append(inputPort.getActor().getName())
 			.append("->").append(inputPort.getName())
 			.append('\n')
diff --git a/codegen/org.eclipse.efm.modeling.codegen.xlia.sdf.polygraph/src/org/eclipse/efm/modeling/codegen/xlia/sdf/polygraph/mocc/ast/MoccPort.java b/codegen/org.eclipse.efm.modeling.codegen.xlia.sdf.polygraph/src/org/eclipse/efm/modeling/codegen/xlia/sdf/polygraph/mocc/ast/MoccPort.java
index 1065f37..4ce2154 100644
--- a/codegen/org.eclipse.efm.modeling.codegen.xlia.sdf.polygraph/src/org/eclipse/efm/modeling/codegen/xlia/sdf/polygraph/mocc/ast/MoccPort.java
+++ b/codegen/org.eclipse.efm.modeling.codegen.xlia.sdf.polygraph/src/org/eclipse/efm/modeling/codegen/xlia/sdf/polygraph/mocc/ast/MoccPort.java
@@ -12,6 +12,8 @@
  *******************************************************************************/
 package org.eclipse.efm.modeling.codegen.xlia.sdf.polygraph.mocc.ast;
 
+import org.eclipse.efm.modeling.codegen.xlia.sdf.polygraph.util.Rational;
+
 public class MoccPort {
 
 	public final MoccActor actor;
@@ -26,6 +28,8 @@
 
 	protected final int rateDenominator;
 
+	protected int[] cycloStaticRate;
+
 	protected MoccChannel channel;
 
 	public MoccPort(final MoccActor actor, final Direction direction,
@@ -40,6 +44,7 @@
 
 		this.rate = rate;
 		this.rateDenominator = rateDenominator;
+		cycloStaticRate = null;
 
 		this.channel = null;
 
@@ -103,6 +108,14 @@
 		return( rateDenominator > 1 );
 	}
 
+	public int[] getCycloStaticRate() {
+		return cycloStaticRate;
+	}
+
+	public boolean hasCycloStaticRate() {
+		return( cycloStaticRate != null );
+	}
+
 
 	public boolean isInputRational() {
 		return( (channel != null) && channel.getInputPort().isRational() );
@@ -139,6 +152,127 @@
 	}
 
 
+/*
+	def csdf_sequence(rate, rate_initial):
+	    s = []
+	    for i in range(rate.denominator):
+	        r = rate_initial + rate
+	        s += [abs(floor(r)-floor(rate_initial))]
+	        rate_initial = r
+	    return s
+*/
+	public static int[] computeRateCSDF(final Rational rate, Rational initial ) {
+		final int[] cycloStaticRate = new int[rate.getDenominator()];
+
+		for (int i = 0; i < cycloStaticRate.length; i++) {
+			final Rational sum = (new Rational(initial)).add(rate);
+			cycloStaticRate[i] = Math.abs(sum.floor() - initial.floor());
+			initial = sum;
+		}
+
+		return cycloStaticRate;
+	}
+
+
+	public static void printRate(final int[] rate) {
+		System.out.print('[');
+		for (final int r : rate) {
+			System.out.print(' ');
+			System.out.print(r);
+		}
+		System.out.println(" ]");
+	}
+
+
+/*
+	for den in range(5):
+	    for num in range(1,den):
+	        rate = Fraction(num,den)
+	        for ps in range(den):
+	            rate_initial = Fraction(ps,den)
+	            print("case:",rate,"-",rate_initial,"->",2)
+	            print("csdf production:",csdf_sequence(rate,rate_initial))
+	            print("csdf consumption:",csdf_sequence(-2,rate_initial))
+	            print("case:",2,"-",rate_initial,"->",rate)
+	            print("csdf production:",csdf_sequence(2,rate_initial))
+	            print("csdf consumption:",csdf_sequence(-rate,rate_initial))
+	            print()
+	        print()
+	    print()
+*/
+	public static void main(final String[] args) {
+		final Rational deux = new Rational(2,  1);
+		final Rational neg_deux = new Rational(-2,  1);
+
+		for (int den = 0; den < 5; den++) {
+			for (int num = 1; num < den; num++) {
+				final Rational rate = new Rational(num,den);
+				for (int ps = 0; ps < den; ps++) {
+					final Rational rate_initial = new Rational(ps,den);
+					System.out.println("case: " + rate + " -- " + rate_initial + " --> " + 2);
+					System.out.print("csdf production : "); printRate(computeRateCSDF(rate , rate_initial));
+					System.out.print("csdf consumption: "); printRate(computeRateCSDF(neg_deux , rate_initial));
+
+					System.out.println("case: " + 2 + " -- " + rate_initial + " --> " + rate);
+					System.out.print("csdf production : "); printRate(computeRateCSDF(deux , rate_initial));
+					System.out.print("csdf consumption: "); printRate(computeRateCSDF(rate.negate() , rate_initial));
+					System.out.println();
+				}
+				System.out.println();
+			}
+			System.out.println();
+		}
+
+		final Rational prod = new Rational(4, 3);
+		final Rational init = new Rational(0, 1);
+		final Rational conso = new Rational(-1, 1);
+		System.out.println("case: 4/3 -- 0 --> 1");
+		System.out.print("csdf prod : "); printRate(computeRateCSDF(prod , init));
+		System.out.print("csdf conso: "); printRate(computeRateCSDF(conso , init));
+		System.out.println();
+	}
+
+	public void computeCycloStaticInputRate() {
+		cycloStaticRate = computeRateCSDF(
+				new Rational(-rate, rateDenominator),
+				new Rational(channel.initialRate, channel.initialRateDenominator));
+
+//		cycloStaticRate = new int[rateDenominator];
+//		int intTokenCount = 0;
+//		float floatTokenCount = 0;
+//		for (int i = 0; i < cycloStaticRate.length; i++) {
+//			floatTokenCount += ((float)rate) / rateDenominator;
+//			if( ((int) floatTokenCount) <= (rate - 1) ) {
+//				cycloStaticRate[i] = ((int) floatTokenCount ) + 1 - intTokenCount;
+//
+//				intTokenCount += cycloStaticRate[i];
+//			}
+//			else {
+//				cycloStaticRate[i] = 0;
+//			}
+//		}
+	}
+
+	public void computeCycloStaticOutputRate() {
+		cycloStaticRate = computeRateCSDF(
+				new Rational(rate, rateDenominator),
+				new Rational(0, 1));
+//				new Rational(channel.initialRate, channel.initialRateDenominator));
+
+
+
+//		cycloStaticRate = new int[rateDenominator];
+//		int intTokenCount = 0;
+//		float floatTokenCount = 0;
+//		for (int i = 0; i < cycloStaticRate.length; i++) {
+//			floatTokenCount += rate;
+//			cycloStaticRate[i] = ((int) (floatTokenCount / rateDenominator)) - intTokenCount;
+//			intTokenCount += cycloStaticRate[i];
+//		}
+	}
+
+
+
 	public MoccChannel getChannel() {
 		return channel;
 	}
@@ -170,6 +304,16 @@
 		}
 	}
 
+	public void strCycloStaticRate(final StringBuilder sout) {
+		sout.append('[');
+		for (final int rate : cycloStaticRate) {
+			sout.append(' ').append(rate);
+		}
+		sout.append(" ]");
+	}
+
+
+
 	@Override
 	public String toString() {
 		final StringBuilder sout = new StringBuilder();
@@ -177,6 +321,11 @@
 		sout.append(direction.toString().toLowerCase())
 			.append(" port< rate = ").append(strRate());
 
+		if( cycloStaticRate != null ) {
+			sout.append(" , cyclo = ");
+			strCycloStaticRate(sout);
+		}
+
 		if( channel.hasInitialRate() ) {
 			sout.append(" , initial = ").append(channel.strInitialRate());
 		}
diff --git a/codegen/org.eclipse.efm.modeling.codegen.xlia.sdf.polygraph/src/org/eclipse/efm/modeling/codegen/xlia/sdf/polygraph/mocc/ast/feature/MoccActorFeature.java b/codegen/org.eclipse.efm.modeling.codegen.xlia.sdf.polygraph/src/org/eclipse/efm/modeling/codegen/xlia/sdf/polygraph/mocc/ast/feature/MoccActorFeature.java
index e66e186..20a30c7 100644
--- a/codegen/org.eclipse.efm.modeling.codegen.xlia.sdf.polygraph/src/org/eclipse/efm/modeling/codegen/xlia/sdf/polygraph/mocc/ast/feature/MoccActorFeature.java
+++ b/codegen/org.eclipse.efm.modeling.codegen.xlia.sdf.polygraph/src/org/eclipse/efm/modeling/codegen/xlia/sdf/polygraph/mocc/ast/feature/MoccActorFeature.java
@@ -190,4 +190,20 @@
 			return "[null]";
 		}
 	}
+
+
+	public void computeCycloStaticRate() {
+		for( final MoccPort moccPort : actor.getInputPort() ) {
+			if( moccPort.isRational() ) {
+				moccPort.computeCycloStaticInputRate();
+			}
+		}
+
+		for( final MoccPort moccPort : actor.getOutputPort() ) {
+			if( moccPort.isRational() ) {
+				moccPort.computeCycloStaticOutputRate();
+			}
+		}
+	}
+
 }
diff --git a/codegen/org.eclipse.efm.modeling.codegen.xlia.sdf.polygraph/src/org/eclipse/efm/modeling/codegen/xlia/sdf/polygraph/mocc/ast/feature/MoccSystemFeature.java b/codegen/org.eclipse.efm.modeling.codegen.xlia.sdf.polygraph/src/org/eclipse/efm/modeling/codegen/xlia/sdf/polygraph/mocc/ast/feature/MoccSystemFeature.java
index e97998a..fa660ca 100644
--- a/codegen/org.eclipse.efm.modeling.codegen.xlia.sdf.polygraph/src/org/eclipse/efm/modeling/codegen/xlia/sdf/polygraph/mocc/ast/feature/MoccSystemFeature.java
+++ b/codegen/org.eclipse.efm.modeling.codegen.xlia.sdf.polygraph/src/org/eclipse/efm/modeling/codegen/xlia/sdf/polygraph/mocc/ast/feature/MoccSystemFeature.java
@@ -199,6 +199,7 @@
 		this.consistency = checkConsistency();
 
 		for( final MoccActor actor : system.getActor() ) {
+			actor.FEATURE.computeCycloStaticRate();
 			actor.FEATURE.computeActivation(this);
 		}
 	}
diff --git a/codegen/org.eclipse.efm.modeling.codegen.xlia.sdf.polygraph/src/org/eclipse/efm/modeling/codegen/xlia/sdf/polygraph/mocc/helper/MoccPortHelper.java b/codegen/org.eclipse.efm.modeling.codegen.xlia.sdf.polygraph/src/org/eclipse/efm/modeling/codegen/xlia/sdf/polygraph/mocc/helper/MoccPortHelper.java
index a2e6889..244c35a 100644
--- a/codegen/org.eclipse.efm.modeling.codegen.xlia.sdf.polygraph/src/org/eclipse/efm/modeling/codegen/xlia/sdf/polygraph/mocc/helper/MoccPortHelper.java
+++ b/codegen/org.eclipse.efm.modeling.codegen.xlia.sdf.polygraph/src/org/eclipse/efm/modeling/codegen/xlia/sdf/polygraph/mocc/helper/MoccPortHelper.java
@@ -28,6 +28,8 @@
 
 	public Variable constTOKEN_RATE;
 
+	public Variable constTOKEN_RATE_CSDF;
+
 
 	public MoccPortHelper(final Port xliaPort,
 			final Port xliaChannelPort,
@@ -35,7 +37,8 @@
 			final Variable varReceivedModeTokenCount,
 			final Variable constModeInitial,
 			final Variable varReceivedMode,
-			final Variable constTokenRate) {
+			final Variable constTokenRate,
+			final Variable constTokenRateCSDF) {
 		super();
 
 		this.xliaPort = xliaPort;
@@ -48,10 +51,18 @@
 		this.varReceivedMode = varReceivedMode;
 
 		this.constTOKEN_RATE = constTokenRate;
+
+		this.constTOKEN_RATE_CSDF = constTokenRateCSDF;
 	}
 
-	public MoccPortHelper(final Port xliaPort, final Variable constTokenRate) {
-		this(xliaPort, xliaPort, null, null, null, null, constTokenRate);
+//	public MoccPortHelper(final Port xliaPort, final Variable constTokenRate) {
+//		this(xliaPort, xliaPort, null, null, null, null, constTokenRate, null);
+//	}
+
+	public MoccPortHelper(final Port xliaPort,
+			final Variable constTokenRate, final Variable constTokenRateCSDF) {
+		this(xliaPort, xliaPort, null, null, null, null,
+				constTokenRate, constTokenRateCSDF);
 	}
 
 }
diff --git a/codegen/org.eclipse.efm.modeling.codegen.xlia.sdf.polygraph/src/org/eclipse/efm/modeling/codegen/xlia/sdf/polygraph/mocc/xlia/MoCC2XLIA.java b/codegen/org.eclipse.efm.modeling.codegen.xlia.sdf.polygraph/src/org/eclipse/efm/modeling/codegen/xlia/sdf/polygraph/mocc/xlia/MoCC2XLIA.java
index 82ac16d..c8c0838 100644
--- a/codegen/org.eclipse.efm.modeling.codegen.xlia.sdf.polygraph/src/org/eclipse/efm/modeling/codegen/xlia/sdf/polygraph/mocc/xlia/MoCC2XLIA.java
+++ b/codegen/org.eclipse.efm.modeling.codegen.xlia.sdf.polygraph/src/org/eclipse/efm/modeling/codegen/xlia/sdf/polygraph/mocc/xlia/MoCC2XLIA.java
@@ -786,6 +786,17 @@
 						varType, "PRODUCTION_TO_" + targetActor, value);
 		xliaActor.getVariable().add(constTokenProductionRate);
 
+
+		Variable constTokenProductionRateCSDF = null;
+		if( moccPort.hasCycloStaticRate() ) {
+			final int[] cycloStaticRate = moccPort.getCycloStaticRate();
+			constTokenProductionRateCSDF = XLIA_INFRA.createVariable(
+					XLIA_DATATYPE.createInterger(cycloStaticRate.length),
+					"CSDF_PRODUCTION_TO_" + targetActor,
+					XLIA_EXPRESSION.createCollection(cycloStaticRate));
+			xliaActor.getVariable().add(constTokenProductionRateCSDF);
+		}
+
 		// OUTPUT PORT
 		final DataType tokenType =
 				XLIA_DATATYPE.createRationalOrInteger(moccPort.isRational());
@@ -805,8 +816,8 @@
 					moccPort, ChannelDirection.OUTPUT, xliaActor, tokenType);
 		}
 
-		portHelper.put(moccPort,
-				new MoccPortHelper(xliaPort, constTokenProductionRate));
+		portHelper.put(moccPort, new MoccPortHelper(xliaPort,
+				constTokenProductionRate, constTokenProductionRateCSDF));
 	}
 
 	/**
@@ -833,6 +844,16 @@
 				"REQUIRED_FROM_" + sourceActor/*.toUpperCase()*/, value);
 		xliaActor.getVariable().add(constREQ);
 
+		Variable constTokenConsumptionRateCSDF = null;
+		if( moccPort.hasCycloStaticRate() ) {
+			final int[] cycloStaticRate = moccPort.getCycloStaticRate();
+			constTokenConsumptionRateCSDF = XLIA_INFRA.createVariable(
+					XLIA_DATATYPE.createInterger(cycloStaticRate.length),
+					"CSDF_REQUIRED_FROM_" + sourceActor,
+					XLIA_EXPRESSION.createCollection(cycloStaticRate));
+			xliaActor.getVariable().add(constTokenConsumptionRateCSDF);
+		}
+
 		// CONSTANT: INITIAL TOKEN COUNT
 		Variable tokenInitialRate = null;
 		Variable modeInitial = null;
@@ -918,10 +939,9 @@
 			}
 
 		// Mapping: MoccPort-->PortHelper
-		portHelper.put(moccPort,
-				new MoccPortHelper(xliaPort, xliaChannelPort,
-						tokenInitialRate, varTokenCount,
-						modeInitial, varReceivedMode, constREQ));
+		portHelper.put(moccPort, new MoccPortHelper(xliaPort, xliaChannelPort,
+				tokenInitialRate, varTokenCount, modeInitial,
+				varReceivedMode, constREQ, constTokenConsumptionRateCSDF));
 	}
 
 
@@ -1806,6 +1826,8 @@
 		XLIA_STATEMENT.addAssignment(thenBlock,

 				actorHELPER.varProcessingMode, this.MODE_UNDEFINED);

 

+		XLIA_STATEMENT.addInvokeExit(thenBlock, "MoCC::MODE<UNDEFINED>");
+
 		// Else Nominal Mode Passing

 		final BlockStatement elseBlock =

 				XLIA_STATEMENT.createElseBlockStatement(ifStatement);

@@ -1841,6 +1863,8 @@
 		XLIA_STATEMENT.addAssignment(thenBlock,
 				actorHELPER.varProcessingMode, this.MODE_UNDEFINED);
 
+		XLIA_STATEMENT.addInvokeExit(thenBlock, "MoCC::MODE<UNDEFINED>");
+
 		// Else Identical i.e. Singleton
 		final BlockStatement elseBlock =
 				XLIA_STATEMENT.createElseBlockStatement(ifStatement);
@@ -1907,6 +1931,8 @@
 			XLIA_STATEMENT.addAssignment(thenBlock,
 					actorHELPER.varProcessingMode, this.MODE_UNDEFINED);
 
+			XLIA_STATEMENT.addInvokeExit(thenBlock, "MoCC::MODE<UNDEFINED>");
+
 			// Else Mode computing
 			ifStatement.setElseBlock(blockCollectMode);
 
@@ -1932,6 +1958,9 @@
 			XLIA_STATEMENT.addAssignment(elseIfBlockMultiple,
 					actorHELPER.varProcessingMode, this.MODE_UNDEFINED);
 
+			XLIA_STATEMENT.addInvokeExit(
+					elseIfBlockMultiple, "MoCC::MODE<UNDEFINED>");
+
 //			// Different Mode passing
 //			final ConditionalBlockStatement diffElseIfStatement =
 //					XLIA_STATEMENT.addElseIf(ifSingleton);
diff --git a/codegen/org.eclipse.efm.modeling.codegen.xlia.sdf.polygraph/src/org/eclipse/efm/modeling/codegen/xlia/sdf/polygraph/util/Rational.java b/codegen/org.eclipse.efm.modeling.codegen.xlia.sdf.polygraph/src/org/eclipse/efm/modeling/codegen/xlia/sdf/polygraph/util/Rational.java
index 3f066e2..3d048a0 100644
--- a/codegen/org.eclipse.efm.modeling.codegen.xlia.sdf.polygraph/src/org/eclipse/efm/modeling/codegen/xlia/sdf/polygraph/util/Rational.java
+++ b/codegen/org.eclipse.efm.modeling.codegen.xlia.sdf.polygraph/src/org/eclipse/efm/modeling/codegen/xlia/sdf/polygraph/util/Rational.java
@@ -15,7 +15,7 @@
 public class Rational implements Comparable<Rational> {
 //	private static Rational zero = new Rational(0, 1);
 
-	public static int gcd(int m, int n) {
+	public static int gcd(final int m, final int n) {
 		if (0 == n) {
 			return m;
 		} else {
@@ -23,7 +23,7 @@
 		}
 	}
 
-	public static int lcm(int m, int n) {
+	public static int lcm(final int m, final int n) {
 		return m * (n / gcd(m, n));
 	}
 
@@ -31,9 +31,9 @@
 
 	private int numerator;
 
-	public Rational(int numerator, int denominator) {
+	public Rational(final int numerator, final int denominator) {
 
-		int g = gcd(numerator, denominator);
+		final int g = gcd(numerator, denominator);
 		this.numerator = numerator / g;
 		this.denominator = denominator / g;
 		if (this.denominator < 0) {
@@ -42,6 +42,10 @@
 		}
 	}
 
+	public Rational(final Rational initial) {
+		this(initial.numerator, initial.denominator);
+	}
+
 	public int getDenominator() {
 		return denominator;
 	}
@@ -51,10 +55,10 @@
 	}
 
 	@Override
-	public int compareTo(Rational b) {
-		Rational a = this;
-		int lhs = a.numerator * b.denominator;
-		int rhs = a.denominator * b.numerator;
+	public int compareTo(final Rational b) {
+		final Rational a = this;
+		final int lhs = a.numerator * b.denominator;
+		final int rhs = a.denominator * b.numerator;
 		if (lhs < rhs)
 			return -1;
 		if (lhs > rhs)
@@ -63,15 +67,19 @@
 	}
 
 	@Override
-	public boolean equals(Object y) {
+	public boolean equals(final Object y) {
 		if (y == null)
 			return false;
 		if (y.getClass() != this.getClass())
 			return false;
-		Rational b = (Rational) y;
+		final Rational b = (Rational) y;
 		return compareTo(b) == 0;
 	}
 
+	public boolean isZero() {
+		return (numerator == 0);
+	}
+
 //	// return a / b
 //	public Rational div(Rational b) {
 //		return this.mul(b.reciprocal());
@@ -81,48 +89,52 @@
 //	public Rational sub(Rational b) {
 //		return this.add(b.negate());
 //	}
-//
-//	// return -a
-//	public Rational negate() {
-//		return new Rational(-numerator, denominator);
-//	}
-//
-//	public Rational add(Rational b) {
-//		if (this.compareTo(zero) == 0) {
-//			return b;
-//		}
-//		if (b.compareTo(zero) == 0) {
-//			return this;
-//		}
-//
-//		// Find gcd of numerators and denominators
-//		int f = gcd(numerator, b.numerator);
-//		int g = gcd(denominator, b.denominator);
-//
-//		// add cross-product terms for numerator
-//		Rational s = new Rational((numerator / f) * (b.denominator / g)
-//				+ (b.numerator / f) * (denominator / g), lcm(denominator,
-//				b.denominator));
-//
-//		// multiply back in
-//		s.numerator *= f;
-//		return s;
-//	}
-//
+
+	// return -a
+	public Rational negate() {
+		return new Rational(-numerator, denominator);
+	}
+
+	public Rational add(final Rational b) {
+		if (this.isZero()) {
+			return b;
+		}
+		if (b.isZero()) {
+			return this;
+		}
+
+		// Find gcd of numerators and denominators
+		final int f = gcd(numerator, b.numerator);
+		final int g = gcd(denominator, b.denominator);
+
+		// add cross-product terms for numerator
+		final Rational s = new Rational((numerator / f) * (b.denominator / g)
+				+ (b.numerator / f) * (denominator / g), lcm(denominator,
+				b.denominator));
+
+		// multiply back in
+		s.numerator *= f;
+		return s;
+	}
+
 //	public Rational reciprocal() {
 //		return new Rational(denominator, numerator);
 //	}
 //
-	public Rational mul(Rational b) {
-		Rational c = new Rational(numerator, b.denominator);
-		Rational d = new Rational(b.numerator, denominator);
+	public Rational mul(final Rational b) {
+		final Rational c = new Rational(numerator, b.denominator);
+		final Rational d = new Rational(b.numerator, denominator);
 		return new Rational(c.numerator * d.numerator, c.denominator
 				* d.denominator);
 	}
 
 //	public double toDouble() {
-//		return (double) numerator / denominator;
-//	}
+//	return (double) numerator / denominator;
+//}
+
+	public int floor() {
+	return Math.floorDiv(numerator, denominator);
+}
 
 	@Override
 	public String toString() {
diff --git a/editor/xlia/org.eclipse.efm.formalml.ecore/src/org/eclipse/efm/formalml/ecore/factory/XLIA_DATATYPE.java b/editor/xlia/org.eclipse.efm.formalml.ecore/src/org/eclipse/efm/formalml/ecore/factory/XLIA_DATATYPE.java
index 0dc4f95..ef7856f 100644
--- a/editor/xlia/org.eclipse.efm.formalml.ecore/src/org/eclipse/efm/formalml/ecore/factory/XLIA_DATATYPE.java
+++ b/editor/xlia/org.eclipse.efm.formalml.ecore/src/org/eclipse/efm/formalml/ecore/factory/XLIA_DATATYPE.java
@@ -51,6 +51,14 @@
 		return FACTORY.createPrimitiveIntegerType();

 	}

 

+	public static PrimitiveIntegerType createInterger(final int size) {

+		final PrimitiveIntegerType intArray = FACTORY.createPrimitiveIntegerType();

+

+		intArray.setMultiplicity(XLIA_EXPRESSION.createInteger(size));

+

+		return intArray;

+	}

+

 	public static PrimitiveRationalType createRational() {

 		return FACTORY.createPrimitiveRationalType();

 	}

diff --git a/editor/xlia/org.eclipse.efm.formalml.ecore/src/org/eclipse/efm/formalml/ecore/factory/XLIA_EXPRESSION.java b/editor/xlia/org.eclipse.efm.formalml.ecore/src/org/eclipse/efm/formalml/ecore/factory/XLIA_EXPRESSION.java
index 3a2277f..b4db7ff 100644
--- a/editor/xlia/org.eclipse.efm.formalml.ecore/src/org/eclipse/efm/formalml/ecore/factory/XLIA_EXPRESSION.java
+++ b/editor/xlia/org.eclipse.efm.formalml.ecore/src/org/eclipse/efm/formalml/ecore/factory/XLIA_EXPRESSION.java
@@ -543,6 +543,18 @@
 

 	// COLLECTION

 	public static LiteralCollectionExpression createCollection(

+			final int[] values) {

+		final LiteralCollectionExpression expression =

+				FACTORY.createLiteralCollectionExpression();

+

+		for (final int value : values) {

+			expression.getValue().add( XLIA_EXPRESSION.createInteger(value) );

+		}

+

+		return expression;

+	}

+

+	public static LiteralCollectionExpression createCollection(

 			final String[] values) {

 		final LiteralCollectionExpression expression =

 				FACTORY.createLiteralCollectionExpression();

diff --git a/editor/xlia/org.eclipse.efm.formalml.ecore/src/org/eclipse/efm/formalml/ecore/factory/XLIA_STATEMENT.java b/editor/xlia/org.eclipse.efm.formalml.ecore/src/org/eclipse/efm/formalml/ecore/factory/XLIA_STATEMENT.java
index c347b8b..10b0616 100644
--- a/editor/xlia/org.eclipse.efm.formalml.ecore/src/org/eclipse/efm/formalml/ecore/factory/XLIA_STATEMENT.java
+++ b/editor/xlia/org.eclipse.efm.formalml.ecore/src/org/eclipse/efm/formalml/ecore/factory/XLIA_STATEMENT.java
@@ -50,6 +50,8 @@
 

 	public static final Routine CLEAR = XLIA_INFRA.createRoutine("clear");

 

+	public static final Routine EXIT = XLIA_INFRA.createRoutine("exit");

+

 	// StatementFactory FACTORY

 	static StatementFactory FACTORY = StatementFactory.eINSTANCE;

 

@@ -382,8 +384,13 @@
 

 	public static void addInvokeClear(

 			final BlockStatement block, final NamedElement collection) {

-		block.getStatement().add(

-				createInvoke(CLEAR, collection) );

+		block.getStatement().add( createInvoke(CLEAR, collection) );

+	}

+

+	public static void addInvokeExit(

+			final BlockStatement block, final String exitMessage) {

+		block.getStatement().add( createInvoke(EXIT,

+				XLIA_EXPRESSION.createExpression(exitMessage)) );

 	}

 

 

diff --git a/execution/org.eclipse.efm.execution.launchconfiguration/src/org/eclipse/efm/execution/launchconfiguration/ui/views/page/SWTSpider.java b/execution/org.eclipse.efm.execution.launchconfiguration/src/org/eclipse/efm/execution/launchconfiguration/ui/views/page/SWTSpider.java
index 75580eb..e0a4244 100644
--- a/execution/org.eclipse.efm.execution.launchconfiguration/src/org/eclipse/efm/execution/launchconfiguration/ui/views/page/SWTSpider.java
+++ b/execution/org.eclipse.efm.execution.launchconfiguration/src/org/eclipse/efm/execution/launchconfiguration/ui/views/page/SWTSpider.java
@@ -200,9 +200,10 @@
 			final FontData[] saveFontData = SAVE_FONT.getFontData();

 

 			final FontData[] fontData16 = new FontData[saveFontData.length];

-			for(int i = 0; i < saveFontData.length; ++ i)

+			for(int i = 0; i < saveFontData.length; ++i)

 				fontData16[i] = new FontData(

-						saveFontData[i].getName(), 18, saveFontData[i].getStyle());

+						saveFontData[i].getName(), 16,

+						saveFontData[i].getStyle());

 			TITLE_FONT = new Font(device, fontData16);

 		}