//--------------------------------------------------------------------------------//
// 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.xfsg;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
import xfuzzy.lang.CrispBlockCall;
import xfuzzy.lang.ModuleCall;
import xfuzzy.lang.RulebaseCall;
import xfuzzy.lang.Specification;
import xfuzzy.lang.SystemModule;
import xfuzzy.lang.Variable;
/**
* Clase que mantiene un directorio de los componentes disponibles en la
* librer�a XfuzzyLib y la informaci�n utilizada para generar los ficheros .txt
* y .mdl
*
* @author Jes�s Izquierdo Tena
*/
public class XfsgArchitecturesSimulink {
// Almacena el m�dulo de la librer�a XfuzzyLib que implementa cada bloque de
// un sistema difuso (base de reglas o bloque crisp)
private static Map<String, String> dir_architectures = new TreeMap<String, String>();
// Almacena las coordenadas de cada bloque dentro del modelo Simulink
private static Map<String, int[]> coorden_comp = new TreeMap<String, int[]>();
private static Map<String, Collection<int[]>> conexiones = new TreeMap<String, Collection<int[]>>();
// Almacena las coordenadas de cada entrada dentro del modelo Simulink
private static Map<String, int[]> coorden_inputs = new TreeMap<String, int[]>();
// Almacena las coordenadas de cada salida dentro del modelo Simulink
private static Map<String, int[]> coorden_outputs = new TreeMap<String, int[]>();
// ----------------------------------------------------------------------------//
// CONSTRUCTORES //
// ----------------------------------------------------------------------------//
public XfsgArchitecturesSimulink() {
// Directorio de los diferentes componentes de XfuzzyLib
// FLCs
dir_architectures.put("1-1-prod-FuzzyMeans", "XfuzzyLib/FLCs/FLC1_FMs");
dir_architectures.put("2-1-prod-FuzzyMeans", "XfuzzyLib/FLCs/FLC2_P_FMs");
dir_architectures.put("2-2-prod-FuzzyMeans", "XfuzzyLib/FLCs/FLC2_P_FMs_2");
dir_architectures.put("2-1-prod-FuzzyMean", "XfuzzyLib/FLCs/FLC2_P_FM");
dir_architectures.put("2-1-min-FuzzyMean_extD", "XfuzzyLib/FLCs/FLC2_M_FM_extD");
dir_architectures.put("2-1-min-FuzzyMean", "XfuzzyLib/FLCs/FLC2_M_FM");
dir_architectures.put("2-1-prod-MaxLabel", "XfuzzyLib/FLCs/FLC2_P_ML");
dir_architectures.put("2-1-min-MaxLabel", "XfuzzyLib/FLCs/FLC2_M_ML");
dir_architectures.put("2-1-prod-WeightedFuzzyMean", "XfuzzyLib/FLCs/FLC2_P_WFM");
dir_architectures.put("2-1-prod-WeightedFuzzyMean_extD", "XfuzzyLib/FLCs/FLC2_P_WFM_extD");
dir_architectures.put("2-1-min-WeightedFuzzyMean", "XfuzzyLib/FLCs/FLC2_M_WFM");
dir_architectures.put("2-1-min-WeightedFuzzyMean_extD", "XfuzzyLib/FLCs/FLC2_M_WFM_extD");
dir_architectures.put("2-1-prod-Quality", "XfuzzyLib/FLCs/FLC2_P_WFM");
dir_architectures.put("2-1-prod-GammaQuality", "XfuzzyLib/FLCs/FLC2_P_WFM");
dir_architectures.put("2-1-prod-TakagiSugenos", "XfuzzyLib/FLCs/FLC2_P_TS1s");
dir_architectures.put("2-1-prod-TakagiSugeno_extD", "XfuzzyLib/FLCs/FLC2_P_TS1_extD");
dir_architectures.put("2-1-prod-TakagiSugeno", "XfuzzyLib/FLCs/FLC2_P_TS1");
dir_architectures.put("2-1-min-TakagiSugeno_extD", "XfuzzyLib/FLCs/FLC2_M_TS1_extD");
dir_architectures.put("2-1-min-TakagiSugeno", "XfuzzyLib/FLCs/FLC2_M_TS1");
// Bloques Crisp
dir_architectures.put("select", "XfuzzyLib/Crisp/select");
dir_architectures.put("prod", "XfuzzyLib/Crisp/prod");
dir_architectures.put("div", "XfuzzyLib/Crisp/div");
dir_architectures.put("add2", "XfuzzyLib/Crisp/add2");
dir_architectures.put("addN3", "XfuzzyLib/Crisp/add3");
dir_architectures.put("addN4", "XfuzzyLib/Crisp/add4");
dir_architectures.put("diff2", "XfuzzyLib/Crisp/diff2");
}
public XfsgArchitecturesSimulink(String name, int x, int y, int n) {
int[] c = { x, y };
if (n == 0)
coorden_comp.put(name, c);
else if (n == 1)
coorden_inputs.put(name, c);
else if (n == 2)
coorden_outputs.put(name, c);
}
public XfsgArchitecturesSimulink(String conexion, Collection<int[]> puntos) {
conexiones.put(conexion, puntos);
// System.out.println("Conexi�n: "+conexion+" Puntos: "+puntos.size());
}
/**
* Funci�n que genera la descripci�n txt de un componente:
* FLC o bloque crisp
*/
public String getDescriptionTxt(XfsgBlock block, String propiedades) {
String txt = "";
String propiedades2 = propiedades;
String architecture1;
if (block instanceof XfsgFLC) {
XfsgFLC aux_flc = (XfsgFLC) block;
if (aux_flc.getconnective().equals("prod")
&& XfsgProperties.use_components_simplified
&& (aux_flc.getdeffuzy().equals("FuzzyMean") || aux_flc
.getdeffuzy().equals("TakagiSugeno"))) {
propiedades2 = propiedades2 + "s";
if (!aux_flc.getcomplete()) {
XfsgError err = new XfsgError();
err.newWarning(9, aux_flc.getname() + " in .txt file");
}
}
if (XfsgProperties.use_components_simplified) {
if (!aux_flc.getconnective().equals("prod")
|| !(aux_flc.getdeffuzy().equals("FuzzyMean") || aux_flc
.getdeffuzy().equals("TakagiSugeno"))) {
XfsgError err = new XfsgError();
err.newWarning(13, aux_flc.getname() + " in .txt file");
}
}
architecture1 = dir_architectures.get(propiedades2);
RulebaseCall rbc = (RulebaseCall) aux_flc.rbc;
txt += "\nRuleBase: " + rbc.getName() + "\n{\n";
txt += "Inputs: \n";
Variable[] var_inputs = rbc.getInputVariables();
for (int i = 0; i < rbc.getNumberOfInputs(); i++) {
txt += " " + var_inputs[i].getName() + "\n";
}
txt += "Outputs: \n";
Variable[] var_outputs = rbc.getOutputVariables();
for (int i = 0; i < rbc.getNumberOfOutputs(); i++) {
txt += " " + var_outputs[i].getName() + "\n";
}
txt += "Component: " + "\n " + architecture1 + "\n}\n";
}
else if (block instanceof XfsgCrisp) {
XfsgCrisp aux_crisp = (XfsgCrisp) block;
architecture1 = dir_architectures.get(propiedades2);
CrispBlockCall cbc = (CrispBlockCall) aux_crisp.cbc;
txt += "\nCrispBlock: " + cbc.getName() + "\n{\n";
txt += "Inputs: \n";
Variable[] var_inputs = cbc.getInputVariables();
for (int i = 0; i < cbc.getNumberOfInputs(); i++) {
txt += " " + var_inputs[i].getName() + "\n";
}
txt += "Outputs: \n";
Variable[] var_outputs = cbc.getOutputVariables();
for (int i = 0; i < cbc.getNumberOfOutputs(); i++) {
txt += " " + var_outputs[i].getName() + "\n";
}
txt += "Component: " + "\n " + architecture1 + "\n}\n";
}
return txt;
}
/**
* Funci�n que genera la descripci�n mdl de un componente:
* FLC o bloque crisp
*/
public String getDescriptionMdl(XfsgBlock block, String propiedades) {
String mdl = "";
String propiedades2 = propiedades;
int[] coord = coorden_comp.get(block.getname());
// Coordenadas del nuevo componente
int x1 = coord[0];
int y1 = coord[1];
int x2 = x1 + 100;
int y2 = y1 + 100;
String architecture;
String name = block.getname();
if (block instanceof XfsgFLC) {
XfsgFLC aux_flc = (XfsgFLC) block;
if (aux_flc.getconnective().equals("prod")
&& XfsgProperties.use_components_simplified
&& (aux_flc.getdeffuzy().equals("FuzzyMean") || aux_flc
.getdeffuzy().equals("TakagiSugeno"))) {
propiedades2 = propiedades2 + "s";
if (!aux_flc.getcomplete()) {
XfsgError err = new XfsgError();
err.newWarning(9, aux_flc.getname() + " in .mdl file");
}
}
if (XfsgProperties.use_components_simplified) {
if (!aux_flc.getconnective().equals("prod")
|| !(aux_flc.getdeffuzy().equals("FuzzyMean") || aux_flc
.getdeffuzy().equals("TakagiSugeno"))) {
XfsgError err = new XfsgError();
err.newWarning(13, aux_flc.getname() + " in .mdl file");
}
}
architecture = dir_architectures.get(propiedades2);
if (architecture == null) {
XfsgError err = new XfsgError();
err.newWarning(11, name);
}
mdl = " Block {\n" + " BlockType Reference\n"
+ " Name \"" + name + "\"\n" + " Ports ["
+ block.getinputs() + " , " + block.getoutputs() + "]\n"
+ " Position [" + x1 + "," + y1 + "," + x2 + ","
+ y2 + "]\n" + " SourceBlock \"" + architecture
+ "\"\n" + " SourceType \"Subsystem\"\n"
+ " ShowPortLabels \"FromPortIcon\"\n"
+ " SystemSampleTime \"-1\"\n"
+ " FunctionWithSeparateData off\n"
+ " RTWMemSecFuncInitTerm \"Inherit from model\"\n"
+ " RTWMemSecFuncExecute \"Inherit from model\"\n"
+ " RTWMemSecDataConstants \"Inherit from model\"\n"
+ " RTWMemSecDataInternal \"Inherit from model\"\n"
+ " RTWMemSecDataParameters \"Inherit from model\"\n"
+ " N \"" + name + ".N\"\n" + " grad \"" + name
+ ".grad\"\n" + " P \"" + name + ".P\"\n"
+ " No \"" + name + ".No\"\n" + " Pb \"" + name
+ ".Pb\"\n";
int n_inputs = aux_flc.getinputs();
int n_outputs = aux_flc.getoutputs();
if (n_inputs == 1) {
mdl += " n_fp \"" + name + ".n_fp\"\n" + " MFC_a \""
+ name + ".MFC_a\"\n" + " MFC_m \"" + name
+ ".MFC_m\"\n";
} else if (n_inputs > 1) {
for (int i = 0; i < n_inputs; i++) {
mdl += " n_fp" + (i + 1) + " \"" + name + ".MFC"
+ (i + 1) + ".n_fp\"\n" + " MFC_a" + (i + 1)
+ " \"" + name + ".MFC" + (i + 1) + ".MFC_a\"\n"
+ " MFC_m" + (i + 1) + " \"" + name + ".MFC"
+ (i + 1) + ".MFC_m\"\n";
}
}
if (n_outputs == 1) {
mdl += " RB \"" + name + ".RB"
+ aux_flc.getRB().get(0).getnombre() + "\"\n";
mdl += " }\n";
} else if (n_outputs > 1) {
for (int i1 = 0; i1 < n_outputs; i1++) {
mdl += " RB" + (i1 + 1) + " \"" + name + ".RB"
+ aux_flc.getRB().get(i1).getnombre() + "\"\n";
}
mdl += " }\n";
}
} else if (block instanceof XfsgCrisp) {
architecture = dir_architectures.get(propiedades2);
if (architecture == null) {
XfsgError err = new XfsgError();
err.newWarning(14, name);
}
mdl = " Block {\n" + " BlockType Reference\n"
+ " Name \"" + name + "\"\n" + " Ports ["
+ block.getinputs() + " , " + block.getoutputs() + "]\n"
+ " Position [" + x1 + "," + y1 + "," + x2 + ","
+ y2 + "]\n" + " SourceBlock \"" + architecture
+ "\"\n" + " SourceType \"Subsystem\"\n"
+ " ShowPortLabels \"FromPortIcon\"\n"
+ " SystemSampleTime \"-1\"\n"
+ " FunctionWithSeparateData off\n"
+ " RTWMemSecFuncInitTerm \"Inherit from model\"\n"
+ " RTWMemSecFuncExecute \"Inherit from model\"\n"
+ " RTWMemSecDataConstants \"Inherit from model\"\n"
+ " RTWMemSecDataInternal \"Inherit from model\"\n"
+ " RTWMemSecDataParameters \"Inherit from model\"\n"
+ " No \"" + name + ".No\"\n" + " }\n";
}
return mdl;
}
/**
* generaConexiones
*/
public static String generaConexiones(Specification spec) {
String res = "";
SystemModule sm = spec.getSystemModule();
ModuleCall[] mc = sm.getModuleCalls();
// Mapas para almacenar las coordenadas de las entradas y las salidas.
Map<String, int[]> coord_inputs = new TreeMap<String, int[]>();
Map<String, int[]> coord_outputs = new TreeMap<String, int[]>();
// Coloca las entradas
Variable[] inputs = sm.getInputs();
if (inputs.length >= 1) {
for (int i = 0; i < inputs.length; i++) {
int[] coord_aux = coorden_inputs.get(inputs[i].getName());
// Coordenadas de la entrada
int x1 = coord_aux[0];
int y1 = coord_aux[1];
int x2 = x1 + 20;
int y2 = y1 + 20;
int coord[] = { x1, y1, x2, y2 };
coord_inputs.put(inputs[i].getName(), coord);
res += " Block {\n" + " BlockType Inport\n"
+ " Name \"" + inputs[i].getName() + "\"\n"
+ " Position [" + x1 + "," + y1 + "," + x2
+ "," + y2 + "]\n"
+ " IconDisplay \"Port number\"\n"
+ " OutDataType \"sfix(16)\"\n"
+ " OutScaling \"2^0\"\n" + " }\n";
}
}
// Coloca las salidas.
Variable[] outputs = sm.getOutputs();
if (outputs.length >= 1) {
for (int i = 0; i < outputs.length; i++) {
int[] coord_aux = coorden_outputs.get(outputs[i].getName());
// Coordenadas de la salida
int x1 = coord_aux[0];
int y1 = coord_aux[1];
int x2 = x1 + 20;
int y2 = y1 + 20;
int coord[] = { x1, y1, x2, y2 };
coord_outputs.put(outputs[i].getName(), coord);
res += " Block {\n" + " BlockType Outport\n"
+ " Name \"" + outputs[i].getName() + "\"\n"
+ " Position [" + x1 + "," + y1 + "," + x2
+ "," + y2 + "]\n"
+ " IconDisplay \"Port number\"\n"
+ " OutDataType \"sfix(16)\"\n"
+ " OutScaling \"2^0\"\n" + " }\n";
}
}
// Coloca las conexiones internas
for (int i = 0; i < mc.length; i++) {
ModuleCall mc1 = mc[i];
Variable[] salidas = mc1.getOutputVariables();
for (int k = 0; k < salidas.length; k++) {
res += " Line {\n" + " SrcBlock \"" + mc1.getName()
+ "\"\n" + " SrcPort " + (k + 1) + "\n"
+ " Points [0, 0]\n";
for (int j = 0; j < mc.length; j++) {
ModuleCall mc2 = mc[j];
Variable[] entradas = mc2.getInputVariables();
for (int l = 0; l < entradas.length; l++) {
if (entradas[l].equals(salidas[k])) {
String aux6 = genera_cable2(entradas[l].getName()
+ mc1.getName() + mc2.getName(), mc1, mc2,
l + 1, k + 1);
// String
// aux6=genera_cable(entradas[l].getName()+mc1.getName()+mc2.getName());
res += " Branch {\n" + " Points " + aux6
+ "\n" + " DstBlock \"" + mc2.getName()
+ "\"\n" + " DstPort " + (l + 1)
+ "\n" + " }\n";
}
}
}
// Comprueba las salidas hacia fuera
for (int i2 = 0; i2 < outputs.length; i2++) {
if (outputs[i2].equals(salidas[k])) {
String aux6 = genera_cable3(outputs[i2].getName()
+ mc1.getName() + "null",
outputs[i2].getName(), mc1, k + 1);
// String
// aux6=genera_cable(outputs[i2].getName()+mc1.getName()+"null");
res += " Branch {\n" + " Points " + aux6 + "\n"
+ " DstBlock \"" + outputs[i2].getName()
+ "\"\n" + " DstPort 1\n" + " }\n";
}
}
res += " }\n";
}
}
// Crea el c�digo para las conexiones de las variables de entrada con
// los FLCs
for (int i = 0; i < inputs.length; i++) {
res += " Line {\n" + " SrcBlock \""
+ inputs[i].getName() + "\"\n" + " SrcPort 1\n"
+ " Points [0, 0]\n";
for (int k = 0; k < mc.length; k++) {
ModuleCall mc1 = mc[k];
Variable[] entradas = mc1.getInputVariables();
for (int j = 0; j < entradas.length; j++) {
if (entradas[j].equals(inputs[i])) {
String aux6 = genera_cable1(entradas[j].getName()
+ "null" + mc1.getName(), inputs[i].getName(),
mc1, j + 1);
// String
// aux6=genera_cable(entradas[j].getName()+"null"+mc1.getName());
res += " Branch {\n" + " Points " + aux6 + "\n"
+ " DstBlock \"" + mc1.getName() + "\"\n"
+ " DstPort " + (j + 1) + "\n" + " }\n";
}
}
}
res += " }\n";
}
return res;
}
/**
* genera_cable
*/
private static String genera_cable(String conex) {
String cable = "[ ", cable2 = "";
Collection<int[]> c = conexiones.get(conex);
Iterator<int[]> it = c.iterator();
while (it.hasNext()) {
int[] aux = it.next();
cable += (aux[2] - aux[0]) + " , " + (aux[3] - aux[1]) + " ; ";
}
cable += "]";
cable = cable.replace(" ; ]", "]");
// resto 30 a la �ltima coordenada de fila
int n = cable.lastIndexOf(";");
cable2 = cable.substring(0, n + 1);
int m = cable.lastIndexOf(",");
String valor = cable.substring(n + 1, m - 1).trim();
int valor1 = Integer.parseInt(valor);
// String aux=cable.substring(n+1, m-1);
cable2 += " " + (valor1 - 30) + cable.substring(m);
return cable2;
}
/**
* genera_cable1
*/
private static String genera_cable1(String conex, String input,
ModuleCall mc1, int ent) {
String cable = "[ ";
Collection<int[]> c = conexiones.get(conex);
// int tam=c.size();
// int i=1;
boolean end = false;
int[] coord1 = coorden_inputs.get(input);
int salx = coord1[0] + 20;
int saly = coord1[1] + 10;
// System.out.println(salx+" "+saly);
int[] coord2 = coorden_comp.get(mc1.getName());
int metx = coord2[0] - 30;
int mety = coord2[1]
+ (int) calcula_coord(mc1.getNumberOfInputs(), ent);
// System.out.println(metx+" "+mety);
Iterator<int[]> it = c.iterator();
while (it.hasNext() && !end) {
int[] aux = it.next();
if ((salx + (aux[2] - aux[0])) > metx) {
cable += (metx - salx) + " , 0 ;";
salx += metx - salx;
end = true;
} else {
salx += aux[2] - aux[0];
saly += aux[3] - aux[1];
cable += (aux[2] - aux[0]) + " , " + (aux[3] - aux[1]) + " ; ";
}
// System.out.println(salx+" "+saly);
}
if (!end)
cable += (metx - salx) + " , 0 ;";
cable += " 0 , " + (mety - saly);
cable += "]";
return cable;
}
/**
* genera_cable2 (conexiones internas)
*/
private static String genera_cable2(String conex, ModuleCall mc1,
ModuleCall mc2, int ent, int sal) {
String cable = "[ ";
Collection<int[]> c = conexiones.get(conex);
// int tam=c.size();
// int i=1;
// int v=0;
boolean end = false;
int[] coord1 = coorden_comp.get(mc1.getName());
int salx = coord1[0] + 100;
int saly = coord1[1]
+ (int) calcula_coord(mc1.getNumberOfOutputs(), sal);
int[] coord2 = coorden_comp.get(mc2.getName());
int metx = coord2[0] - 30;
int mety = coord2[1]
+ (int) calcula_coord(mc2.getNumberOfInputs(), ent);
Iterator<int[]> it = c.iterator();
while (it.hasNext() && !end) {
int[] aux = it.next();
if ((salx + (aux[2] - aux[0])) > metx) {
cable += (metx - salx) + " , 0 ;";
salx += metx - salx;
end = true;
} else {
salx += aux[2] - aux[0];
saly += aux[3] - aux[1];
cable += (aux[2] - aux[0]) + " , " + (aux[3] - aux[1]) + " ; ";
}
}
if (!end)
cable += (metx - salx) + " , 0 ;";
cable += " 0 , " + (mety - saly);
cable += "]";
return cable;
}
// cables hacia las salidas de fuera
private static String genera_cable3(String conex, String out,
ModuleCall mc1, int sal) {
String cable = "[ ";
Collection<int[]> c = conexiones.get(conex);
// int tam=c.size();
// int i=1;
boolean end = false;
int[] coord1 = coorden_comp.get(mc1.getName());
int salx = coord1[0] + 100;
int saly = coord1[1]
+ (int) calcula_coord(mc1.getNumberOfOutputs(), sal);
int[] coord2 = coorden_outputs.get(out);
int metx = coord2[0] - 30;
int mety = coord2[1] + 10;
Iterator<int[]> it = c.iterator();
// System.out.println(c.size());
while (it.hasNext() && !end) {
int[] aux = it.next();
if ((salx + (aux[2] - aux[0])) > metx) {
cable += (metx - salx) + " , 0 ;";
salx += metx - salx;
end = true;
// System.out.println("entro");
} else {
salx += aux[2] - aux[0];
saly += aux[3] - aux[1];
cable += (aux[2] - aux[0]) + " , " + (aux[3] - aux[1]) + " ; ";
}
}
if (!end)
cable += (metx - salx) + " , 0 ;";
cable += " 0 , " + (mety - saly);
cable += "]";
return cable;
}
/**
* calcula_coord
*/
private static double calcula_coord(int n_inputs, int input) {
double res = 0;
if (n_inputs == 1)
res = 50;
else if (n_inputs == 2) {
if (input == 1)
res = 25;
else
res = 75;
} else if (n_inputs == 3) {
if (input == 1)
res = 15;
else if (input == 2)
res = 50;
else
res = 85;
}
return res;
}
}