//--------------------------------------------------------------------------------// // 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.lang; import java.io.*; /** * Clase que permite almacenar los ficheros XFL de forma eficiente * * @author Francisco Jos� Moreno Velo * */ public class XflSaver { //----------------------------------------------------------------------------// // M�TODOS P�BLICOS // //----------------------------------------------------------------------------// /** * Almacena el sistema difuso en formato XFL3 */ public static boolean save(Specification spec, File file) { try { spec.setFile(file); FileOutputStream fos = new FileOutputStream(file); PrintStream stream = new PrintStream(fos); printSpecification(stream,spec); stream.close(); } catch(IOException e) { return false; } return true; } //----------------------------------------------------------------------------// // M�TODOS PRIVADOS // //----------------------------------------------------------------------------// /** * Escribe sobre el flujo la descripcion XFL3 del sistema difuso */ private static void printSpecification(PrintStream stream, Specification spec) { Operatorset[] opset = spec.getOperatorsets(); Type[] type = spec.getTypes(); Rulebase[] rulebase = spec.getRulebases(); CrispBlockSet crisp = spec.getCrispBlockSet(); SystemModule system = spec.getSystemModule(); for(int i=0; i<opset.length; i++) printOperatorSet(stream,opset[i]); for(int i=0; i<type.length; i++) printType(stream, type[i]); for(int i=0; i<rulebase.length; i++) printRulebase(stream, rulebase[i]); if(crisp != null) printCrispBlockSet(stream, crisp); if(system != null) printSystemModule(stream, system); } /** * Escribe sobre el flujo la descripci�n XFL3 de un conjunto de operadores * @param stream * @param opset */ private static void printOperatorSet(PrintStream stream, Operatorset opset) { if(opset.isDefault()) return; stream.println("operatorset "+opset.getName()+" {"); printFuzzyOperator(stream,opset.and,"and"); printFuzzyOperator(stream,opset.or,"or"); printFuzzyOperator(stream,opset.imp,"imp"); printFuzzyOperator(stream,opset.also,"also"); printFuzzyOperator(stream,opset.not,"not"); printFuzzyOperator(stream,opset.very,"strongly"); printFuzzyOperator(stream,opset.moreorless,"moreorless"); printFuzzyOperator(stream,opset.slightly,"slightly"); printFuzzyOperator(stream,opset.defuz,"defuz"); stream.println("}"); stream.println(); } /** * Escribe sobre el flujo la descripci�n XFL3 de un operador * @param stream * @param fzop * @param label */ private static void printFuzzyOperator(PrintStream stream, FuzzyOperator fzop, String label) { if(!fzop.isDefault()) stream.println(" "+label+" "+fzop.getXflDescription()); } /** * Escribe sobre el flujo la descripci�n XFL3 de un tipo de variable * @param stream * @param type */ private static void printType(PrintStream stream, Type type) { Family[] fam = type.getFamilies(); LinguisticLabel[] mf = type.getMembershipFunctions(); stream.print("type "+type.getName()+" "); if(type.getParent() == null) { Universe u = type.getUniverse(); stream.print("["+u.min()+","+u.max()+";"+u.card()+"]"); } else stream.print("extends "+type.getParent().getName()); stream.println(" {"); for(int i=0; i<fam.length; i++) printFamily(stream,fam[i]); for(int i=0; i<mf.length; i++) printLabel(stream,mf[i]); stream.println("}"); stream.println(); } /** * Escribe sobre el flujo la descripci�n XFL3 de una familia de MFs * @param stream * @param fam */ private static void printFamily(PrintStream stream, Family fam) { stream.println(" "+fam.getLabel()+"[] "+fam.getXflDescription()); } /** * Escribe sobre el flujo la descripci�n XFL3 de una etiqueta ling��stica * @param stream * @param mf */ private static void printLabel(PrintStream stream, LinguisticLabel mf) { if(mf instanceof FamiliarMemFunc) { FamiliarMemFunc fmf = (FamiliarMemFunc) mf; stream.print(" "+fmf.getLabel()+" "+fmf.getFamily().getLabel()); stream.println("["+fmf.getIndex()+"];"); } else { ParamMemFunc pmf = (ParamMemFunc) mf; stream.println(" "+pmf.getLabel()+" "+pmf.getXflDescription()); } } /** * Escribe sobre el flujo la descripci�n XFL3 de una base de reglas * @param stream * @param base */ private static void printRulebase(PrintStream stream, Rulebase base) { Variable[] inputvar = base.getInputs(); Variable[] outputvar = base.getOutputs(); Operatorset opset = base.getOperatorset(); Rule[] rule = base.getRules(); stream.print("rulebase "+base.getName()+" ("); for(int i=0; i<inputvar.length; i++) { if(i>0) stream.print(", "); stream.print(inputvar[i].getType().getName()+" "+inputvar[i].getName()); } stream.print(" : "); for(int i=0; i<outputvar.length; i++) { if(i>0) stream.print(", "); stream.print(outputvar[i].getType().getName()+" "+outputvar[i].getName()); } stream.print(")"); if(!opset.isDefault()) stream.print(" using "+opset.getName()); stream.println(" {"); for(int i=0; i<rule.length; i++) printRule(stream,rule[i]); stream.println("}"); stream.println(); } /** * Escribe sobre el flujo la descripci�n XFL3 de una regla * @param stream * @param rule */ private static void printRule(PrintStream stream, Rule rule) { double degree = rule.getDegree(); Relation antecedent = rule.getPremise(); Conclusion[] conclusion = rule.getConclusions(); stream.print(" "); if(degree != 1.0) stream.print("["+degree+"] "); stream.print( "if(" ); printRelation(stream,antecedent); stream.print(") -> "); printConclusion(stream,conclusion[0]); for(int i=1; i<conclusion.length; i++) { stream.print(", "); printConclusion(stream,conclusion[i]); } stream.println(";"); } /** * Escribe sobre el flujo la descripci�n XFL3 de una proposici�n difusa * @param stream * @param rel */ private static void printRelation(PrintStream stream, Relation rel) { if(rel instanceof SingleRelation) { String var = rel.getVariable().getName(); String label = rel.getMembershipFunction().getLabel(); String op = ""; switch(rel.getKind()) { case Relation.IS: op = " == "; break; case Relation.GREATER: op = " > "; break; case Relation.GR_EQ: op = " >= "; break; case Relation.SMALLER: op = " < "; break; case Relation.SM_EQ: op = " <= "; break; case Relation.APP_EQ: op = " ~= "; break; case Relation.ISNOT: op = " != "; break; case Relation.SL_EQ: op = " %= "; break; case Relation.VERY_EQ: op = " += "; break; } stream.print(var+op+label); } else if(rel instanceof UnaryRelation) { Relation rr = rel.getRightRelation(); String op = ""; switch(rel.getKind()) { case Relation.NOT : op = "!"; break; case Relation.MoL : op = "~"; break; case Relation.VERY : op = "+"; break; case Relation.SLIGHTLY : op = "%"; break; } stream.print(op+"("); printRelation(stream,rr); stream.print(")"); } else if(rel instanceof BinaryRelation) { Relation left = rel.getLeftRelation(); Relation right = rel.getRightRelation(); boolean lparen = (left instanceof BinaryRelation && left.getKind() != rel.getKind()); boolean rparen = (right instanceof BinaryRelation && right.getKind() != rel.getKind()); if(lparen) stream.print("("); printRelation(stream,left); if(lparen) stream.print(")"); if(rel.getKind() == Relation.AND) stream.print(" & "); else if(rel.getKind() == Relation.OR) stream.print(" | "); if(rparen) stream.print("("); printRelation(stream,right); if(rparen) stream.print(")"); } } /** * Escribe sobre el flujo la descripci�n XFL3 de una conclusi�n de una regla * @param stream * @param conc */ private static void printConclusion(PrintStream stream, Conclusion conc) { String var = conc.getVariable().getName(); String label = conc.getMembershipFunction().getLabel(); stream.print(var+" = "+label); } /** * Escribe sobre el flujo la descripci�n XFL3 de los bloques no difusos * @param stream * @param crisp */ private static void printCrispBlockSet(PrintStream stream, CrispBlockSet crisp) { CrispBlock[] block = crisp.getBlocks(); if(block.length == 0) return; stream.println("crisp {"); for(int i=0; i<block.length; i++) printCrispBlock(stream,block[i]); stream.println("}"); stream.println(); } /** * Escribe sobre el flujo la descripci�n XFL3 de un bloques no difuso * @param stream * @param block */ private static void printCrispBlock(PrintStream stream, CrispBlock block) { stream.println(" "+block.getLabel()+" "+block.getXflDescription()); } /** * Escribe sobre el flujo la descripci�n XFL3 de la estructura modular * @param stream * @param system */ private static void printSystemModule(PrintStream stream, SystemModule system) { Variable input[] = system.getInputs(); Variable output[] = system.getOutputs(); ModuleCall[] call = system.getModuleCalls(); stream.print("system ("); for(int i=0; i<input.length; i++) { if(i>0) stream.print(", "); stream.print(input[i].getType().getName()+" "+input[i].getName()); } stream.print(" : "); for(int i=0; i<output.length; i++) { if(i>0) stream.print(", "); stream.print(output[i].getType().getName()+" "+output[i].getName()); } stream.println(") {"); for(int i=0; i<call.length; i++) printModuleCall(stream,call[i]); stream.println(" }"); } /** * Escribe sobre el flujo la descripci�n XFL3 de la llamada a un m�dulo * @param stream * @param call */ private static void printModuleCall(PrintStream stream, ModuleCall call) { Variable[] inputvar = call.getInputVariables(); Variable[] outputvar = call.getOutputVariables(); stream.print(" "+call.getName()+"("); for(int i=0; i<inputvar.length; i++) { stream.print( (i==0? "": ", ") ); stream.print((inputvar[i] == null? "null" : inputvar[i].getName())); } stream.print( " : " ); for(int i=0; i<outputvar.length; i++) { stream.print( (i==0? "": ", ") ); stream.print( (outputvar[i] == null? "null" : outputvar[i].getName()) ); } stream.println(");"); } }