//--------------------------------------------------------------------------------//
// 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.xfvhdl;
import xfuzzy.lang.*;
import xfuzzy.xfsg.XfsgError;
import java.io.*;
import java.util.ArrayList;
/**
* Clase que gestiona la estructura que contiene la informaci�n
* de la base de reglas de cada m�dulo de inferencia del sistema jer�rquico.
*
* @author Lidia Delgado Carretero.
*
*/
public class XfvhdlRulesMemData {
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
// ATRIBUTOS PRIVADOS DE LA CLASE
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/**Guarda el contenido de la memoria de reglas.
* Estructura de vector:
* vector[_][0] ==> Almacena el n�mero de fila en binario.
* vector[_][1] ==> Almacena el valor de la mf que se activa en la salida.
* vector[_][2] ==> Almacena el peso (si se ha definido).
* vector[_][3] ==> Indica si la fila es v�lida o no.
* vector[_][4] ==> Almacena el nombre de la mf que se activa.*/
private Object vector[][]; // Estructura de datos
/**Estructura para almacenar las constantes en Takagi-sugeno*/
private Object tak_sug[][];
/**N�mero de filas de la estructura.*/
private int longitud;
/**N�mero de bits con los que se codifica el valor de entrada.*/
private int N;
/**N�mero de bits con los que se codifica el peso.*/
private int K;
/**Variables de entrada.*/
private Variable[] var_in; // Variables de entrada
/**Variables de salida.*/
private Variable[] var_output; // Variables de salida
/**Funciones de pertenencia de las variables de entrada ordenadas.*/
private XfvhdlInOrderParamMemFunc[] inOrderMfInput;
/**Funciones de pertenencia de la variable de salida ordenadas.*/
private XfvhdlInOrderParamMemFunc inOrderMfOutput;
private XfvhdlInOrderParamMemFunc[] inOrderMfOutput2;
/**Funciones de pertenencia usadas.*/
private int mfUsed[][];
private double val;
private double[] val2;
/**Lista con el n� de funciones de pertenencia de cada entrada.*/
private int [] n_mf_var;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
// CONSTRUCTOR DE LA CLASE
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/**
* Constructor de XFvhdlRulesMemData.
* Inicializa la estructura l�nea a l�nea a partir de los datos
* obtenidos de la base de reglas.
*
* NOTA: Cuando una l�nea de la estructura contiene datos la marca
* como verdadero y en caso contrario la marca como falso. Esto
* facilita la generaci�n de c�digo VHDL.
*/
public XfvhdlRulesMemData(int filas, int n, int kk, Specification spec,
String nombre_i, ArrayList<Integer> bits_var, boolean calculateWeights)
throws IOException {
int No=n;
int W=kk;
int regla_i=-1;
// Calcula la longitud de la estructura
longitud = (int) Math.pow((double) 2, (double) filas);
// Inicializa la estructura
vector = new Object[longitud][5];
this.N = n;
this.K = kk;
var_in = spec.getRulebases()[0].getInputs();
n_mf_var=new int[var_in.length];
for(int i=0;i<n_mf_var.length;i++){
n_mf_var[i]=var_in[i].getType().getAllMembershipFunctions().length;
}
// Obtiene las variables de entrada y salida de la base de reglas
Rulebase[] rulebases = spec.getRulebases();
for (int i=0;i<rulebases.length;i++){
if(rulebases[i].getName().equalsIgnoreCase(nombre_i))
regla_i=i;
}
// Ahora permitimos m�s de una base de reglas
//if (rulebases.length > 1) {
// XfvhdlError err = new XfvhdlError();
// err.newWarning(9);
//}
//Como ahora tenemos m�s de una base de reglas, tenemos que pasar el
//�ndice de la base de reglas
var_in = rulebases[regla_i].getInputs();
//Ahora tenemos que tener una lista de enteros con en n�mero de
//bits para cada entrada.
//bits_var = filas / var_in.length;
var_output = rulebases[regla_i].getOutputs();
// PARA N VARIABLES DE ENTRADA:
// PASO 1: Se crea la estructura inOrderMfInput[i] (donde el
// �ndice i direcciona las distintas variables de entrada)
// que contiene una lista con las funciones de pertenencia
// ordenadas
inOrderMfInput = new XfvhdlInOrderParamMemFunc[var_in.length];
for (int i = 0; i < var_in.length; i++) {
inOrderMfInput[i] = new XfvhdlInOrderParamMemFunc(var_in[i]);
inOrderMfInput[i].sort();
}
// PASO 2: Guarda en inOrderMfOutput las funciones de pertenencia
// ordenadas de la variable de salida
// SOLO VALIDO PARA 1 VARIABLE DE SALIDA
inOrderMfOutput = new XfvhdlInOrderParamMemFunc(var_output[0]);
inOrderMfOutput.sort();
// PASO 3: Guarda las reglas del sistema XFL en cprule
Rule[] cprule = rulebases[regla_i].getRules();
// PASO 4: Inicializa la estructura vector donde se guardar� el
// contenido de la memoria de reglas. Inicializa todas
// sus filas a false
//
// Estructura de vector:
// vector[_][0] ==> Almacena el n�mero de fila en binario
// vector[_][1] ==> Almacena el valor de la mf que se activa
// en la salida
// vector[_][2] ==> Almacena el peso (si se ha definido)
// vector[_][3] ==> Indica si la fila es v�lida o no
// vector[_][4] ==> Almacena el nombre de la mf que se activa
XfvhdlBinaryDecimal converter = new XfvhdlBinaryDecimal();
for (int i = 0; i < longitud; i++) {
vector[i][0] = converter.toBinary(i, filas);
vector[i][3] = new Boolean(false);
vector[i][4] = new String ("0");
}
// PASO 5: Se van recorriendo las reglas y se guarda su informaci�n en
// vector
mfUsed = new int[var_in.length][2];
for (int k = 0; k < cprule.length; k++) {
// Obtiene el consecuente
Conclusion conc[] = cprule[k].getConclusions();
if (conc.length == 0) {
new XfvhdlError(13, "" + k);
}
// Inicializa mfUsed
for (int i = 0; i < mfUsed.length; i++){
mfUsed[i][0] = -1;
mfUsed[i][1] = -1;
}
Relation left = null;
Relation right = null;
// Aseguramos que la regla es de tipo AND o IS
Relation rl = cprule[k].getPremise();
if (rl.getKind() != Relation.AND && rl.getKind() != Relation.IS
&& rl.getKind()!=Relation.GREATER
&& rl.getKind()!=Relation.GR_EQ && rl.getKind()!=Relation.SMALLER
&& rl.getKind()!=Relation.SM_EQ && rl.getKind()!=Relation.ISNOT) {
new XfvhdlError(10, "" + k);
//err.show();
return;
} else if (rl.getKind() == Relation.IS
|| rl.getKind()==Relation.GREATER
|| rl.getKind()==Relation.GR_EQ || rl.getKind()==Relation.SMALLER
|| rl.getKind()==Relation.SM_EQ || rl.getKind()==Relation.ISNOT) {
left = rl;
} else {
// parte izquierda
left = rl.getLeftRelation();
// parte derecha
right = rl.getRightRelation();
}
// calcula las mf usadas
getMfUsed(left, right, k);
// averigua la conclusion
int pos_c = 0;
ParamMemFunc c = null;
try {
c = (ParamMemFunc) conc[0].getMembershipFunction();
} catch(Exception ex) {
new XfvhdlError(31);
}
// averiguA de qu� mf se trata dentro de la variable de salida
// Y LA GUARDO EN TMP
boolean enc = false;
ParamMemFunc tmp;
for (kk = 0;
kk < inOrderMfOutput.getInOrderParamMemFunc().size() && !enc;
kk++) {
tmp =
(ParamMemFunc) inOrderMfOutput
.getInOrderParamMemFunc()
.get(
kk);
val = tmp.center();
if (c != null && tmp.equals(c.getLabel())) {
pos_c = kk;
enc = true;
}
}
// PASO 6: Guarda la informaci�n correspondiente en vector
XfvhdlVectorCount v =
new XfvhdlVectorCount(
var_in.length,
n_mf_var,
mfUsed);
int tmp1, tmp2;
String aux = new String();
for (int tt = 0; tt < var_in.length; tt++) {
tmp1 = v.get(tt);
aux += converter.toBinary(tmp1, bits_var.get(tt));
}
tmp2 = converter.toDecimal(aux);
ParamMemFunc p;
double _min=0, _max=0;
p = inOrderMfOutput.getParamMemFunc(pos_c);
_min = p.universe().min();
_max = p.universe().max();
vector[tmp2][1] = converter.toBinaryInRange(val, _min, _max, No);
vector[tmp2][3] = new Boolean(true);
vector[tmp2][4] = p.getLabel();
// calcula el peso
if (calculateWeights == true) {
vector[tmp2][2] =
converter.toBinaryInRange(
calculateWeight(pos_c),
0.0,
1.0,
W);
}
while (v.sub()) {
aux = "";
for (int tt = 0; tt < var_in.length; tt++) {
tmp1 = v.get(tt);
aux += converter.toBinary(tmp1, bits_var.get(tt));
}
tmp2 = converter.toDecimal(aux);
// vector[tmp2][1] = converter.toBinary(pos_c, N);
vector[tmp2][1] = converter.toBinaryInRange(val, _min, _max, No);
vector[tmp2][3] = new Boolean(true);
vector[tmp2][4] = p.getLabel();
// calcula el peso
if (calculateWeights == true) {
vector[tmp2][2] =
converter.toBinaryInRange(
calculateWeight(pos_c),
0.0,
1.0,
W);
}
}
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
// M�TO_DOS P�BLICOS DE LA CLASE
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/**
* M�todo que modifica el valor de una l�nea dada. Si la l�nea
* estaba inactiva, la activa.
* @param line L�nea a la que se le actualizar� el valor.
* @param value Nuevo valor que se le asignar� a la l�nea.
*/
public void setValue(int line, int value) {
// Crea un objeto conversor de formatos
XfvhdlBinaryDecimal converter = new XfvhdlBinaryDecimal();
// Modifica el valor de la l�nea
vector[line][1] = converter.toBinary(value, N);
if (!isActive(line)) {
vector[line][3] = new Boolean(true);
}
}
/**
* M�todo que modifica el peso de una l�nea dada. Si la l�nea estaba
* inactiva, la activa.
*/
public void setWeight(int line, int weight) {
// Crea un objeto conversor de formatos
XfvhdlBinaryDecimal converter = new XfvhdlBinaryDecimal();
// Modifica el peso de la l�nea
vector[line][2] = converter.toBinary(weight, K);
if (!isActive(line)) {
vector[line][3] = new Boolean(true);
}
}
/**
* M�todo que obtiene el valor de una l�nea dada.
*/
public String getValue(int line) {
return (String) vector[line][1];
}
/**
* M�todo que obtiene el peso de una l�nea dada.
*/
public String getWeight(int line) {
return (String) vector[line][2];
}
/**
* M�todo que obtiene la funci�n de pertenencia de una linea dada.
*/
public String getMF(int line) {
return (String) vector[line][4];
}
/**
* M�todo que obtiene cualquier elemento de vector de una linea dada.
*/
public String getMF2(int line, int j) {
return (String) vector[line][j];
}
/**
* M�todo para obtener una l�nea de la estructura (s�lo el nombre).
*/
public String getLine(int line) {
String l = new String();
l = getBinaryData(line);
return l;
}
/**
* M�todo para obtener una l�nea de la estructura (nombre,valor y peso).
*/
public String getLineComplete(int line) {
String l = new String();
l = getBinaryData(line) + getValue(line) + getWeight(line);
return l;
}
/**
* M�todo para obtener el estado de una l�nea.
*/
public boolean isActive(int line) {
Object o;
Boolean b;
o = vector[line][3];
b = (Boolean) o;
return b.booleanValue();
}
public boolean isActive2(int line) {
return ((Boolean)vector[line][1]).booleanValue();
}
/**
* M�todo para imprimir por pantalla el contenido de la estructura.
*/
public void toScreen() {
for (int i = 0; i < longitud; i++)
System.out.println(
vector[i][0]
+ " "
+ vector[i][1]
+ " "
+ vector[i][2]
+ " "
+ vector[i][3]
+ " "
+ vector[i][4]
+ " ");
}
public void toScreen2() {
for (int i = 0; i < longitud; i++){
for(int j=0;j<vector[i].length;j++){
System.out.print(vector[i][j]+" ");
}
System.out.println(" ");
}
}
/**
* M�todo para obtener el n�mero de l�neas de la estructura.
*/
public int getLength() {
return longitud;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
// M�TO_DOS PRIVADOS DE LA CLASE
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/**
* M�todo privado para obtener el valor binario de una l�nea.
*/
private String getBinaryData(int line) {
return (String) vector[line][0];
}
/**Le da valor a la variable mfUsed.*/
private void getMfUsed(Relation left, Relation right, int nrule) {
int min=0,max=0;
if ((left.getKind() == Relation.IS || left.getKind() == Relation.GREATER ||
left.getKind() == Relation.GR_EQ || left.getKind() == Relation.SMALLER ||
left.getKind() == Relation.SM_EQ || left.getKind()==Relation.ISNOT) && (right == null || right.getKind() == Relation.IS ||
right.getKind() == Relation.GREATER || right.getKind() == Relation.GR_EQ ||
right.getKind() == Relation.SMALLER || right.getKind() == Relation.SM_EQ
|| right.getKind()==Relation.ISNOT)) {
// ********** Trata la parte izquierda ***********
int pos_v = 0, pos_mf = 0;
Variable v = left.getVariable();
ParamMemFunc mf = null;
FamiliarMemFunc mf2=null;
try {
if(left.getMembershipFunction() instanceof ParamMemFunc)
mf = (ParamMemFunc) left.getMembershipFunction();
else if (left.getMembershipFunction() instanceof FamiliarMemFunc)
mf2 = (FamiliarMemFunc) left.getMembershipFunction();
} catch(Exception ex) {
new XfvhdlError(31);
}
// averigua de qu� variable se trata
boolean enc = false;
for (int kk = 0; kk < var_in.length && !enc; kk++) {
if (var_in[kk].equals(v.getName())) {
pos_v = kk;
enc = true;
}
}
// averigua de qu� mf se trata
enc = false;
ParamMemFunc tmp=null;
FamiliarMemFunc tmp2=null;
for (int kk = 0;
kk < (inOrderMfInput[pos_v].getInOrderParamMemFunc().size()+
inOrderMfInput[pos_v].getFamiliarMemFunc().length)
&& !enc;
kk++) {
if(inOrderMfInput[pos_v].getInOrderParamMemFunc().size()!=0)
tmp =
(ParamMemFunc) inOrderMfInput[pos_v]
.getInOrderParamMemFunc()
.get(kk);
if(inOrderMfInput[pos_v].getFamiliarMemFunc().length!=0)
tmp2=inOrderMfInput[pos_v].getFamiliarMemFunc()[kk];
if(tmp!=null){
if (mf != null && tmp.equals(mf.getLabel())) {
pos_mf = kk;
enc = true;
}
}
if(tmp2!=null){
if (mf2 != null &&
tmp2.equals(mf2.getLabel())) {
pos_mf = kk;
enc = true;
}
}
}
// guarda la informaci�n en mfUsed
min = calculamin_max(pos_mf,v,"min", left.getKind());
max = calculamin_max(pos_mf,v,"max", left.getKind());
actuliza_min_max(min,max,pos_v,left.getKind());
//mfUsed[pos_v] = pos_mf;
// ****** Trata la parte derecha, si es distinta de null *****
if (right != null) {
pos_v = 0;
pos_mf = 0;
v = right.getVariable();
try {
if(right.getMembershipFunction() instanceof ParamMemFunc)
mf = (ParamMemFunc) right.getMembershipFunction();
else if (right.getMembershipFunction() instanceof FamiliarMemFunc)
mf2 = (FamiliarMemFunc) right.getMembershipFunction();
} catch(Exception ex) {
new XfvhdlError(31);
}
// averigua de qu� variable se trata
enc = false;
for (int kk = 0; kk < var_in.length && !enc; kk++) {
if (var_in[kk].equals(v.getName())) {
pos_v = kk;
enc = true;
}
}
// averigua de qu� mf se trata
enc = false;
tmp=null;
tmp2=null;
for (int kk = 0;
kk < (inOrderMfInput[pos_v].getInOrderParamMemFunc().size()+
inOrderMfInput[pos_v].getFamiliarMemFunc().length)
&& !enc;
kk++) {
if(inOrderMfInput[pos_v].getInOrderParamMemFunc().size()!=0)
tmp =
(ParamMemFunc) inOrderMfInput[pos_v]
.getInOrderParamMemFunc()
.get(kk);
if(inOrderMfInput[pos_v].getFamiliarMemFunc().length!=0)
tmp2=inOrderMfInput[pos_v].getFamiliarMemFunc()[kk];
if(tmp!=null){
if (mf != null && tmp.equals(mf.getLabel())) {
pos_mf = kk;
enc = true;
}
}
if(tmp2!=null){
if (mf2 != null && tmp2.equals(mf2.getLabel())) {
pos_mf = kk;
enc = true;
}
}
}
// guarda la informaci�n en mfUsed
//mfUsed[pos_v] = pos_mf;
min = calculamin_max(pos_mf,v,"min", right.getKind());
max = calculamin_max(pos_mf,v,"max", right.getKind());
actuliza_min_max(min,max,pos_v,right.getKind());
}
} else if (
(left.getKind() == Relation.AND) && (right.getKind() == Relation.IS ||
right.getKind() == Relation.GREATER || right.getKind() == Relation.GR_EQ ||
right.getKind() == Relation.SMALLER || right.getKind() == Relation.SM_EQ
|| right.getKind()==Relation.ISNOT)) {
// ***** Trata la parte derecha que es de tipo IS, GREATER, GR_EQ, SMALLER, SM_EQ � ISNOT *****
int pos_v = 0, pos_mf = 0;
Variable v = right.getVariable();
ParamMemFunc mf = null;
FamiliarMemFunc mf2 = null;
try {
//mf = (ParamMemFunc) right.getMembershipFunction();
if(right.getMembershipFunction() instanceof ParamMemFunc)
mf = (ParamMemFunc) right.getMembershipFunction();
else if (right.getMembershipFunction() instanceof FamiliarMemFunc)
mf2 = (FamiliarMemFunc) right.getMembershipFunction();
} catch(Exception ex) {
new XfvhdlError(31);
}
// averigua de qu� variable se trata
boolean enc = false;
for (int kk = 0; kk < var_in.length && !enc; kk++) {
if (var_in[kk].equals(v.getName())) {
pos_v = kk;
enc = true;
}
}
// averigua de qu� mf se trata
enc = false;
ParamMemFunc tmp=null;
FamiliarMemFunc tmp2=null;
for (int kk = 0;
kk < (inOrderMfInput[pos_v].getInOrderParamMemFunc().size()+
inOrderMfInput[pos_v].getFamiliarMemFunc().length)
&& !enc;
kk++) {
if(inOrderMfInput[pos_v].getInOrderParamMemFunc().size()!=0)
tmp =
(ParamMemFunc) inOrderMfInput[pos_v]
.getInOrderParamMemFunc()
.get(kk);
if(inOrderMfInput[pos_v].getFamiliarMemFunc().length!=0)
tmp2=inOrderMfInput[pos_v].getFamiliarMemFunc()[kk];
if (mf != null && tmp.equals(mf.getLabel())) {
pos_mf = kk;
enc = true;
}
if(tmp2!=null){
if (mf2 != null && tmp2.equals(mf2.getLabel())) {
pos_mf = kk;
enc = true;
}
}
}
// guarda la informaci�n en mfUsed
//mfUsed[pos_v] = pos_mf;
min = calculamin_max(pos_mf,v,"min", right.getKind());
max = calculamin_max(pos_mf,v,"max", right.getKind());
actuliza_min_max(min,max,pos_v,right.getKind());
// ******* Llama recursivamente a esta funci�n con ****
// ******* la parte izquierda ****
// ******* es de tipo AND. ****************************
Relation newLeft = left.getLeftRelation();
Relation newRight = left.getRightRelation();
getMfUsed(newLeft, newRight, nrule);
} else {
// Informa de que la regla nrule no es del tipo
// A & B & C ... ==> Z
new XfvhdlError(10, "Left: " + left.toXfl()+" Right: "+right.toXfl());
return;
}
}
/**@return Peso asociado a una entrada dada.*/
private double calculateWeight(int pos_c) {
ParamMemFunc p;
double universeRange = 0, peso = 0;
p = inOrderMfOutput.getParamMemFunc(pos_c);
universeRange = p.universe().range();
try {
peso = p.basis() / universeRange;
} catch (Exception e) {
XfvhdlError err = new XfvhdlError(0);
err.show();
return 0;
}
return peso;
}
private double calculateWeight2(int j, int pos_c) {
ParamMemFunc p;
double universeRange = 0, peso = 0;
p = inOrderMfOutput2[j].getParamMemFunc(pos_c);
universeRange = p.universe().range();
try {
peso = p.basis() / universeRange;
} catch (Exception e) {
XfvhdlError err = new XfvhdlError(0);
err.show();
return 0;
}
return peso;
}
private double calculateWeight2(LinguisticLabel p, String defuzzy, double gamma) {
double universeRange = 0, peso = 0;
universeRange = p.max()-p.min();
try {
if(defuzzy.equals("WeightedFuzzyMean")){
peso = p.basis() / universeRange;
}
else if(defuzzy.equals("GammaQuality")){
double w = Math.pow(p.basis(), gamma);
peso=w/universeRange;
}
else if(defuzzy.equals("Quality")){
peso=(1/ p.basis()) / universeRange;
}
} catch (Exception e) {
new XfsgError(5, defuzzy);
//err.show();
return 0;
}
return peso;
}
/**M�todo que nos ayuda a completar cuando tenemos bares de reglas incompletas.*/
private int calculamin_max(int valor, Variable var, String s, int tipo){
int res=0;
int nmf=var.getType().getAllMembershipFunctions().length;
if(tipo==Relation.IS){
if(s.equals("min")){
res=valor;
}else if(s.equals("max")){
res=valor;
}
}else if(tipo==Relation.GREATER){
if(s.equals("min")){
res=valor+1;
}else if(s.equals("max")){
res=nmf-1;
}
}else if(tipo==Relation.GR_EQ){
if(s.equals("min")){
res=valor;
}else if(s.equals("max")){
res=nmf-1;
}
}else if(tipo==Relation.SMALLER){
if(s.equals("min")){
res=0;
}else if(s.equals("max")){
res=valor-1;
}
}else if(tipo==Relation.SM_EQ){
if(s.equals("min")){
res=0;
}else if(s.equals("max")){
res=valor;
}
}else if(tipo==Relation.ISNOT){
if(s.equals("min")){
res=-2;
}else if(s.equals("max")){
res=valor;
}
}
return res;
}
/**M�todo que nos ayuda a completar cuando tenemos bares de reglas incompletas.*/
private void actuliza_min_max(int min, int max, int pos_v, int tipo){
if(mfUsed[pos_v][0]==-1 && mfUsed[pos_v][1]==-1){
mfUsed[pos_v][0]=min;
mfUsed[pos_v][1]=max;
}
else if(mfUsed[pos_v][0]!=-1 && mfUsed[pos_v][1]!=-1){
if(tipo==Relation.GR_EQ | tipo==Relation.GREATER)
mfUsed[pos_v][0]=min;
else if(tipo==Relation.SM_EQ | tipo==Relation.SMALLER)
mfUsed[pos_v][1]=max;
}
}
} // Fin de la clase