//--------------------------------------------------------------------------------//
// 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.xfsp.model.rulebases;
import java.util.ArrayList;
import java.util.List;
import xfuzzy.lang.Conclusion;
import xfuzzy.lang.Relation;
import xfuzzy.lang.Rule;
import xfuzzy.lang.Rulebase;
/**
* <p> <b>Descripci�n:</b> constructor de reglas contra�das equivalentes a una
* dada.
* <p> <b>E-mail</b>: <ADDRESS>joragupra@us.es</ADDRRESS>
* @author Jorge Agudo Praena
* @version 2.1
* @see IXfspRulebaseSimplifier
* @see XfspModel
* @see XfspRuleConverter
*
*/
public class XfspCompactBuilder
extends XfspRuleConverter {
//lista de reglas que tiene que ya procesado el constructor
private List list;
//nueva base de reglas expandida equivalente a la original
private Rulebase newrb;
/**
* <p> <b>Descripci�n:</b> crea un constructor de reglas expandidas
* equivalentes a una dada.
* @param rulebase Base de reglas a la que pertenencen las reglas que se le
* pasan al constructor mediante el m�tod buildRule.
*
*/
public XfspCompactBuilder(Rulebase rb) {
//inicializa la lista de reglas que quedan por procesar
list = new ArrayList();
//inicializa la nueva base de reglas como el clon de la original
//newrb = (Rulebase) rb.clone();
newrb = new Rulebase(rb.getName());
newrb.setOperatorset(rb.getOperatorset());
for(int i=0;i<rb.getInputs().length;i++){
newrb.addInputVariable(rb.getInputs()[i]);
}
for(int i=0;i<rb.getOutputs().length;i++){
newrb.addOutputVariable(rb.getOutputs()[i]);
}
}
/**
* <p> <b>Descripci�n:</b> transforma la regla indicada en un conjunto de
* reglas equivalentes en forma contra�da.
* @param rule Regla que se quiere transformar en otras equivalentes en forma
* contra�da para ser a�adida a la base de reglas que est� construyendo.
*
*/
public void buildRule(Rule rule) {
//permite recorrer la lista de reglas
int i = 0;
//indica si la regla que se est� procesando se tiene que insertar en la
//lista de reglas
boolean insert = false;
//mientras queden reglas por procesar y todav�a no se haya insertado la
//regla en la lista
while (i < list.size() && !insert) {
//si la regla que se est� procesando de la lista tiene la misma
//conclusi�n que la regla que se quiere transformar...
if (sameConclusions( (Rule) ( (List) list.get(i)).get(0), rule)) {
//...se indica que puede insertar la nueva regla en la posici�n
//i-�sima de la lista de reglas
insert = true;
}
//en otro caso...
else {
//...se sigue buscando
i++;
}
}
//si se puede insertar la regla a transformar en la lista de reglas...
if (insert) {
//...se a�ade a la lista en la posici�n encontrada
( (List) list.get(i)).add(rule);
}
//en otro caso...
else {
//...crea una nueva lista...
List newl = new ArrayList();
//...le a�ade la regla a transformar...
newl.add(rule);
//...y a�ade dicha lista a la lista de reglas tratadas
list.add(newl);
}
}
/**
* <p> <b>Descripci�n:</b> devuelve la base de reglas que se ha construido a
* partir de la original mediante contracci�n de las reglas que la formaban.
* @return Devuelve una base de reglas contra�da que contiene reglas
* equivalentes a las que se le han pasado por el m�todo type buildRule.
*
*/
public Rulebase getRulebase() {
//deja la nueva base de reglas vac�a de toda regla que pudiera contener
newrb.removeAllRules();
//recorre la lista que agrupa reglas por consecuentes iguales...
for (int i = 0; i < list.size(); i++) {
//...y obtiene una regla (por ejemplo, la primera) para el consecuente
//actual
Rule aux = (Rule) ( (List) list.get(i)).get(0);
//para todas las dem�s reglas que tienen el mismo consecuente...
for (int j = 1; j < ( (List) list.get(i)).size(); j++) {
//...crea una nueva premisa que consiste en la disyunci�n de la que ya
//exist�a antes y la de la regla actual
Relation premise = Relation.create(Relation.OR, aux.getPremise(),
( (Rule) ( (List) list.get(i)).get(j)).
getPremise(), null, null, newrb);
//obtiene la conclusi�n de la regla...
Conclusion[] conc = aux.getConclusions();
//...y crea una nueva regla con la premisa que acaba de crear...
aux = new Rule(premise);
//...y con las conclusiones que se obtuvieron antes
for (int k = 0; k < conc.length; k++) {
aux.add(conc[k]);
}
}
//elimina todas las reglas que se acaban de procesar de la nueva base de
//reglas...
for (int j = 0; j < ( (List) list.get(i)).size(); j++) {
newrb.remove( (Rule) ( (List) list.get(i)).get(j));
}
//...y le a�ade la nueva regla creada
newrb.addRule(aux);
}
return newrb;
}
/**
* <p> <b>Descripci�n:</b> comprueba las conclusiones de dos reglas son
* iguales.
* @param r1 Primera regla.
* @param r2 Segunda regla.
* @return Devuelve cierto si las conclusiones de las dos reglas son iguales
* y falso en caso contrario.
*
*/
private boolean sameConclusions(Rule r1, Rule r2) {
//resultado que se devolver� inicializado a cierto
boolean result = true;
//obtiene las conclusiones de la primera regla
Conclusion[] c1 = r1.getConclusions();
//obtiene las conclusiones de la segunda regla
Conclusion[] c2 = r2.getConclusions();
//si las reglas tienen un n�mero distinto de conclusiones...
if (c1.length != c2.length) {
//...entonces tienen distintas conclusiones
result = false;
}
//...en otro caso...
else {
//...comprueba que las dos reglas tienen las mismas conclusiones
//recorre todas las conclusiones de la primera regla...
for (int i = 0; i < c1.length && result; i++) {
//...y busca una conclusi�n de la segunda regla igual a la de la primera
boolean found = false;
for (int j = 0; j < c2.length && !found; j++) {
if (sameConclusion(c1[i], c2[j])) {
found = true;
}
}
//si no encontr� ninguna conclusi�n de la segunda regla igual a la de
//la primera...
if (!found) {
//...las dos reglas no tienen las mismas conclusiones
result = false;
}
}
}
return result;
}
/**
* <p> <b>Descripci�n:</b> comprueba si dos reglas son iguales.
* @param c1 Primera conclusi�n.
* @param c2 Segunda conclusi�n.
* @return Devuelve cierto si las dos conclusiones son iguales y falso en
* caso contrario.
*
*/
private boolean sameConclusion(Conclusion c1, Conclusion c2) {
//resultado que se devolver� inicializado a cierto
boolean result = true;
//si la variable de la primera conclusi�n es distinta de la de la segunda...
if (!c1.getVariable().getName().equals(c2.getVariable().getName())) {
//...las conclusiones son distintas
result = false;
}
//en otro caso...
else {
//...si la funci�n de pertenencia de la primera conclusi�n es distinta de
//la segunda...
String lb2 = c2.getMembershipFunction().getLabel();
if (!c1.getMembershipFunction().equals(lb2)) {
//...las conclusiones son distintas
result = false;
}
}
return result;
}
}