//--------------------------------------------------------------------------------// // 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.xfsw; import xfuzzy.lang.*; /** * Clase que estudia las funciones que realmente se utilizan en un * sistema difuso * * @author Francisco Jos� Moreno Velo * */ public class XfswDataUsage { //----------------------------------------------------------------------------// // MIEMBROS PRIVADOS // //----------------------------------------------------------------------------// /** * Sistema difuso a estudiar */ private Specification spec; /** * Funciones de pertenencia utilizadas en el sistema */ private ParamMemFunc[] mflist; /** * Lista de los nombres de las funciones de pertenencia * utilizadas en el sistema */ private String[] mfnames; /** * Marcadores para indicar la utilizaci�n del modificador * mayor_o_igual sobre una funci�n de pertenencia */ private boolean[] mfgreq; /** * Marcadores para indicar la utilizaci�n del modificador * menor_o_igual sobre una funci�n de pertenencia */ private boolean[] mfsmeq; /** * Marcadores para indicar la utilizaci�n del m�todo center * sobre una funci�n de pertenencia */ private boolean[] mfcenter; /** * Marcadores para indicar la utilizaci�n del m�todo basis * sobre una funci�n de pertenencia */ private boolean[] mfbasis; /** * Marcadores para indicar la utilizaci�n del m�todo param * sobre una funci�n de pertenencia */ private boolean[] mfparam; /** * Familias de funciones de pertenencia utilizadas en el sistema */ private Family[] famlist; /** * Lista de los nombres de las familias de funciones de pertenencia * utilizadas en el sistema */ private String[] famnames; /** * Marcadores para indicar la utilizaci�n del modificador * mayor_o_igual sobre una familia de funciones de pertenencia */ private boolean[] famgreq; /** * Marcadores para indicar la utilizaci�n del modificador * menor_o_igual sobre una familia de funciones de pertenencia */ private boolean[] famsmeq; /** * Marcadores para indicar la utilizaci�n del m�todo center * sobre una familia de funciones de pertenencia */ private boolean[] famcenter; /** * Marcadores para indicar la utilizaci�n del m�todo basis * sobre una familia de funciones de pertenencia */ private boolean[] fambasis; /** * Marcadores para indicar la utilizaci�n del m�todo param * sobre una familia de funciones de pertenencia */ private boolean[] famparam; /** * Lista de tipos definidos en el sistema */ private Type[] type; /** * Marcadores para indicar si un tipo se utiliza en variables * de entrada de las bases de reglas */ private boolean[] inputtype; /** * Marcadores para indicar si un tipo se utiliza en variables * de salida de las bases de reglas */ private boolean[] outputtype; /** * Marcadores de los conjuntos de operadores */ private boolean[][] opsetflags; //----------------------------------------------------------------------------// // CONSTRUCTOR // //----------------------------------------------------------------------------// public XfswDataUsage(Specification spec) { this.spec = spec; Operatorset[] opset = spec.getOperatorsets(); this.opsetflags = new boolean[opset.length][7]; // Funciones de pertenencia createMFList(); int mfsize = mflist.length; this.mfgreq = new boolean[mfsize]; this.mfsmeq = new boolean[mfsize]; this.mfcenter = new boolean[mfsize]; this.mfbasis = new boolean[mfsize]; this.mfparam = new boolean[mfsize]; // Familias de funciones de pertenencia createFamilyList(); int famsize = famlist.length; this.famgreq = new boolean[famsize]; this.famsmeq = new boolean[famsize]; this.famcenter = new boolean[famsize]; this.fambasis = new boolean[famsize]; this.famparam = new boolean[famsize]; // Usos de las familias y funciones de pertenencia setUses(); // Usos de los tipos this.type = spec.getTypes(); this.inputtype = new boolean[type.length]; this.outputtype = new boolean[type.length]; setTypeUses(); } //----------------------------------------------------------------------------// // M�TODOS P�BLICOS // //----------------------------------------------------------------------------// /** * Verifica si los m�todos de concreci�n utilizados hacen uso * del m�todo "compute", referido al c�lculo del grado de pertenencia * de una salida como agregaci�n de implicaciones. * Esto lo usan los m�todos de concreci�n tipo "CenterOfArea" */ public boolean isComputeUsed() { Operatorset[] opset = spec.getOperatorsets(); for(int i=0; i<opset.length; i++) { if(isComputeUsed(opset[i].defuz)) return true; } return false; } /** * Obtiene los marcadores de un determinado conjunto de operadores * @param os * @return */ public boolean[] getOpsetUsages(Operatorset os) { int index = getIndex(os); return opsetflags[index]; } //----------------------------------------------------------------------------// // M�todos referidos a los usos de las funciones de pertenencia // //----------------------------------------------------------------------------// /** * Obtiene la lista de funciones de pertenencia utilizadas */ public ParamMemFunc[] getMFList() { return this.mflist; } /** * Obtiene el nombre utilizado para codificar la funci�n de * pertenencia * @param mf * @return */ public String getMFname(ParamMemFunc mf) { return "MF_"+mf.getPackageName()+"_"+mf.getFunctionName(); } /** * Verifica si se utiliza el modificador mayor_o_igual sobre * la funci�n de pertenencia * @param mf * @return */ public boolean isMFGreqUsed(String name) { int index = getIndex(mfnames, name); return this.mfgreq[index]; } /** * Verifica si se utiliza el modificador menor_o_igual sobre * la funci�n de pertenencia * @param mf * @return */ public boolean isMFSmeqUsed(String name) { int index = getIndex(mfnames, name); return this.mfsmeq[index]; } /** * Verifica si se utiliza el m�todo center sobre * la funci�n de pertenencia * @param mf * @return */ public boolean isMFCenterUsed(String name) { int index = getIndex(mfnames, name); return this.mfcenter[index]; } /** * Verifica si se utiliza el m�todo basis sobre * la funci�n de pertenencia * @param mf * @return */ public boolean isMFBasisUsed(String name) { int index = getIndex(mfnames, name); return this.mfbasis[index]; } /** * Verifica si se utiliza el m�todo param sobre * la funci�n de pertenencia * @param mf * @return */ public boolean isMFParamUsed(String name) { int index = getIndex(mfnames, name); return this.mfparam[index]; } //----------------------------------------------------------------------------// // M�todos referidos a los usos de las familias de funciones de pertenencia // //----------------------------------------------------------------------------// /** * Obtiene la lista de familias de funciones de pertenencia utilizadas */ public Family[] getFamilyList() { return this.famlist; } /** * Obtiene el nombre utilizado para codificar la familia de * funciones de pertenencia * @param fam * @return */ public String getFamilyName(Family fam) { return "FMF_"+fam.getPackageName()+"_"+fam.getFunctionName(); } /** * Verifica si se utiliza el modificador mayor_o_igual sobre * la familia de funciones de pertenencia * @param mf * @return */ public boolean isFamilyGreqUsed(String name) { int index = getIndex(famnames, name); return this.famgreq[index]; } /** * Verifica si se utiliza el modificador menor_o_igual sobre * la familia de funciones de pertenencia * @param mf * @return */ public boolean isFamilySmeqUsed(String name) { int index = getIndex(famnames, name); return this.famsmeq[index]; } /** * Verifica si se utiliza el m�todo center sobre * la familia de funciones de pertenencia * @param mf * @return */ public boolean isFamilyCenterUsed(String name) { int index = getIndex(famnames, name); return this.famcenter[index]; } /** * Verifica si se utiliza el m�todo basis sobre * la familia de funciones de pertenencia * @param mf * @return */ public boolean isFamilyBasisUsed(String name) { int index = getIndex(famnames, name); return this.fambasis[index]; } /** * Verifica si se utiliza el m�todo param sobre * la familia de funciones de pertenencia * @param mf * @return */ public boolean isFamilyParamUsed(String name) { int index = getIndex(famnames, name); return this.famparam[index]; } //----------------------------------------------------------------------------// // M�todos relacionados con los conjuntos de operadores //----------------------------------------------------------------------------// /** * Verifica si el m�todo de concreci�n utiliza la funci�n compute */ public boolean isComputeUsed(DefuzMethod defuz) { String code = defuz.getCCode(); return code.contains("compute"); } /** * Verifica si el m�todo de concreci�n utiliza la funci�n center * @param defuz * @return */ public boolean isCenterUsed(DefuzMethod defuz) { String code = defuz.getCCode(); return code.contains("center"); } /** * Verifica si el m�todo de concreci�n utiliza la funci�n basis * @param defuz * @return */ public boolean isBasisUsed(DefuzMethod defuz) { String code = defuz.getCCode(); return code.contains("basis"); } /** * Verifica si el m�todo de concreci�n utiliza la funci�n param * @param defuz * @return */ public boolean isParamUsed(DefuzMethod defuz) { String code = defuz.getCCode(); return code.contains("param"); } /** * Verifica si el m�todo de concreci�n utiliza los valores de las entradas * @param defuz * @return */ public boolean isInputUsed(DefuzMethod defuz) { String code = defuz.getCCode(); return code.contains("input"); } //----------------------------------------------------------------------------// // M�todos relacionados con los tipos de variables difusas // //----------------------------------------------------------------------------// /** * Verifica si un tipo de variable se utiliza como entrada */ public boolean isUsedAsInput(Type t) { for(int i=0; i<type.length; i++) if(type[i] == t) return inputtype[i]; return false; } /** * Verifica si un tipo de variable se utiliza como salida * @param t * @return */ public boolean isUsedAsOutput(Type t) { for(int i=0; i<type.length; i++) if(type[i] == t) return outputtype[i]; return false; } //----------------------------------------------------------------------------// // M�TODOS PRIVADOS // //----------------------------------------------------------------------------// /** * Busca las funciones de pertenencia incluidas */ private void createMFList() { this.mfnames = new String[0]; this.mflist = new ParamMemFunc[0]; Type[] type = spec.getTypes(); for(int i=0; i<type.length; i++) { ParamMemFunc[] mf = type[i].getParamMembershipFunctions(); for(int j=0; j<mf.length; j++) { String mfname = getMFname(mf[j]); if(!contains(mfnames,mfname)) { mfnames = addString(mfnames,mfname); mflist = addMF(mflist,mf[j]); } } } } /** * Busca las familias de funciones de pertenencia incluidas */ private void createFamilyList() { this.famnames = new String[0]; this.famlist = new Family[0]; Type[] type = spec.getTypes(); for(int i=0; i<type.length; i++) { Family[] fam = type[i].getFamilies(); for(int j=0; j<fam.length; j++) { String famname = getFamilyName(fam[j]); if(!contains(famnames, famname)) { famnames = addString(famnames, famname); famlist = addFamily(famlist,fam[j]); } } } } /** * A�ade una familia a una lista de familias * @param list * @param added * @return */ private Family[] addFamily(Family[] list, Family added) { Family[] aux = new Family[list.length+1]; System.arraycopy(list, 0, aux, 0, list.length); aux[list.length] = added; return aux; } /** * A�ade una funci�n de pertenencia a una lista de funciones de pertenencia * @param list * @param added * @return */ private ParamMemFunc[] addMF(ParamMemFunc[] list, ParamMemFunc added) { ParamMemFunc[] aux = new ParamMemFunc[list.length+1]; System.arraycopy(list, 0, aux, 0, list.length); aux[list.length] = added; return aux; } /** * A�ade una cadena a una lista de cadenas * @param list * @param added * @return */ private String[] addString(String[] list, String added) { String[] aux = new String[list.length+1]; System.arraycopy(list, 0, aux, 0, list.length); aux[list.length] = added; return aux; } /** * Estudia si una cadena est� incluida en una lista * @param list * @param element * @return */ private boolean contains(String[] list, String element) { for(int i=0; i<list.length; i++) if(list[i].equals(element)) return true; return false; } /** * Obtiene la posici�n de un nombre en una lista de nombres * @param mf * @return */ private int getIndex(String[] list, String name) { for(int i=0; i<list.length; i++) { if(list[i].equals(name)) return i; } return 0; } /** * Obtiene la posici�n de un conjunto de operadores * @param os * @return */ private int getIndex(Operatorset os) { Operatorset[] opsetlist = spec.getOperatorsets(); for(int i=0; i<opsetlist.length; i++) { if(opsetlist[i] == os) return i; } return 0; } /** * Calcula el valor de los marcadores de uso realizando un recorrido * sobre las bases de reglas * */ private void setUses() { Rulebase[] rulebase = this.spec.getRulebases(); for(int i=0; i<rulebase.length; i++) { Rule[] rule = rulebase[i].getRules(); Operatorset opset = rulebase[i].getOperatorset(); int opsetindex = getIndex(opset); opsetflags[opsetindex][6] = isComputeUsed(opset.defuz); boolean usesCenter = isCenterUsed(opset.defuz); boolean usesBasis = isBasisUsed(opset.defuz); boolean usesParam = isParamUsed(opset.defuz); for(int j=0; j<rule.length; j++) { setUses(rule[j].getPremise(),opsetindex); Conclusion[] conc = rule[j].getConclusions(); for(int k=0; k<conc.length; k++) setUses(conc[k],usesCenter,usesBasis, usesParam); } } } /** * Recorre el antecedente de una regla para calcular los marcadores * de uso * @param rel */ private void setUses(Relation rel, int osi) { int kind = rel.getKind(); LinguisticLabel label; switch(kind) { case Relation.AND: opsetflags[osi][0] = true; setUses(rel.getLeftRelation(),osi); setUses(rel.getRightRelation(),osi); break; case Relation.OR: opsetflags[osi][1] = true; setUses(rel.getLeftRelation(),osi); setUses(rel.getRightRelation(),osi); break; case Relation.NOT: opsetflags[osi][2] = true; setUses(rel.getLeftRelation(),osi); break; case Relation.MoL: opsetflags[osi][3] = true; setUses(rel.getLeftRelation(),osi); break; case Relation.SLIGHTLY: opsetflags[osi][4] = true; setUses(rel.getLeftRelation(),osi); break; case Relation.VERY: opsetflags[osi][5] = true; setUses(rel.getLeftRelation(),osi); break; case Relation.GR_EQ: case Relation.SMALLER: label = rel.getMembershipFunction(); if(label instanceof ParamMemFunc) { int index = getIndex(mfnames,getMFname( (ParamMemFunc) label)); mfgreq[index] = true; } else { Family fam = ((FamiliarMemFunc) label).getFamily(); int index = getIndex(famnames, getFamilyName(fam)); famgreq[index] = true; } break; case Relation.SM_EQ: case Relation.GREATER: label = rel.getMembershipFunction(); if(label instanceof ParamMemFunc) { int index = getIndex(mfnames,getMFname( (ParamMemFunc) label)); mfsmeq[index] = true; } else { Family fam = ((FamiliarMemFunc) label).getFamily(); int index = getIndex(famnames, getFamilyName(fam)); famsmeq[index] = true; } break; } } /** * Asigna los marcadores asociados a los consecuentes de las reglas * @param conc * @param center * @param basis * @param param */ private void setUses(Conclusion conc, boolean center, boolean basis, boolean param) { LinguisticLabel label = conc.getMembershipFunction(); if(label instanceof ParamMemFunc) { int index = getIndex(mfnames,getMFname( (ParamMemFunc) label)); if(center) mfcenter[index] = true; if(basis) mfbasis[index] = true; if(param) mfparam[index] = true; } else { Family fam = ((FamiliarMemFunc) label).getFamily(); int index = getIndex(famnames, getFamilyName(fam)); if(center) famcenter[index] = true; if(basis) fambasis[index] = true; if(param) famparam[index] = true; } } /** * Asigna los marcadores que indican si un tipo se utiliza como * entrada o como salida * */ private void setTypeUses() { Rulebase[] base = spec.getRulebases(); for(int i=0; i<base.length; i++) { Variable[] input = base[i].getInputs(); for(int j=0; j<input.length; j++) { Type itype = input[j].getType(); for(int k=0; k<type.length; k++) { if(type[k] == itype) inputtype[k] = true; } } Variable[] output = base[i].getOutputs(); for(int j=0; j<output.length; j++) { Type otype = output[j].getType(); for(int k=0; k<type.length; k++) { if(type[k] == otype) outputtype[k] = true; } } } } }