//--------------------------------------------------------------------------------//
// 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.cpp"
*
* @author Francisco Jos� Moreno Velo
*
*/
public class XfcppSpecCppCode {
//----------------------------------------------------------------------------//
// 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 XfcppSpecCppCode(Specification spec, File dir) {
this.spec = spec;
this.dir = dir;
}
//----------------------------------------------------------------------------//
// M�TODOS P�BLICOS EST�TICOS //
//----------------------------------------------------------------------------//
/**
* Genera el archivo ".cpp" correspondiente a la especificaci�n en el
* directorio indicado
*/
public static final String create(Specification spec, File dir)
throws XflException {
XfcppSpecCppCode creator = new XfcppSpecCppCode(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()+".cpp");
return file.getAbsolutePath();
}
/**
* Genera el fichero ".cpp"
*/
public void createFile() throws XflException {
File file = new File(dir,spec.getName()+".cpp");
try {
OutputStream os = new FileOutputStream(file);
PrintStream stream = new PrintStream(os);
printHeading(stream);
printSource(stream);
stream.close();
}
catch (IOException e) {}
}
//----------------------------------------------------------------------------//
// M�TODOS PRIVADOS //
//----------------------------------------------------------------------------//
/**
* Genera el c�digo de cabecera del fichero
*/
private void printHeading(PrintStream stream) {
stream.println("//++++++++++++++++++++++++++++++++++++++++++++++++++++++//");
stream.println("// //");
stream.println(complete("// File: "+spec.getName()+".cpp"));
stream.println("// //");
stream.println("// Author: Automatically generated by Xfuzzy //");
stream.println("// //");
stream.println("//++++++++++++++++++++++++++++++++++++++++++++++++++++++//");
stream.println();
}
/**
* Genera el c�digo de las clases del sistema
*/
private void printSource(PrintStream stream) throws XflException {
String name = spec.getName();
Operatorset[] opset = spec.getOperatorsets();
Type[] type = spec.getTypes();
Rulebase[] base = spec.getRulebases();
CrispBlock[] crisp = spec.getCrispBlockSet().getBlocks();
stream.println("#ifndef _"+name+"_INFERENCE_ENGINE_");
stream.println("#define _"+name+"_INFERENCE_ENGINE_");
stream.println();
stream.println("#include <stdio.h>");
stream.println("#include <math.h>");
stream.println("#include \"xfuzzy.hpp\"");
stream.println("#include \""+name+".hpp\"");
stream.println();
Vector famv = searchFamilyClasses();
for(int i=0; i<famv.size(); i++) {
printFamilyCppCode(stream,(Family) famv.elementAt(i));
}
Vector mfv = searchMFClasses();
for(int i=0; i<mfv.size(); i++) {
printMFCppCode(stream,(ParamMemFunc) mfv.elementAt(i));
}
for(int i=0; i<opset.length; i++) printOperatorSetCode(stream,opset[i]);
for(int i=0; i<type.length; i++) printTypeCode(stream,type[i]);
printSystemCode(stream);
for(int i=0; i<base.length; i++) printRulebaseCode(stream,base[i]);
for(int i=0; i<crisp.length; i++) printCrispBlockCode(stream,crisp[i]);
stream.println("#endif /* _"+name+"_INFERENCE_ENGINE_ */");
}
//----------------------------------------------------------------------------//
// M�todos que generan el codigo de las MF //
//----------------------------------------------------------------------------//
/**
* Decripci�n de una funci�n de pertenencia familiar
*/
private void printFamilyCppCode(PrintStream stream,Family fam) throws XflException {
String spname = spec.getName();
String pkgname = fam.getPackageName();
String classname = "FMF_"+spname+"_"+pkgname+"_"+fam.getFunctionName();
String equal = fam.getEqualCppCode();
String listname = fam.getParamListName();
Parameter[] single = fam.getSingleParameters();
boolean haslist = (listname != null && listname.length() > 0);
if(equal==null || equal.length()==0) throw new XflException();
stream.println("//++++++++++++++++++++++++++++++++++++++++++++++++++++++//");
stream.println(complete("// MembershipFunction "+classname));
stream.println("//++++++++++++++++++++++++++++++++++++++++++++++++++++++//");
stream.println();
stream.println("//------------------------------------------------------//");
stream.println("// Constructor //");
stream.println("//------------------------------------------------------//");
stream.println();
stream.print(classname+"::"+classname+"(int i,double min,double max,double step");
stream.println(",double *single,double *list,int length) :");
stream.println("ParamMembershipFunction(min,max,step) {");
stream.println(" this->name = \""+classname+"\";");
stream.println(" this->i = i;");
for(int i=0; i<single.length; i++) {
stream.println(" this->"+single[i].getName()+" = single["+i+"];");
}
if(listname != null && listname.length() > 0) {
stream.println(" this->length = length;");
stream.println(" this->"+listname+" = new double[length];");
stream.println(" for(int i=0; i<length; i++) this->"+listname+"[i] = list[i];");
}
stream.println("}");
stream.println();
stream.println("//------------------------------------------------------//");
stream.println("// Function to get a clone of the object //");
stream.println("//------------------------------------------------------//");
stream.println();
stream.println(classname+" * "+classname+"::dup() {");
stream.print(" double _param["+single.length+"] = {");
for(int i=0; i<single.length; i++) {
stream.print((i==0? "":",")+single[i].getName());
}
stream.println("};");
if(haslist) {
stream.println(" double *_list = this->"+listname+";");
stream.println(" int _length = this->length;");
} else {
stream.println(" double *_list = NULL;");
stream.println(" int _length = 0;");
}
stream.println(" return new "+classname+"(i,min,max,step,_param,_list,_length);");
stream.println("}");
stream.println();
stream.println("//------------------------------------------------------//");
stream.println("// Function to get a parameter of the function //");
stream.println("//------------------------------------------------------//");
stream.println();
stream.println("double "+classname+"::param(int _i) {");
if(single.length == 0 && haslist) {
stream.println(" return "+listname+"[_i];");
} else if(!haslist) {
stream.println(" switch(_i) {");
for(int i=0; i<single.length; i++) {
stream.println(" case "+i+": return "+single[i].getName()+";");
}
stream.println(" default: return 0;");
stream.println(" }");
} else {
stream.print(" if(_i>="+single.length+")");
stream.println(" return "+listname+"[_i-"+single.length+"];");
stream.println(" switch(_i) {");
for(int i=0; i<single.length; i++) {
stream.println(" case "+i+": return "+single[i].getName()+";");
}
stream.println(" default: return 0;");
stream.println(" }");
}
stream.println("}");
stream.println();
stream.println("//------------------------------------------------------//");
stream.println("// Function to compute the membership degree //");
stream.println("//------------------------------------------------------//");
stream.println();
stream.println("double "+classname+"::compute_eq(double x) {");
stream.println(equal);
stream.println("}");
stream.println();
String greq = fam.getGreqCppCode();
if(greq != null && greq.length()>0) {
stream.println("//------------------------------------------------------//");
stream.println("// Compute the Greater_or_equal membership degree //");
stream.println("//------------------------------------------------------//");
stream.println();
stream.println("double "+classname+"::compute_greq(double x) {");
stream.println(greq);
stream.println("}");
stream.println();
}
String smeq = fam.getSmeqCppCode();
if(smeq != null && smeq.length()>0) {
stream.println("//------------------------------------------------------//");
stream.println("// Compute the Smaller_or_equal membership degree //");
stream.println("//------------------------------------------------------//");
stream.println();
stream.println("double "+classname+"::compute_smeq(double x) {");
stream.println(smeq);
stream.println("}");
stream.println();
}
String center = fam.getCenterCppCode();
if(center != null && center.length()>0) {
stream.println("//------------------------------------------------------//");
stream.println("// Function to get the center of the MF //");
stream.println("//------------------------------------------------------//");
stream.println();
stream.println("double "+classname+"::center() {");
stream.println(center);
stream.println("}");
stream.println();
}
String basis = fam.getBasisCppCode();
if(basis != null && basis.length()>0) {
stream.println("//------------------------------------------------------//");
stream.println("// Function to get the basis of the MF //");
stream.println("//------------------------------------------------------//");
stream.println();
stream.println("double "+classname+"::basis() {");
stream.println(basis);
stream.println("}");
stream.println();
}
}
/**
* Descripci�n de una funci�n de pertenencia
*/
private void printMFCppCode(PrintStream stream,ParamMemFunc mf) throws XflException {
String spname = spec.getName();
String pkgname = mf.getPackageName();
String classname = "MF_"+spname+"_"+pkgname+"_"+mf.getFunctionName();
String equal = mf.getEqualCppCode();
String listname = mf.getParamListName();
Parameter[] single = mf.getSingleParameters();
boolean haslist = (listname != null && listname.length() > 0);
if(equal==null || equal.length()==0) throw new XflException();
stream.println("//++++++++++++++++++++++++++++++++++++++++++++++++++++++//");
stream.println(complete("// MembershipFunction "+classname));
stream.println("//++++++++++++++++++++++++++++++++++++++++++++++++++++++//");
stream.println();
stream.println("//------------------------------------------------------//");
stream.println("// Constructor //");
stream.println("//------------------------------------------------------//");
stream.println();
stream.print(classname+"::"+classname+"(double min,double max,double step");
stream.println(",double *single,double *list, int length) :");
stream.println("ParamMembershipFunction(min,max,step) {");
stream.println(" this->name = \""+classname+"\";");
for(int i=0; i<single.length; i++) {
stream.println(" this->"+single[i].getName()+" = single["+i+"];");
}
if(haslist) {
stream.println(" this->length = length;");
stream.println(" this->"+listname+" = new double[length];");
stream.println(" for(int i=0; i<length; i++) this->list[i] = list[i];");
} else {
}
stream.println("}");
stream.println();
stream.println("//------------------------------------------------------//");
stream.println("// Function to get a clone of the object //");
stream.println("//------------------------------------------------------//");
stream.println();
stream.println(classname+" * "+classname+"::dup() {");
stream.print(" double _param["+single.length+"] = {");
for(int i=0; i<single.length; i++) {
stream.print((i==0? "":",")+single[i].getName());
}
stream.println("};");
if(haslist) {
stream.println(" double *_list = this->"+listname+";");
stream.println(" int _length = this->length;");
} else {
stream.println(" double *_list = NULL;");
stream.println(" int _length = 0;");
}
stream.println(" return new "+classname+"(min,max,step,_param,_list,_length);");
stream.println("}");
stream.println();
stream.println("//------------------------------------------------------//");
stream.println("// Function to get a parameter of the function //");
stream.println("//------------------------------------------------------//");
stream.println();
stream.println("double "+classname+"::param(int _i) {");
if(single.length == 0 && haslist) {
stream.println(" return "+listname+"[_i];");
} else if(!haslist) {
stream.println(" switch(_i) {");
for(int i=0; i<single.length; i++) {
stream.println(" case "+i+": return "+single[i].getName()+";");
}
stream.println(" default: return 0;");
stream.println(" }");
} else {
stream.print(" if(_i>="+single.length+")");
stream.println(" return "+listname+"[_i-"+single.length+"];");
stream.println(" switch(_i) {");
for(int i=0; i<single.length; i++) {
stream.println(" case "+i+": return "+single[i].getName()+";");
}
stream.println(" default: return 0;");
stream.println(" }");
}
stream.println("}");
stream.println();
stream.println("//------------------------------------------------------//");
stream.println("// Function to compute the membership degree //");
stream.println("//------------------------------------------------------//");
stream.println();
stream.println("double "+classname+"::compute_eq(double x) {");
stream.println(equal);
stream.println("}");
stream.println();
String greq = mf.getGreqCppCode();
if(greq != null && greq.length()>0) {
stream.println("//------------------------------------------------------//");
stream.println("// Compute the Greater_or_equal membership degree //");
stream.println("//------------------------------------------------------//");
stream.println();
stream.println("double "+classname+"::compute_greq(double x) {");
stream.println(greq);
stream.println("}");
stream.println();
}
String smeq = mf.getSmeqCppCode();
if(smeq != null && smeq.length()>0) {
stream.println("//------------------------------------------------------//");
stream.println("// Compute the Smaller_or_equal membership degree //");
stream.println("//------------------------------------------------------//");
stream.println();
stream.println("double "+classname+"::compute_smeq(double x) {");
stream.println(smeq);
stream.println("}");
stream.println();
}
String center = mf.getCenterCppCode();
if(center != null && center.length()>0) {
stream.println("//------------------------------------------------------//");
stream.println("// Function to get the center of the MF //");
stream.println("//------------------------------------------------------//");
stream.println();
stream.println("double "+classname+"::center() {");
stream.println(center);
stream.println("}");
stream.println();
}
String basis = mf.getBasisCppCode();
if(basis != null && basis.length()>0) {
stream.println("//------------------------------------------------------//");
stream.println("// Function to get the basis of the MF //");
stream.println("//------------------------------------------------------//");
stream.println();
stream.println("double "+classname+"::basis() {");
stream.println(basis);
stream.println("}");
stream.println();
}
}
//----------------------------------------------------------------------------//
// M�todos que generan la estructura global //
//----------------------------------------------------------------------------//
/**
* Descripci�n de la estructura global del sistema
*/
private void printSystemCode(PrintStream stream) {
String spname = spec.getName();
SystemModule system = spec.getSystemModule();
Variable input[] = system.getInputs();
Variable output[] = system.getOutputs();
Variable inner[] = system.getInners();
ModuleCall call[] = system.getModuleCalls();
stream.println("//++++++++++++++++++++++++++++++++++++++++++++++++++++++//");
stream.println("// Inference Engine //");
stream.println("//++++++++++++++++++++++++++++++++++++++++++++++++++++++//");
stream.println();
stream.println("//------------------------------------------------------//");
stream.println("// Inference from crisp numbers giving crisp numbers //");
stream.println("//------------------------------------------------------//");
stream.println();
stream.println("double* "+spname+"::crispInference(double *_input) {");
for(int i=0; i<input.length; i++)
stream.println(" FuzzySingleton "+input[i]+"(_input["+i+"]);");
stream.print(" MembershipFunction ");
for(int i=0; i<output.length; i++) stream.print((i!=0? ", *": "*")+output[i]);
for(int i=1; i<inner.length; i++) stream.print(", *"+inner[i]);
stream.println(";");
for(int i=0; i<call.length; i++) if(call[i] instanceof RulebaseCall) {
printRulebaseCallCode(stream, (RulebaseCall) call[i]);
} else printCrispBlockCallCode(stream, (CrispBlockCall) call[i]);
stream.println(" double *_output = new double["+output.length+"];");
for(int i=0; i<output.length; i++) {
stream.print(" if("+output[i]+"->getType() == MembershipFunction::CRISP) ");
stream.print("_output["+i+"] = ((FuzzySingleton *) ");
stream.println(output[i]+")->getValue();");
stream.print(" else _output["+i+"] = ((OutputMembershipFunction *) ");
stream.println(output[i]+")->defuzzify();");
}
for(int i=0; i<output.length; i++) stream.println(" delete "+output[i]+";");
for(int i=1; i<inner.length; i++) stream.println(" delete "+inner[i]+";");
stream.println(" return _output;");
stream.println("}");
stream.println();
stream.println("//------------------------------------------------------//");
stream.println("// Inference from fuzzy numbers giving crisp numbers //");
stream.println("//------------------------------------------------------//");
stream.println();
stream.print("double* "+spname+"::crispInference");
stream.println("(MembershipFunction* &_input) {");
for(int i=0; i<input.length; i++)
stream.println(" MembershipFunction & "+input[i]+" = _input["+i+"];");
stream.print(" MembershipFunction ");
for(int i=0; i<output.length; i++) stream.print((i!=0? ", *": "*")+output[i]);
for(int i=1; i<inner.length; i++) stream.print(", *"+inner[i]);
stream.println(";");
for(int i=0; i<call.length; i++) if(call[i] instanceof RulebaseCall) {
printRulebaseCallCode(stream, (RulebaseCall) call[i]);
} else printCrispBlockCallCode(stream, (CrispBlockCall) call[i]);
stream.println(" double *_output = new double["+output.length+"];");
for(int i=0; i<output.length; i++) {
stream.print(" if("+output[i]+"->getType() == MembershipFunction::CRISP) ");
stream.print("_output["+i+"] = ((FuzzySingleton *) ");
stream.println(output[i]+")->getValue();");
stream.print(" else _output["+i+"] = ((OutputMembershipFunction *) ");
stream.println(output[i]+")->defuzzify();");
}
for(int i=0; i<output.length; i++) stream.println(" delete "+output[i]+";");
for(int i=1; i<inner.length; i++) stream.println(" delete "+inner[i]+";");
stream.println(" return _output;");
stream.println("}");
stream.println();
stream.println("//------------------------------------------------------//");
stream.println("// Inference from crisp numbers giving fuzzy numbers //");
stream.println("//------------------------------------------------------//");
stream.println();
stream.print("MembershipFunction** "+spname+"::fuzzyInference");
stream.println("(double *_input) {");
for(int i=0; i<input.length; i++)
stream.println(" FuzzySingleton "+input[i]+"(_input["+i+"]);");
stream.print(" MembershipFunction ");
for(int i=0; i<output.length; i++) stream.print((i!=0? ", *": "*")+output[i]);
for(int i=1; i<inner.length; i++) stream.print(", *"+inner[i]);
stream.println(";");
for(int i=0; i<call.length; i++) if(call[i] instanceof RulebaseCall) {
printRulebaseCallCode(stream, (RulebaseCall) call[i]);
} else printCrispBlockCallCode(stream, (CrispBlockCall) call[i]);
for(int i=1; i<inner.length; i++) stream.println(" delete "+inner[i]+";");
stream.print(" MembershipFunction **_output = ");
stream.println("new (MembershipFunction *)["+output.length+"];");
for(int i=0; i<output.length; i++)
stream.println(" _output["+i+"] = "+output[i]+";");
stream.println(" return _output;");
stream.println("}");
stream.println();
stream.println("//------------------------------------------------------//");
stream.println("// Inference from fuzzy numbers giving fuzzy numbers //");
stream.println("//------------------------------------------------------//");
stream.println();
stream.print("MembershipFunction** "+spname+"::fuzzyInference");
stream.println("(MembershipFunction* &_input) {");
for(int i=0; i<input.length; i++)
stream.println(" MembershipFunction & "+input[i]+" = _input["+i+"];");
stream.print(" MembershipFunction ");
for(int i=0; i<output.length; i++) stream.print((i!=0? ", *": "*")+output[i]);
for(int i=1; i<inner.length; i++) stream.print(", *"+inner[i]);
stream.println(";");
for(int i=0; i<call.length; i++) if(call[i] instanceof RulebaseCall) {
printRulebaseCallCode(stream, (RulebaseCall) call[i]);
} else printCrispBlockCallCode(stream, (CrispBlockCall) call[i]);
for(int i=1; i<inner.length; i++) stream.println(" delete "+inner[i]+";");
stream.print(" MembershipFunction **_output = ");
stream.println("new (MembershipFunction *)["+output.length+"];");
for(int i=0; i<output.length; i++)
stream.println(" _output["+i+"] = "+output[i]+";");
stream.println(" return _output;");
stream.println("}");
stream.println();
stream.println("//------------------------------------------------------//");
stream.println("// Crisp Inference with single variables (not arrays) //");
stream.println("//------------------------------------------------------//");
stream.println();
stream.print("void "+spname+"::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(" ) {");
for(int i=0; i<input.length; i++)
stream.println(" FuzzySingleton "+input[i]+"(_i_"+input[i]+");");
stream.print(" MembershipFunction ");
for(int i=0; i<output.length; i++) stream.print((i!=0? ", *": "*")+output[i]);
for(int i=1; i<inner.length; i++) stream.print(", *"+inner[i]);
stream.println(";");
for(int i=0; i<call.length; i++) if(call[i] instanceof RulebaseCall) {
printRulebaseCallCode( stream,(RulebaseCall) call[i]);
} else printCrispBlockCallCode( stream,(CrispBlockCall) call[i]);
for(int i=0; i<output.length; i++) {
stream.print(" if("+output[i]+"->getType() == MembershipFunction::CRISP) ");
stream.print("(*_o_"+output[i]+") = ((FuzzySingleton *) ");
stream.println(output[i]+")->getValue();");
stream.print(" else (*_o_"+output[i]+") = ((OutputMembershipFunction *) ");
stream.println(output[i]+")->defuzzify();");
}
for(int i=0; i<output.length; i++) stream.println(" delete "+output[i]+";");
for(int i=1; i<inner.length; i++) stream.println(" delete "+inner[i]+";");
stream.println("}");
stream.println();
}
/**
* Descripci�n de una llamada a una base de reglas
*/
private void printRulebaseCallCode(PrintStream stream,RulebaseCall call) {
Rulebase base = call.getRulebase();
Variable[] inputvar = call.getInputVariables();
Variable[] outputvar = call.getOutputVariables();
stream.print(" RL_"+base+"(");
for(int i=0; i < inputvar.length; i++) {
if(inputvar[i].isInput()) stream.print((i==0? "" : ", ")+inputvar[i]);
else stream.print((i==0? "*" : ", *")+inputvar[i]);
}
for(int i=0; i < outputvar.length; i++) stream.print(", &"+outputvar[i]);
stream.println(");");
}
/**
* Descripci�n de una llamada a un bloque no difuso
*/
private void printCrispBlockCallCode(PrintStream stream,CrispBlockCall call) {
Variable[] inputvar = call.getInputVariables();
Variable outputvar = call.getOutputVariable();
stream.print(" "+outputvar+" = new FuzzySingleton(");
stream.print(" CB_"+call.getName()+"(");
for(int i=0; i < inputvar.length; i++) {
if(inputvar[i].isInput()) stream.print((i==0? "" : ", ")+inputvar[i]);
else stream.print((i==0? "*" : ", *")+inputvar[i]);
}
stream.println(") );");
}
//----------------------------------------------------------------------------//
// M�todos que generan los conjuntos de operadores //
//----------------------------------------------------------------------------//
/**
* Descripci�n de un conjunto de operadores
*/
private void printOperatorSetCode(PrintStream stream,Operatorset opset) throws XflException {
String opname = "OP_"+spec.getName()+"_"+opset.getName();
stream.println("//++++++++++++++++++++++++++++++++++++++++++++++++++++++//");
stream.println(complete("// Operatorset "+opname));
stream.println("//++++++++++++++++++++++++++++++++++++++++++++++++++++++//");
stream.println();
stream.println("//------------------------------------------------------//");
stream.println("// Description of the operator AND //");
stream.println("//------------------------------------------------------//");
stream.println();
createBinaryCode(stream,opset.and, opname+"::_and");
stream.println("//------------------------------------------------------//");
stream.println("// Description of the operator OR //");
stream.println("//------------------------------------------------------//");
stream.println();
createBinaryCode(stream,opset.or, opname+"::_or");
stream.println("//------------------------------------------------------//");
stream.println("// Description of the operator ALSO //");
stream.println("//------------------------------------------------------//");
stream.println();
createBinaryCode(stream,opset.also, opname+"::_also");
stream.println("//------------------------------------------------------//");
stream.println("// Description of the operator IMPLICATION //");
stream.println("//------------------------------------------------------//");
stream.println();
createBinaryCode(stream,opset.imp, opname+"::_imp");
stream.println("//------------------------------------------------------//");
stream.println("// Description of the operator NOT //");
stream.println("//------------------------------------------------------//");
stream.println();
createUnaryCode(stream,opset.not, opname+"::_not");
stream.println("//------------------------------------------------------//");
stream.println("// Description of the operator STRONGLY //");
stream.println("//------------------------------------------------------//");
stream.println();
createUnaryCode(stream,opset.very, opname+"::_very");
stream.println("//------------------------------------------------------//");
stream.println("// Description of the operator MORE OR LESS //");
stream.println("//------------------------------------------------------//");
stream.println();
createUnaryCode(stream,opset.moreorless, opname+"::_moreorless");
stream.println("//------------------------------------------------------//");
stream.println("// Description of the operator SLIGHTLY //");
stream.println("//------------------------------------------------------//");
stream.println();
createUnaryCode(stream,opset.slightly, opname+"::_slightly");
stream.println("//------------------------------------------------------//");
stream.println("// Description of the defuzzification method //");
stream.println("//------------------------------------------------------//");
stream.println();
createDefuzCode(stream,opset.defuz, opname+"::_defuz");
}
/**
* Descripci�n de un operador binario
*/
private void createBinaryCode(PrintStream stream, Binary op, String name) throws XflException {
String listname = op.getParamListName();
Parameter single[] = op.getSingleParameters();
Parameter list[] = op.getParamList();
stream.println("double "+name+"(double a, double b) {");
for(int i=0; i<single.length; i++) {
stream.println(" double "+single[i].getName()+" = "+single[i].value+";");
}
if(listname != null && listname.length()>0) {
stream.print(" double "+listname+"["+list.length+"] = {");
for(int i=0; i<list.length; i++)
stream.print((i>0? ",":"")+list[i].value);
stream.println("};");
}
stream.println(op.getCppCode());
stream.println("}");
stream.println();
}
/**
* Descripci�n de un operador unario
*/
private void createUnaryCode(PrintStream stream, Unary op, String name) throws XflException {
String listname = op.getParamListName();
Parameter single[] = op.getSingleParameters();
Parameter list[] = op.getParamList();
stream.println("double "+name+"(double a) {");
for(int i=0; i<single.length; i++) {
stream.println(" double "+single[i].getName()+" = "+single[i].value+";");
}
if(listname != null && listname.length()>0) {
stream.print(" double "+listname+"["+list.length+"] = {");
for(int i=0; i<list.length; i++)
stream.print((i>0? ",":"")+list[i].value);
stream.println("};");
}
stream.println(op.getCppCode());
stream.println("}");
stream.println();
}
/**
* Descripci�n de un m�todo de concreci�n
*/
private void createDefuzCode(PrintStream stream, DefuzMethod op, String name)
throws XflException {
String listname = op.getParamListName();
Parameter single[] = op.getSingleParameters();
Parameter list[] = op.getParamList();
String defuzcode = op.getCppCode();
stream.println("double "+name+"(OutputMembershipFunction &mf) {");
if(defuzcode.indexOf("min")!=-1) stream.println( " double min = mf.min();");
if(defuzcode.indexOf("max")!=-1) stream.println(" double max = mf.max();");
if(defuzcode.indexOf("step")!=-1) stream.println(" double step = mf.step();");
for(int i=0; i<single.length; i++) {
stream.println( " double "+single[i].getName()+" = "+single[i].value+";" );
}
if(listname != null && listname.length()>0) {
stream.print(" double "+listname+"["+list.length+"] = {");
for(int i=0; i<list.length; i++)
stream.print( (i>0? ",":"")+list[i].value );
stream.println( "};" );
}
stream.println(defuzcode);
stream.println("}");
stream.println();
}
//----------------------------------------------------------------------------//
// M�todos que generan los tipos de variables //
//----------------------------------------------------------------------------//
/**
* Descripci�n de un tipo de variable linguistica
*/
private void printTypeCode(PrintStream stream,Type type) throws XflException {
String specname = spec.getName();
String typename = "TP_"+specname+"_"+type.getName();
Universe u = type.getUniverse();
Family[] fam = type.getFamilies();
LinguisticLabel[] allmf = type.getAllMembershipFunctions();
stream.println("//++++++++++++++++++++++++++++++++++++++++++++++++++++++//");
stream.println(complete("// Type "+typename));
stream.println("//++++++++++++++++++++++++++++++++++++++++++++++++++++++//");
stream.println();
stream.println("//------------------------------------------------------//");
stream.println("// Constructor //");
stream.println("//------------------------------------------------------//");
stream.println();
stream.println(typename+"::"+typename+"() {");
stream.println(" min = "+u.min()+";");
stream.println(" max = "+u.max()+";");
stream.println(" step = "+u.step()+";");
for(int i=0; i<fam.length; i++) {
Parameter single[] = fam[i].getSingleParameters();
stream.print(" double _pfs_"+fam[i]+"[] = { ");
for(int j=0; j<single.length; j++) stream.print((j==0? "":",")+single[j].value);
stream.println(" };");
Parameter list[] = fam[i].getParamList();
int listlength = (list == null? 0 : list.length);
stream.print(" double _pfl_"+fam[i]+"[] = { ");
for(int j=0; j<listlength; j++) stream.print((j==0? "":",")+list[j].value);
stream.println(" };");
}
for(int i=0; i<allmf.length; i++) if(allmf[i] instanceof ParamMemFunc) {
ParamMemFunc pmf = (ParamMemFunc) allmf[i];
Parameter single[] = pmf.getSingleParameters();
stream.print(" double _ps_"+pmf.getLabel()+"[] = { ");
for(int j=0; j<single.length; j++) stream.print((j==0? "":",")+single[j].value);
stream.println(" };");
Parameter list[] = pmf.getParamList();
int listlength = (list == null? 0 : list.length);
stream.print(" double _pl_"+pmf.getLabel()+"[] = { ");
for(int j=0; j<listlength; j++) stream.print((j==0? "":",")+list[j].value);
stream.println(" };");
}
for(int i=0; i<allmf.length; i++) {
if(allmf[i] instanceof ParamMemFunc) {
ParamMemFunc pmf = (ParamMemFunc) allmf[i];
String pkgname = pmf.getPackageName();
Parameter list[] = pmf.getParamList();
int length = (list == null? 0 : list.length);
String mfname = "MF_"+specname+"_"+pkgname+"_"+pmf.getFunctionName();
stream.print(" "+pmf.getLabel()+" = "+mfname);
stream.print("(min,max,step,");
stream.println("_ps_"+pmf.getLabel()+",_pl_"+pmf.getLabel()+","+length+");");
} else {
FamiliarMemFunc fmf = (FamiliarMemFunc) allmf[i];
Family fammf = fmf.getFamily();
int index = fmf.getIndex();
String pkgname = fammf.getPackageName();
Parameter list[] = fammf.getParamList();
int length = (list == null? 0 : list.length);
String mfname = "FMF_"+specname+"_"+pkgname+"_"+fammf.getFunctionName();
stream.print(" "+fmf.getLabel()+" = "+mfname+"("+index+",min,max,step");
stream.println( ",_pfs_"+fammf+",_pfl_"+fammf+","+length+");");
}
}
stream.println("}");
stream.println();
}
//----------------------------------------------------------------------------//
// M�todos que generan las bases de reglas //
//----------------------------------------------------------------------------//
/**
* Descripci�n de una base de reglas
*/
private void printRulebaseCode(PrintStream stream,Rulebase base) throws XflException {
String spname = spec.getName();
String rbname = "RL_"+base.getName();
Variable[] inputvar = base.getInputs();
Variable[] outputvar = base.getOutputs();
Operatorset operation = base.getOperatorset();
Rule[] rule = base.getRules();
stream.println( "//------------------------------------------------------//" );
stream.println( complete("// Rulebase "+rbname) );
stream.println( "//------------------------------------------------------//" );
stream.println();
stream.print( "void "+spname+"::"+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( ") {" );
stream.println( " OP_"+spname+"_"+operation.getName()+" _op;" );
stream.println( " double _rl;" );
for(int i=0; i<outputvar.length; i++)
stream.println( " int _i_"+outputvar[i]+"=0;" );
stream.println( " double *_input = new double["+inputvar.length+"];" );
for(int i=0; i<inputvar.length; i++)
stream.println( " _input["+i+"] = "+inputvar[i]+".getValue();" );
for(int i=0; i<outputvar.length; i++) {
stream.print( " OutputMembershipFunction *"+outputvar[i] );
stream.print( " = new OutputMembershipFunction(" );
stream.print( "new OP_"+spname+"_"+operation.getName()+"()," );
stream.println( base.computeOutputSize(i)+","+inputvar.length+",_input);");
}
for(int i=0; i<inputvar.length; i++)
stream.println( " TP_"+spname+"_"+inputvar[i].getType()+" _t_"+inputvar[i]+";");
for(int i=0; i<outputvar.length; i++)
stream.println( " TP_"+spname+"_"+outputvar[i].getType()+" _t_"+outputvar[i]+";");
for(int i=0; i<rule.length; i++) createRuleCode(stream, rule[i]);
if(operation.defuz.isDefault())
for(int i=0; i<outputvar.length; i++)
stream.println( " *_o_"+outputvar[i]+" = "+outputvar[i]+";");
else for(int i=0; i<outputvar.length; i++) {
stream.print( " *_o_"+outputvar[i] );
stream.println( " = new FuzzySingleton( (*"+outputvar[i]+").defuzzify());");
stream.println( " delete "+outputvar[i]+";" );
}
stream.println(" delete _input;");
stream.println("}");
stream.println();
}
/**
* Descripci�n de una regla
*/
private void createRuleCode(PrintStream stream, Rule rule) throws XflException {
double degree = rule.getDegree();
Relation premise = rule.getPremise();
Conclusion[] conc = rule.getConclusions();
stream.print(" _rl = ");
if(degree != 1.0) stream.print(degree+"*");
stream.println(createRelationCode(premise)+";");
for(int j=0; j<conc.length; j++) stream.println(createConclusionCode(conc[j]));
}
/**
* Descripci�n de la conclusi�n de una regla
*/
private String createConclusionCode(Conclusion conc) throws XflException {
Variable var = conc.getVariable();
LinguisticLabel mf = conc.getMembershipFunction();
String code = " (*"+var+").conc[_i_"+var+"] = new RuleConclusion(_rl, ";
code += "_t_"+var+"."+mf+".dup());";
code += " _i_"+var+"++;";
return code;
}
/**
* Descripci�n de una proposicion
*/
private String createRelationCode(Relation rel) throws XflException {
Variable var = rel.getVariable();
LinguisticLabel mf = rel.getMembershipFunction();
Relation l = rel.getLeftRelation();
Relation r = rel.getRightRelation();
switch(rel.getKind()) {
case Relation.AND:
return "_op._and("+createRelationCode(l)+","+createRelationCode(r)+")";
case Relation.OR:
return "_op._or("+createRelationCode(l)+","+createRelationCode(r)+")";
case Relation.IS:
return "_t_"+var+"."+mf.getLabel()+".isEqual("+var+")";
case Relation.ISNOT:
return "_t_"+var+"."+mf.getLabel()+".isNotEqual("+var+", _op)";
case Relation.GR_EQ:
return "_t_"+var+"."+mf.getLabel()+".isGreaterOrEqual("+var+")";
case Relation.SM_EQ:
return "_t_"+var+"."+mf.getLabel()+".isSmallerOrEqual("+var+")";
case Relation.GREATER:
return "_t_"+var+"."+mf.getLabel()+".isGreater("+var+", _op)";
case Relation.SMALLER:
return "_t_"+var+"."+mf.getLabel()+".isSmaller("+var+", _op)";
case Relation.APP_EQ:
return "_t_"+var+"."+mf.getLabel()+".isApproxEqual("+var+", _op)";
case Relation.VERY_EQ:
return "_t_"+var+"."+mf.getLabel()+".isVeryEqual("+var+", _op)";
case Relation.SL_EQ:
return "_t_"+var+"."+mf.getLabel()+".isSlightlyEqual("+var+", _op)";
case Relation.NOT:
return "_op._not("+createRelationCode(r)+")";
case Relation.MoL:
return "_op._moreorless("+createRelationCode(r)+")";
case Relation.SLIGHTLY:
return "_op.slightly("+createRelationCode(r)+")";
case Relation.VERY:
return "_op._very("+createRelationCode(r)+")";
default: return "";
}
}
//----------------------------------------------------------------------------//
// M�todos que generan el c�digo de un bloque no difuso //
//----------------------------------------------------------------------------//
/**
* Descripci�n de un bloque no difuso
*/
private void printCrispBlockCode(PrintStream stream,CrispBlock crisp) throws XflException {
String spname = spec.getName();
String cbname = "CB_"+crisp.getName();
int inputs = crisp.inputs();
stream.println("//------------------------------------------------------//");
stream.println(complete("// CrsipBlock "+cbname));
stream.println("//------------------------------------------------------//");
stream.println();
stream.print("double "+spname+"::"+cbname+"(");
for(int i=0; i<inputs; i++) stream.print((i==0?"":", ")+"MembershipFunction &_i"+i);
stream.println(") {");
Parameter singleparam[] = crisp.getSingleParameters();
for(int i=0; i<singleparam.length; i++) {
stream.print(" double "+singleparam[i].getName());
stream.println(" = "+singleparam[i].value+";");
}
if(crisp.hasParamList()) {
Parameter paramlist[] = crisp.getParamList();
int listlength = (paramlist == null? 0 : paramlist.length);
stream.print(" double "+crisp.getParamListName()+"["+listlength+"] = {");
for(int i=0; i<listlength; i++)
stream.print((i>0? ",":"")+paramlist[i].value);
stream.println("};");
}
stream.println(" double x["+inputs+"];");
stream.println();
for(int i=0; i<inputs; i++) {
stream.println(" if(_i"+i+".getType() == MembershipFunction::CRISP) {");
stream.println(" x["+i+"] = ((FuzzySingleton &) _i"+i+").getValue();");
stream.println(" } else {");
stream.println(" x["+i+"] = ((OutputMembershipFunction &) _i"+i+").defuzzify();");
stream.println(" }");
stream.println();
}
stream.println(crisp.getCppCode());
stream.println("}");
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;
}
}