//--------------------------------------------------------------------------------// // 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; import java.awt.Point; import java.io.File; import java.util.ArrayList; import java.util.List; import javax.swing.JFileChooser; import javax.swing.filechooser.FileNameExtensionFilter; import xfuzzy.Xfuzzy; import xfuzzy.lang.Rulebase; import xfuzzy.lang.Specification; import xfuzzy.lang.Type; import xfuzzy.util.JFileChooserConfig; import xfuzzy.util.XDialog; import xfuzzy.xfsp.Xfsp; import xfuzzy.xfsp.XfspEvent; import xfuzzy.xfsp.controller.XfspController; import xfuzzy.xfsp.controller.XfspStore; import xfuzzy.xfsp.model.rulebases.IXfspRulebaseSimplifier; import xfuzzy.xfsp.model.rulebases.IXfspRulebaseSimplifierFactory; import xfuzzy.xfsp.model.rulebases.XfspRulebaseSimplifierFactory; import xfuzzy.xfsp.model.types.IXfspTypeSimplifier; import xfuzzy.xfsp.model.types.IXfspTypeSimplifierFactory; import xfuzzy.xfsp.model.types.XfspTypeSimplifierFactory; import xfuzzy.xfsp.view.XfspView; /** * <p> <b>Descripci�n:</b> Modelo del sistema de simplificaci�n de sistemas * difusos que gestiona los distintos tipos de simplificaci�n que se pueden * hacer. Es completamente independiente de la representaci�n que se haga * mediante vistas. * <p> <b>E-mail</b>: <ADDRESS>joragupra@us.es</ADDRRESS> * @author Jorge Agudo Praena * @version 4.1 * @see XfspController * @see XfspView * */ public class XfspModel { //referencia al objeto de tipo Xfuzzy que solicit� la simplificaci�n del //sistema private Xfuzzy xfuzzy; //especificaci�n original del sistema que permite deshacer cambios realizados private Specification original; //especificaci�n sobre la que trabajar� el modelo para llevar a cabo los //procesos de simplificaci�n private Specification workingcopy; //almac�n donde enviar los eventos destinados a las vistas para su //procesamiento por los controladores private XfspStore store; //conjunto de controladores registrados por el modelo private List controller; /** * <p> <b>Descripci�n:</b> crea una modelo a partir de un objeto de tipo * <b>Xfuzzy</b> indic�ndole el almac�n donde debe guardar los mensajes que * quiera enviar a las vistas para que puedan ser procesados por un * controlador. * @param xfuzzy Solicitante de simplificaci�n de tipos a trav�s de la * ventana principal de la aplicaci�n. * @param store Almac�n donde hay que enviar los mensajes para que puedan ser * procesados convenientemente por alg�n controlador. * */ public XfspModel(Xfuzzy xfuzzy, Specification spec, XfspStore store) { //establece la ventana principal de la aplicaci�n que sollicit� la //simplificaci�n de un sistema difuso this.xfuzzy = xfuzzy; //establece la copia de trabajo para llevar a cabo los procesos de //simplificaci�n this.workingcopy = xfuzzy.duplicate(spec); //hace una copia del sistema original this.original = spec; //xfuzzy.duplicate(spec); //con este constructor no se necesita parser, pues ya tiene la //especificaci�n del sistema a simplificar //this.parser = null; //establece el almac�n donde guardar los mensajes para que sean procesados //por los controladores this.store = store; //inicializa a lista de controladores registrados por el modelo this.controller = new ArrayList(); } /** * <p> <b>Descripci�n:</b> hace que el modelo registre un nuevo controlador * para procesar los mensajes que quiera enviar a las vistas. En caso de que * el controlador ya estuviera registrado por el modelo, este m�todo no hace * nada. * @param controller Nuevo controlador que debe registrar el modelo. * */ public void registerController(XfspController controller) { //inicializa un booleano a falso que nos indicar� si ha encontrado el //controlador entre los registrados por el modelo boolean found = false; //�ndice que permitir� recorrer todos los controladores registrados por //el modelo hasta el momento int i = 0; //recorre todos los controladores registrados por el modelo hasta que //encuentre uno igual al que se quiere a�adir o bien no quede ninguno por //comprobar while ((i < this.controller.size()) && (found == false)) { //si el controlador actual coincide con el que se quiere a�adir a los //registrados por el modelo... if (controller == this.controller.get(i)) { //...sale dell bucle de b�squeda y no hace nada m�s found = true; } //si el controlador actual no es igual al que se quiere a�adir... else { //...sigue buscando i++; } } //si no ha encontrador el controlador que se quiere a�adir entre los que ya //estaban registrados por el modelo... if (found == false) { //...a�ade el controlador nuevo a los que debe registrar el modelo this.controller.add(controller); } } /** * <p> <b>Descripci�n:</b> devuelve el objeto xfuzzy utilizado por el modelo * para hacer las copias del sistema que est� modificando. * @return Devuelve un objeto de la clase Xfuzzy que est� siendo utilizado * por el modelo para la realizaci�n de copias de sistemas. * */ public Xfuzzy getXfuzzy() { return this.xfuzzy; } /** * <p> <b>Descripci�n:</b> establece un nuevo objeto xfuzzy para que el * modelo pueda realizar las copias necesarias del sistema que est� * modifiando. * @param xfuzzy Nuevo objeto de la clase Xfuzzy que ser� empleado por el * modelo para la realizaci�n de copias de sistemas difusos. * */ public void setXfuzzy(Xfuzzy xfuzzy) { this.xfuzzy = xfuzzy; } /** * <p> <b>Descripci�n:</b> devuelve la copia de trabajo que est� utilizando * el modelo para la simplificaci�n del sistema seleccionado por el usuario. * @return Una copia de trabajo del sistema que se quiere simplificar. * */ public Specification getWorkingcopy() { return this.workingcopy; } /** * <p> <b>Descripci�n:</b> establece una nueva copia de trabajo para que el * modelo pueda realizar su simplificaci�n. * @param spec Nueva copia de trabajo del sistema que se quiere simplificar * para que sea manipulada por el modelo. * */ public void setWorkingcopy(Specification spec) { this.workingcopy = spec; } /** * <p> <b>Descripci�n:</b> devuelve el almac�n de eventos que est� utilizando * el modelo. * @return Almac�n de eventos que est� utilizando el modelo para que sean * procesados por un controlador. * */ public XfspStore getStore() { return this.store; } /** * <p> <b>Descripci�n:</b> establece el almac�n de eventos que debe utilizar * el modelo. * @param store Nuevo almac�n de eventos que debe utilizar el modelo. * */ public void setStore(XfspStore store) { this.store = store; } /** * <p> <b>Descripci�n:</b> indica al modelo un controlador que ya no debe * tener regitrado. Si el controlador indicado no estaba siendo registrado por * el modelo, este m�todo no hace nada. * @param controller Controlador que debe dejar de tener registrado el modelo. * */ public void deleteController(XfspController controller) { //busca entre todos los controladores registrados por el modelo for (int i = 0; i < this.controller.size(); i++) { //si encuentra un controlador igual al indicado... if (controller == this.controller.get(i)) { //...lo elimina de la lista de controladores que tiene el modelo //registrados this.controller.remove(i); } } } /** * <p> <b>Descripci�n:</b> permite obtener la especificaci�n de un sistema * difuso con la que est� trabajando el modelo actualmente. * @return Especificaci�n con la que trabaja el modelo para lograr su * simplificaci�n. * */ public Specification getSpecification() { //devuelve la especificaci�n con la que le modelo est� trabajando return workingcopy; } /** * <p> <b>Descripci�n:</b> simplifica un tipo mediante el m�todo indicado y * tomando los argumentos establecidos por el usuario. * @param type Tipo que se quiere simplificar de la espeficiaci�n con la que * trabaja el modelo. * @param method M�todo de simplificaci�n de tipos que se debe utilizar. * @param args Argumentos que se deben utilizar para la simplificaci�n del * tipo. * */ public void simplifyType(Type type, String method, Object[] args) { //n�mero inicial de funciones de pertenencia que tiene el tipo antes de su //simplificaci�n int initialMFs = type.getMembershipFunctions().length; //simplificador de tipos de un sistema difuso IXfspTypeSimplifier ts; //crea un f�brica de objetos simplificadores de tipos IXfspTypeSimplifierFactory f = XfspTypeSimplifierFactory.getInstance(); //obtiene de la f�bria un simplificador de tipos seg�n el m�todo deseado //y que utilice los argumentos indicados ts = f.create(method, args); //ordena al simplificador de tipos que simplifique el tipo elegido y //actualice la especificaci�n con la que trabaja el modelo ts.simplify(type, this.workingcopy); //n�mero de funciones de pertenencia que tiene el tipo despu�s de su //simplificaci�n int finalMFs = type.getMembershipFunctions().length; //crea los argumentos para el refresco de las vistas... Object[] refreshArgs = new Object[3]; //...el primero de ellos son los tipos... refreshArgs[0] = this.workingcopy.getTypes(); //...el segundo las bases de reglas... refreshArgs[1] = this.workingcopy.getRulebases(); //...y el tercero el mensaje que se debe mostrar String[] msg = { "Process finished.", initialMFs + " membership functions reduced to " + finalMFs }; refreshArgs[2] = msg; //crea un nuevo evento que indica que las vistas deben regenerar el gr�fico //de simplificaci�n de tipos... XfspEvent ev = new XfspEvent("Refresh", refreshArgs); //...y lo almacena para que alg�n controlador pueda procesarlo store.store(ev); } /** * <p> <b>Descripci�n:</b> simplifica una base de reglas mediante el m�todo * indicado y tomando los argumentos establecidos por el usuario. * @param rulebase Base de reglas que se quiere simplificar de la * espeficiaci�n con la que trabaja el modelo. * @param method M�todo de simplificaci�n de tipos que se debe utilizar. * @param args Argumentos que se deben utilizar para la simplificaci�n del * tipo. * */ public void simplifyRulebase(Rulebase rulebase, String method, Object[] args) { //n�mero inicial de reglas que tiene la base de reglas antes de su //simplificaci�n int initialRules = rulebase.getRules().length; //crea un f�brica de objetos simplificadores de bases de reglas IXfspRulebaseSimplifierFactory f = XfspRulebaseSimplifierFactory .getInstance(); //obtiene de la f�bria un simplificador de bases de reglas seg�n el m�todo //deseado y que utilice los argumentos indicados IXfspRulebaseSimplifier s = f.create(method, args); //ordena al simplificador de bases de reglas que simplifique la base de //reglas elegida y actualice la especificaci�n con la que trabaja el modelo s.simplify(rulebase, this.workingcopy); //n�mero de reglas que tiene la base de reglas despu�s de su simplificaci�n int finalRules = rulebase.getRules().length; //crea los argumentos para el refresco de las vistas... Object[] refreshArgs = new Object[3]; //...el primero de ellos son los tipos... refreshArgs[0] = this.workingcopy.getTypes(); //...el segundo las bases de reglas... refreshArgs[1] = this.workingcopy.getRulebases(); //...y el tercero el mensaje que se debe mostrar String[] msg = { "Process finished.", initialRules + " rules transformed into " + finalRules + " equivalent rules" }; refreshArgs[2] = msg; //crea un nuevo evento que indica que las vistas deben regenerar el listado //reglas en la ventada de simplificaci�n de bases de reglas... XfspEvent ev = new XfspEvent("Refresh", refreshArgs); //...y lo almacena para que alg�n controlador pueda procesarlo store.store(ev); } /** * <p> <b>Descripci�n:</b> almacena el sistema con el que est� trabajando el * modelo de forma permanente en un fichero. * */ public void save() { //obtiene el fichero correspondiente a la especificaci�n original del //sistema File root = original.getFile(); //si no se puede obtener dicho fichero... if (root == null) { //...obtiene el directorio de trabajo de la aplicaci�n root = xfuzzy.getWorkingDirectory(); } JFileChooser chooser = new JFileChooser(root); JFileChooserConfig.configure(chooser); FileNameExtensionFilter filter = new FileNameExtensionFilter( "Xfuzzy system files (.xfl)", "xfl"); chooser.setFileFilter(filter); chooser.setSelectedFile(original.getFile()); chooser.setFileSelectionMode(JFileChooser.FILES_ONLY); chooser.setDialogTitle("Save System As ..."); if (chooser.showSaveDialog(null) != JFileChooser.APPROVE_OPTION) return; File file = chooser.getSelectedFile(); if (file.exists()) { String question[] = new String[2]; question[0] = "File " + file.getName() + " already exists."; question[1] = "Do you want to overwrite this file?"; if (!XDialog.showQuestion(null, question)) return; } //guarda la copia de trabajo del sistema en el fichero seleccionado workingcopy.save_as(file); //carga el nuevo fichero en el sistema xfuzzy xfuzzy.load(file); } /** * <p> <b>Descripci�n:</b> aplica al sistema original los cambios que se han * realizado sobre el sistema en el que trabaja el modelo. * */ public void apply() { //duplica la especificaci�n sobre la que trabaja el sistema Specification dup = xfuzzy.duplicate(workingcopy); //spec); //establece en el modelo original el conjunto de operadores del sistema //duplicado... original.setOperatorsets(dup.getOperatorsets()); //...el conjunto de tipos... original.setTypes(dup.getTypes()); //...las bases de reglas... original.setRulebases(dup.getRulebases()); //...y los m�dulos del sistema original.setSystemModule(dup.getSystemModule()); //indica que el sistema original ha sido modificado original.setModified(true); } /** * <p> <b>Descripci�n:</b> reestablece el sistema original sobre la copia de * trabajo del modelo. * @param location Localizaci�n en la pantalla que debe ocupar la vista tras * reestablecer el sistema original. * */ public void reload(Point location) { //crea un nuevo evento que solicita el cierre del sistema... XfspEvent ev = new XfspEvent("Close", null); //...y lo almacena en el almac�n store.store(ev); //crea un nuevo sistema de simplificaci�n... Xfsp newInstance = new Xfsp(this.xfuzzy, this.original, location); //...y lo muestra en pantalla newInstance.show(); } /** * <p> <b>Descripci�n:</b> termina la simplificaci�n del sistema devolviendo * el sistema con el que se estaba trabajando al estado que ten�a el sistema * original. * */ public void close() { //cambia el conjunto de operadores de la especificaci�n del sistema con el //que estaba trabajando el modelo por el del sistema original... workingcopy.setOperatorsets(original.getOperatorsets()); //...el conjunto de tipos utilizados... workingcopy.setTypes(original.getTypes()); //...el conjunto de bases de reglas... workingcopy.setRulebases(original.getRulebases()); //...y el conjunto de m�dulos del sistema workingcopy.setSystemModule(original.getSystemModule()); } }