//--------------------------------------------------------------------------------//
// COPYRIGHT NOTICE //
//--------------------------------------------------------------------------------//
// Copyright (c) 2012, Instituto de Microelectronica de Sevilla (IMSE-CNM) //
// //
// All rights reserved. //
// //
// Redistribution and use in source and binary forms, with or without //
// modification, are permitted provided that the following conditions are met: //
// //
// * Redistributions of source code must retain the above copyright notice, //
// this list of conditions and the following disclaimer. //
// //
// * Redistributions in binary form must reproduce the above copyright //
// notice, this list of conditions and the following disclaimer in the //
// documentation and/or other materials provided with the distribution. //
// //
// * Neither the name of the IMSE-CNM nor the names of its contributors may //
// be used to endorse or promote products derived from this software //
// without specific prior written permission. //
// //
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" //
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE //
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE //
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE //
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL //
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR //
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER //
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, //
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE //
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. //
//--------------------------------------------------------------------------------//
package xfuzzy.pkg;
import java.io.*;
import java.util.*;
/**
* Clase gen�rica que describe una operaci�n difusa (funciones unarias,
* funciones binarias, funciones de pertenencia, familias de funciones de
* pertenencia, m�todos de concreci�n o funciones no difusas)
*
* @author Francisco Jos� Moreno Velo
*
*/
public abstract class Definition implements Cloneable {
//----------------------------------------------------------------------------//
// CONSTANTES P�BLICAS //
//----------------------------------------------------------------------------//
public static final int REQUIREMENTS = 0;
public static final int SOURCE = 1;
public static final int JAVA_EQUAL = 2;
public static final int JAVA_GREQ = 3;
public static final int JAVA_SMEQ = 4;
public static final int JAVA_CENTER = 5;
public static final int JAVA_BASIS = 6;
public static final int DERIV_EQUAL = 7;
public static final int DERIV_GREQ = 8;
public static final int DERIV_SMEQ = 9;
public static final int DERIV_CENTER = 10;
public static final int DERIV_BASIS = 11;
public static final int C_EQUAL = 12;
public static final int C_GREQ = 13;
public static final int C_SMEQ = 14;
public static final int C_CENTER = 15;
public static final int C_BASIS = 16;
public static final int CPP_EQUAL = 17;
public static final int CPP_GREQ = 18;
public static final int CPP_SMEQ = 19;
public static final int CPP_CENTER = 20;
public static final int CPP_BASIS = 21;
public static final int UPDATE = 22;
public static final int MEMBERS = 23;
public static final int INPUTS = 24;
//----------------------------------------------------------------------------//
// MIEMBROS PRIVADOS //
//----------------------------------------------------------------------------//
/**
* Constante que define el salto de l�nea en cada plataforma
*/
protected String eol = System.getProperty("line.separator", "\n");
/**
* Nombre del paquete al que pertenece la definici�n
*/
protected String pkg;
/**
* Nombre de la funci�n que describe la definici�n
*/
protected String name;
/**
* Lista de nombres alternativos para la funci�n
*/
protected Vector alias;
/**
* Lista de par�metros independientes de la funci�n
*/
protected Vector param;
/**
* Nombre de la lista de par�metros
*/
protected String paramlist;
/**
* Descripci�n de los requisitos de los par�metros
*/
protected String requires;
/**
* Descripci�n del proceso de actualizaci�n de la funci�n
*/
protected String update;
/**
* Otro c�digo a insertar directamente en la clase a generar
*/
protected String other;
/**
* Clase compilada a partir de toda la informaci�n
*/
private Class defclass;
/**
* Ventana de edici�n de la definici�n
*/
private Object editor;
//----------------------------------------------------------------------------//
// CONSTRUCTOR //
//----------------------------------------------------------------------------//
/**
* Constructor
* @param pkg Nombre del paquete al que pertenece
* @param name Nombre de la funci�n
*/
public Definition(String pkg, String name) {
this.pkg = pkg;
this.name = name;
this.alias = new Vector();
this.param = new Vector();
this.defclass = getDefClass();
this.editor = null;
}
//----------------------------------------------------------------------------//
// M�TODOS P�BLICOS CONSTANTES //
//----------------------------------------------------------------------------//
/**
* Crea la definici�n de una funci�n binaria
*/
public static Definition createBinaryDefinition(String pkg, String name) {
return new BinaryDefinition(pkg,name);
}
/**
* Crea la definici�n de una funci�n unaria
*/
public static Definition createUnaryDefinition(String pkg, String name) {
return new UnaryDefinition(pkg,name);
}
/**
* Crea la definici�n de una funci�n de pertenencia
*/
public static Definition createMFDefinition(String pkg, String name) {
return new MFDefinition(pkg,name);
}
/**
* Crea la definici�n de un m�todo de concreci�n
*/
public static Definition createDefuzDefinition(String pkg, String name) {
return new DefuzDefinition(pkg,name);
}
/**
* Crea la definici�n de una familia de MFs
*/
public static Definition createFamilyDefinition(String pkg, String name) {
return new FamilyDefinition(pkg,name);
}
/**
* Crea la definici�n de una funci�n no difusa
*/
public static Definition createCrispDefinition(String pkg, String name) {
return new CrispDefinition(pkg,name);
}
//----------------------------------------------------------------------------//
// M�TODOS P�BLICOS //
//----------------------------------------------------------------------------//
/**
* Obtiene el nombre de la funci�n definida
*/
public String toString() {
return this.name;
}
/**
* Compara un nombre con los distintos identificadores de la funci�n definida
*/
public boolean equals(String name) {
if(this.name.equals(name)) return true;
for(int i=0, size=alias.size(); i<size; i++)
if(alias.elementAt(i).equals(name)) return true;
return false;
}
/**
* Obtiene un duplicado del objeto
*/
public Object clone() {
try { return super.clone(); }
catch(CloneNotSupportedException e) { return null; }
}
/**
* Asigna la referencia a la ventana de edici�n
*/
public void setEditor(Object editor) {
this.editor = editor;
}
/**
* Verifica si la definici�n est� siendo editada
*/
public boolean isEditing() {
return this.editor != null;
}
/**
* Elimina los ficheros creados por la definicion
*/
public void unlink() {
String javafilename = classname()+".java";
File path = new File( System.getProperty("xfuzzy.path") );
File javafile = new File(path,javafilename);
String classfilename = classname()+".class";
File classfile = new File(path,classfilename);
javafile.delete();
classfile.delete();
}
/**
* Genera la descripci�n de la funci�n y la compila
*/
public boolean compile() {
String filename = classname()+".java";
File path = new File( System.getProperty("xfuzzy.path") );
File file = new File(path,filename);
byte buf[] = source().getBytes();
String command;
try {
file.getParentFile().mkdirs();
OutputStream f = new FileOutputStream(file);
f.write(buf);
f.close();
if(File.separatorChar == '\\')
command = "javac \""+file.getAbsolutePath()+"\"";
else command = "javac "+file.getAbsolutePath();
Runtime r = Runtime.getRuntime();
Process p = r.exec(command);
p.waitFor();
} catch (Exception e) {
System.err.println(e.toString());
return false;
}
this.defclass = getDefClass();
if(this.defclass == null) return false;
return true;
}
/**
* Obtiene una instancia de la clase de la definici�n
*/
public Object instantiate() {
Object newobject;
if(defclass == null) return null;
try { newobject = this.defclass.newInstance(); }
catch (IllegalAccessException e) { return null; }
catch (InstantiationException e) { return null; }
return newobject;
}
/**
* Obtiene el c�digo fuente de la clase de la definici�n
*/
public String source() {
String code = headline_code();
code += class_code();
code += constructor_code();
code += compute_code();
code += test_code();
code += update_code();
code += defined_code();
code += java_code();
code += c_code();
code += cpp_code();
code += other_code();
code += "}"+eol;
return code;
}
/**
* Asigna el nombre de la funci�n
*/
public void setName(String name) {
this.name = name;
}
/**
* Asigna los alias de la funci�n
*/
public void setAlias(Vector alias) {
this.alias = alias;
}
/**
* Asigna los par�metros de la funci�n
*/
public void setParameters(Vector param) {
this.param = param;
}
/**
* Asigna el identificador de la lista de par�metros
*/
public void setParamList(String paramlist) {
this.paramlist = paramlist;
}
/**
* Asigna las funciones admitidas para un m�todo de concreci�n
*/
public void setDefinedFor(Vector v) {
}
/**
* Asigna el nombre del paquete al que pertenece la definici�n
*/
public void setPackageName(String name) {
this.pkg = name;
}
/**
* Obtiene el nombre del paquete de la definici�n
*/
public String getPackageName() {
return this.pkg;
}
/**
* Obtiene el nombre de la funci�nn definida
*/
public String getName() {
return this.name;
}
/**
* Obtiene los nombres alternativos (alias) de la funci�n
*/
public Vector getAlias() {
return this.alias;
}
/**
* Obtiene los par�metros de la funci�n definida
*/
public Vector getParameters() {
return this.param;
}
/**
* Obtiene el nombre de la lista de par�metros (en su caso)
*/
public String getParamList() {
return this.paramlist;
}
/**
* Obtiene las funciones admitidas para un metodo de concreci�N
*/
public Vector getDefinedFor() {
return new Vector();
}
//----------------------------------------------------------------------------//
// M�TODOS P�BLICOS ABSTRACTOS //
//----------------------------------------------------------------------------//
/**
* Obtiene las descripci�n XFL3 de la definici�n
*/
public abstract String toPkg();
/**
* Obtiene el tipo de definici�n
*/
public abstract int getKind();
/**
* Obtiene el c�digo XFL3 de un bloque
*/
public abstract String getCode(int kind);
/**
* Asigna el c�digo XFL3 de un bloque
*/
public abstract void setCode(int kind, String code);
//----------------------------------------------------------------------------//
// M�TODOS PRIVADOS //
//----------------------------------------------------------------------------//
/**
* Obtiene un referencia a la clase compilada de la funci�n
*/
private Class getDefClass() {
Class getclass;
try { getclass = Class.forName("pkg."+pkg+"."+getKindString()+"."+name); }
catch (ClassNotFoundException e){ return null; }
return getclass;
}
/**
* Obtiene el tipo de definici�n en forma de String
* @return
*/
private String getKindString() {
String kind="";
switch(getKind()) {
case PackageDefinition.BINARY: kind = "binary"; break;
case PackageDefinition.UNARY: kind = "unary"; break;
case PackageDefinition.CRISP: kind = "crisp"; break;
case PackageDefinition.DEFUZ: kind = "defuz"; break;
case PackageDefinition.MFUNC: kind = "mfunc"; break;
case PackageDefinition.FAMILY: kind = "family"; break;
}
return kind;
}
/**
* Obtiene el nombre del fichero que describe la definici�n (sin extensi�n)
* @return
*/
private String classname() {
String sep = File.separator;
return "pkg"+sep+pkg+sep+getKindString()+sep+name;
}
/**
* Cambia algunos caracteres de una cadena
*/
protected String [] sample(String str) {
int lines=1;
if(str == null) return new String[0];
for(int i=0; i<str.length(); i++) if(str.charAt(i) == '\n') lines++;
String value[] = new String[lines];
int line=0;
value[0] = "";
for(int i=0; i<str.length(); i++)
switch(str.charAt(i)) {
case '\b': value[line] += "\\b"; continue;
case '\t': value[line] += "\\t"; continue;
case '\f': value[line] += "\\f"; continue;
case '\"': value[line] += "\\\""; continue;
case '\'': value[line] += "\\\'"; continue;
case '\\': value[line] += "\\\\"; continue;
case '\n': line++; value[line] = ""; continue;
case '\r': continue;
case '\0': continue;
default: value[line] += str.substring(i,i+1);
}
return value;
}
//----------------------------------------------------------------------------//
// M�todos que generan el c�digo XFL3 //
//----------------------------------------------------------------------------//
/**
* Obtiene la descripci�n XFL3 del bloque "alias"
*/
protected String aliasblock() {
int size = this.alias.size();
if(size==0) return "";
String code = " alias "+this.alias.elementAt(0);
for(int i=1; i<size; i++) code += ", "+this.alias.elementAt(i);
code += ";"+eol;
return code;
}
/**
* Obtiene la descripci�n XFL3 del bloque "parameter"
*/
protected String paramblock() {
int size = this.param.size();
boolean list = (paramlist != null && paramlist.length() >0);
if(size==0 && !list) return "";
String code = " parameter ";
for(int i=0; i<size; i++) {
if(i>0) code += ", ";
code += ""+this.param.elementAt(i);
}
if(list) {
if(size>0) code += ", ";
code += paramlist+"[]";
}
code += ";"+eol;
return code;
}
/**
* Obtiene la descripci�n XFL3 del bloque "requires"
*/
protected String requiresblock() {
if(this.requires == null || this.requires.length()==0) return "";
return " requires {"+eol+this.requires+eol+" }"+eol;
}
/**
* Obtiene la descripci�n XFL3 del bloque "update"
*/
protected String updateblock() {
if(this.update == null || this.update.length()==0) return "";
return " update {"+eol+this.update+eol+" }"+eol;
}
/**
* Obtiene la descripci�n XFL3 del bloque "source"
*/
protected String otherblock() {
if(this.other == null || this.other.length()==0) return "";
return " source {"+eol+this.other+eol+" }"+eol;
}
//----------------------------------------------------------------------------//
// M�todos que generan el c�digo de la clase //
//----------------------------------------------------------------------------//
/**
* Genera el c�digo de cabecera
*/
protected String headline_code() {
String headline;
headline = "//+++++++++++++++++++++++++++++++++++++++++++++++++++++"+eol;
headline += "// File automatically generated by Xfuzzy - DO NOT EDIT"+eol;
headline += "//+++++++++++++++++++++++++++++++++++++++++++++++++++++"+eol;
headline += eol+"package pkg."+pkg+"."+getKindString()+";"+eol+eol;
headline += "import xfuzzy.lang.*;"+eol+eol;
return headline;
}
/**
* Genera el c�digo del constructor
*/
protected String constructor_code() {
String code = " public "+name+"() {"+eol;
code += " super(\""+pkg+"\",\""+name+"\");"+eol;
code += " Parameter single[] = new Parameter["+param.size()+"];"+eol;
for(int i=0, size = param.size(); i<size; i++) {
code += " single["+i+"] = ";
code += "new Parameter(\""+param.elementAt(i)+"\");"+eol;
}
code += " setSingleParameters(single);"+eol;
if(paramlist != null && paramlist.length() >0) {
code += " setParamListName(\""+paramlist+"\");"+eol;
code += " setParamList(new Parameter[0]);"+eol;
}
code += " }"+eol;
return code;
}
/**
* Genera el c�digo del m�todo "test"
*/
protected String test_code() {
String code = eol+" public boolean test () {"+eol;
if( this.requires == null ) code += " return true;"+eol;
else {
code += variable_code(this.requires);
code += " return ("+this.requires+");"+eol;
}
code += " }"+eol;
return code;
}
/**
* Genera el c�digo de actualizaci�n de los par�metros
*/
protected String update_code() {
String code = "";
if(this.update != null) {
code += eol;
code += " public void update() {"+eol;
code += " if(!isAdjustable()) return;"+eol;
code += " double[] pos = get();"+eol;
code += " double[] desp = getDesp();"+eol;
code += " boolean[] adj = getAdjustable();"+eol;
code += variable_code(this.update);
code += this.update+eol;
code += " updateValues(pos);"+eol;
code += " }"+eol;
}
return code;
}
/**
* Genera el c�digo extra del bloque "source"
*/
protected String other_code() {
if(this.other == null) return "";
return this.other+eol;
}
/**
* Genera el c�digo del bloque "definedfor"
*/
protected String defined_code() { return ""; }
/**
* Genera el c�digo del m�todo "toC"
*/
protected String c_code() {
String ccode = eol+" public String getCCode()";
ccode += " throws XflException {"+eol;
ccode += " throw new XflException();"+eol;
ccode += " }"+eol;
return ccode;
}
/**
* Genera el c�digo del m�todo "toCpp"
*/
protected String cpp_code() {
String ccode = eol+" public String getCppCode()";
ccode += " throws XflException {"+eol;
ccode += " throw new XflException();"+eol;
ccode += " }"+eol;
return ccode;
}
/**
* Genera el c�digo para los par�metros dentro de un m�todo
*/
protected String variable_code(String source) {
String code = "";
for(int i=0; i<param.size(); i++)
code += " double "+param.elementAt(i)+" = singleparam["+i+"].value;"+eol;
if(paramlist != null && paramlist.length() > 0)
code += " double[] "+paramlist+" = getParamListValues();"+eol;
return code;
}
//----------------------------------------------------------------------------//
// M�TODOS PRIVADOS ABSTRACTOS //
//----------------------------------------------------------------------------//
/**
* Genera el c�digo de la clase
*/
protected abstract String class_code();
/**
* Genera el c�digo del m�todo "compute"
*/
protected abstract String compute_code();
/**
* Genera el c�digo del m�todo "toJava"
*/
protected abstract String java_code();
}