PageRenderTime 59ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/src/xfuzzy/xfsw/XfswCCode.java

https://github.com/dayse/gesplan
Java | 1311 lines | 941 code | 149 blank | 221 comment | 194 complexity | d5dda2517c4aea84adccc0fdf84a03b3 MD5 | raw file
  1. //--------------------------------------------------------------------------------//
  2. // COPYRIGHT NOTICE //
  3. //--------------------------------------------------------------------------------//
  4. // Copyright (c) 2012, Instituto de Microelectronica de Sevilla (IMSE-CNM) //
  5. // //
  6. // All rights reserved. //
  7. // //
  8. // Redistribution and use in source and binary forms, with or without //
  9. // modification, are permitted provided that the following conditions are met: //
  10. // //
  11. // * Redistributions of source code must retain the above copyright notice, //
  12. // this list of conditions and the following disclaimer. //
  13. // //
  14. // * Redistributions in binary form must reproduce the above copyright //
  15. // notice, this list of conditions and the following disclaimer in the //
  16. // documentation and/or other materials provided with the distribution. //
  17. // //
  18. // * Neither the name of the IMSE-CNM nor the names of its contributors may //
  19. // be used to endorse or promote products derived from this software //
  20. // without specific prior written permission. //
  21. // //
  22. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" //
  23. // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE //
  24. // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE //
  25. // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE //
  26. // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL //
  27. // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR //
  28. // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER //
  29. // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, //
  30. // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE //
  31. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. //
  32. //--------------------------------------------------------------------------------//
  33. package xfuzzy.xfsw;
  34. import xfuzzy.lang.*;
  35. import java.io.*;
  36. /**
  37. * Generador del fichero de código de la descripción C
  38. *
  39. * @author Francisco José Moreno Velo
  40. *
  41. */
  42. public class XfswCCode {
  43. //----------------------------------------------------------------------------//
  44. // MIEMBROS PRIVADOS //
  45. //----------------------------------------------------------------------------//
  46. /**
  47. * Sistema difuso a compilar
  48. */
  49. private Specification spec;
  50. /**
  51. * Directorio base para la creación del archivo
  52. */
  53. private File dir;
  54. /**
  55. * Clase que analiza los funciones utilizadas en el sistema
  56. */
  57. private XfswDataUsage usage;
  58. //----------------------------------------------------------------------------//
  59. // CONSTRUCTOR //
  60. //----------------------------------------------------------------------------//
  61. /**
  62. * Constructor
  63. */
  64. public XfswCCode(Specification spec, File dir) {
  65. this.spec = spec;
  66. this.dir = dir;
  67. this.usage = new XfswDataUsage(spec);
  68. }
  69. //----------------------------------------------------------------------------//
  70. // MÉTODOS PÚBLICOS ESTÁTICOS //
  71. //----------------------------------------------------------------------------//
  72. /**
  73. * Genera el fichero C asociado al sistema difuso
  74. */
  75. public static final String create(Specification spec,File dir)
  76. throws XflException {
  77. XfswCCode creator = new XfswCCode(spec,dir);
  78. creator.createFile();
  79. return creator.getMessage();
  80. }
  81. //----------------------------------------------------------------------------//
  82. // MÉTODOS PÚBLICOS //
  83. //----------------------------------------------------------------------------//
  84. /**
  85. * Método que describe el resultado
  86. */
  87. public String getMessage() {
  88. File file = new File(dir,spec.getName()+".c");
  89. return file.getAbsolutePath();
  90. }
  91. /**
  92. * Genera el fichero "sistema.c"
  93. */
  94. public void createFile() throws XflException {
  95. File file = new File(dir,spec.getName()+".c");
  96. try {
  97. OutputStream ostream = new FileOutputStream(file);
  98. PrintStream stream = new PrintStream(ostream);
  99. writeHeading(stream);
  100. writeSource(stream);
  101. stream.close();
  102. }
  103. catch(IOException e) {}
  104. }
  105. //----------------------------------------------------------------------------//
  106. // MÉTODOS PRIVADOS //
  107. //----------------------------------------------------------------------------//
  108. //----------------------------------------------------------------------------//
  109. // Métodos que generan el contenido del fichero //
  110. //----------------------------------------------------------------------------//
  111. /**
  112. * Genera el código de cabecera
  113. */
  114. private void writeHeading(PrintStream stream) {
  115. stream.println("/*++++++++++++++++++++++++++++++++++++++++++++++++++++++*/");
  116. stream.println("/* */");
  117. stream.println(complete("/* File: "+spec.getName()+".c"));
  118. stream.println("/* */");
  119. stream.println("/* Author: Automatically generated by Xfuzzy */");
  120. stream.println("/* */");
  121. stream.println("/*++++++++++++++++++++++++++++++++++++++++++++++++++++++*/");
  122. stream.println();
  123. }
  124. /**
  125. * Genera el contenido del fichero
  126. */
  127. private void writeSource(PrintStream stream) throws XflException {
  128. String name = spec.getName();
  129. Operatorset[] opset = spec.getOperatorsets();
  130. Type[] type = spec.getTypes();
  131. Rulebase[] base = spec.getRulebases();
  132. CrispBlock[] crisp = spec.getCrispBlockSet().getBlocks();
  133. stream.println("#include <stdio.h>");
  134. stream.println("#include <math.h>");
  135. stream.println("#include \""+name+".h\"");
  136. stream.println();
  137. if(usage.isComputeUsed()) createComputeFunction(stream);
  138. Family[] famlist = usage.getFamilyList();
  139. for(int i=0; i<famlist.length; i++) createFamilyCode(stream, famlist[i]);
  140. ParamMemFunc[] mflist = usage.getMFList();
  141. for(int i=0; i<mflist.length; i++) createMFCode(stream, mflist[i]);
  142. for(int i=0; i<opset.length; i++) createOperatorSetCode(stream,opset[i]);
  143. for(int i=0; i<type.length; i++) createTypeCode(stream,type[i]);
  144. for(int i=0; i<base.length; i++) createRulebaseCode(stream,base[i]);
  145. for(int i=0; i<crisp.length; i++) createCrispBlockCode(stream,crisp[i]);
  146. createSystemModuleCode(stream);
  147. }
  148. //----------------------------------------------------------------------------//
  149. // Métodos que generan el código de las familias //
  150. //----------------------------------------------------------------------------//
  151. private void createComputeFunction(PrintStream stream) {
  152. stream.println("/*======================================================*/");
  153. stream.println("/* Common function to compute a fuzzy number */");
  154. stream.println("/*======================================================*/");
  155. stream.println();
  156. stream.println("static double compute(FuzzyNumber fn,double x) {");
  157. stream.println(" int length = fn.length;");
  158. stream.println(" int i;");
  159. stream.println(" double imp = fn.imp(fn.degree[0],fn.conc[0].equal(x));");
  160. stream.println(" double mu = imp");
  161. stream.println();
  162. stream.println(" for(i=1; i<length; i++) {");
  163. stream.println(" imp = fn.imp(fn.degree[i],fn.conc[i].equal(x));");
  164. stream.println(" mu = fn.also(mu,imp);");
  165. stream.println(" }");
  166. stream.println(" return mu;");
  167. stream.println("}");
  168. stream.println();
  169. }
  170. //----------------------------------------------------------------------------//
  171. // Métodos que generan el código de las familias //
  172. //----------------------------------------------------------------------------//
  173. /**
  174. * Descripción de una familia de funciones de pertenencia
  175. */
  176. private void createFamilyCode(PrintStream stream, Family fam) throws XflException {
  177. String classname = usage.getFamilyName(fam);
  178. String equal = fam.getEqualCCode();
  179. if(equal==null || equal.length()==0) throw new XflException();
  180. stream.println("/*======================================================*/");
  181. stream.println(complete("/* MembershipFunction "+classname));
  182. stream.println("/*======================================================*/");
  183. stream.println();
  184. stream.println("/*------------------------------------------------------*/");
  185. stream.println("/* Function to compute an equal relationship */");
  186. stream.println("/*------------------------------------------------------*/");
  187. stream.println();
  188. stream.print("static double "+classname+"_equal(double x");
  189. createFamVariableCode(stream, fam);
  190. stream.println(") {");
  191. stream.print(equal);
  192. stream.println("}");
  193. stream.println();
  194. if(usage.isFamilyGreqUsed( classname )) {
  195. String greq = fam.getGreqCCode();
  196. stream.println("/*------------------------------------------------------*/");
  197. stream.println("/* Function to compute a greater_or_equal relationship */");
  198. stream.println("/*------------------------------------------------------*/");
  199. stream.println();
  200. stream.print("static double "+classname+"_greq(double x, ");
  201. createFamVariableCode(stream,fam);
  202. stream.println(") {");
  203. if(greq != null && greq.length()>0) {
  204. stream.print(greq);
  205. } else {
  206. stream.println(" double _y, _mu, _degree=0;");
  207. stream.println(" for(_y = min; _y <= x ; _y += step) {");
  208. stream.print(" _mu = "+classname+"_equal(_y,");
  209. createFamVariableCallCode(stream,fam);
  210. stream.println(");");
  211. stream.println(" if( _mu > _degree) _degree = _mu;");
  212. stream.println(" }");
  213. stream.println(" return _degree;");
  214. }
  215. stream.println("}");
  216. stream.println();
  217. }
  218. if(usage.isFamilySmeqUsed( classname )) {
  219. String smeq = fam.getSmeqCCode();
  220. stream.println("/*------------------------------------------------------*/");
  221. stream.println("/* Function to compute a smaller_or_equal relationship */");
  222. stream.println("/*------------------------------------------------------*/");
  223. stream.println();
  224. stream.print("static double "+classname+"_smeq(double x, ");
  225. createFamVariableCode(stream,fam);
  226. stream.println(") {");
  227. if(smeq != null && smeq.length()>0) {
  228. stream.print(smeq);
  229. } else {
  230. stream.println(" double _y, _mu, _degree=0;");
  231. stream.println(" for(_y = max; _y >= x ; _y -= step) {");
  232. stream.print( " _mu = "+classname+"_equal(_y,");
  233. createFamVariableCallCode(stream,fam);
  234. stream.println(");");
  235. stream.println(" if( _mu > _degree) _degree = _mu;");
  236. stream.println(" }");
  237. stream.println(" return _degree;");
  238. }
  239. stream.println("}");
  240. stream.println();
  241. }
  242. if(usage.isFamilyCenterUsed( classname )) {
  243. String center = fam.getCenterCCode();
  244. stream.println("/*------------------------------------------------------*/");
  245. stream.println("/* Function to compute the center of the MF */");
  246. stream.println("/*------------------------------------------------------*/");
  247. stream.println();
  248. stream.print("static double "+classname+"_center(");
  249. createFamVariableCode(stream,fam);
  250. stream.println(") {");
  251. if(center != null && center.length()>0) {
  252. stream.print(center);
  253. } else {
  254. stream.println(" return 0;");
  255. }
  256. stream.println("}");
  257. stream.println();
  258. }
  259. if(usage.isFamilyBasisUsed( classname )) {
  260. String basis = fam.getBasisCCode();
  261. stream.println("/*------------------------------------------------------*/");
  262. stream.println("/* Function to compute the basis of the MF */");
  263. stream.println("/*------------------------------------------------------*/");
  264. stream.println();
  265. stream.print("static double "+classname+"_basis(");
  266. createFamVariableCode(stream,fam);
  267. stream.println(") {");
  268. if(basis != null && basis.length()>0) {
  269. stream.print(basis);
  270. } else {
  271. stream.println(" return 0;");
  272. }
  273. stream.println("}");
  274. stream.println();
  275. }
  276. if(usage.isFamilyParamUsed( classname )) {
  277. Parameter[] single = fam.getSingleParameters();
  278. String listname = fam.getParamListName();
  279. stream.println("/*------------------------------------------------------*/");
  280. stream.println("/* Function to get a parameter of the MF */");
  281. stream.println("/*------------------------------------------------------*/");
  282. stream.println();
  283. stream.print("static double "+classname+"_param(int _i, ");
  284. createFamVariableCode(stream,fam);
  285. stream.println(") {");
  286. for(int i=0; i<single.length; i++) {
  287. stream.println(" if(_i == "+i+") return "+single[i].getName()+";");
  288. }
  289. if(listname != null && listname.length()>0) {
  290. stream.println(" return "+listname+"[_i-"+single.length+"];");
  291. } else {
  292. stream.println(" return 0.0;");
  293. }
  294. stream.println("}");
  295. stream.println();
  296. }
  297. }
  298. /**
  299. * Método auxiliar para generar las variables de la función
  300. */
  301. private void createFamVariableCode(PrintStream stream, Family fam) {
  302. Parameter single[] = fam.getSingleParameters();
  303. String listname = fam.getParamListName();
  304. stream.print("int i, double min, double max, double step");
  305. for(int i=0; i<single.length; i++) {
  306. stream.print(", double "+single[i].getName());
  307. }
  308. if(listname != null && listname.length() > 0) {
  309. stream.print(", double *"+listname+", int length");
  310. }
  311. }
  312. /**
  313. * Método auxiliar para generar las variables de la función
  314. */
  315. private void createFamVariableCallCode(PrintStream stream, Family fam) {
  316. Parameter single[] = fam.getSingleParameters();
  317. String listname = fam.getParamListName();
  318. stream.print(" i, min, max, step");
  319. for(int i=0; i<single.length; i++) {
  320. stream.print(", "+single[i].getName());
  321. }
  322. if(listname != null && listname.length() > 0) {
  323. stream.print(", "+listname+", length");
  324. }
  325. }
  326. //----------------------------------------------------------------------------//
  327. // Métodos que generan el código de las M.F. //
  328. //----------------------------------------------------------------------------//
  329. /**
  330. * Descripción de un función de pertenencia
  331. */
  332. private void createMFCode(PrintStream stream,ParamMemFunc mf) throws XflException {
  333. String classname = usage.getMFname(mf);
  334. String equal = mf.getEqualCCode();
  335. if(equal==null || equal.length()==0) throw new XflException();
  336. stream.println("/*======================================================*/");
  337. stream.println(complete("/* MembershipFunction "+classname));
  338. stream.println("/*======================================================*/");
  339. stream.println();
  340. stream.println("/*------------------------------------------------------*/");
  341. stream.println("/* Function to compute an equal relationship */");
  342. stream.println("/*------------------------------------------------------*/");
  343. stream.println();
  344. stream.print("static double "+classname+"_equal(double x, ");
  345. createVariableCode(stream,mf);
  346. stream.println(") {");
  347. stream.println(equal);
  348. stream.println("}");
  349. stream.println();
  350. if(usage.isMFGreqUsed( classname )) {
  351. String greq = mf.getGreqCCode();
  352. stream.println("/*------------------------------------------------------*/");
  353. stream.println("/* Function to compute a greater_or_equal relationship */");
  354. stream.println("/*------------------------------------------------------*/");
  355. stream.println();
  356. stream.print("static double "+classname+"_greq(double x, ");
  357. createVariableCode(stream,mf);
  358. stream.println(") {");
  359. if(greq != null && greq.length()>0) {
  360. stream.println(greq);
  361. } else {
  362. stream.println(" double _y, _mu, _degree=0;");
  363. stream.println(" for(_y = min; _y <= x ; _y += step) {");
  364. stream.print(" _mu = "+classname+"_equal(_y,");
  365. createVariableCallCode(stream,mf);
  366. stream.println(");");
  367. stream.println(" if( _mu > _degree) _degree = _mu;");
  368. stream.println(" }");
  369. stream.println(" return _degree;");
  370. }
  371. stream.println("}");
  372. stream.println();
  373. }
  374. if(usage.isMFSmeqUsed( classname )) {
  375. String smeq = mf.getSmeqCCode();
  376. stream.println("/*------------------------------------------------------*/");
  377. stream.println("/* Function to compute a smaller_or_equal relationship */");
  378. stream.println("/*------------------------------------------------------*/");
  379. stream.println();
  380. stream.print("static double "+classname+"_smeq(double x, ");
  381. createVariableCode(stream,mf);
  382. stream.println(") {");
  383. if(smeq != null && smeq.length()>0) {
  384. stream.println(smeq);
  385. } else {
  386. stream.println(" double _y, _mu, _degree=0;");
  387. stream.println(" for(_y = max; _y >= x ; _y -= step) {");
  388. stream.print( " _mu = "+classname+"_equal(_y,");
  389. createVariableCallCode(stream,mf);
  390. stream.println(");");
  391. stream.println(" if( _mu > _degree) _degree = _mu;");
  392. stream.println(" }");
  393. stream.println(" return _degree;");
  394. }
  395. stream.println("}");
  396. stream.println();
  397. }
  398. if(usage.isMFParamUsed( classname )) {
  399. Parameter[] single = mf.getSingleParameters();
  400. String listname = mf.getParamListName();
  401. stream.println("/*------------------------------------------------------*/");
  402. stream.println("/* Function to get a parameter of the MF */");
  403. stream.println("/*------------------------------------------------------*/");
  404. stream.println();
  405. stream.print("static double "+classname+"_param(int _i, ");
  406. createVariableCode(stream,mf);
  407. stream.println(") {");
  408. for(int i=0; i<single.length; i++) {
  409. stream.println(" if(_i == "+i+") return "+single[i].getName()+";");
  410. }
  411. if(listname != null && listname.length()>0) {
  412. stream.println(" return "+listname+"[_i-"+single.length+"];");
  413. } else {
  414. stream.println(" return 0.0;");
  415. }
  416. stream.println("}");
  417. stream.println();
  418. }
  419. }
  420. /**
  421. * Método auxiliar para generar las variables de la función
  422. */
  423. private void createVariableCode(PrintStream stream, ParamMemFunc mf) {
  424. Parameter single[] = mf.getSingleParameters();
  425. String listname = mf.getParamListName();
  426. stream.print("double min, double max, double step");
  427. for(int i=0; i<single.length; i++) {
  428. stream.print(", double "+single[i].getName());
  429. }
  430. if(listname != null && listname.length() > 0) {
  431. stream.print(", double *"+listname+", int length");
  432. }
  433. }
  434. /**
  435. * Método auxiliar para generar las variables de la función
  436. */
  437. private void createVariableCallCode(PrintStream stream, ParamMemFunc mf) {
  438. Parameter single[] = mf.getSingleParameters();
  439. String listname = mf.getParamListName();
  440. stream.print(" min, max, step");
  441. for(int i=0; i<single.length; i++) {
  442. stream.print(", "+single[i].getName());
  443. }
  444. if(listname != null && listname.length() > 0) {
  445. stream.print(", "+listname+", length");
  446. }
  447. }
  448. //----------------------------------------------------------------------------//
  449. // Métodos que generan el código de los conjuntos de operadores //
  450. //----------------------------------------------------------------------------//
  451. /**
  452. * Descripción de un conjunto de operadores
  453. */
  454. private void createOperatorSetCode(PrintStream stream, Operatorset opset) throws XflException {
  455. boolean[] flags = usage.getOpsetUsages(opset);
  456. String name = opset.getName();
  457. stream.println("/*======================================================*/");
  458. stream.println(complete("/* Operatorset OP_"+name));
  459. stream.println("/*======================================================*/");
  460. stream.println();
  461. if(flags[0]) {
  462. stream.println("/*------------------------------------------------------*/");
  463. stream.println("/* Description of the operator AND */");
  464. stream.println("/*------------------------------------------------------*/");
  465. stream.println();
  466. createBinaryCode(stream,opset.and, "OP_"+name+"_And");
  467. }
  468. if(flags[1]) {
  469. stream.println("/*------------------------------------------------------*/");
  470. stream.println("/* Description of the operator OR */");
  471. stream.println("/*------------------------------------------------------*/");
  472. stream.println();
  473. createBinaryCode(stream,opset.or, "OP_"+name+"_Or");
  474. }
  475. if(flags[2]) {
  476. stream.println("/*------------------------------------------------------*/");
  477. stream.println("/* Description of the operator NOT */");
  478. stream.println("/*------------------------------------------------------*/");
  479. stream.println();
  480. createUnaryCode(stream,opset.not, "OP_"+name+"_Not");
  481. }
  482. if(flags[3]) {
  483. stream.println("/*------------------------------------------------------*/");
  484. stream.println("/* Description of the operator MORE OR LESS */");
  485. stream.println("/*------------------------------------------------------*/");
  486. stream.println();
  487. createUnaryCode(stream,opset.moreorless, "OP_"+name+"_MoreOrLess");
  488. }
  489. if(flags[4]) {
  490. stream.println("/*------------------------------------------------------*/");
  491. stream.println("/* Description of the operator SLIGHTLY */");
  492. stream.println("/*------------------------------------------------------*/");
  493. stream.println();
  494. createUnaryCode(stream,opset.slightly, "OP_"+name+"_Slightly");
  495. }
  496. if(flags[5]) {
  497. stream.println("/*------------------------------------------------------*/");
  498. stream.println("/* Description of the operator STRONGLY */");
  499. stream.println("/*------------------------------------------------------*/");
  500. stream.println();
  501. createUnaryCode(stream,opset.very, "OP_"+name+"_Very");
  502. }
  503. if(flags[6]) {
  504. stream.println("/*------------------------------------------------------*/");
  505. stream.println("/* Description of the operator ALSO */");
  506. stream.println("/*------------------------------------------------------*/");
  507. stream.println();
  508. createBinaryCode(stream,opset.also, "OP_"+name+"_Also");
  509. stream.println("/*------------------------------------------------------*/");
  510. stream.println("/* Description of the operator IMPLICATION */");
  511. stream.println("/*------------------------------------------------------*/");
  512. stream.println();
  513. createBinaryCode(stream,opset.imp, "OP_"+name+"_Imp");
  514. }
  515. stream.println("/*------------------------------------------------------*/");
  516. stream.println("/* Description of the defuzzification method */");
  517. stream.println("/*------------------------------------------------------*/");
  518. stream.println();
  519. createDefuzCode(stream,opset.defuz, "OP_"+name+"_Defuz");
  520. stream.println();
  521. }
  522. /**
  523. * Descripcion de un operador binario
  524. */
  525. private void createBinaryCode(PrintStream stream, Binary op, String name) throws XflException {
  526. stream.println("static double "+name+"(double a, double b) {");
  527. Parameter singleparam[] = op.getSingleParameters();
  528. for(int i=0; i<singleparam.length; i++) {
  529. stream.print(" double "+singleparam[i].getName());
  530. stream.println(" = "+singleparam[i].value+";");
  531. }
  532. String listname = op.getParamListName();
  533. if(listname != null && listname.length() > 0) {
  534. Parameter paramlist[] = op.getParamList();
  535. stream.print(" double "+listname+"["+paramlist.length+"] = {");
  536. for(int i=0; i<paramlist.length; i++)
  537. stream.print((i>0? ",":"")+paramlist[i].value);
  538. stream.println("};");
  539. }
  540. stream.println(op.getCCode());
  541. stream.println("}");
  542. stream.println();
  543. }
  544. /**
  545. * Descripción de un operador unario
  546. */
  547. private void createUnaryCode(PrintStream stream, Unary op, String name) throws XflException {
  548. stream.println("static double "+name+"(double a) {");
  549. Parameter singleparam[] = op.getSingleParameters();
  550. for(int i=0; i<singleparam.length; i++) {
  551. stream.print(" double "+singleparam[i].getName());
  552. stream.println(" = "+singleparam[i].value+";");
  553. }
  554. String listname = op.getParamListName();
  555. if(listname != null && listname.length() > 0) {
  556. Parameter paramlist[] = op.getParamList();
  557. stream.print(" double "+listname+"["+paramlist.length+"] = {");
  558. for(int i=0; i<paramlist.length; i++)
  559. stream.print((i>0? ",":"")+paramlist[i].value);
  560. stream.println("};");
  561. }
  562. stream.println(op.getCCode());
  563. stream.println("}");
  564. stream.println();
  565. }
  566. /**
  567. * Descripción de un método de concreción
  568. */
  569. private void createDefuzCode(PrintStream stream, DefuzMethod op, String name) {
  570. String defuzcode = op.getCCode();
  571. stream.println("static double "+name+"(FuzzyNumber mf) {");
  572. if(defuzcode.indexOf("min")!=-1)
  573. stream.println(" double min = mf.min;");
  574. if(defuzcode.indexOf("max")!=-1)
  575. stream.println(" double max = mf.max;");
  576. if(defuzcode.indexOf("step")!=-1)
  577. stream.println(" double step = mf.step;");
  578. Parameter singleparam[] = op.getSingleParameters();
  579. for(int i=0; i<singleparam.length; i++) {
  580. stream.print(" double "+singleparam[i].getName());
  581. stream.println(" = "+singleparam[i].value+";");
  582. }
  583. String listname = op.getParamListName();
  584. if(listname != null && listname.length() > 0) {
  585. Parameter paramlist[] = op.getParamList();
  586. stream.print(" double "+listname+"["+paramlist.length+"] = {");
  587. for(int i=0; i<paramlist.length; i++)
  588. stream.print((i>0? ",":"")+paramlist[i].value);
  589. stream.println("};");
  590. }
  591. stream.println(defuzcode);
  592. stream.println("}");
  593. stream.println();
  594. }
  595. //----------------------------------------------------------------------------//
  596. // Métodos que generan el código de los tipos //
  597. //----------------------------------------------------------------------------//
  598. /**
  599. * Descripción de un tipo de variable lingüística
  600. */
  601. private void createTypeCode(PrintStream stream, Type type) throws XflException {
  602. Family[] fam = type.getFamilies();
  603. LinguisticLabel[] allmf = type.getAllMembershipFunctions();
  604. stream.println("/*======================================================*/");
  605. stream.println(complete("/* Type TP_"+type.getName()));
  606. stream.println("/*======================================================*/");
  607. stream.println();
  608. for(int i=0; i<fam.length; i++) {
  609. createTypeFamilyCode(stream,type,fam[i]);
  610. }
  611. for(int i=0; i<allmf.length; i++) {
  612. if(allmf[i] instanceof ParamMemFunc) {
  613. createTypePMFCode(stream, type, (ParamMemFunc) allmf[i]);
  614. } else {
  615. createTypeFMFCode(stream, type, (FamiliarMemFunc) allmf[i]);
  616. }
  617. }
  618. }
  619. /**
  620. * Descripción de una familia pertenenciente a un tipo de variable
  621. * @param stream
  622. * @param type
  623. * @param fam
  624. */
  625. private void createTypeFamilyCode(PrintStream stream, Type type, Family fam) {
  626. String typename = type.getName();
  627. double min = type.min();
  628. double max = type.max();
  629. double step = type.step();
  630. boolean isUsedAsInput = usage.isUsedAsInput(type);
  631. boolean isUsedAsOutput = usage.isUsedAsOutput(type);
  632. String famname = usage.getFamilyName(fam);
  633. Parameter single[] = fam.getSingleParameters();
  634. Parameter list[] = fam.getParamList();
  635. String listname = fam.getParamListName();
  636. if(listname == null || listname.length() == 0) list = null;
  637. stream.println("/*------------------------------------------------------*/");
  638. stream.println(complete("/* Description of the family "+fam));
  639. stream.println("/*------------------------------------------------------*/");
  640. stream.println();
  641. stream.println("static double TP_"+typename+"_"+fam+"_equal(double x, int i){");
  642. createParamListCode(stream,list);
  643. stream.print(" return "+famname+"_equal(x,i,"+min+","+max+","+step);
  644. createParamCallCode(stream,single,list);
  645. stream.println(");");
  646. stream.println("}");
  647. stream.println();
  648. if(isUsedAsInput && usage.isFamilyGreqUsed(famname)) {
  649. stream.println("static double TP_"+typename+"_"+fam+"_greq(double x, int i){");
  650. createParamListCode(stream,list);
  651. stream.print(" return "+famname+"_greq(x,i,"+min+","+max+","+step);
  652. createParamCallCode(stream,single,list);
  653. stream.println(");");
  654. stream.println("}");
  655. stream.println();
  656. }
  657. if(isUsedAsInput && usage.isFamilySmeqUsed(famname)) {
  658. stream.println("static double TP_"+typename+"_"+fam+"_smeq(double x, int i){");
  659. createParamListCode(stream,list);
  660. stream.print(" return "+famname+"_smeq(x,i,"+min+","+max+","+step);
  661. createParamCallCode(stream,single,list);
  662. stream.println(");");
  663. stream.println("}");
  664. stream.println();
  665. }
  666. if(isUsedAsOutput && usage.isFamilyParamUsed(famname)) {
  667. stream.println("static double TP_"+typename+"_"+fam+"_param(int index, int i){");
  668. createParamListCode(stream,list);
  669. stream.print(" return "+famname+"_param(index,i,"+min+","+max+","+step);
  670. createParamCallCode(stream,single,list);
  671. stream.println(");");
  672. stream.println("}");
  673. stream.println();
  674. }
  675. }
  676. /**
  677. * Descripción de las funciones asociadas a una función de pertenencia paramétrica
  678. * @param stream
  679. * @param type
  680. * @param pmf
  681. */
  682. private void createTypePMFCode(PrintStream stream, Type type, ParamMemFunc pmf) {
  683. String typename = type.getName();
  684. double min = type.min();
  685. double max = type.max();
  686. double step = type.step();
  687. boolean isUsedAsInput = usage.isUsedAsInput(type);
  688. boolean isUsedAsOutput = usage.isUsedAsOutput(type);
  689. String mfname = usage.getMFname(pmf);
  690. String labelname = "TP_"+typename+"_"+pmf;
  691. Parameter single[] = pmf.getSingleParameters();
  692. Parameter list[] = pmf.getParamList();
  693. String listname = pmf.getParamListName();
  694. if(listname == null || listname.length() == 0) list = null;
  695. stream.println("/*------------------------------------------------------*/");
  696. stream.println(complete("/* Description of the label "+pmf));
  697. stream.println("/*------------------------------------------------------*/");
  698. stream.println();
  699. stream.println("static double "+labelname+"_equal(double x){");
  700. createParamListCode(stream,list);
  701. stream.print(" return "+mfname+"_equal(x,"+min+","+max+","+step);
  702. createParamCallCode(stream,single,list);
  703. stream.println(");");
  704. stream.println("}");
  705. stream.println();
  706. if(isUsedAsInput && usage.isMFGreqUsed(mfname)) {
  707. stream.println("static double "+labelname+"_greq(double x){");
  708. createParamListCode(stream,list);
  709. stream.print(" return "+mfname+"_greq(x,"+min+","+max+","+step);
  710. createParamCallCode(stream,single,list);
  711. stream.println(");");
  712. stream.println("}");
  713. stream.println();
  714. }
  715. if(isUsedAsInput && usage.isMFSmeqUsed(mfname)) {
  716. stream.println("static double "+labelname+"_smeq(double x){");
  717. createParamListCode(stream,list);
  718. stream.print(" return "+mfname+"_smeq(x,"+min+","+max+","+step);
  719. createParamCallCode(stream,single,list);
  720. stream.println(");");
  721. stream.println("}");
  722. stream.println();
  723. }
  724. if(isUsedAsOutput && usage.isMFCenterUsed(mfname)) {
  725. double center = pmf.center();
  726. stream.println("static double "+labelname+"_center(){");
  727. stream.println(" return "+center+";");
  728. stream.println("}");
  729. stream.println();
  730. }
  731. if(isUsedAsOutput && usage.isMFBasisUsed(mfname)) {
  732. double basis = pmf.basis();
  733. stream.println("static double "+labelname+"_basis(){");
  734. stream.println(" return "+basis+";");
  735. stream.println("}");
  736. stream.println();
  737. }
  738. if(isUsedAsOutput && usage.isMFParamUsed(mfname)) {
  739. stream.println("static double "+labelname+"_param(int index){");
  740. createParamListCode(stream,list);
  741. stream.print(" return "+mfname+"_param(index,"+min+","+max+","+step);
  742. createParamCallCode(stream,single,list);
  743. stream.println(");");
  744. stream.println("}");
  745. stream.println();
  746. }
  747. }
  748. /**
  749. * Descripción de las funciones asociadas a una función de pertenencia familiar
  750. * @param stream
  751. * @param type
  752. * @param fmf
  753. */
  754. private void createTypeFMFCode(PrintStream stream, Type type, FamiliarMemFunc fmf) {
  755. String typename = type.getName();
  756. Family fam = fmf.getFamily();
  757. int index = fmf.getIndex();
  758. boolean isUsedAsInput = usage.isUsedAsInput(type);
  759. boolean isUsedAsOutput = usage.isUsedAsOutput(type);
  760. String famname = "TP_"+typename+"_"+fam;
  761. String labelname = "TP_"+typename+"_"+fmf;
  762. String classname = usage.getFamilyName(fam);
  763. stream.println("/*------------------------------------------------------*/");
  764. stream.println(complete("/* Description of the label "+fmf));
  765. stream.println("/*------------------------------------------------------*/");
  766. stream.println();
  767. stream.println("static double "+labelname+"_equal(double x){");
  768. stream.print(" return "+famname+"_equal(x,"+index+");");
  769. stream.println("}");
  770. stream.println();
  771. if(isUsedAsInput && usage.isFamilyGreqUsed(classname)) {
  772. stream.println("static double "+labelname+"_greq(double x){");
  773. stream.println(" return "+famname+"_greq(x,"+index+");");
  774. stream.println("}");
  775. stream.println();
  776. }
  777. if(isUsedAsInput && usage.isFamilySmeqUsed(classname)) {
  778. stream.println("static double "+labelname+"_smeq(double x){");
  779. stream.println(" return "+famname+"_smeq(x,"+index+");");
  780. stream.println("}");
  781. stream.println();
  782. }
  783. if(isUsedAsOutput && usage.isFamilyCenterUsed(classname)) {
  784. double center = fmf.center();
  785. stream.println("static double "+labelname+"_center(){");
  786. stream.println(" return "+center+";");
  787. stream.println("}");
  788. stream.println();
  789. }
  790. if(isUsedAsOutput && usage.isFamilyBasisUsed(classname)) {
  791. double basis = fmf.basis();
  792. stream.println("static double "+labelname+"_basis(){");
  793. stream.println(" return "+basis+";");
  794. stream.println("}");
  795. stream.println();
  796. }
  797. if(isUsedAsOutput && usage.isFamilyParamUsed(classname)) {
  798. stream.println("static double "+labelname+"_param(int index){");
  799. stream.println(" return "+famname+"_param(index,"+index+");");
  800. stream.println("}");
  801. stream.println();
  802. }
  803. }
  804. /**
  805. * Crea la declaración de la lista de parámetros
  806. * @param stream
  807. * @param list
  808. */
  809. private void createParamListCode(PrintStream stream, Parameter[] list) {
  810. if(list == null) return;
  811. stream.print(" double list["+list.length+"] = {");
  812. for(int i=0; i<list.length; i++) stream.print((i==0? "":",")+list[i].value);
  813. stream.println("};");
  814. }
  815. /**
  816. * Escribe los valores de los parámetros en una llamada
  817. * @param stream
  818. * @param single
  819. * @param list
  820. */
  821. private void createParamCallCode(PrintStream stream, Parameter[] single, Parameter[] list) {
  822. for(int i=0; i<single.length; i++) {
  823. stream.print(","+single[i].value);
  824. }
  825. if(list != null) {
  826. stream.print(",list,"+list.length);
  827. }
  828. }
  829. //----------------------------------------------------------------------------//
  830. // Métodos que generan el código de las bases de reglas //
  831. //----------------------------------------------------------------------------//
  832. /**
  833. * Descripcion de una base de reglas
  834. */
  835. private void createRulebaseCode(PrintStream stream, Rulebase base) throws XflException {
  836. String rbname = base.getName();
  837. Operatorset opset = base.getOperatorset();
  838. boolean center = usage.isCenterUsed(opset.defuz);
  839. boolean basis = usage.isBasisUsed(opset.defuz);
  840. boolean param = usage.isParamUsed(opset.defuz);
  841. boolean input = usage.isInputUsed(opset.defuz);
  842. String opsetname = "OP_"+opset.getName()+"_";
  843. Variable[] inputvar = base.getInputs();
  844. Variable[] outputvar = base.getOutputs();
  845. Rule[] rule = base.getRules();
  846. stream.println("/*======================================================*/");
  847. stream.println(complete("/* Rulebase RL_"+rbname));
  848. stream.println("/*======================================================*/");
  849. stream.println();
  850. stream.print("static void RL_"+rbname+"(");
  851. for(int i=0; i<inputvar.length; i++)
  852. stream.print((i==0? "": ", ")+"double "+inputvar[i]);
  853. for(int i=0; i<outputvar.length; i++)
  854. stream.print(", double *"+outputvar[i]);
  855. stream.println(") {");
  856. stream.println(" double _rl;");
  857. stream.println();
  858. if(input) {
  859. stream.println(" double _input["+inputvar.length+"];");
  860. for(int i=0; i<inputvar.length; i++) {
  861. stream.println(" _input["+i+"] = "+inputvar[i]+";");
  862. }
  863. stream.println();
  864. }
  865. for(int i=0; i<outputvar.length; i++) {
  866. createRulebaseOutputInitialization(stream,base,outputvar[i]);
  867. }
  868. for(int i=0; i<inputvar.length; i++) {
  869. createRulebaseInputInitialization(stream,base,inputvar[i]);
  870. }
  871. for(int i=0; i<rule.length; i++) {
  872. createRuleCode(stream,rule[i],opsetname,center,basis,param);
  873. }
  874. for(int i=0; i<outputvar.length; i++) {
  875. stream.print(" *"+outputvar[i]+" = "+opsetname+"Defuz(");
  876. stream.println("_"+outputvar[i]+");");
  877. }
  878. stream.println("}");
  879. stream.println();
  880. }
  881. /**
  882. * Código de inicialización de la salida de una base de reglas
  883. * @param stream
  884. * @param base
  885. * @param output
  886. */
  887. private void createRulebaseOutputInitialization(PrintStream stream, Rulebase base, Variable output){
  888. Operatorset opset = base.getOperatorset();
  889. boolean imp_also = usage.isComputeUsed(opset.defuz);
  890. boolean input = usage.isInputUsed(opset.defuz);
  891. String opsetname = "OP_"+opset.getName()+"_";
  892. int inputlength = base.getInputs().length;
  893. /* Contar el número de conclusiones */
  894. int outputcount = getNumberOfConsequents(base,output);
  895. double min = output.getType().min();
  896. double max = output.getType().max();
  897. double step = output.getType().step();
  898. stream.println(" double _"+output+"_degree["+outputcount+"];");
  899. stream.println(" Consequent _"+output+"_conc["+outputcount+"];");
  900. stream.println(" FuzzyNumber _"+output+";");
  901. stream.println(" _"+output+".min = "+min+";");
  902. stream.println(" _"+output+".max = "+max+";");
  903. stream.println(" _"+output+".step = "+step+";");
  904. if(imp_also) {
  905. stream.println(" _"+output+".imp = "+opsetname+"Imp;");
  906. stream.println(" _"+output+".also = "+opsetname+"Also;");
  907. }
  908. if(input) {
  909. stream.println(" _"+output+".inputlength = "+inputlength+";");
  910. stream.println(" _"+output+".input = _input;");
  911. }
  912. stream.println(" _"+output+".length = "+outputcount+";");
  913. stream.println(" _"+output+".degree = _"+output+"_degree;");
  914. stream.println(" _"+output+".conc = _"+output+"_conc;");
  915. stream.println(" int _"+output+"_i = 0;");
  916. stream.println();
  917. }
  918. /**
  919. * Cuenta el número de veces que una variable de salida aparece en el
  920. * consecuente de una base de reglas
  921. * @param base
  922. * @param output
  923. * @return
  924. */
  925. private int getNumberOfConsequents(Rulebase base, Variable output) {
  926. Rule[] rule = base.getRules();
  927. int count = 0;
  928. for(int i=0; i<rule.length; i++) {
  929. Conclusion[] conc = rule[i].getConclusions();
  930. for(int j=0; j<conc.length; j++) {
  931. if(conc[j].getVariable() == output) count++;
  932. }
  933. }
  934. return count;
  935. }
  936. /**
  937. * Genera el código de inicialización de una variable de entrada de una
  938. * base de reglas.
  939. *
  940. * @param stream
  941. * @param base
  942. * @param input
  943. */
  944. private void createRulebaseInputInitialization(PrintStream stream, Rulebase base, Variable input) {
  945. LinguisticLabel[] label = input.getType().getAllMembershipFunctions();
  946. boolean[] lbGreqUsed = new boolean[label.length];
  947. boolean[] lbSmeqUsed = new boolean[label.length];
  948. boolean globalGreqUsed = false;
  949. boolean globalSmeqUsed = false;
  950. for(int i=0; i<label.length; i++) {
  951. if(label[i] instanceof ParamMemFunc) {
  952. String mfname = usage.getMFname( (ParamMemFunc) label[i]);
  953. if(usage.isMFGreqUsed(mfname)) { lbGreqUsed[i] = true; globalGreqUsed = true; }
  954. if(usage.isMFSmeqUsed(mfname)) { lbSmeqUsed[i] = true; globalSmeqUsed = true; }
  955. } else {
  956. FamiliarMemFunc fmf = (FamiliarMemFunc) label[i];
  957. String famname = usage.getFamilyName(fmf.getFamily());
  958. if(usage.isFamilyGreqUsed(famname)) { lbGreqUsed[i] = true; globalGreqUsed = true; }
  959. if(usage.isFamilySmeqUsed(famname)) { lbSmeqUsed[i] = true; globalSmeqUsed = true; }
  960. }
  961. }
  962. stream.println(" double _"+input+"_eq["+label.length+"];");
  963. if(globalGreqUsed) stream.println(" double _"+input+"_greq["+label.length+"];");
  964. if(globalSmeqUsed) stream.println(" double _"+input+"_smeq["+label.length+"];");
  965. for(int i=0; i<label.length; i++) {
  966. String lbname = "TP_"+input.getType().getName()+"_"+label[i].getLabel();
  967. stream.print(" _"+input+"_eq["+i+"] = ");
  968. stream.println(lbname+"_equal("+input+");");
  969. if(lbGreqUsed[i]) {
  970. stream.print(" _"+input+"_greq["+i+"] = ");
  971. stream.println(lbname+"_greq("+input+");");
  972. }
  973. if(lbSmeqUsed[i]) {
  974. stream.print(" _"+input+"_smeq["+i+"] = ");
  975. stream.println(lbname+"_smeq("+input+");");
  976. }
  977. }
  978. stream.println();
  979. }
  980. /**
  981. * Descripción de una regla
  982. */
  983. private void createRuleCode(PrintStream stream, Rule rule, String op, boolean center, boolean basis, boolean param) throws XflException {
  984. double degree = rule.getDegree();
  985. Relation premise = rule.getPremise();
  986. Conclusion[] conc = rule.getConclusions();
  987. stream.print(" _rl = ");
  988. stream.println(createRelationCode(premise, op)+";");
  989. if(degree != 1.0) stream.println(" _rl = "+degree+" * _rl;");
  990. for(int j=0; j<conc.length; j++) createConclusionCode(stream,conc[j],center,basis,param);
  991. stream.println();
  992. }
  993. /**
  994. * Descripción de una conclusión de una regla
  995. */
  996. private void createConclusionCode(PrintStream stream, Conclusion conc, boolean center, boolean basis, boolean param)
  997. throws XflException {
  998. Variable var = conc.getVariable();
  999. LinguisticLabel mf = conc.getMembershipFunction();
  1000. String mfname = "TP_"+var.getType().getName()+"_"+mf.getLabel()+"_";
  1001. stream.println(" _"+var+"_degree[_"+var+"_i] = _rl;");
  1002. stream.println(" _"+var+"_conc[_"+var+"_i].equal = "+mfname+"equal;");
  1003. if(center) stream.println(" _"+var+"_conc[_"+var+"_i].center = "+mfname+"center;");
  1004. if(basis) stream.println(" _"+var+"_conc[_"+var+"_i].basis = "+mfname+"basis;");
  1005. if(param) stream.println(" _"+var+"_conc[_"+var+"_i].param = "+mfname+"param;");
  1006. stream.println(" _"+var+"_i++;");
  1007. }
  1008. /**
  1009. * Descripción de una proposición de una regla
  1010. */
  1011. private String createRelationCode(Relation rel, String op) throws XflException {
  1012. Variable var = rel.getVariable();
  1013. LinguisticLabel mf = rel.getMembershipFunction();
  1014. Relation l = rel.getLeftRelation();
  1015. Relation r = rel.getRightRelation();
  1016. int index = 0;
  1017. if(mf != null) {
  1018. LinguisticLabel[] lb = var.getType().getAllMembershipFunctions();
  1019. for(int i=0; i<lb.length; i++) if(lb[i] == mf) index = i;
  1020. }
  1021. switch(rel.getKind()) {
  1022. case Relation.AND:
  1023. return op+"And("+createRelationCode(l,op)+","+createRelationCode(r,op)+")";
  1024. case Relation.OR:
  1025. return op+"Or("+createRelationCode(l,op)+","+createRelationCode(r,op)+")";
  1026. case Relation.IS:
  1027. return "_"+var+"_eq["+index+"]";
  1028. case Relation.ISNOT:
  1029. return op+"Not( _"+var+"_eq["+index+"] )";
  1030. case Relation.GR_EQ:
  1031. return "_"+var+"_greq["+index+"]";
  1032. case Relation.SM_EQ:
  1033. return "_"+var+"_smeq["+index+"]";
  1034. case Relation.GREATER:
  1035. return op+"Not( _"+var+"_smeq["+index+"] )";
  1036. case Relation.SMALLER:
  1037. return op+"Not( _"+var+"_greq["+var+"] )";
  1038. case Relation.APP_EQ:
  1039. return op+"MoreOrLess( _"+var+"_eq["+index+"] )";
  1040. case Relation.VERY_EQ:
  1041. return op+"Very( _"+var+"_eq["+index+"] )";
  1042. case Relation.SL_EQ:
  1043. return op+"Slightly( _"+var+"_eq["+index+"] )";
  1044. case Relation.NOT:
  1045. return op+"Not("+createRelationCode(r,op)+")";
  1046. case Relation.MoL:
  1047. return op+"MoreOrLess("+createRelationCode(r,op)+")";
  1048. case Relation.SLIGHTLY:
  1049. return op+"Slightly("+createRelationCode(r,op)+")";
  1050. case Relation.VERY:
  1051. return op+"Very("+createRelationCode(r,op)+")";
  1052. default: return "";
  1053. }
  1054. }
  1055. //----------------------------------------------------------------------------//
  1056. // Métodos que generan el código de un bloque no difuso //
  1057. //----------------------------------------------------------------------------//
  1058. /**
  1059. * Descripción de un bloque no difuso
  1060. */
  1061. private void createCrispBlockCode(PrintStream stream, CrispBlock crisp) throws XflException {
  1062. String name = crisp.getName();
  1063. int inputs = crisp.inputs();
  1064. stream.println("/*======================================================*/");
  1065. stream.println(complete("/* CrispBlock CB_"+name));
  1066. stream.println("/*======================================================*/");
  1067. stream.println();
  1068. stream.print("static double CB_"+name+"(");
  1069. for(int i=0; i<inputs; i++) stream.print((i==0? "":", ")+"double _i"+i);
  1070. stream.println(") {");
  1071. Parameter singleparam[] = crisp.getSingleParameters();
  1072. for(int i=0; i<singleparam.length; i++) {
  1073. stream.print(" double "+singleparam[i].getName());
  1074. stream.println(" = "+singleparam[i].value+";");
  1075. }
  1076. if(crisp.hasParamList()) {
  1077. Parameter paramlist[] = crisp.getParamList();
  1078. int listlength = (paramlist == null? 0 : paramlist.length);
  1079. stream.print(" double "+crisp.getParamListName()+"["+listlength+"] = {");
  1080. for(int i=0; i<listlength; i++)
  1081. stream.print((i>0? ",":"")+paramlist[i].value);
  1082. stream.println("};");
  1083. }
  1084. stream.println(" double x["+inputs+"];");
  1085. for(int i=0; i<inputs; i++) stream.println(" x["+i+"] = _i"+i+";");
  1086. stream.println(crisp.getCCode());
  1087. stream.println("}");
  1088. stream.println();
  1089. }
  1090. //----------------------------------------------------------------------------//
  1091. // Métodos que generan el código de ejecución del sistema //
  1092. //----------------------------------------------------------------------------//
  1093. /**
  1094. * Descripción de la estructura jerárquica del sistema
  1095. */
  1096. private void createSystemModuleCode(PrintStream stream) throws XflException {
  1097. SystemModule system = spec.getSystemModule();
  1098. Variable input[] = system.getInputs();
  1099. Variable output[] = system.getOutputs();
  1100. Variable inner[] = system.getInners();
  1101. ModuleCall call[] = system.getModuleCalls();
  1102. String name = spec.getName()+"InferenceEngine";
  1103. stream.println();
  1104. stream.println("/*======================================================*/");
  1105. stream.println("/* Inference Engine */");
  1106. stream.println("/*======================================================*/");
  1107. stream.println();
  1108. stream.print("void "+name+"(");
  1109. for(int i=0; i<input.length; i++)
  1110. stream.print((i==0? "" : ", ")+"double "+input[i]);
  1111. for(int i=0; i<output.length; i++)
  1112. stream.print(", double *_d_"+output[i]);
  1113. stream.println(") {");
  1114. for(int i=0; i<inner.length; i++) {
  1115. if(!inner[i].equals("NULL")) stream.println(" double "+inner[i]+";");
  1116. }
  1117. for(int i=0; i<output.length; i++) stream.println(" double "+output[i]+";");
  1118. for(int i=0; i<call.length; i++) if(call[i] instanceof RulebaseCall) {
  1119. createRulebaseCallCode(stream, (RulebaseCall) call[i]);
  1120. } else createCrispBlockCallCode( stream, (CrispBlockCall) call[i]);
  1121. for(int i=0; i<output.length; i++) {
  1122. stream.println(" *_d_"+output[i]+" = "+output[i]+";");
  1123. }
  1124. stream.println("}");
  1125. stream.println();
  1126. }
  1127. /**
  1128. * Descripción de una llamada a una base de reglas
  1129. */
  1130. private void createRulebaseCallCode(PrintStream stream, RulebaseCall call) throws XflException {
  1131. Rulebase base = call.getRulebase();
  1132. Variable[] inputvar = call.getInputVariables();
  1133. Variable[] outputvar = call.getOutputVariables();
  1134. stream.print(" RL_"+base+"(");
  1135. for(int i=0; i < inputvar.length; i++) stream.print((i==0? "" : ", ")+inputvar[i]);
  1136. for(int i=0; i < outputvar.length; i++) stream.print(", &"+outputvar[i]);
  1137. stream.println(");");
  1138. }
  1139. /**
  1140. * Descripción de una llamada a un bloque no difuso
  1141. */
  1142. private void createCrispBlockCallCode(PrintStream stream, CrispBlockCall call)
  1143. throws XflException {
  1144. Variable[] inputvar = call.getInputVariables();
  1145. Variable outputvar = call.getOutputVariable();
  1146. stream.print(" "+outputvar+" = CB_"+call.getName()+"(");
  1147. for(int j=0; j < inputvar.length; j++) stream.print((j==0? "":",")+inputvar[j]);
  1148. stream.println(");");
  1149. }
  1150. //----------------------------------------------------------------------------//
  1151. // Métodos auxiliares //
  1152. //----------------------------------------------------------------------------//
  1153. /**
  1154. * Completa la cadena hasta 58 caracteres
  1155. */
  1156. private String complete(String begining) {
  1157. String line = begining;
  1158. for(int i=begining.length(); i<56; i++) line += " ";
  1159. line += "*/";
  1160. return line;
  1161. }
  1162. }