package jcircus.util;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;
import java.util.Vector;
import org.jcsp.lang.Alternative;
import org.jcsp.lang.AltingBarrier;
import org.jcsp.lang.Any2OneChannel;
import org.jcsp.lang.CSProcess;
import org.jcsp.lang.Guard;
import org.jcsp.lang.Parallel;
import net.sourceforge.czt.circus.ast.*;
import net.sourceforge.czt.z.ast.ApplExpr;
import net.sourceforge.czt.z.ast.BindExpr;
import net.sourceforge.czt.z.ast.Expr;
import net.sourceforge.czt.z.ast.NumExpr;
import net.sourceforge.czt.z.ast.RefExpr;
//Classe implementada por Samuel, para auxiliar na tradução de comunicações complexas, do tipo c?x?y?z!5
import newjcircusutil.multisync.GeneralChannel;
public class GuardsGenerator {
Communication communication;
CircusFieldList fieldList;
String paper;
String src;
String name;
private String packageDecl;
private String classDecl;
private int sizeChannel;
private int dimChannel;
public static String brackets (int n) {
String s = "";
for (int i = 1; i <= n; i++) {
s = s + "[]";
}
return s;
}
public static String bracketized (String x) {
return "[" + x + "]";
}
public static String bracketizeds (int n, String x) {
String s = "";
for (int i = 0; i < n; i++) {
s = s + bracketized (x);
}
return s;
}
//____________________________________________________________________________________________________
public GuardsGenerator (Communication c, String name, String paper, String src, int sizeChannel) {
this.communication = c;
this.paper = paper;
this.src = src;
this.name = name;
this.sizeChannel = sizeChannel;
this.dimChannel = c.getCircusFieldList().size();
this.fieldList = c.getCircusFieldList();
this.packageDecl = "package " + name + "." + paper + "." + src + "." + paper + ";\n";
}
public GuardsGenerator (Communication c) {
this (c, "Exemplo", "paper", "src", 10);
System.out.println ("*********\n" + getClassCode() + "\n*****************\n");
}
public GuardsGenerator (String speName, Communication c) {
this (c, speName, "paper", "src", 10);
}
public GuardsGenerator () {
}
//____________________________________________________________________________________________________
public boolean hasOutputFieldAnn (Field field) {
if (!(field instanceof DotField)) {
return false;
}
for (int i = 0; i < field.getAnns().size(); i++) {
if (field.getAnns().get(0) instanceof OutputFieldAnn) {
return true;
}
}
return false;
}
public String getClassName (CircusFieldList cfl) {
String st = "C" + communication.getChannelExpr().getName().toString();
Field field;
for (int i = 0; i < cfl.size(); i++) {
field = cfl.get(i);
if (field instanceof InputField) {
st = st + "In" + ((InputField)field).getVariableZName().toString();
}
else if (field instanceof DotField && hasOutputFieldAnn (field)) {
st = st + "Out" + ((DotField)field).getExpr().toString();
}
else {
st = st + "Dot" + ((DotField)field).getExpr().toString();
}
}
return st;
}
public String getClassCode () {
String st =
packageDecl +
"import org.jcsp.lang.Guard;\n" +
"import newjcircusutil.multisync.GeneralChannel;\n" +
"public class " + getClassName (this.fieldList) + " {\n" +
" public static Guard [] getGuards (GeneralChannel " + brackets (this.dimChannel) + " b) {\n" +
" return new Guard [] {\n" + guards() + " };\n }\n}\n";
return st;
}
//*****************************************************
public int potInt (int b, int e) {
int aux = 1;
for (int i = 1; i <= e; i++) {
aux = aux * b;
}
return aux;
}
public int indexOfGuardPart (int line, int pos) {
return (line / (potInt (this.sizeChannel, this.dimChannel - 1 - pos))) % this.sizeChannel;
}
public int numberOfGuards () {
int total = 1;
for (int i = 1; i <= this.dimChannel; i++) {
total = total * this.sizeChannel;
}
return total;
}
//*****************************************************
public String guard (int line/*, boolean b*/) {
String st = "";
for (int i = 0; i < this.dimChannel; i++) {
st = st + bracketized ((new Integer (indexOfGuardPart (line, i))).toString());
}
return st;
}
public String guards () {
String st = "";
for (int i = 0; i < this.numberOfGuards() - 1; i++) {
st = st + " b " + guard (i/*, true*/) + ".getBarrier() [b " + guard (i) + ".getChannelInfo().get(b " + guard (i) + ".getProcId())],\n";
}
st = st + " b " + guard (this.numberOfGuards() - 1/*, true*/) + ".getBarrier() [b " + guard (this.numberOfGuards() - 1) + ".getChannelInfo().get(b " + guard (this.numberOfGuards() - 1) + ".getProcId())],\n";
return st;
}
public void generateClass (String path) {
try {
BufferedWriter bw = new BufferedWriter (new FileWriter (path + "\\" + this.getClassName (this.fieldList) + ".java"));
bw.write(this.getClassCode());
bw.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void generateClass () {
generateClass ("C:\\Users\\sam\\Mestrado\\JCircus3\\JCircus\\Exemplo\\paper\\src\\paper\\");
}
//______________________________________________________________________________________________________________
//getGuards (Vector /*<Vector <Vector <GeneralChannel>>>*/ /*GeneralChannel [][][]*/ genChan, int nDim, int size)
/*public class P2 implements CSProcess {
Vector <Vector <AltingBarrier []>> barr;
public P2 (Vector <Vector <AltingBarrier []>> barr) {
this.barr = barr;
}
public void run () {
int x = (new Alternative (
new Guard [] {
this.barr.elementAt(0).elementAt (0)[0],
this.barr.elementAt(0).elementAt (1)[0],
this.barr.elementAt(0).elementAt (2)[0],
this.barr.elementAt(0).elementAt (3)[0],
this.barr.elementAt(0).elementAt (4)[0],
this.barr.elementAt(1).elementAt (0)[0],
this.barr.elementAt(1).elementAt (1)[0],
this.barr.elementAt(1).elementAt (2)[0],
this.barr.elementAt(1).elementAt (3)[0],
this.barr.elementAt(1).elementAt (4)[0],
this.barr.elementAt(2).elementAt (0)[0],
this.barr.elementAt(2).elementAt (1)[0],
this.barr.elementAt(2).elementAt (2)[0],
this.barr.elementAt(2).elementAt (3)[0],
this.barr.elementAt(2).elementAt (4)[0],
this.barr.elementAt(3).elementAt (0)[0],
this.barr.elementAt(3).elementAt (1)[0],
this.barr.elementAt(3).elementAt (2)[0],
this.barr.elementAt(3).elementAt (3)[0],
this.barr.elementAt(3).elementAt (4)[0],
this.barr.elementAt(4).elementAt (0)[0],
this.barr.elementAt(4).elementAt (1)[0],
this.barr.elementAt(4).elementAt (2)[0],
this.barr.elementAt(4).elementAt (3)[0],
this.barr.elementAt(4).elementAt (4)[0]
})).select();
System.out.println ("Guarda escolhido: " + x);
}
}*/
public static Vector createBarrierVector (int dim, int nproc, int size) {
Vector v = new Vector (size);
if (dim == 1) {
for (int i = 0; i < size; i++) {
v.addElement(AltingBarrier.create(nproc));
}
return v;
}
else {
for (int i = 0; i < size; i++) {
v.addElement(createBarrierVector (dim - 1, nproc, size));
}
}
return v;
}
public static int dimVector (Vector v) {
Vector t = v;
int counter = 0;
while (t instanceof Vector) {
System.out.println (t.getClass());
if (t.elementAt(0) instanceof Vector)
t = (Vector) t.elementAt(0);
else break;
counter++;
}
return counter + 1;
}
//______________________________________________________________________________________________________________
//______________________________________________________________________________________________________________
public GeneralChannel getIndividualGuard (int index, Vector v, int cflsize) {
Vector t = v;
int counter = 0;
while (t.elementAt(indexOfGuardPart (index, counter)) instanceof Vector) {
t = (Vector) t.elementAt(indexOfGuardPart (index, counter));
counter++;
}
return (GeneralChannel) t.elementAt(indexOfGuardPart (index, counter));
}
//Método alternativo para retornar os guardas de qualquer array de qualquer dimensão de GeneralChannels
//Testes com vectors de vectors de Any2OneChannel
public class P1 implements CSProcess {
Vector <Vector <Vector <AltingBarrier []>>> barr;
public P1 (Vector <Vector <Vector <AltingBarrier []>>> barr) {
//O construtor não deve receber Vector <Vector <Vector <AltingBarrier []>>>. Deverei modificar isto para receber apenas o "end" da barreira (de acordo com o id do processo),
// ao invés da barreira inteira
this.barr = barr;
}
public void run () {
this.barr.elementAt(3).elementAt(2).elementAt(1) [1].sync();
}
}
public class P15 implements CSProcess {
Vector <Vector <Vector <AltingBarrier []>>> barr;
public P15 (Vector <Vector <Vector <AltingBarrier []>>> barr) {
this.barr = barr;
}
public void run () {
int x = (new Alternative (getGuardsTest (this.barr, 3, 5)).select());
}
}
public static void main (String args []) {
GuardsGenerator gg = new GuardsGenerator ();
Vector <Vector <Vector <AltingBarrier []>>> ab = createBarrierVector (3, 2, 5);
(new Parallel (new CSProcess [] {gg.new P1(ab), gg.new P15(ab)})).run();
}
//ABAIXO TODOS DE TESTE, DEVERÃO SER DELETADOS QUANDO O TESTE DER CERTO
public AltingBarrier [] getIndividualGuardTest (int index, Vector v, int cflsize, int dim) {
Vector t = v;
int counter = 0;
while (t.elementAt(indexOfGuardPartTest (index, counter, cflsize, dim)) instanceof Vector) {
t = (Vector) t.elementAt(indexOfGuardPartTest (index, counter, cflsize, dim));
counter ++;
}
return (AltingBarrier []) t.elementAt (indexOfGuardPartTest (index, counter, cflsize, dim));
}
public int indexOfGuardPartTest (int line, int pos, int size, int dim) {
return (line / (potInt (size, dim - 1 - pos))) % size;
}
public Guard [] getGuardsTest (Vector genChan, int nDim, int size) {
int roof = potInt (size, nDim);
Guard [] guards = new Guard [roof];
int indexGuards = 0;
for (int i = 0; i < roof; i++) {
guards [indexGuards] = ((AltingBarrier []) getIndividualGuardTest (i, genChan, size, nDim)) [0];
indexGuards++;
}
Guard [] guards2 = new Guard [indexGuards];
for (int i = 0; i < indexGuards; i++) {
guards2[i] = guards[i];
}
return guards2;
}
//ACIMA TODOS DE TESTE, DEVERÃO SER DELETADOS DEPOIS QUE TUDO DER CERTO
public Guard [] getGuards (Vector genChan, int nDim, int size) {
int roof = potInt (size, nDim);
CircusFieldList cfl = this.fieldList;
int cflsize = cfl.size();
Guard [] guards = new Guard [roof];
int counter;
int indexGuards = 0;
int [] igp = new int [cflsize];
for (int i = 0; i < roof; i++) {
counter = 0;
for (int j = 0; j < cflsize; j++) {
Field field = cfl.get(j);
if (field instanceof DotField) {
Expr expr = ((DotField)field).getExpr();
if (expr instanceof RefExpr) {
//TODO verificar como pegar o valor numérico (inteiro) de RefExpr
}
else {
if (expr.toString().equals((new Integer (indexOfGuardPart (i, j))))) {
counter ++; //verifica, um por um, os valores comunicados. Se forem todos iguais
}
}
/*else if (expr instanceof NumExpr) {
}*/
}
else { /*(if field instanceof InputField)*/
counter ++; //Se não for instância de DotField, é InputField com certeza, e por isso deverá entrar no array de guardas
}
}
if (counter == cflsize) {
//guards [indexGuards] = ((GeneralChannel) getIndividualGuard (i, genChan, cflsize)).getBarrier() [((GeneralChannel)getIndividualGuard (i, genChan, cflsize)).getChannelInfo().get(((GeneralChannel)getIndividualGuard (i, genChan, cflsize)).getProcId())];
}
indexGuards++;
}
Guard [] guards2 = new Guard [indexGuards];
for (int i = 0; i < indexGuards; i++) {
guards2[i] = guards[i];
}
return guards2;
}
//______________________________________________________________________________________________________________
}