home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 9 / 09.iso / e / e065 / 3.ddi / BSBWH.C < prev    next >
Encoding:
C/C++ Source or Header  |  1991-08-28  |  28.0 KB  |  925 lines

  1. /* 15:40 04-Jul-88  (bsbwh.c)  Brain-State-in-a-Box, Widrow-Hoff learning */
  2.  
  3. /************************************************************************
  4.  * Copyright(C) 1988-1990 NeuralWare Inc        *
  5.  * Penn Center West, IV-227, Pittsburgh, PA 15276     *
  6.  *                  *
  7.  * All rights reserved.  No part of this program may be reproduced, *
  8.  * stored in a retrieval system, or transmitted, in any form or by any  *
  9.  * means, electronic, mechanical, photocopying, recording or otherwise  *
  10.  * without the prior written permission of the copyright owner,   *
  11.  * NeuralWare, Inc.             *
  12.  ************************************************************************
  13.  */
  14.  
  15.  
  16. #include "userutl.h"
  17. #include <string.h>
  18. #ifndef SUN
  19. #ifndef DLC
  20. #include <stdlib.h>
  21. #endif
  22. #endif
  23.  
  24. #ifdef MAC
  25. #include "macuio.redef"
  26. #endif
  27. /************************************************************************
  28.  *                  *
  29.  *  User I/O for Brain-State-in-a-Box Widrow-Hoff Example   *
  30.  *                  *
  31.  ************************************************************************
  32.     The data examples contained in this module can be written to a
  33.     standard ".nna" Ascii File by "EXECUTE NETWORK/ATTENTION".
  34.  */
  35.  
  36. #define ORGANISM  0
  37. #define TYPE_ORG  1
  38. #define DISEASE   2
  39. #define DRUG1   3
  40. #define SIDE_EFF  4
  41. #define M_ADMIN   5
  42. #define DRUG2   6
  43.  
  44. #define N_CATEG   7 /* Number of categories */
  45.  
  46. #define N_ORG   16
  47. #define N_TYO   7
  48. #define N_DIS   15
  49. #define N_SID   5
  50. #define N_ADM   3
  51. #define N_DRG   8
  52.  
  53. #define NULL_STR    0
  54.  
  55. /* Indices into arrays */
  56. static  int  curr_index[N_CATEG] = {0};
  57.  
  58. static  int  num_words[N_CATEG] =
  59.        { N_ORG, N_TYO, N_DIS, N_DRG, N_SID, N_ADM, N_DRG };
  60. static  int  pos_abbrev[N_CATEG] = { 0, 8, 12, 18, 4, 13, 18 };
  61.  
  62. static  char  **c_cat_array[N_CATEG] = {0};
  63. static  char  **a_cat_array[N_CATEG] = {0};
  64.  
  65. static  short  curr_mode = 0;
  66.  
  67. static char *c_organism[] = { /* Complete words for organisms */
  68.  NULL_STR, NULL_STR, NULL_STR, NULL_STR,
  69.  NULL_STR, NULL_STR, NULL_STR, NULL_STR,
  70.  NULL_STR, NULL_STR, NULL_STR, NULL_STR,
  71.  NULL_STR, NULL_STR, NULL_STR, NULL_STR
  72. };
  73. static char *a_organism[] = { /* Abbreviated words for organisms */
  74.  NULL_STR, NULL_STR, NULL_STR, NULL_STR,
  75.  NULL_STR, NULL_STR, NULL_STR, NULL_STR,
  76.  NULL_STR, NULL_STR, NULL_STR, NULL_STR,
  77.  NULL_STR, NULL_STR, NULL_STR, NULL_STR
  78. };
  79. static char *c_type_org[] = { /* Complete words for organism types */
  80.  NULL_STR, NULL_STR, NULL_STR,
  81.  NULL_STR, NULL_STR, NULL_STR,
  82.  NULL_STR
  83. };
  84. static  char    *a_type_org[] = { /* Abbrev words for organism types */
  85.  NULL_STR, NULL_STR, NULL_STR,
  86.  NULL_STR, NULL_STR, NULL_STR,
  87.  NULL_STR
  88. };
  89. static  char    *c_disease[] = { /* Complete words for diseases */
  90.  NULL_STR, NULL_STR, NULL_STR, NULL_STR,
  91.  NULL_STR, NULL_STR, NULL_STR, NULL_STR,
  92.  NULL_STR, NULL_STR, NULL_STR, NULL_STR,
  93.  NULL_STR, NULL_STR, NULL_STR
  94. };
  95. static  char    *a_disease[] = { /* Abbreviated words for diseases */
  96.  NULL_STR, NULL_STR, NULL_STR, NULL_STR,
  97.  NULL_STR, NULL_STR, NULL_STR, NULL_STR,
  98.  NULL_STR, NULL_STR, NULL_STR, NULL_STR,
  99.  NULL_STR, NULL_STR, NULL_STR
  100. };
  101. static  char    *c_side_eff[] = { /* Side effects */
  102.  NULL_STR, NULL_STR, NULL_STR,
  103.  NULL_STR, NULL_STR
  104. };
  105. static  char    *a_side_eff[] = { /* Side effects ( abbrev ) */
  106.  NULL_STR, NULL_STR, NULL_STR,
  107.  NULL_STR, NULL_STR
  108. };
  109. static  char    *c_m_admin[] = { /* Methods of administration */
  110.  NULL_STR, NULL_STR, NULL_STR
  111. };
  112. static  char    *a_m_admin[] = { /* Meth admin */
  113.  NULL_STR, NULL_STR, NULL_STR
  114. };
  115. static  char    *c_drug[] = { /* Drugs */
  116.  NULL_STR, NULL_STR, NULL_STR,
  117.  NULL_STR, NULL_STR, NULL_STR,
  118.  NULL_STR, NULL_STR
  119. };
  120. static  char    *a_drug[] = { /* Drgs */
  121.  NULL_STR, NULL_STR, NULL_STR,
  122.  NULL_STR, NULL_STR, NULL_STR,
  123.  NULL_STR, NULL_STR
  124. };
  125.  
  126. /* Local menu definitions */
  127.  
  128. static  char    *mode_text[] = { /* menu text for mode option */
  129.  NULL_STR, NULL_STR
  130. };
  131.  
  132. #define M_MODE    0
  133. #define M_CLEAR   1
  134. #define M_ENTER   2
  135. #define M_QUIT    3
  136.  
  137. #define M_INPUT   0
  138.  
  139. #define M_OUTPUT  0
  140.  
  141. static GMENU_ITEM Cat1List[] = { /* Menu List */
  142.     { ORGANISM, NULL_STR, NULL_STR },
  143.     { TYPE_ORG, NULL_STR, NULL_STR },
  144.     { DISEASE,  NULL_STR, NULL_STR },
  145.     { DRUG1,     NULL_STR, NULL_STR }
  146. };
  147.  
  148. static GMENU_ITEM Cat2List[] = { /* Menu List */
  149.     { SIDE_EFF, NULL_STR, NULL_STR  },
  150.     { M_ADMIN,  NULL_STR, NULL_STR },
  151.     { DRUG2,      NULL_STR, NULL_STR }
  152. };
  153. static GMENU_ITEM UtList[] = { /* Menu List */
  154.       { M_MODE,     NULL_STR, NULL_STR },
  155.       { M_CLEAR,    NULL_STR, NULL_STR },
  156.       { M_ENTER,    NULL_STR, NULL_STR },
  157.       { M_QUIT,     NULL_STR, NULL_STR }
  158. };
  159. static GMENU_ITEM InItem = 
  160.     { M_INPUT, NULL_STR, NULL_STR , 0x0002 };
  161. static GMENU_ITEM OutItem = 
  162.     { M_OUTPUT, NULL_STR, NULL_STR , 0x0002 };
  163.  
  164. static GMENU  CatMenu[2]  = { /* Category menus */
  165.   { 0,    /* Organism mode */
  166.   4,        /* 4 items */
  167.   1       /* key */
  168.   },
  169.   { 0,    /* Side effect mode */
  170.   3,        /* 3 items */
  171.   1       /* key */
  172.   }
  173. };
  174.  
  175. static GMENU  UtMenu = {  /* Utility menu */
  176.   0,
  177.   4,        /* 4 items */
  178.   2       /* key */
  179. };
  180.  
  181. static GMENU  InpMenu = { /* Displays abbreviated input vector */
  182.   0,
  183.   1,        /* 1 item */
  184.   3       /* key */
  185. };
  186.  
  187. static GMENU  OutMenu = { /* Displays abbreviated ouput vector */
  188.   0,
  189.   1,        /* 1 item */
  190.   4       /* key */
  191. };
  192.  
  193. /* menu window positions */
  194. static int  x_cat,y_cat,x_cat1,x_ut,y_ut,x_inp,y_inp,x_out,y_out;
  195.  
  196. #ifdef PROTOTYPING
  197. /* --- prototypes --- */
  198. void    abbreviate( int );
  199. void    encode( int, float * );
  200. char  decode( float *, double );
  201. #endif
  202.  
  203. void abbreviate( item ) /* abbreviate Input vector */
  204. int item; /* item to abbreviate ( all = -1 ) */
  205. {
  206.   if ( item == -1 ) {
  207.     if ( curr_mode == 0 ) {
  208.       strcpy( InItem.text, a_organism[curr_index[ORGANISM]] );
  209.       strcat( InItem.text, a_type_org[curr_index[TYPE_ORG]] );
  210.       strcat( InItem.text, a_disease[curr_index[DISEASE]] );
  211.       strcat( InItem.text, a_drug[curr_index[DRUG1]] );
  212.     } else if ( curr_mode == 1 ) {
  213.       strcpy( InItem.text, "SiEf" );
  214.       strcat( InItem.text, a_side_eff[curr_index[SIDE_EFF]] );
  215.       strcat( InItem.text, a_m_admin[curr_index[M_ADMIN]] );
  216.       strcat( InItem.text, a_drug[curr_index[DRUG2]] );
  217.     }
  218.   } else {
  219.     if ( item == SIDE_EFF ) strncpy( InItem.text, "SiEf", 4 );
  220.     strncpy( &InItem.text[pos_abbrev[item]],
  221.       a_cat_array[item][curr_index[item]],
  222.       strlen( a_cat_array[item][0] ) );
  223.   }
  224. }
  225.  
  226. void encode( a, vp )
  227. int a;  /* character to encode */
  228. float *vp;  /* pointer to vector of floats containing encoded char */
  229. {
  230.   unsigned char   wa;
  231.   unsigned char mask;
  232.   int   wx, parity;
  233.  
  234.   if ( a == '_' ) wa = 0xff;
  235.   else if ( a >= 'a' && a <= 'z' ) wa = a - 'a';
  236.   else if ( a >= 'A' && a <= 'Z' ) wa = a - 'A';
  237.   else if ( a == '+' ) wa = 26;
  238.   else if ( a == '-' ) wa = 27;
  239.   else if ( a == '.' ) wa = 28;
  240.   else if ( a == ' ' ) wa = 29;
  241.   else wa = 30;
  242.  
  243.   /* Find parity */
  244.   parity = 0;
  245.   for ( wx = 0, mask = 0x10; wx < 5; wx++, mask >>= 1 )
  246.     if ( (wa & mask) != 0 ) parity++;
  247.   parity %= 2;
  248.   
  249.   if ( a >= 'A' && a <= 'Z' ) { /* Make capitals odd parity */
  250.     if (parity == 0) wa |= 0x20;
  251.   } else if ( a != '_' ) { /* make rest even parity */
  252.     if ( parity ) wa |= 0x20;
  253.   }
  254.   
  255.   for ( wx = 0, mask = 0x20; wx < 6; wx++, mask >>= 1 ) {
  256.     if ( wa == 0xff ) vp[wx] = 0.0;
  257.     else if ( (wa & mask) != 0 ) vp[wx] = 1.0;
  258.     else vp[wx] = -1.0;
  259.   }
  260. }
  261.   
  262. char decode( vp, thr )  /* Returns character */
  263. float *vp;  /* vector of floats containing encoded char */
  264. double  thr;  /* threshold to determine ON/OFF */
  265. {
  266.   unsigned char wa;
  267.   char    rc;
  268.   unsigned char mask;
  269.   int   wx, parity;
  270.  
  271.   wa = 0;
  272.  
  273.   for ( wx = 0, mask = 0x20; wx < 6; wx++, mask >>= 1 ) {
  274.     if ( vp[wx] >= thr ) wa |= mask;
  275.     else if ( vp[wx] > -thr ) { /* if between thresholds set all to 0 */
  276.       wa = 0xff;
  277.       break;
  278.     }
  279.   }
  280.  
  281.   /* Find parity */
  282.   parity = 0;
  283.   for ( wx = 0, mask = 0x20; wx < 6; wx++, mask >>= 1 )
  284.     if ( (wa & mask) != 0 ) parity++;
  285.   parity %= 2;
  286.   
  287.   if ( wa == 0xff ) rc = '_';
  288.   else if ( parity ) { /* odd parity - check for capitals */
  289.     wa &= 0x001f;
  290.     if ( wa >= 0 && wa < 26 ) rc = wa + 'A';
  291.     else rc = '?';
  292.   } else { /* Even parity - check for rest */
  293.     wa &= 0x001f;
  294.     if ( wa >= 0 && wa < 26 ) rc = wa + 'a';
  295.     else if ( wa == 26 ) rc = '+';
  296.     else if ( wa == 27 ) rc = '-';
  297.     else if ( wa == 28 ) rc = '.';
  298.     else if ( wa == 29 ) rc = ' ';
  299.     else rc = '?';
  300.   }
  301.   
  302.   return( rc );
  303. }
  304.   
  305. /************************************************************************
  306.  *                  *
  307.  *  UsrIO - user I/O routine to handle requests from NWORKS   *
  308.  *                  *
  309.  ************************************************************************
  310.  */
  311.  
  312. static int InitFlag = 0;    /* initialize things flag */
  313.  
  314. int UsrIO()     /* handle NWORKS requests */
  315. {
  316.     GMENU_ITEM  *gmip;
  317.     char *sp;         /* string pointer */
  318.     char  buf[100];       /* character buffer */
  319.     int   wx, wy;       /* work indices */
  320.     int   key, xp, yp, button;      /* mouse parameters */
  321.     int  *ci, nw;
  322.     int   xsize, ysize, ncolor, chrx, chry; /* graphics parameters */
  323.     int   iv_num;       /* input vector number */
  324.     static int   wr_count;      /* count for RQ_WRSTEP */
  325.     float wr[6], *p_outv;
  326.     FILE *asc_fp;
  327.     static char InItemTextBuf[30] = {0};  /* work buffer */
  328.     static char OutItemTextBuf[30] = {0}; /* second work buffer */
  329.  
  330.   if ( InitFlag == 0 ) {
  331.   /* open any files which may be required at this point in the
  332.      code. */
  333.   /* Complete words for organisms */
  334.   c_organism[0] = "               ";
  335.   c_organism[1] = "Staphylococcus ";
  336.   c_organism[2] = "Streptococcus  ";
  337.   c_organism[3] = "Neisseria      ";
  338.   c_organism[4] = "Corynebacterium";
  339.   c_organism[5] = "Clostridium        ";
  340.   c_organism[6] = "Enterobacter   ";
  341.   c_organism[7] = "Salmonella         ";
  342.   c_organism[8] = "Treponema      ";
  343.   c_organism[9] = "Candida            ";
  344.   c_organism[10] = "Histoplasma    ";
  345.   c_organism[11] = "Escherichia        ";
  346.   c_organism[12] = "Proteus        ";
  347.   c_organism[13] = "Yersinia           ";
  348.   c_organism[14] = "Cryptococcus   ";
  349.   c_organism[15] = "Aspergillus        ";
  350.  
  351.   /* Abbreviated words for organisms */
  352.   a_organism[0] = "________";
  353.   a_organism[1] = "Staphaur";
  354.   a_organism[2] = "Streptop";
  355.   a_organism[3] = "Neisseri";
  356.   a_organism[4] = "Coryneba";
  357.   a_organism[5] = "Clostrid";
  358.   a_organism[6] = "Enteroba";
  359.   a_organism[7] = "Salmonel";
  360.   a_organism[8] = "Treponem";
  361.   a_organism[9] = "Candidaa";
  362.   a_organism[10] = "Histopla";
  363.   a_organism[11] = "E. Coli ";
  364.   a_organism[12] = "Proteus ";
  365.   a_organism[13] = "Yersinap";
  366.   a_organism[14] = "Cryptoco";
  367.   a_organism[15] = "Aspergil";
  368.  
  369.   /* Complete words for organism types */
  370.   c_type_org[0] = "                 ";
  371.   c_type_org[1] = "Gram +ve coccus  ";
  372.   c_type_org[2] = "Gram -ve coccus      ";
  373.   c_type_org[3] = "Gram +ve bacillus";
  374.   c_type_org[4] = "Gram -ve bacillus";
  375.   c_type_org[5] = "Spirochetal          ";
  376.   c_type_org[6] = "Fungal           " ;
  377.  
  378.   /* Abbrev words for organism types */
  379.   a_type_org[0] = "____";
  380.   a_type_org[1] = "+coc";
  381.   a_type_org[2] = "-coc";
  382.   a_type_org[3] = "+bac";
  383.   a_type_org[4] = "-bac";
  384.   a_type_org[5] = "spir";
  385.   a_type_org[6] = "fung";
  386.     
  387.   /* Complete words for diseases */
  388.   c_disease[0] = "                 ";
  389.   c_disease[1] = "Endocarditis ";
  390.   c_disease[2] = "Pneumonia        ";
  391.   c_disease[3] = "Gonorrhea    ";
  392.   c_disease[4] = "Tetanus          ";
  393.   c_disease[5] = "Urinary Tract";
  394.   c_disease[6] = "Typhoid  ";
  395.   c_disease[7] = "Syphilis     ";
  396.   c_disease[8] = "Lesion           ";
  397.   c_disease[9] = "Meningitis       ";
  398.   c_disease[10] = "Scarlet Fever";
  399.   c_disease[11] = "Pharyngitis  ";
  400.   c_disease[12] = "Gangrene         ";
  401.   c_disease[13] = "Plague   ";
  402.   c_disease[14] = "Yaws         ";
  403.  
  404.   /* Abbreviated words for diseases */
  405.   a_disease[0] = "______";
  406.   a_disease[1] = "Endoca";
  407.   a_disease[2] = "Pneumo";
  408.   a_disease[3] = "Gonorh";
  409.   a_disease[4] = "Tetanu";
  410.   a_disease[5] = "UrTrIn";
  411.   a_disease[6] = "Typhoi";
  412.   a_disease[7] = "Syphil";
  413.   a_disease[8] = "Lesion";
  414.   a_disease[9] = "Mening";
  415.   a_disease[10] = "ScarFe";
  416.   a_disease[11] = "Pharyn";
  417.   a_disease[12] = "Gangre";
  418.   a_disease[13] = "Plague";
  419.   a_disease[14] = "Yaws      ";
  420.  
  421.   /* Side effects */ 
  422.   c_side_eff[0] = "                ";
  423.   c_side_eff[1] = "Hypersensitivity";
  424.   c_side_eff[2] = "Aplastic Anemia ";
  425.   c_side_eff[3] = "Ototoxicity     ";
  426.   c_side_eff[4] = "Kidneys             ";
  427.  
  428.     /* Side effects ( abbrev ) */
  429.     a_side_eff[0] = "_________";
  430.     a_side_eff[1] = "Hypersens";
  431.     a_side_eff[2] = "AplasticA";
  432.   a_side_eff[3] = "Ototoxic ";
  433.   a_side_eff[4] = "Kidneys++";
  434.  
  435.   /* Methods of administration */
  436.   c_m_admin[0] = "         ";
  437.   c_m_admin[1] = "Injection";
  438.   c_m_admin[2] = "Oral         ";
  439.  
  440.   /* Meth admin */
  441.   a_m_admin[0] = "_____";
  442.   a_m_admin[1] = "Inje ";
  443.   a_m_admin[2] = "Oral ";
  444.    
  445.   /* Drugs */
  446.   c_drug[0] = "               ";
  447.   c_drug[1] = "Penicillin         ";
  448.   c_drug[2] = "Ampicillin     ";
  449.   c_drug[3] = "Cephalosporin  ";
  450.   c_drug[4] = "Chloramphenicol";
  451.   c_drug[5] = "Amphotericin   ";
  452.   c_drug[6] = "Gentamycin     ";
  453.   c_drug[7] = "Tetracyclin        ";
  454.   
  455.   /* Drugs (abbrev)*/
  456.   a_drug[0] = "_______";
  457.   a_drug[1] = "Penicil";
  458.   a_drug[2] = "Ampicil";
  459.   a_drug[3] = "Cephalo";
  460.   a_drug[4] = "Chloram";
  461.   a_drug[5] = "Amphote";
  462.   a_drug[6] = "Gentamy";
  463.   a_drug[7] = "Tetracy";
  464.  
  465.   /* menu text for mode option */
  466.   mode_text[0] = "Mode: Disease         ";
  467.   mode_text[1] = "Mode: Side Effects";
  468.  
  469.   /* Menu List */
  470.   UtList[0].text = "Mode: Disease     ";
  471.   UtList[1].text = "Clear";
  472.   UtList[2].text = "Enter";
  473.   UtList[3].text = "Quit";
  474.   
  475.   strcpy( InItemTextBuf, "_________________________" );
  476.   strcpy( OutItemTextBuf, InItemTextBuf );
  477.   InItem.text  = &InItemTextBuf[0];
  478.   OutItem.text = &OutItemTextBuf[0];
  479.   
  480.   CatMenu[0].item  = Cat1List;
  481.   CatMenu[1].item  = Cat2List;
  482.   UtMenu.item  = UtList;
  483.   InpMenu.item  = &InItem;
  484.   OutMenu.item  = &OutItem;
  485.  
  486.     c_cat_array[ORGANISM] = &c_organism[0];
  487.   c_cat_array[TYPE_ORG] = &c_type_org[0];
  488.   c_cat_array[DISEASE]  = &c_disease[0];
  489.   c_cat_array[SIDE_EFF] = &c_side_eff[0];
  490.   c_cat_array[M_ADMIN]  = &c_m_admin[0];
  491.   c_cat_array[DRUG1]  = &c_drug[0];
  492.   c_cat_array[DRUG2]  = &c_drug[0];
  493.  
  494.   a_cat_array[ORGANISM] = &a_organism[0];
  495.   a_cat_array[TYPE_ORG] = &a_type_org[0];
  496.   a_cat_array[DISEASE]  = &a_disease[0];
  497.   a_cat_array[SIDE_EFF] = &a_side_eff[0];
  498.   a_cat_array[M_ADMIN]  = &a_m_admin[0];
  499.   a_cat_array[DRUG1]  = &a_drug[0];
  500.   a_cat_array[DRUG2]  = &a_drug[0];
  501.  
  502.   /* Initialize menu text */
  503.   for ( wy = 0; wy < 2; wy++ ) {
  504.     for ( wx = 0, gmip = CatMenu[wy].item; wx < CatMenu[wy].num_items;
  505.     wx++, gmip++ ) {
  506.       curr_index[gmip->code] = 1;
  507.       gmip->text = c_cat_array[gmip->code][1];
  508.     }
  509.   }
  510.   curr_mode = 0;
  511.   abbreviate( -1 );
  512.   
  513.   /* Get screen parameters */
  514.   ug_gparms( &xsize, &ysize, &ncolor, &chrx, &chry);
  515.   
  516.   if ( ncolor < 8 ) {
  517.     gm_intcolor = 1;
  518.     gm_txtcolor = 0;
  519.     gm_outcolor = 0;
  520.   } else {
  521.     gm_intcolor = 7;
  522.     gm_txtcolor = 4;
  523.     gm_outcolor = 0;
  524.   }
  525.  
  526.   /* Initialize menus and set window positions */
  527.   InitGMenu( &InpMenu, chrx, chry );
  528.   InitGMenu( &OutMenu, chrx, chry );
  529.   InitGMenu( &UtMenu, chrx, chry );
  530.   InitGMenu( &CatMenu[0], chrx, chry );
  531.   InitGMenu( &CatMenu[1], chrx, chry );
  532.   x_inp = (xsize - InpMenu.x1) / 2;
  533.   x_out = (xsize - OutMenu.x1) / 2;
  534.   x_ut = (xsize - UtMenu.x1) / 2;
  535.   if ( (wx = CatMenu[0].x1 - CatMenu[1].x1) >= 0 ) {
  536.     x_cat = (xsize - CatMenu[0].x1) / 2;
  537.     x_cat1 = x_cat + CatMenu[0].x1 + 2;
  538.     CatMenu[0].x0 = 0;
  539.     CatMenu[1].x0 = wx / 2;
  540.   } else {
  541.     x_cat = (xsize - CatMenu[1].x1) / 2;
  542.     x_cat1 = x_cat + CatMenu[1].x1 + 2;
  543.     CatMenu[0].x0 = - (wx / 2);
  544.     CatMenu[1].x0 = 0;
  545.   }
  546.   y_cat = ysize / 4;
  547.   y_ut = y_cat + 30;
  548.   y_out = y_ut + 30;
  549.   y_inp = y_out + 30;
  550.  
  551.   InpMenu.x0 = 0; /* Menu position relative to window */
  552.   InpMenu.y0 = 0;
  553.   OutMenu.x0 = 0; /* Menu position relative to window */
  554.   OutMenu.y0 = 0;
  555.   UtMenu.x0 = 0;  /* Menu position relative to window */
  556.   UtMenu.y0 = 0;
  557.   CatMenu[0].y0 = CatMenu[1].y0 = 0;
  558.  
  559.   InitFlag = 1;
  560.     }
  561.  
  562.     IORTNCDE = 0;       /* good return for data */
  563.     switch( IOREQCDE ) {
  564.     case RQ_ATTENTION:
  565.   /* This is invoked at the request of the user from the
  566.      execute menu.  It allows parameters to be changed or
  567.      altered.  Any graphics or other interactions are allowable
  568.      as usual for the other options.
  569.   */
  570.   asc_fp = (FILE * ) 0;
  571.   iv_num = 1;
  572.   PutStr("Create <.nna> file ? - previous bsbwh.nna will be deleted.\n");
  573.   PutStr( "Press right button to abort, left button to continue.\n" );
  574.   for ( ; ; ) {
  575.     ug_mouse( &key, &xp, &yp, &button );
  576.     if ( button == MBUT_RIGHT ) goto end_attn;
  577.     if ( button == MBUT_LEFT  ) break;
  578.   }
  579. #ifndef MAC
  580.   unlink( "bsbwh.nna" );  /* Delete file if it exists */
  581. #endif
  582.   asc_fp = fopen( "bsbwh.nna", "w" ); /* Open for writing */
  583.   if ( asc_fp == (FILE *)0 ) goto end_attn;
  584.   fprintf( asc_fp,
  585.     "! Input file for antibiotic example. Autoassociative network%s",
  586.      NEW_LINE_STR );
  587.   
  588.   /* Display menus and await inputs */
  589.   ug_window( InpMenu.key, gm_intcolor, x_inp, y_inp,
  590.        x_inp + InpMenu.x1 + 2, y_inp + InpMenu.y1 + 2);
  591.   ug_window( UtMenu.key, gm_intcolor, x_ut, y_ut,
  592.        x_ut + UtMenu.x1 + 2, y_ut + UtMenu.y1 + 2);
  593.   ug_window( CatMenu[curr_mode].key, gm_intcolor, x_cat, y_cat,
  594.        x_cat1, y_cat + CatMenu[0].y1 + 2);
  595.  
  596.   DispGMenu( &InpMenu );
  597.   DispGMenu( &UtMenu );
  598.   DispGMenu( &CatMenu[curr_mode] );
  599.   
  600.   for ( ; ; ) {
  601.     while ( (gmip=LookGMenu(&CatMenu[curr_mode],&button))
  602.       != (GMENU_ITEM *) 0 ) {
  603.         if ( button == MBUT_LEFT || button == MBUT_RIGHT ) {
  604.         ci = &curr_index[gmip->code];
  605.         nw = num_words[gmip->code];
  606.         if (button == MBUT_LEFT ) *ci = (*ci + 1) % nw;
  607.         else *ci = (*ci + nw - 1) % nw;
  608.         gmip->text = c_cat_array[gmip->code][*ci];
  609.         DispGItem( &CatMenu[curr_mode], gmip,
  610.        gm_intcolor, gm_txtcolor );
  611.         abbreviate( -1 );
  612.         DispGMenu( &InpMenu );
  613.       }
  614.       /* If button was pressed, wait for it to be released */
  615.       while ( button != 0 )
  616.         ug_mouse( &key, &xp, &yp, &button );
  617.     }
  618.   
  619.     while ( (gmip=LookGMenu( &UtMenu, &button )) != (GMENU_ITEM *) 0 ) {
  620.       switch( gmip->code ) {
  621.     case M_MODE:
  622.         if ( button == MBUT_LEFT || button == MBUT_RIGHT ) {
  623.       curr_mode = (curr_mode + 1) % 2;
  624.       gmip->text = mode_text[curr_mode];
  625.       DispGItem( &UtMenu, gmip, gm_intcolor, gm_txtcolor );
  626.       ug_winclr( CatMenu[0].key );
  627.       DispGMenu( &CatMenu[curr_mode] );
  628.       abbreviate( -1 );
  629.       DispGMenu( &InpMenu );
  630.     }
  631.     break;
  632.     case M_CLEAR:
  633.         if ( button == MBUT_LEFT || button == MBUT_RIGHT ) {
  634.     /* Set current index to 0 for all menu items and redisplay */
  635.       for ( gmip = CatMenu[curr_mode].item, wx = 0;
  636.       wx < CatMenu[curr_mode].num_items; wx++, gmip++ ) {
  637.         curr_index[gmip->code] = 0;
  638.         gmip->text = c_cat_array[gmip->code][0];
  639.       }
  640.       DispGMenu( &CatMenu[curr_mode] );
  641.       abbreviate( -1 );
  642.       DispGMenu( &InpMenu );
  643.     }
  644.     break;
  645.     case M_ENTER:
  646.         if ( button == MBUT_LEFT || button == MBUT_RIGHT ) {
  647.       fprintf( asc_fp, "! F%ld: ", (long)iv_num );
  648.       iv_num++;
  649.       fprintf( asc_fp, InItem.text );
  650.       fprintf( asc_fp, "%s ", NEW_LINE_STR );
  651.       for ( sp = InItem.text, wx = 0; wx < 25; sp++, wx++ ) {
  652.         encode( (int)(*sp), wr );
  653.         if ( wx != 0 && wx%3 == 0 ) fprintf( asc_fp, "%s&", NEW_LINE_STR);
  654.         for ( wy = 0; wy < 6; wy++ )
  655.           fprintf( asc_fp, " %2.0f.", wr[wy] );
  656.       }
  657.       fprintf( asc_fp, NEW_LINE_STR );
  658.     }
  659.     break;
  660.     case M_QUIT:
  661.         if ( button == MBUT_LEFT || button == MBUT_RIGHT ) {
  662.       IORTNCDE = -1;
  663.       goto end_attn;
  664.     }
  665.     break;
  666.         }
  667.       /* If button was pressed, wait for it to be released */
  668.       while ( button != 0 )
  669.         ug_mouse( &key, &xp, &yp, &button );
  670.     }
  671.   }
  672.  
  673. end_attn:     
  674.   if ( asc_fp != (FILE * ) 0 ) fclose( asc_fp );
  675.   break;
  676.  
  677.     case RQ_LSTART:       /* starting learn */
  678.   /* This tells the user that the program is about to start
  679.      learning.  It is called once for a LEARN ALL, LEARN ONE,
  680.      LEARN N, or LEARN START
  681.   */
  682.   break;
  683.  
  684.     case RQ_LEARNIN:        /* read training input */
  685.   /* IODATA points to an empty array of IOCOUNT elements.  The
  686.      values placed in this array by the user will become the
  687.      inputs to the network for training purposes.
  688.   */
  689.  
  690.     case RQ_READ:       /* read test data */
  691.   /* IODATA points to an empty array of IOCOUNT values.  The
  692.      user must fill in these values.  The elements of the
  693.      array will become the "sum" of the inputs to the input
  694.      layer of processing elements.
  695.   */ 
  696.  
  697.   wr_count = 0;
  698.  
  699.   ug_window( InpMenu.key, gm_intcolor, x_inp, y_inp,
  700.        x_inp + InpMenu.x1 + 2, y_inp + InpMenu.y1 + 2);
  701.   ug_window( UtMenu.key, gm_intcolor, x_ut, y_ut,
  702.        x_ut + UtMenu.x1 + 2, y_ut + UtMenu.y1 + 2);
  703.   ug_window( CatMenu[curr_mode].key, gm_intcolor, x_cat, y_cat,
  704.        x_cat1, y_cat + CatMenu[0].y1 + 2);
  705.  
  706.   DispGMenu( &InpMenu );
  707.   DispGMenu( &UtMenu );
  708.   DispGMenu( &CatMenu[curr_mode] );
  709.  
  710.   for ( ; ; ) {
  711.     while ( (gmip=LookGMenu(&CatMenu[curr_mode],&button))
  712.       != (GMENU_ITEM *) 0 ) {
  713.         if ( button == MBUT_LEFT || button == MBUT_RIGHT ) {
  714.         ci = &curr_index[gmip->code];
  715.         nw = num_words[gmip->code];
  716.         if (button == MBUT_LEFT ) 
  717.       *ci = (*ci + 1) % nw;
  718.         else 
  719.       *ci = (*ci + nw - 1) % nw;
  720.         gmip->text = c_cat_array[gmip->code][*ci];
  721.         DispGItem( &CatMenu[curr_mode], gmip,
  722.        gm_intcolor, gm_txtcolor );
  723.         abbreviate( gmip->code );
  724.         DispGMenu( &InpMenu );
  725.       }
  726.       /* If button was pressed, wait for it to be released */
  727.       while ( button != 0 )
  728.         ug_mouse( &key, &xp, &yp, &button );
  729.     }
  730.   
  731.     while ( (gmip=LookGMenu( &UtMenu, &button )) != (GMENU_ITEM *) 0 ) {
  732.       switch( gmip->code ) {
  733.       case M_MODE:
  734.         if ( button == MBUT_LEFT || button == MBUT_RIGHT ) {
  735.     curr_mode = (curr_mode + 1) % 2;
  736.     gmip->text = mode_text[curr_mode];
  737.     DispGItem( &UtMenu, gmip, gm_intcolor, gm_txtcolor );
  738.     ug_winclr( CatMenu[0].key );
  739.     DispGMenu( &CatMenu[curr_mode] );
  740.     if ( IOREQCDE == RQ_LEARNIN ) abbreviate( -1 );
  741.     DispGMenu( &InpMenu );
  742.         }
  743.         break;
  744.       case M_CLEAR:
  745.         if ( button == MBUT_LEFT || button == MBUT_RIGHT ) {
  746.     /* Set current index to 0 for all menu items and redisplay */
  747.     for ( gmip = CatMenu[curr_mode].item, wx = 0;
  748.          wx < CatMenu[curr_mode].num_items; wx++, gmip++ ) {
  749.       curr_index[gmip->code] = 0;
  750.       gmip->text = c_cat_array[gmip->code][0];
  751.     }
  752.     DispGMenu( &CatMenu[curr_mode] );
  753.     abbreviate( -1 );
  754.     DispGMenu( &InpMenu );
  755.         }
  756.         break;
  757.       case M_ENTER:
  758.         if ( button == MBUT_LEFT || button == MBUT_RIGHT ) {
  759.     /* Fill in IODATA with bit patterns for current input */
  760.     for ( sp = InItem.text, wx = 0, p_outv = IODATA;
  761.          wx < 25; sp++, wx++, p_outv += 6 ) {
  762.       encode( (int)(*sp), p_outv );
  763.     }
  764.     goto end_read;
  765.         }
  766.         break;
  767.       case M_QUIT:
  768.         if ( button == MBUT_LEFT || button == MBUT_RIGHT ) {
  769.     IORTNCDE = -1;
  770.     goto end_read;
  771.         }
  772.         break;
  773.       }
  774.       /* If button was pressed, wait for it to be released */
  775.       while ( button != 0 )
  776.         ug_mouse( &key, &xp, &yp, &button );
  777.     }
  778.   }
  779. end_read:
  780.   break;
  781.  
  782.     case RQ_LEARNOUT:       /* read desired output */
  783.   /* IODATA points to an empty array of IOCOUNT values.  The
  784.      elements of the array will become the desired outputs for
  785.      training purposes.  These desired outputs correspond to
  786.      the most recent "RQ_LEARNIN" request.
  787.   */
  788.  
  789.   break;
  790.  
  791.     case RQ_WRITE:        /* write out results */
  792.   /* IODATA points to an array of IOCOUNT "float" type values.
  793.      The values are the outputs of the top-most layer of the
  794.      network.
  795.   */
  796.   IORTNCDE = 1; /* Redraw */
  797.   break;
  798.  
  799.     case RQ_LEARNRSLT:
  800.   /* IODATA points to an array of IOCOUNT values.  These are the
  801.      output of the network caused by the inputs from RQ_LEARNIN.
  802.   */
  803.  
  804.   ug_window( OutMenu.key, gm_intcolor, x_out, y_out,
  805.        x_out + OutMenu.x1 + 2, y_out + OutMenu.y1 + 2);
  806.  
  807.   for ( sp = OutItem.text, wx = 0, p_outv = IODATA;
  808.       wx < 25; wx++, p_outv += 6 )
  809.     *sp++ = decode( p_outv, 0.1 );
  810.  
  811.   DispGMenu( &OutMenu );
  812.  
  813.   /* Lock Items */
  814.   for ( wy = 0; wy < 2; wy++ )
  815.     for ( wx = 0, gmip = CatMenu[wy].item;
  816.     wx < CatMenu[wy].num_items; wx++, gmip++ )
  817.     gmip->flag |= GM_LOCKED;
  818.   
  819.   UtList[M_MODE].flag |= GM_LOCKED;
  820.   UtList[M_CLEAR].flag |= GM_LOCKED;
  821.   UtList[M_QUIT].flag |= GM_LOCKED;
  822.  
  823.   for ( ; ; ) {
  824.     while ( (gmip=LookGMenu( &UtMenu, &button )) == (GMENU_ITEM *)0 ) ;
  825.     if ( button == MBUT_LEFT || button == MBUT_RIGHT ) break;
  826.   }
  827.   /* Unlock Items */
  828.   for ( wy = 0; wy < 2; wy++ )
  829.     for ( wx = 0, gmip = CatMenu[wy].item;
  830.     wx < CatMenu[wy].num_items; wx++, gmip++ )
  831.     gmip->flag &= ~GM_LOCKED;
  832.   
  833.   UtList[M_MODE].flag &= ~GM_LOCKED;
  834.   UtList[M_CLEAR].flag &= ~GM_LOCKED;
  835.   UtList[M_QUIT].flag &= ~GM_LOCKED;
  836.  
  837.   IORTNCDE = 1;
  838.   break;
  839.  
  840.     case RQ_WRSTEP:       /* write interim results */
  841.   /* each recall cycle for the Hopfield and BAM control strategies,
  842.      the intermediate output is made available to userio to test
  843.      for convergence or other desired states.  This option is
  844.      not used for other control strategies.
  845.   */
  846.  
  847.   if ( wr_count++ % 5 == 0 ) {
  848.     ug_window( OutMenu.key, gm_intcolor, x_out, y_out,
  849.          x_out + OutMenu.x1 + 2, y_out + OutMenu.y1 + 2);
  850.  
  851.     for ( sp = OutItem.text, wx = 0, p_outv = IODATA;
  852.     wx < 25; wx++, p_outv += 6 )
  853.       *sp++ = decode( p_outv, 0.1 );
  854.  
  855.     DispGMenu( &OutMenu );
  856.  
  857.     /* Lock Items */
  858.     for ( wy = 0; wy < 2; wy++ )
  859.       for ( wx = 0, gmip = CatMenu[wy].item;
  860.       wx < CatMenu[wy].num_items; wx++, gmip++ )
  861.         gmip->flag |= GM_LOCKED;
  862.   
  863.     UtList[M_MODE].flag |= GM_LOCKED;
  864.     UtList[M_CLEAR].flag |= GM_LOCKED;
  865.  
  866.     sprintf( buf, "Recall iteration number %ld%s", (long)wr_count, NEW_LINE_STR );
  867.     PutStr( buf );
  868.     PutStr( "Select ENTER to continue, QUIT to terminate recall\n" );
  869.     for ( ; ; ) {
  870.       while ( (gmip=LookGMenu(&UtMenu,&button )) == (GMENU_ITEM *)0 ) ;
  871.       switch( gmip->code ) {
  872.       case M_ENTER:
  873.         if ( button == MBUT_LEFT || button == MBUT_RIGHT ) goto end_wr;
  874.         break;
  875.       case M_QUIT:
  876.         if ( button == MBUT_LEFT || button == MBUT_RIGHT ) {
  877.     IORTNCDE = -1;
  878.     goto end_wr;
  879.         }
  880.         break;
  881.       }
  882.     }
  883. end_wr:
  884.     /* Unlock Items */
  885.     for ( wy = 0; wy < 2; wy++ )
  886.       for ( wx = 0, gmip = CatMenu[wy].item;
  887.       wx < CatMenu[wy].num_items; wx++, gmip++ )
  888.       gmip->flag &= ~GM_LOCKED;
  889.   
  890.     UtList[M_MODE].flag &= ~GM_LOCKED;
  891.     UtList[M_CLEAR].flag &= ~GM_LOCKED;
  892.   }
  893.  
  894.   break;
  895.  
  896.     case RQ_RSTART:       /* starting recall */
  897.   /* This tells the user that the program is about to start
  898.      a recall.  It is called once for a REACLL ALL, RECALL ONE,
  899.      RECALL N, or RECALL START.
  900.   */
  901.   break;
  902.   
  903.     case RQ_RCLTST:   /* read desired output during recall test */
  904.   /* IODATA points to an empty array of IOCOUNT values.  The
  905.      elements of the array will become the desired outputs for
  906.      recall purposes.  This request is only made during a
  907.      Execute Network/Recall Test.
  908.   */
  909.  
  910.   break;
  911.  
  912.     case RQ_TERM:       /* terminate interface */
  913.   /* close any files which may be open.  Deallocate any memory
  914.      which was allocated.  (This is VERY VERY important.  If
  915.      allocated memory is NOT released, dos memory will become
  916.      fragmented and it will become necessary to reboot.
  917.   */
  918.  
  919.   PutStr( "bye bye\n" );
  920.   break;
  921.     }
  922.  
  923.     return;
  924. }
  925.