//--------------------------------------------------------------------------------// // 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.xfcpp; import xfuzzy.lang.*; import java.io.*; import java.util.Vector; /** * Generador del fichero "fuzzysystem.hpp" * * @author Francisco Jos� Moreno Velo * */ public class XfcppSpecHppCode { //----------------------------------------------------------------------------// // MIEMBROS PRIVADOS // //----------------------------------------------------------------------------// /** * Sistema difuso a tratar */ private Specification spec; /** * Directorio en el que se va a crear el archivo ".hpp" */ private File dir; //----------------------------------------------------------------------------// // CONSTRUCTOR // //----------------------------------------------------------------------------// /** * Constructor */ public XfcppSpecHppCode(Specification spec, File dir) { this.spec = spec; this.dir = dir; } //----------------------------------------------------------------------------// // M�TODOS P�BLICOS EST�TICOS // //----------------------------------------------------------------------------// /** * Genera el archivo ".hpp" correspondiente a la especificaci�n en el * directorio indicado */ public static final String create(Specification spec, File dir) throws XflException { XfcppSpecHppCode creator = new XfcppSpecHppCode(spec, dir); creator.createFile(); return creator.getMessage(); } //----------------------------------------------------------------------------// // M�TODOS P�BLICOS // //----------------------------------------------------------------------------// /** * Devuelve la descripci�n del resultado de la compilaci�n */ public String getMessage() { File file = new File(dir,spec.getName()+".hpp"); return file.getAbsolutePath(); } /** * Genera el fichero ".hpp" */ public void createFile() throws XflException { File file = new File(dir,spec.getName()+".hpp"); try { OutputStream os = new FileOutputStream(file); PrintStream stream = new PrintStream(os); printHeading(stream); printSource(stream); stream.close(); } catch (IOException e) {} } //----------------------------------------------------------------------------// // M�TODOS P�BLICOS // //----------------------------------------------------------------------------// /** * Genera el c�digo de cabecera del fichero */ private void printHeading(PrintStream stream) { stream.println("//++++++++++++++++++++++++++++++++++++++++++++++++++++++//"); stream.println("// //"); stream.println(complete("// File: "+spec.getName()+".hpp")); stream.println("// //"); stream.println("// Author: Automatically generated by Xfuzzy //"); stream.println("// //"); stream.println("//++++++++++++++++++++++++++++++++++++++++++++++++++++++//"); stream.println(); } /** * Genera las estructuras de las clases del sistema */ private void printSource(PrintStream stream) throws XflException { Operatorset[] opset = spec.getOperatorsets(); Type[] type = spec.getTypes(); String name = spec.getName(); stream.println("#ifndef _"+name+"_INFERENCE_ENGINE_HPP"); stream.println("#define _"+name+"_INFERENCE_ENGINE_HPP"); stream.println(); stream.println("#include \"xfuzzy.hpp\""); stream.println(); Vector famv = searchFamilyClasses(); for(int i=0; i<famv.size(); i++) { printFamilyHppCode(stream,(Family) famv.elementAt(i)); } Vector mfv = searchMFClasses(); for(int i=0; i<mfv.size(); i++) { printMFHppCode(stream,(ParamMemFunc) mfv.elementAt(i)); } for(int i=0; i<opset.length; i++) printOperatorSetHppCode(stream,opset[i]); for(int i=0; i<type.length; i++) printTypeHppCode(stream,type[i]); printInferenceEngineHppCode(stream); stream.println("#endif /* _"+name+"_INFERENCE_ENGINE_HPP */"); } //----------------------------------------------------------------------------// // M�todos que generan el fichero de cabecera // //----------------------------------------------------------------------------// /** * Contenido de cabecera de las familias de funciones */ private void printFamilyHppCode(PrintStream stream, Family fam) throws XflException { String spname = spec.getName(); String pkgname = fam.getPackageName(); String classname = "FMF_"+spname+"_"+pkgname+"_"+fam.getFunctionName(); stream.println("//++++++++++++++++++++++++++++++++++++++++++++++++++++++//"); stream.println(complete("// MembershipFunction "+classname)); stream.println("//++++++++++++++++++++++++++++++++++++++++++++++++++++++//"); stream.println(); stream.println("class "+classname+": public ParamMembershipFunction {"); stream.println("private:"); stream.println(" int i;"); Parameter[] single = fam.getSingleParameters(); for(int i=0; i<single.length; i++) { stream.println(" double "+single[i].getName()+";"); } String listname = fam.getParamListName(); if(listname != null && listname.length() > 0) { stream.println(" double *"+listname+";"); stream.println(" int length;"); } stream.println(); stream.println("public:"); stream.println(" "+classname+"() {};"); if(listname != null && listname.length() > 0) { stream.println(" virtual ~"+classname+"() { delete "+listname+"; };"); } else { stream.println(" virtual ~"+classname+"() {};"); } stream.print(" "+classname+"(int index,double min,double max,double step"); stream.println(",double *single,double *list,int length);"); stream.println(" "+classname+"*dup();"); stream.println(" virtual double param(int _i);"); stream.println(" virtual double compute_eq(double x);"); String greq = fam.getGreqCppCode(); if(greq != null && greq.length()>0) stream.println(" virtual double compute_greq(double x);"); String smeq = fam.getSmeqCppCode(); if(smeq != null && smeq.length()>0) stream.println(" virtual double compute_smeq(double x);"); String center = fam.getCenterCppCode(); if(center != null && center.length()>0) stream.println(" virtual double center();"); String basis = fam.getBasisCppCode(); if(basis != null && basis.length()>0) stream.println(" virtual double basis();"); stream.println("};"); stream.println(); } /** * Contenido de cabecera de las funciones de pertenencia */ private void printMFHppCode(PrintStream stream, ParamMemFunc mf) throws XflException { String spname = spec.getName(); String pkgname = mf.getPackageName(); String classname = "MF_"+spname+"_"+pkgname+"_"+mf.getFunctionName(); stream.println("//++++++++++++++++++++++++++++++++++++++++++++++++++++++//"); stream.println(complete("// MembershipFunction "+classname)); stream.println("//++++++++++++++++++++++++++++++++++++++++++++++++++++++//"); stream.println(); stream.println("class "+classname+": public ParamMembershipFunction {"); stream.println("private:"); Parameter[] single = mf.getSingleParameters(); for(int i=0; i<single.length; i++) { stream.println(" double "+single[i].getName()+";"); } String listname = mf.getParamListName(); if(listname != null && listname.length() > 0) { stream.println(" double *"+listname+";"); stream.println(" int length;"); } stream.println(); stream.println("public:"); stream.println(" "+classname+"() {};"); if(listname != null && listname.length() > 0) { stream.println(" virtual ~"+classname+"() { delete "+listname+"; };"); } else { stream.println(" virtual ~"+classname+"() {};"); } stream.print(" "+classname+"(double min,double max,double step"); stream.println(",double *single,double *list,int length);"); stream.println(" "+classname+"*dup();"); stream.println(" virtual double param(int _i);"); stream.println(" virtual double compute_eq(double x);"); String greq = mf.getGreqCppCode(); if(greq != null && greq.length()>0) stream.println(" virtual double compute_greq(double x);"); String smeq = mf.getSmeqCppCode(); if(smeq != null && smeq.length()>0) stream.println(" virtual double compute_smeq(double x);"); String center = mf.getCenterCppCode(); if(center != null && center.length()>0) stream.println(" virtual double center();"); String basis = mf.getBasisCppCode(); if(basis != null && basis.length()>0) stream.println(" virtual double basis();"); stream.println("};"); stream.println(); } /** * Contenido de cabecera de los conjuntos de operadores */ private void printOperatorSetHppCode(PrintStream stream, Operatorset opset) throws XflException{ String opname = "OP_"+spec.getName()+"_"+opset.getName(); stream.println("//++++++++++++++++++++++++++++++++++++++++++++++++++++++//"); stream.println(complete("// Operator set "+opname)); stream.println("//++++++++++++++++++++++++++++++++++++++++++++++++++++++//"); stream.println(); stream.println("class "+opname+": public Operatorset {"); stream.println("public:"); stream.println(" virtual ~"+opname+"() {};"); stream.println(" virtual double _and(double a, double b);"); stream.println(" virtual double _or(double a, double b);"); stream.println(" virtual double _also(double a, double b);"); stream.println(" virtual double _imp(double a, double b);"); stream.println(" virtual double _not(double a);"); stream.println(" virtual double _very(double a);"); stream.println(" virtual double _moreorless(double a);"); stream.println(" virtual double _slightly(double a);"); stream.println(" virtual double _defuz(OutputMembershipFunction &mf);"); stream.println("};"); stream.println(); } /** * Contenido de cabecera de los tipos de variable */ private void printTypeHppCode(PrintStream stream, Type type) throws XflException { String specname = spec.getName(); String typename = "TP_"+specname+"_"+type.getName(); stream.println("//++++++++++++++++++++++++++++++++++++++++++++++++++++++//"); stream.println(complete("// Type "+typename)); stream.println("//++++++++++++++++++++++++++++++++++++++++++++++++++++++//"); stream.println(); stream.println("class "+typename+" {"); stream.println("private:"); stream.println(" double min;"); stream.println(" double max;"); stream.println(" double step;"); stream.println("public:"); LinguisticLabel[] allmf = type.getAllMembershipFunctions(); for(int i=0; i<allmf.length; i++) { if(allmf[i] instanceof ParamMemFunc) { ParamMemFunc pmf = (ParamMemFunc) allmf[i]; String pkgname = pmf.getPackageName(); String mfname = "MF_"+specname+"_"+pkgname+"_"+pmf.getFunctionName(); stream.println(" "+mfname+" "+pmf.getLabel()+";"); } else { FamiliarMemFunc fmf = (FamiliarMemFunc) allmf[i]; Family fammf = fmf.getFamily(); String pkgname = fammf.getPackageName(); String mfname = "FMF_"+specname+"_"+pkgname+"_"+fammf.getFunctionName(); stream.println(" "+mfname+" "+fmf.getLabel()+";"); } } stream.println(" "+typename+"();"); stream.println("};"); stream.println(); } /** * Genera la estructura de la clase "sistema" */ private void printInferenceEngineHppCode(PrintStream stream) throws XflException { Rulebase[] base = spec.getRulebases(); CrispBlock[] crisp = spec.getCrispBlockSet().getBlocks(); Variable input[] = spec.getSystemModule().getInputs(); Variable output[] = spec.getSystemModule().getOutputs(); String name = spec.getName(); stream.println("//++++++++++++++++++++++++++++++++++++++++++++++++++++++//"); stream.println(complete("// Fuzzy Inference Engine "+name)); stream.println("//++++++++++++++++++++++++++++++++++++++++++++++++++++++//"); stream.println(); stream.println("class "+name+": public FuzzyInferenceEngine {"); stream.println("public:"); stream.println(" "+name+"() {};"); stream.println(" virtual ~"+name+"() {};"); stream.println(" virtual double* crispInference(double* input);"); stream.println(" virtual double* crispInference(MembershipFunction* &input);"); stream.println(" virtual MembershipFunction** fuzzyInference(double* input);"); stream.print(" virtual MembershipFunction** fuzzyInference"); stream.println("(MembershipFunction* &input);"); stream.print(" void inference("); for(int i=0; i<input.length; i++) stream.print((i!=0?",":"")+" double _i_"+input[i]); for(int i=0; i<output.length; i++) stream.print(", double *_o_"+output[i]); stream.println(" );"); stream.println("private:"); for(int i=0; i<base.length; i++) printRulebaseHppCode(stream,base[i]); for(int i=0; i<crisp.length; i++) printCrispBlockHppCode(stream,crisp[i]); stream.println("};"); stream.println(); } /** * Contenido de cabecera de las bases de reglas */ private void printRulebaseHppCode(PrintStream stream, Rulebase base) throws XflException { String rbname = "RL_"+base.getName(); Variable[] inputvar = base.getInputs(); Variable[] outputvar = base.getOutputs(); stream.print(" void "+rbname+"("); for(int i=0; i<inputvar.length; i++) stream.print((i==0? "": ", ")+"MembershipFunction &"+inputvar[i]); for(int i=0; i<outputvar.length; i++) stream.print(", MembershipFunction ** _o_"+outputvar[i]); stream.println(");"); } /** * Contenido de cabecera de los bloques no difusos */ private void printCrispBlockHppCode(PrintStream stream, CrispBlock crisp) throws XflException { stream.print(" double CB_"+crisp.getName()+"("); for(int i=0; i<crisp.inputs(); i++) stream.print((i==0? "": ", ")+"MembershipFunction &i"+i); stream.println(");"); } //----------------------------------------------------------------------------// // M�todos auxiliares // //----------------------------------------------------------------------------// /** * Busca las familias de funciones de pertenencia incluidas */ private Vector searchFamilyClasses() { Vector nmv = new Vector(); Vector famv = new Vector(); Type[] type = spec.getTypes(); String spname = spec.getName(); for(int i=0; i<type.length; i++) { Family[] fam = type[i].getFamilies(); for(int j=0; j<fam.length; j++) { String pkgname = fam[j].getPackageName(); String classname = "FMF_"+spname+"_"+pkgname+"_"+fam[j].getFunctionName(); boolean included = false; for(int k=0; k<nmv.size(); k++) if(classname.equals( (String) nmv.elementAt(k) )) included = true; if(!included) { nmv.addElement(classname); famv.addElement(fam[j]); } } } return famv; } /** * Busca las funciones de pertenencia incluidas */ private Vector searchMFClasses() { Vector nmv = new Vector(); Vector mfv = new Vector(); Type[] type = spec.getTypes(); String spname = spec.getName(); for(int i=0; i<type.length; i++) { ParamMemFunc[] mf = type[i].getParamMembershipFunctions(); for(int j=0; j<mf.length; j++) { String pkgname = mf[j].getPackageName(); String classname = "MF_"+spname+"_"+pkgname+"_"+mf[j].getFunctionName(); boolean included = false; for(int k=0; k<nmv.size(); k++) if(classname.equals( (String) nmv.elementAt(k) )) included = true; if(!included) { nmv.addElement(classname); mfv.addElement(mf[j]); } } } return mfv; } /** * Completa la cadena hasta 58 caracteres */ private String complete(String begining) { String line = begining; for(int i=begining.length(); i<56; i++) line += " "; line += "//"; return line; } }