home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / mac / source / luschsrc.sit / gnosis.c < prev    next >
Text File  |  1990-05-23  |  9KB  |  476 lines

  1. /********************************************************************************
  2.  *    gnosis.c
  3.  *
  4.  *    Prognosis Management Package
  5.  *
  6.  *    Written by Paco Xander Nathan
  7.  *    ⌐1990, Motorola Inc.  Public domain source code.
  8.  ********************************************************************************/
  9.  
  10. #include "applic.h"
  11. #include "window.h"
  12. #include "dialog.h"
  13. #include "error.h"
  14. #include "string.h"
  15. #include "text.h"
  16. #include "document.h"
  17. #include "neural.h"
  18.  
  19. #include "test.h"
  20. #include "gnosis.h"
  21. #include "analysis.h"
  22.  
  23.  
  24. #define GNOS_BITS    181
  25.  
  26.  
  27. /* Local Data Structures
  28.  */
  29.  
  30.  
  31. /* External Data Structures
  32.  */
  33. GnosList
  34.     gnosList = { 0, NULL, NULL };
  35.  
  36.  
  37. /* Local Function Prototypes
  38.  */
  39. #ifdef PROTOTYPES
  40. #endif
  41.  
  42.  
  43. /* Allocate a new prognosis record and insert it at the head of the list
  44.  */
  45. GnosPtr
  46. GnosNew ()
  47. {
  48.     register GnosPtr gnosPtr = NULL;
  49.     
  50.     GnosSave();
  51.  
  52.     if (gnosPtr = (GnosPtr) ErrNewPtr(sizeof(GnosData))) {
  53.         gnosPtr->next = gnosList.head;
  54.         gnosList.head = gnosPtr;
  55.         gnosList.count++;
  56.  
  57.         gnosPtr->textHdl = (Handle) ErrNewHandle(0L);
  58.     }
  59.  
  60.     return gnosPtr;
  61. }
  62.  
  63.  
  64. void
  65. GnosDelete ()
  66. {
  67.     register GnosPtr gnosPtr = gnosList.head;
  68.     
  69.     if (gnosList.open == gnosList.head)
  70.         gnosList.head = gnosPtr->next;
  71.     else {
  72.     }
  73.     
  74.     gnosList.count--;
  75.     gnosList.open = NULL;
  76.  
  77.     DisposHandle(gnosPtr->textHdl);
  78.     DisposPtr(gnosPtr);
  79.     
  80.     WindSwitch(dPtrAnal, FALSE);
  81.     WindSwitch(wPtrText, FALSE);
  82. }
  83.  
  84.  
  85. /* Read the set of prognosis from the opened resource file and display the 
  86.  * titles in the resource list window
  87.  */
  88. void
  89. GnosRefresh ()
  90. {
  91.     register InfoPtr infoPtr = (InfoPtr) GetWRefCon(wPtrGnos);
  92.     register ListHandle listHdl = infoPtr->item.list;
  93.     register GnosPtr gnosPtr = gnosList.head;
  94.     register Cell theCell;
  95.     Str255 itemText;
  96.     GrafPtr savePort;
  97.  
  98.     GetPort(&savePort);
  99.     SetPort(wPtrGnos);
  100.  
  101.     /* Resize the list length
  102.      */
  103.     LDoDraw(FALSE, listHdl);
  104.     LDelRow(0, 0, listHdl);
  105.     theCell.h = 0;
  106.     theCell.v = 0;
  107.  
  108.     for (theCell.v = 0; gnosPtr; gnosPtr = gnosPtr->next) {
  109.         ApplSpinCurs(FALSE);
  110.         StrPCpy(itemText, gnosPtr->title);
  111.  
  112.         LAddRow(1, 0, listHdl);
  113.         LSetCell(itemText + 1, itemText[0], theCell, listHdl);
  114.     }
  115.  
  116.     /* Switch to the resource list window and redraw it
  117.      */
  118.     InvalRect(&wPtrGnos->portRect);
  119.     LDoDraw(TRUE, listHdl);
  120.  
  121.     if (!((WindowPeek) wPtrGnos)->visible)
  122.         WindSwitch(wPtrGnos, TRUE);
  123.  
  124.     SetPort(savePort);
  125. }
  126.  
  127.  
  128. /* Open the indexed prognosis analysis
  129.  */
  130. void
  131. GnosOpenAnal (theGnos)
  132.     register WORD theGnos;
  133. {
  134.     register GnosPtr gnosPtr = gnosList.head;
  135.     register WORD theIndex;
  136.     
  137.     if ((theGnos >= 0) && (theGnos < gnosList.count)) {
  138.         for (theIndex = gnosList.count - 1; theIndex > theGnos; theIndex--) 
  139.             gnosPtr = gnosPtr->next;
  140.         
  141.         gnosList.open = gnosPtr;
  142.  
  143.         AnalPutBuf(gnosPtr);
  144.         WindSwitch(dPtrAnal, TRUE);
  145.     }
  146. }
  147.  
  148.  
  149. /* Open the indexed prognosis description text
  150.  */
  151. void
  152. GnosOpenText (WORD theGnos)
  153. {
  154.     register GnosPtr gnosPtr = gnosList.head;
  155.     register SignedByte hdlState;
  156.     register WORD theIndex;
  157.  
  158.     if ((theGnos >= 0) && (theGnos < gnosList.count)) {
  159.         for (theIndex = gnosList.count - 1; theIndex > theGnos; theIndex--) 
  160.             gnosPtr = gnosPtr->next;
  161.         
  162.         hdlState = HGetState(gnosPtr->textHdl);
  163.         HLock(gnosPtr->textHdl);
  164.         
  165.         TextWindReset(wPtrText);
  166.         TextPutText(*(gnosPtr->textHdl), GetHandleSize(gnosPtr->textHdl), wPtrText);
  167.     
  168.         HSetState(gnosPtr->textHdl, hdlState);
  169.         WindSwitch(wPtrText, TRUE);
  170.     }
  171. }
  172.  
  173.  
  174. /* Save the current prognosis
  175.  */
  176. void
  177. GnosSave ()
  178. {
  179.     register TEHandle teHdl = ((InfoPtr) GetWRefCon(wPtrText))->item.text.teHdl;
  180.     register SignedByte hdlState;
  181.  
  182.     if (gnosList.open && !testUser) {
  183.         /* First, read the analysis
  184.          */
  185.         if (((WindowPeek) dPtrAnal)->visible)
  186.             AnalGetBuf(gnosList.open);
  187.     
  188.         /* Next, read the description text
  189.          */
  190.         if (((WindowPeek) wPtrText)->visible) {
  191.             hdlState = HGetState(gnosList.open->textHdl);
  192.             HLock(gnosList.open->textHdl);
  193.             
  194.             SetHandleSize(gnosList.open->textHdl, (Size) (*teHdl)->teLength);
  195.             BlockMove(*(TEGetText(teHdl)), *gnosList.open->textHdl, (Size) (*teHdl)->teLength);
  196.     
  197.             HSetState(gnosList.open->textHdl, hdlState);
  198.         }
  199.         
  200.         gnosList.open = NULL;
  201.     }
  202. }
  203.  
  204.  
  205. /* Close all the prognosis
  206.  */
  207. void
  208. GnosClose ()
  209. {
  210.     register GnosPtr gnosPtr = gnosList.head;
  211.  
  212.     GnosSave();
  213.  
  214.     for (; gnosList.count--; ) {
  215.         gnosList.head = gnosPtr->next;
  216.         DisposHandle(gnosPtr->textHdl);
  217.         DisposPtr(gnosPtr);
  218.         
  219.         gnosPtr = gnosList.head;
  220.     }
  221.  
  222.     gnosList.count = 0;
  223.     gnosList.head = NULL;
  224.     gnosList.open = NULL;
  225.         
  226.     WindSwitch(wPtrGnos, FALSE);
  227.     WindSwitch(dPtrAnal, FALSE);
  228.     WindSwitch(wPtrText, FALSE);
  229. }
  230.  
  231.  
  232. /* Handle a click inside the prognosis list window
  233.  */
  234. void 
  235. GnosClick (theCell, dblClick)
  236.     register Cell theCell;
  237.     register Boolean dblClick;
  238. {
  239.     /* First, save any current prognosis and update titles
  240.      */
  241.     GnosSave();
  242.     GnosRefresh();
  243.  
  244.     /* Open the selected prognosis
  245.      */
  246.     GnosOpenAnal(theCell.v);
  247.     GnosOpenText(theCell.v);
  248. }
  249.  
  250.  
  251. /* Convert from the character based gnos data pointer to the bitmap
  252.  * required to condition the neural network
  253.  */
  254. void
  255. GnosStuffBits (gnosPtr, gnosBits)
  256.     register GnosPtr gnosPtr;
  257.     register Boolean *gnosBits;
  258. {
  259.     register WORD i, value, theBit = 0;
  260.  
  261.     for (i = MAXPAD * 2; --i;) {
  262.         value = gnosPtr->color[0][i] - '0';
  263.         gnosBits[theBit++] = (value & 0x01) ? TRUE : FALSE;
  264.         gnosBits[theBit++] = (value & 0x02) ? TRUE : FALSE;
  265.         gnosBits[theBit++] = (value & 0x04) ? TRUE : FALSE;
  266.     }
  267.     
  268.     ApplSpinCurs(FALSE);
  269.     
  270.     for (i = MAXPAD * 2; --i;) {
  271.         value = gnosPtr->pair[0][i] - '0';
  272.         gnosBits[theBit++] = (value & 0x01) ? TRUE : FALSE;
  273.         gnosBits[theBit++] = (value & 0x02) ? TRUE : FALSE;
  274.         gnosBits[theBit++] = (value & 0x04) ? TRUE : FALSE;
  275.     }
  276.  
  277.     ApplSpinCurs(FALSE);
  278.     
  279.     for (i = MAXPAD * 2; --i;) {
  280.         switch (gnosPtr->mark[0][i]) {
  281.         case '+':
  282.             value = 0;
  283.             break;
  284.         case 'x':
  285.             value = 1;
  286.             break;
  287.         case '=':
  288.             value = 2;
  289.             break;
  290.         case '-':
  291.             value = 3;
  292.             break;
  293.         default:
  294.             break;
  295.         }
  296.  
  297.         gnosBits[theBit++] = (value & 0x01) ? TRUE : FALSE;
  298.         gnosBits[theBit++] = (value & 0x02) ? TRUE : FALSE;
  299.     }
  300.  
  301.     ApplSpinCurs(FALSE);
  302.     
  303.     for (i = MAXPAD * 2; --i;) {
  304.         switch (gnosPtr->anxiety[0][i]) {
  305.         case ' ':
  306.             value = 0;
  307.             break;
  308.         case 'A':
  309.             value = 1;
  310.             break;
  311.         case 'C':
  312.             value = 2;
  313.             break;
  314.         default:
  315.             break;
  316.         }
  317.  
  318.         gnosBits[theBit++] = (value & 0x01) ? TRUE : FALSE;
  319.         gnosBits[theBit++] = (value & 0x02) ? TRUE : FALSE;
  320.     }
  321.  
  322.     ApplSpinCurs(FALSE);
  323.     
  324.     for (i = MAXPAD * 2; --i;) {
  325.         switch (gnosPtr->stress[0][i]) {
  326.         case ' ':
  327.             value = 0;
  328.             break;
  329.         case '1':
  330.             value = 1;
  331.             break;
  332.         case '2':
  333.             value = 2;
  334.             break;
  335.         default:
  336.             break;
  337.         }
  338.  
  339.         gnosBits[theBit++] = (value & 0x01) ? TRUE : FALSE;
  340.         gnosBits[theBit++] = (value & 0x02) ? TRUE : FALSE;
  341.     }
  342.  
  343.     ApplSpinCurs(FALSE);
  344.     
  345.     for (; theBit < GNOS_BITS; theBit++)
  346.          gnosBits[theBit] = FALSE;
  347. }
  348.  
  349.  
  350. /* Teach the neural network using all the saved prognoses
  351.  */
  352. void
  353. GnosLearn ()
  354. {
  355.     register GnosPtr gnosPtr = gnosList.head;
  356.     register WORD theGnos;
  357.     Boolean gnosBits[GNOS_BITS];
  358.  
  359.     /* Clear any previous neural net and get a new one
  360.      */
  361.     NNInit();
  362.  
  363.     /* Now class, please study each chapter in your prognosis list
  364.      */
  365.     for (theGnos = 0; theGnos < gnosList.count; theGnos++, gnosPtr = gnosPtr->next) {
  366.         ApplSpinCurs(FALSE);
  367.         GnosStuffBits(gnosPtr, gnosBits);
  368.         NNLearn(gnosBits, GNOS_BITS, theGnos);
  369.     }
  370. }
  371.  
  372.  
  373. /* Use the neural network to infer saved prognoses
  374.  */
  375. void
  376. GnosRecall ()
  377. {
  378.     register InfoPtr infoPtr = (InfoPtr) GetWRefCon(wPtrGnos);
  379.     register ListHandle listHdl = infoPtr->item.list;
  380.     register Cell theCell;
  381.     Boolean gnosBits[GNOS_BITS];
  382.     WORD theLen = 255;
  383.     Str255 itemText;
  384.     LONG theNum;
  385.  
  386.     /* Convert the current analysis into a network input vector, then activate 
  387.      */
  388.     AnalReadWind();
  389.      GnosStuffBits(&analGnosBuf, gnosBits);
  390.     NNActivate(gnosBits, GNOS_BITS);
  391.  
  392.     /* Clear the certainty column
  393.      */
  394.     theCell.h = 1;
  395.  
  396.     for (theCell.v = (*listHdl)->dataBounds.bottom; theCell.v--; ) 
  397.         LClrCell(theCell, listHdl);
  398.  
  399.     /* Report the certainty factor
  400.      */
  401.     sprintf((char *) itemText, "%5.2f%% certainty", nnCertainty);
  402.     CtoPstr((char *) itemText);
  403.  
  404.     /* Reflect the index
  405.      */
  406.     theCell.h = 1;
  407.     theCell.v = gnosList.count - (nnOutput + 1);
  408.     LSetCell(itemText + 1, itemText[0], theCell, listHdl);
  409.  
  410.     /* Report the description text, but only in user mode...
  411.      */
  412.     if (testUser)
  413.         GnosOpenText(theCell.v);
  414.     else
  415.         SelectWindow(wPtrGnos);
  416. }
  417.  
  418.  
  419. /* Execute the selected Prognosis menu item
  420.  */
  421. void
  422. GnosMenu (theItem)
  423.     register WORD theItem;
  424. {
  425.     register InfoPtr infoPtr = (InfoPtr) GetWRefCon(wPtrGnos);
  426.  
  427.     switch (theItem) {
  428.     case gnosNew:
  429.         GnosNew();
  430.         AnalStub();
  431.         AnalWriteWind();
  432.         AnalGetBuf(gnosList.head);
  433.  
  434.         GnosRefresh();
  435.  
  436.         GnosOpenAnal(gnosList.count - 1);
  437.         GnosOpenText(gnosList.count - 1);
  438.  
  439.         if (!testUser)
  440.             infoPtr->dirty = TRUE;
  441.  
  442.         break;
  443.  
  444.     case gnosDelete:
  445.         GnosDelete();
  446.         GnosRefresh();
  447.  
  448.         if (!testUser)
  449.             infoPtr->dirty = TRUE;
  450.  
  451.         break;
  452.  
  453.     case gnosAnalyze:
  454.         AnalReadWind();
  455.         AnalReport();
  456.  
  457.         if (!testUser)
  458.             infoPtr->dirty = TRUE;
  459.  
  460.         break;
  461.  
  462.     case gnosLearn:
  463.         GnosSave();
  464.         GnosRefresh();
  465.         GnosLearn();
  466.         break;
  467.  
  468.     case gnosRecall:
  469.         GnosRecall();
  470.         break;
  471.  
  472.     default:
  473.         break;
  474.     }
  475. }
  476.