/* * * Copyright (c) 2013 - 2014 INT - National Institute of Technology & COPPE - Alberto Luiz Coimbra Institute - Graduate School and Research in Engineering. * See the file license.txt for copyright permission. * */ package motorInferencia; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import exception.motorInferencia.MotorInferenciaException; import service.anotacao.Transacional; import util.Constantes; import xfuzzy.lang.AggregateMemFunc; import xfuzzy.lang.LinguisticLabel; import xfuzzy.lang.MemFunc; import xfuzzy.lang.ParamMemFunc; import xfuzzy.lang.Rule; import xfuzzy.lang.Rulebase; import xfuzzy.lang.RulebaseCall; import xfuzzy.lang.Specification; import xfuzzy.lang.Type; import xfuzzy.lang.Variable; import xfuzzy.lang.XflParser; /** * Classe respons�vel pela interface entre a aplicacao e a biblioteca XFuzzy * * * @author felipe.arruda * */ public class MotorInferencia { public static final int NUM_VARIAVEIS_ENTRADA = 2; public static final String PATH_MODELAGEM_DEFAULT = "C:\\gesplan2010WorkComFuzzy\\xFuzzyGesplanConsole\\src\\xfl\\gesplan.xfl"; /** * Representa uma modelagem j� carregada pelo sistema, no caso a ultima que foi carregada * por essa instancia do motor de inferencia. */ private Specification modelagemCarregada; public MotorInferencia() { } /** * A partir da informa��o do nome do arquivo que contem a modelagem (*.xfl), * abre o arquivo .xfl indicado. <br/> * instancia a classe parser que vai armazenar a modelagem usando o m�todo * parser.parse. * * Coloca a modelagemCarregada como sendo essa modelagem recem carregada. * atualizando assim a variavel para ser a ultima modelagem carregada com sucesso. * devolve como retorno o objeto da classe Specification que * contem a modelagem. * * * @param nomeArqModelagem * @return * @throws MotorInferenciaException */ public Specification carregarModelagem(String nomeArqModelagem) throws MotorInferenciaException { String caminhoDoArquivo = Constantes.CAMINHO_ABSOLUTO_MODELAGEM_UPLOADFILE; caminhoDoArquivo = caminhoDoArquivo + nomeArqModelagem; File file = new File(caminhoDoArquivo); XflParser parser = new XflParser(); // converte o arquivo XFL para uma Specification Specification modelagem = parser.parse(file.getAbsolutePath()); if (modelagem == null) { modelagem =null; file=null; throw new MotorInferenciaException( "motorInferencia.INCONSISTENCIA_MODELAGEM"); } //Coloca a modelagemCarregada como sendo essa modelagem recem carregada. //atualizando assim a variavel para ser a ultima modelagem carregada com sucesso. this.modelagemCarregada = modelagem; return modelagem; } /** * Verifica se j� possui possui uma modelagem carregada e se o parametro de * usar modelagem carregada � verdadeiro, se for o caso ent�o utiliza a modelagemCarregada * como a modelagem a ser executada. * Caso n�o seja verdadeiro entao carrega o arquivo de modelagem fuzzy (*.xfl) * Depois, independente da modelagem que foi carregada: * executa o motor de * infer�ncia considerando o vetor de double fornecido como input * (inputValue) </br> - obtem o conjunto fuzzy resultante </br> - executa a * defuzzifica��o para obter o valor crisp resultante do motor de infer�ncia * </br> e devolve um vetor de double como saida </br> * * @param inputValue * @return * @throws MotorInferenciaException */ public double[] executaMotorDeInferencia(double[] inputValue, String nomeArqModelagem) throws MotorInferenciaException { Specification modelagem; //se tiver alguma modelagem j� carregada nesse motor de inferencia //e se a variavel de usarModelagemCarregada for verdadeira, e se tem o mesmo nome de arquivo. //usa a mesma para fazer a execucao. if(this.modelagemCarregada != null && (this.modelagemCarregada.getFile().getName().equals(nomeArqModelagem))){ modelagem = this.modelagemCarregada; } //caso contrario carrega arquivo de modelagem .xfl else{ modelagem = carregarModelagem(nomeArqModelagem); } // executa o motor de infer�ncia e retorna o resultado num vetor // result[]da classe MemFunc MemFunc result[] = null; try { result = modelagem.getSystemModule().fuzzyInference(inputValue); } catch (NullPointerException npe) { throw new MotorInferenciaException( "motorInferencia.INCONSISTENCIA_MODELAGEM"); } // cria um vetor de double com o n�mero de vari�veis correspondentes ao // length do vetor result double[] saida = new double[result.length]; // percorre o vetor de saida fazendo typecast de double para // AggregateMemFunc for (int i = 0; i < saida.length; i++) { double val = 0; // obtem o valor defuzzificado que representa essa fun��o de // pertinencia // no caso de ser singleton devolve a propria abcissa como sendo o // valor defuzzificado if (result[i] instanceof pkg.xfl.mfunc.singleton) { val = ((pkg.xfl.mfunc.singleton) result[i]).get()[0]; } else {// Obtem a funcao de pertinencia resultante da agregacao de // todas as regras // usa o metodo defuzzify para obter o valor defuzzificado desse // conjunto resultante // faz typecast de result para o tipo AggregateMemFunc AggregateMemFunc amf = (AggregateMemFunc) result[i]; val = amf.defuzzify(); } saida[i] = val; } return saida; } /** * Salva um arquivo de modelagem(.xfl) no caminhoDoArquivo como path. * Se j� existir um arquivo de modelagem com esse nome ele joga uma exception. * Se der erro na hora de salvar ele tambem joga exception. * * Esse metodo � static pois nao precisa ter uma instancia de motor de inferencia para salvar um arquivo. * @param caminhoDoArquivo * @param data * @throws MotorInferenciaException */ @Transacional public static void salvarArquivoModelagem(String caminhoDoArquivo, byte [] data) throws MotorInferenciaException { //verifica se ja existe um arquivo com esse nome try { FileInputStream input; input = new FileInputStream(caminhoDoArquivo); //caso ja exista joga uma excecao ai throw new MotorInferenciaException("modelagem.NOME_ARQUIVO_MODELAGEM_EXISTENTE"); } catch (FileNotFoundException e) { //isso quer dizer que ele pode salvar o arquivo sem sobreescrever outro. } //pode salvar sem problemas, pois ainda n�o existe arquivo com esse nome. OutputStream out; try { out = new FileOutputStream(caminhoDoArquivo); //salva, escrevendo os dados no arquivo. out.write(data); out.close(); } catch (FileNotFoundException e) { //caso a pasta onde esta tentando salvar nao exista ele entra aqui. throw new MotorInferenciaException("modelagem.ERRO_CAMINHO_INCORRETO_ARQUIVO_MODELAGEM"); } catch(IOException error){ throw new MotorInferenciaException("modelagem.ERRO_ESCRITA_ARQUIVO_MODELAGEM"); } } /** * Remove um arquivo de modelagem no caminho do arquivo passado como parametro * Se nao deletar ou se o arquivo nao existir joga exception. * * Esse metodo � static pois nao precisa ter uma instancia de motor de inferencia para remover um arquivo. * @param caminhoDoArquivo * @throws MotorInferenciaException */ @Transacional public static void removerArquivoModelagem(String caminhoDoArquivo) throws MotorInferenciaException { //um arquivo de modelagem que representa o suposto arquivo que sera deletado File arquivoModelagem = new File(caminhoDoArquivo); // ter certeza que o arquivo existe. if (!arquivoModelagem.exists()) throw new MotorInferenciaException("modelagemFuzzy.ARQUIVO_NAO_ENCONTRADO"); // tenta deletar o arquivo boolean deletou = arquivoModelagem.delete(); if (!deletou) throw new MotorInferenciaException("modelagemFuzzy.ERRO_DELECAO_ARQUIVO"); System.out.println("Deletou arquivo: " + caminhoDoArquivo); } public Specification getModelagemCarregada() { return modelagemCarregada; } public void setModelagemCarregada(Specification modelagemCarregada) { this.modelagemCarregada = modelagemCarregada; } /** * Retorna uma string que representa o arquivo de xfl * @param modelagem * @return */ public static String imprimeModelagem(Specification modelagem) { String conteudo = modelagem.toXfl(); return conteudo; } /** * Retorna uma string que representa o as regras da modelagem * @param modelagem * @return */ public static String imprimeRegras(Specification modelagem) { String conteudo = ""; Rulebase[] basesDeRegras = modelagem.getRulebases(); // para cada base de regras imprime o conjunto de suas regras // no nosso caso so temos uma base de regras entao basesDeRegras.length // = 1 for (int i = 0; i < basesDeRegras.length; i++) { conteudo += "NOME DA BASE DE REGRAS: "; conteudo += basesDeRegras[i].getName() + "\n"; // obtem o vetor de regras desta base de regras // regras = conjunto de todas as regras de uma basesDeRegras Rule[] regras = basesDeRegras[i].getRules(); conteudo += "\n**** REGRAS **** \n"; // //no nosso caso temos aproximadamente 80 regras entao // regras.length = 80 for (int j = 0; j < regras.length; j++) { conteudo += "\t" + regras[j].toXfl() + "\n"; } } return conteudo; } /** * Retorna uma string que representa os operadores do xfl * @param modelagem * @return */ public static String imprimeOperadores(Specification modelagem) { String conteudo = ""; Rulebase[] basesDeRegras = modelagem.getRulebases(); //para cada base de regras imprime o conjunto de suas regras //no nosso caso so temos uma base de regras entao basesDeRegras.length = 1 for(int i =0; i < basesDeRegras.length;i++){ conteudo += "NOME DA BASE DE REGRAS: "; conteudo += basesDeRegras[i].getName()+ "\n"; conteudo += "\n**** OPERADORES **** \n"; conteudo += basesDeRegras[i].operation.toXfl(); } return conteudo; } /** * Retorna uma string que representa os limites do xfl * @param modelagem * @return */ public static String imprimeLimites(Specification modelagem) { String conteudo = ""; //IMPRESSAO DO UNIVERSO DO DISCURSO DE TODAS AS VARIAVEIS LINGUISTICAS Type[] variaveisLinguisticas = modelagem.getTypes(); //executa o loop para todas as variaveis linguisticas for(int varLing=0; varLing < variaveisLinguisticas.length;varLing++){ //pega as informacoes do universo do discurso da variavel linguistica corrente. double min = variaveisLinguisticas[varLing].getUniverse().min(); double max = variaveisLinguisticas[varLing].getUniverse().max(); double card = variaveisLinguisticas[varLing].getUniverse().card(); conteudo += "VARI�VEL LINGU�STICA: "; conteudo += variaveisLinguisticas[varLing].getName(); conteudo += "\n**** UNIVERSO DO DISCURSO ****\n"; conteudo += "\t"+"- M�nimo: " + min+"\n"; conteudo += "\t"+"- M�ximo: " + max+"\n"; conteudo += "\t"+"- Cardinalidade: " + card+"\n\n\n"; } return conteudo; } /** * Retorna uma string que representa as funcoes de pertinencia do xfl * @param modelagem * @return */ public static String imprimeMF(Specification modelagem) { String conteudo = ""; //IMPRESSAO DAS FUNCOES DE PERTINENCIA DE TODAS AS VARIAVEIS LINGUISTICAS Type[] variaveisLinguisticas = modelagem.getTypes(); //executa o loop para todas as variaveis linguisticas for(int varLing=0; varLing < variaveisLinguisticas.length;varLing++){ double min = variaveisLinguisticas[varLing].getUniverse().min(); double max = variaveisLinguisticas[varLing].getUniverse().max(); double card = variaveisLinguisticas[varLing].getUniverse().card(); LinguisticLabel[] mf = variaveisLinguisticas[varLing].getAllMembershipFunctions(); conteudo += "**** VARI�VEL LINGU�STICA ==> "; conteudo += variaveisLinguisticas[varLing].getName()+" ****"; conteudo += "\n\t**** TERMOS LINGUISTICOS ****"; //mf.length devolve o n�mero de termos lingu�sticos desta vari�vel lingu�stica //type.length devolve o n�mero de vari�veis linguisticas //na vari�vel produ��o por exemplo teremos mf.length = 11 (ou seja, teremos 11 termos lingu�sticos) for(int termosLing=0; termosLing<mf.length; termosLing++) { conteudo += "\n"; conteudo += "\t - " + mf[termosLing].toXfl(); } conteudo += "\n\n\n"; } return conteudo; } /** * Retorna uma lista de Regras de uma modelagem * Por padrao esta pegando sempre e unicamente a base de regras(RuleBase) 0. * Isso �: Pegando apenas a primeira base de regras do sistema. * * @param modelagem * @return */ public static ArrayList<Rule> recuperaListaRegras(Specification modelagem){ ArrayList<Rule> regras = new ArrayList<Rule>(); for (Rule rule : modelagem.getSystemModule().getRulebaseCalls()[0].getRulebase().getRules()){ regras.add(rule); } return regras; } /** * Retorna uma lista de Degree da modelagem carregada * Por padrao esta pegando sempre e unicamente a base de regras(RuleBase) 0. * Isso �: Pegando apenas a primeira base de regras do sistema. * * @param modelagem * @return */ public ArrayList<Double> recuperaListaDegree(){ ArrayList<Double> degree = new ArrayList<Double>(); if(this.modelagemCarregada==null) return null; double [] degreesEmVec = this.modelagemCarregada.getSystemModule().getRulebaseCalls()[0].getDegree(); if(degreesEmVec== null){ return null; } for (Double valor : degreesEmVec){ degree.add(valor); } return degree; } /** * Retorna uma lista de Variables de input de uma modelagem * @param modelagem * @return */ public static ArrayList<Variable> recuperaListaVariaveisInput(Specification modelagem){ ArrayList<Variable> variaveis = new ArrayList<Variable>(); for (Variable variable : modelagem.getSystemModule().getInputs()){ variaveis.add(variable); } return variaveis; } /** * Retorna uma lista de Variables de output de uma modelagem * @param modelagem * @return */ public static ArrayList<Variable> recuperaListaVariaveisOutput(Specification modelagem){ ArrayList<Variable> variaveis = new ArrayList<Variable>(); for (Variable variable : modelagem.getSystemModule().getOutputs()){ variaveis.add(variable); } return variaveis; } /** * Retorna uma variavel(Variable) ou null(caso nao encontre) que tenha o mesmo nome da string nomeVariavel, dada uma modelagem * @param modelagem * @return */ public static Variable recuperaVariavelPorNome(String nomeVariavel,Specification modelagem){ for (Variable variable : modelagem.getSystemModule().getVariables()){ if(variable.getName().equals(nomeVariavel)) return variable; } return null; } /** * Retorna o indice de uma variavel(Variable) ou -1(caso nao encontre) que tenha o mesmo nome da string nomeVariavel, dada uma modelagem * Na lista de variaveis de input * @param modelagem * @return */ public static int recuperaIndiceVariavelInputPorNome(String nomeVariavel,Specification modelagem){ for (int i=0;i< modelagem.getSystemModule().getInputs().length;i++){ Variable variable = modelagem.getSystemModule().getInputs()[i]; if(variable.getName().equals(nomeVariavel)) return i; } return -1; } /** * Retorna o indice de uma variavel(Variable) ou -1(caso nao encontre) que tenha o mesmo nome da string nomeVariavel, dada uma modelagem * Na lista de variaveis de output * @param modelagem * @return */ public static int recuperaIndiceVariavelOutputPorNome(String nomeVariavel,Specification modelagem){ for (int i=0;i< modelagem.getSystemModule().getOutputs().length;i++){ Variable variable = modelagem.getSystemModule().getOutputs()[i]; if(variable.getName().equals(nomeVariavel)) return i; } return -1; } /** * recupera a primeira rulebasecall da modelagem carregada * @return */ public RulebaseCall recuperaPrimeiraRuleBaseCall(){ if(this.modelagemCarregada==null) return null; return this.modelagemCarregada.getSystemModule().getRulebaseCalls()[0]; } }