/*****************************************************************************\
* artintel.c                                                                  *
*   Copyright 1998 Swift Concepts Software. All rights reserved.              *
>*****************************************************************************<
* ARTINTEL.C: Concepts Network Based A.I.                     By Jimmy Rising *
*             Date Created       : February 1, 1998                           *
*             Last Modified      : July 16, 1998 by Jimmy                     *
>*****************************************************************************<
*                                                                             *
* The artificial intelligence uses three major files and areas to store data: *
*   the connect net, which is a serial list of data locations, in which those *
*   nearest the end of the file are the ones closest to the front of the mind *
*   and with the greatest salience; the information, which holds info. pieces *
*   that supliment the succinct locations in the dynamic connect net; and the *
*   coderack and slothouse, which hold small sections of code which to run as *
*   a weighted (on "urgency") probability determines, as to simulate parallel *
*   occurence of actions.                                                     *
*                                                                             *
* Artintel is largely inspired by the Copycat artificial intelligence project *
*   and ideas built from those in The Reality Club's anthologies.             *
*                                                                             *
\*****************************************************************************/

/*
 * :: Usage Settings ::
 */

#define BIG_ENDIAN /* specifies that the computer's internal representation
		      of numbers is Big Endian */
// #define USE_FILE

/*
 * :: Program Setup  ::
 */

/*  :    Headers     :  */
/*     Bios Header      */
#include <bios.h>
#include <stdio.h>

/*  :   Constants    :  */
#define DEFAULT_NUM_LEN 4
#define LINK_NUM_LEN 4
#define BOND_NUM_LEN 4
#define INFO_REC_LEN LINK_NUM_LEN + 2 * BOND_NUM_LEN + 2
#define BOND_REC_LEN LINK_NUM_LEN + BOND_NUM_LEN + 2

struct memptr {
  void *start;
  void *curr;
  unsigned long len;
};

/*  :     Macros     :  */
#ifdef USE_FILE
  #define aread(ptr, size, nitms, data) fread(ptr, size, nitms, data)
#else
  #define aread(ptr, size, nitms, data) { \
    bcopy(data.curr, ptr, size * nitms); \
    data.curr += size * nitms; \
  }
#endif

#ifdef USE_FILE
  #define awrite(ptr, size, nitms, data) awrite(ptr, size, nitms, data)
#else
  #define awrite(ptr, size, nitms, data) { \
    bcopy(ptr, data.curr, size * nitms); \
    data.curr += size * nitms; \
  }
#endif

ifdef USE_FILE
  #define agetc(data) fgetc(data)
#else
  #define agetc(data) (*(data.curr++))
#endif

#ifdef USE_FILE
  #define aputc(c, data) fputc(c, data)
#else
  #define aputc(c, data) (*(data.curr++) = c)
#endif

/* Interprets file ##'s */
#ifdef BIG_ENDIAN
  #define char2num(filepointer, charnum, result) \
    fread((void *) &result, 1, charnum, filepointer)
#else
  #define char2num(filepointer, charnum, result) { \
    result = 0; \
    for (x = 0; x <= charnum - 1; x++) \
      result = result * 256 + fgetc(filepointer); \
  }
#endif

/* Change ##'s to chars */
#ifdef BIG_ENDIAN
  #define num2char(filepointer, charnum, inputn) \
    fwrite((void *) &inputn, 1, charnum, filepointer)
#else
  #define num2char(filepointer, charnum, inputn) { \
    double floatn = inputn; \
    for (x = 0; x < charnum - 1; x++) \
      floatn /= 256; \
    for (x = 0; x < charnum; x++) { \
      fputc(floatn, filepointer); \
      floatn *= 256; \
    } \
  }
#endif

/*  :   Functions    :  */
/*  Add New Data Func.  */
void add_data(unsigned char);
void read_keyboard(unsigned char);
void find_similars(unsigned long);
void make_new_bond(unsigned long, unsigned long);
void add_bond(unsigned long, unsigned long, char, unsigned char);
void draw_together(unsigned char, unsigned long, unsigned long);
void template_find(unsigned long);

#include "nlnet.cpp"
#include "codelets.cpp"
#include "coderack.cpp"

/*
 *   :: Main Function ::
 */

int
main(int argc, char *argv[]) {
  /*  :   Variables   :  */
  /*      New Data       */
  long ccodelet;
  long cslot;

  /*   Check arguments   */
  if (argc != 3) {
    printf("Usage: artintel <links.dat> <infos.dat> <bonds.dat>\n");
    exit(-1);
  }

  /*      Get info       */
  connect_net link_root(argv[1]);
  information info_root(argv[2]);
  bond_jumper bond_root(argv[3]);

  /*  : Initializing  :  */
  theCoderack.AddCodelet(new ReadKeyboard_Codelet(255)); /* Starting codelet */

  /*  : Master Repeat :  */
  while (1) {
    /* Run a codelet from the coderack */
    randnum = frand() * total_urgency;      /* Fraction of the total urgency */
    summed_urge = 0;                      /* Make sure correctly initialized */
    for (ccodelet = 0; ccodelet < MAX_CODELETS; ccodelet++)
      if ((summed_urge += coderack[ccodelet].urgency) >= randnum)
	break;      /* Until choose codelet, then quit w/ chosen codelet = x */
    /* Run appropriate function for codelet */
    if (coderack[ccodelet].codelet == READ_KEYBOARD)
      read_keyboard(coderack[ccodelet].urgency);
    else if (coderack[ccodelet].codelet == FIND_SIMILARS)
      find_similars(coderack[ccodelet].argmnt1);
    else if (coderack[ccodelet].codelet == MAKE_NEW_BOND)
      make_new_bond(coderack[ccodelet].argmnt1, coderack[ccodelet].argmnt2);
    else if (coderack[ccodelet].codelet == DRAW_TOGETHER)
      draw_together(coderack[ccodelet].urgency, coderack[ccodelet].argmnt1,
		    coderack[ccodelet].argmnt2);
    /* Delete information from coderack */
    remove_codelet(current_codelet);
  }
}

/*
 *   :: Add New Data Function ::
 */

void
add_data(unsigned char new_data) {

  char frontdata;

  /*  :  Add to information   :  */
  /*      Append to the end      */
  fseek(information.fileloc, 0, SEEK_END);     /* Jump to end of the file */
  fputc(new_data, information.fileloc);        /* Write new byte of data  */
  num2char(information.fileloc, LINK_NUM_LEN, ++information.records);
  /* This is in answer to the question "Where can I find it?"
     Answer: "At the end... for now." */ /* Also increase */
  num2char(information.fileloc, BOND_NUM_LEN, 0);
  /* No links, so say so (will change when add one) */
  num2char(information.fileloc, BOND_NUM_LEN + 1, 0);
  /* The first summed strength of all zero bonds */

  /*  :  Add to bond jumper   :  */
  fseek(connect_net.fileloc, -1 * LINK_NUM_LEN, SEEK_END);
  char2num(connect_net.fileloc, LINK_NUM_LEN, frontdata);
  add_bond(frontdata, information.records + 1, 64, 128);

  /*  :  Add to connect net   :  */
  /*      Append to the end      */
  fseek(connect_net.fileloc, 0, SEEKEND);      /* Jump to end of the file */
  num2char(connect_net.fileloc, LINK_NUM_LEN, information.records);

  /*  :      New Codelet      :  */
  /*  Codelet looks for similars */
  add_codelet(FIND_SIMILARS, 255, information.records, 0);
}

/*
 * :: Read from keyboard function ::
 */

void
read_keyboard(unsigned char old_urge) {
  unsigned char new_urge;
  
  /* : Deal with any characters : */
  if (filelength(0) != 0)               /* Check if there's anything to read */
    add_data(getch());

  /* : Replace with new codelet : */
  /* Find new urgency */
  if ((old_urge + 10 * pow2(filelength(0))) / 2 > 255)
    new_urge = 255;
  else
    new_urge = (old_urge + 10 * pow2(filelength(0))) / 2;
  /* Use function to add */
  add_codelet(READ_FROM_KEYBOARD, new_urge, 0, 0);
}

/*
 * :: Find Similar Data Function ::
 */

find_similars(unsigned long infoloc) {
  /* Locations */
  unsigned long dataloc, frntloc, currloc, chckloc;
  double calced_prob = 1;
  int thedata;

  /* Read in initial information */
  fseek(information.fileloc, SEEK_SET, (infoloc - 1) * INFO_REC_LEN, SEEK_SET);
  /* Go to the right spot */
  thedata = fgetc(information.fileloc);            /* Find what to check for */
  char2num(information.fileloc, LINK_NUM_LEN, dataloc);
  /* Read in link location */
  currloc = frntloc = information.records;         /* Set up other locations */

  /* Check certain links for matches */
  while (!((calced_prob = (2 * pow(M_E, -1 * (currloc - dataloc) / 16)
			   + pow(M_E, -1 * (currloc - frntloc) / 16)) / 2) < .01
	   && currloc < dataloc) && currloc > 0) {                   
    /* Check! */
    fseek(connect_net.fileloc, LINK_NUM_LEN * (currloc - 1), SEEK_SET);
    char2num(connect_net.fileloc, LINK_NUM_LEN, chckloc);
    fseek(information.fileloc, INFO_REC_LEN * (chckloc - 1), SEEK_SET);
    /* Found! */
    if (fgetc(information.fileloc) == thedata) {
      /* Urgency is very rough estimate of salience */
      add_codelet(MAKE_BOND, 128 * currloc / dataloc, infoloc, chckloc);
    }
    /* Go on to next */
    currloc -= abs(100 * (1 - calced_prob) * rand()) + 1;
  }
}

/*
 * :: Find the values for a New Bond ::
 */

make_new_bond(unsigned long infoloc, smlrloc) {
  /* : Variables : */
  unsigned char strength;
  unsigned long link1, link2;
  double salience_info, salience_smlr;
  
  /* : Calculate strength : */
  /* The question for the information is how willing is it to look? */
  fseek(information.fileloc, INFO_REC_LEN * (infoloc - 1) + 1 + LINK_NUM_LEN +
	BOND_NUM_LEN, SEEK_SET);        /* Find the sum of strengths */
  char2num(information.fileloc, BOND_NUM_LEN + 1, salience_info);
  /* salience is in part a function of happiness - how well fit into to all */
  /* If you are happy, then you will not put work into looking for more */
  salience_info  = (1 - (salience_info / (information.records * 255)))
    * (1 - (salience_info / (bond_jumper.records * 255)));
  /* It is also a function of how important you are - the more important, the
     more resources are diverted your way, the more you can look */
  salience_info *= infoloc / information.records;
  /* Since these will most likely be rediculously close to 1, we use extreme
     exponentials to make things more reasonable */
  salience_info = pow(salience_info, sqrt(information.records));
  
  /* The question for the similar is how well is it seen? */
  fseek(information.fileloc, INFO_REC_LEN * (smlrloc - 1) + 1 + LINK_NUM_LEN +
	BOND_NUM_LEN, SEEK_SET);        /* Find the sum of strengths */
  char2num(information.fileloc, BOND_NUM_LEN + 1, salience_smlr);
  /* salience is in part a function of happiness - how well fit into to all */
  /* If you are happy, then you will not put work into flaunting yourself */
  salience_smlr  = (1 - (salience_smlr / (information.records * 255)))
    * (1 - (salience_smlr / (bond_jumper.records * 255)));
  /* It is also a function of how important you are - the more important, the
     better a position you will end up in to be seen */
  salience_smlr *= infoloc / information.records;
  /* Since these will most likely be rediculously close to 1, we use extreme
     exponentials to make things more reasonable */
  salience_smlr = pow(salience_smlr, sqrt(information.records));

  /* So calculate the strength that we think fits based on that information */
  floatn = 128 * (salience_info + salience_smlr);
  
  /* : Really make the bond : */
  add_bond(infoloc, smlrloc, 0, strength);
}

/*       Add Bond       */
/* NOTE: when add bond not adding to summed strength! */
add_bond(unsigned long link1, unsigned long link2,
	 char polar, unsigned char strth) {

  /* : Variables : */
  unsigned long currbond, check;
  
  /* : Check for same bond : */
  fseek(information.fileloc, INFO_REC_LEN * (link1 - 1) + 1 + LINK_NUM_LEN,
	SEEK_SET);                               /* Go to find last bond loc */
  char2num(information.fileloc, BOND_NUM_LEN, currbond);
  /* Get location of last bond */
  while (currbond != 0) {
    fseek(bond_jumper.fileloc, BOND_REC_LEN * (currbond - 1), SEEK_SET);
    /* Go to the last bond */
    char2num(bond_jumper.fileloc, BOND_NUM_LEN, check);  /* link2 loc. */
    if (check == link2) {
      /* If there's already one there, then improve based on new info */
      fseek(bond_jumper.fileloc, BOND_REC_LEN * (currbond - 1) + LINK_NUM_LEN +
	    1, SEEK_SET);
      floatn = (strth + fgetc(bond_jumper.fileloc) + 16) / 2;
      if (floatn > 255) strth = 255;
      else if (floatn < 1) strth = 1;
      else strth = floatn;
    }
    fseek(bond_jumper.fileloc, 2, SEEK_CUR);          /* Jump: prev loc data */
    char2num(bond_jumper.fileloc, BOND_NUM_LEN, currbond);    /* Next! */
  }

  fseek(bond_jumper.fileloc, 0, SEEK_END);            /* Get ready to append */

  /* : The first bond (the order presented) */
  num2char(bond_jumper.fileloc, LINK_NUM_LEN, link2);  /* Write linked */
  fputc(polar, bond_jumper.fileloc);                       /* Write polarity */
  fputc(strth, bond_jumper.fileloc);                       /* Write strength */
  fseek(information.fileloc, (link1 - 1) * INFO_REC_LEN + LINK_NUM_LEN + 1,
	SEEK_SET);                         /* Got to from link's information */
  char2num(information.fileloc, BOND_NUM_LEN, x);    /* Read last bond */
  num2char(bond_jumper.fileloc, BOND_NUM_LEN, x); /* Write as prev bnd */
  fseek(information.fileloc, (link1 - 1) * INFO_REC_LEN + LINK_NUM_LEN + 1,
	SEEK_SET);                        /* Go back to last bond informatin */
  num2char(information.fileloc, BOND_NUM_LEN, ++bond_jumper.records);
  char2num(information.fileloc, BOND_NUM_LEN + 1, x); /* new last, and */
  num2char(information.fileloc, BOND_NUM_LEN + 1, x + strth); /* sum s */

  /* : The second bond (the opposite order) */
  num2char(bond_jumper.fileloc, LINK_NUM_LEN, link1);  /* Write linked */
  fputc(-1 * polar, bond_jumper.fileloc);                  /* Write polarity */
  fputc(strth, bond_jumper.fileloc);                       /* Write strength */
  fseek(information.fileloc, (link2 - 1) * INFO_REC_LEN + LINK_NUM_LEN + 1,
	SEEK_SET);                         /* Got to from link's information */
  char2num(information.fileloc, BOND_NUM_LEN, x);    /* Read last bond */
  num2char(bond_jumper.fileloc, BOND_NUM_LEN, x); /* Write as prev bnd */
  fseek(information.fileloc, (link2 - 1) * INFO_REC_LEN + LINK_NUM_LEN + 1,
	SEEK_SET);                        /* Go back to last bond informatin */
  num2char(information.fileloc, BOND_NUM_LEN, ++bond_jumper.records);
  char2num(information.fileloc, BOND_NUM_LEN + 1, x); /* new last, and */
  num2char(information.fileloc, BOND_NUM_LEN + 1, x + strth); /* sum s */
  /* So draw the newlyweds together */
  add_codelet(DRAW_TOGETHER, strth, link1, link2);
}

/* :: Drawing together algorithm :: */
/* Closer are to front, less likely to be randomly chosen to move.
   urgency / 255 is the degree to which the two should be drawn.
   Each time, recall urgency with a -1.  Then draw together 1/255 of the dist.
   each time until find that would make codelet of urgency 0, so don't */
draw_together(unsigned char strth, unsigned long link1, unsigned long link2) {
  /* : Variables : */
  unsigned long link1_loc, link2_loc;
  long dist;
  unsigned long exchange;            /* ID of the exchanged link */
  
  /* : Get locations of the links : */
  fseek(information.fileloc, INFO_REC_LEN * (link1 - 1) + 1, SEEK_SET);
  char2num(information.fileloc, LINK_NUM_LEN, link1_loc);
  fseek(informaiton.fileloc, INFO_REC_LEN * (link2 - 1) + 1, SEEK_SET);
  char2num(information.fileloc, LINK_NUM_LEN, link2_loc);

  /* : Choose one and make the exchange : */
  if (rand() * (link1_loc + link2_loc) < link1_loc) {
    dist = (link2_loc - link1_loc) / 255;  /* If link1 is further, then neg */
    /* Update the connect net */
    fseek(connect_net.fileloc, (link1_loc + dist -1) * LINK_NUM_LEN, SEEK_SET);
    char2num(connect_net.fileloc, LINK_NUM_LEN, exchange);
    fseek(connect_net.fileloc, -1 * LINK_NUM_LEN, SEEK_CUR);
    num2char(connect_net.fileloc, LINK_NUM_LEN, link1);
    fseek(connect_net.fileloc, (link1_loc - 1) * LINK_NUM_LEN, SEEK_SET);
    num2char(connect_net.fileloc, LINK_NUM_LEN, exchange);
    /* Update the information */
    fseek(information.fileloc, INFO_REC_LEN * (link1 - 1) + 1, SEEK_SET);
    num2char(information.fileloc, LINK_NUM_LEN, link1_loc + dist);
    fseek(information.fileloc, INFO_REC_LEN * (exchange - 1) + 1, SEEK_SET);
    num2char(information.fileloc, LINK_NUM_LEN, link1_loc);
  }
  else {
    dist = (link1_loc - link2_loc) / 255;  /* If link1 is further, then pos */
    /* Update the connect net */
    fseek(connect_net.fileloc, (link2_loc + dist -1) * LINK_NUM_LEN, SEEK_SET);
    char2num(connect_net.fileloc, LINK_NUM_LEN, exchange);
    fseek(connect_net.fileloc, -1 * LINK_NUM_LEN, SEEK_CUR);
    num2char(connect_net.fileloc, LINK_NUM_LEN, link2);
    fseek(connect_net.fileloc, (link2_loc - 1) * LINK_NUM_LEN, SEEK_SET);
    num2char(connect_net.fileloc, LINK_NUM_LEN, exchange);
    /* Update the information */
    fseek(information.fileloc, INFO_REC_LEN * (link2 - 1) + 1, SEEK_SET);
    num2char(information.fileloc, LINK_NUM_LEN, link2_loc + dist);
    fseek(information.fileloc, INFO_REC_LEN * (exchange - 1) + 1, SEEK_SET);
    num2char(information.fileloc, LINK_NUM_LEN, link2_loc);
  }
  /* For the next bit */
  add_codelet(DRAW_TOGETHER, strth - 1, link1, link2);
}

/* :: Template finder :: */
/* Check for any similar polarized bonds at two ends of one equal bond */
template_find(unsigned long fmlink, unsigned long thebond) {
  /* Variables */
  unsigned long tolink;
  unsigned long fmlast, tolast;
  unsigned long fmsum, tosum;
  unsigned long eachto, manyto;
  unsigned long eachcurr, manycurr;
  unsigned char check;
  unsigned long replacelast;
  
  /* Get location of other link */
  fseek(bond_jumper.fileloc, BOND_REC_LEN * (thebond - 1), SEEK_SET);
  char2num(bond_jumper.fileloc, BOND_NUM_LEN, tolink);

  /* : Check to either side of the links : */
  /* Get the locations of each last */
  fseek(information.fileloc, LINK_REC_LEN * (fmlink - 1) + 1 + LINK_NUM_LEN,
	SEEK_SET);
  char2num(information.fileloc, BOND_NUM_LEN, fmlast);
  char2num(information.fileloc, BOND_NUM_LEN + 1, fmsum);
  fseek(information.fileloc, LINK_REC_LEN * (tolink - 1) + 1 + LINK_NUM_LEN,
	SEEK_SET);
  char2num(information.fileloc, BOND_NUM_LEN, tolast);
  char2num(information.fileloc, BOND_NUM_LEN + 1, tosum);

  /* Search by going through one, for each polarized, check other through */
  /* Go through the one thought to be shorter based on summed strengths */
  if (tosum <= fmsum) {     /* Should go all through to */
    eachcurr = fmlast;
    replacelast = tolast;
  }
  else {
    eachcurr = tolast;
    replacelast = fmlast;
  }
       
  while (eachcurr) {
    /* Check the next bond against all the rest for similarities */
    /* First find what should be the same */
    fseek(bond_jumper.fileloc, BOND_REC_LEN * (eachcurr - 1), SEEK_SET);
    char2num(bond_jumper.fileloc, LINK_NUM_LEN, eachto);
    fseek(information.fileloc, LINK_NUM_LEN * (eachto - 1), SEEK_SET);
    check = fgetc(information.fileloc);
    manycurr = replacelast;
    while (manycurr) {
      /* Check through everything else now */
      fseek(bond_jumper.fileloc, BOND_REC_LEN * (manycurr - 1), SEEK_SET);
      char2num(bond_jumper.fileloc, LINK_NUM_LEN, manyto);
      fseek(information.fileloc, LINK_NUM_LEN * (manyto - 1), SEEK_SET);
      if (fgetc(information.fileloc) == check) {
	/* Match found.  Now to post follow up codelet */
	/* Calculate urgency... other information... */
	add_codelet(..........., ........, ........);
      }
    }
  }
}

/*****************************************************************************\
 ***   ***   **   **   *   *   ::    Notes    ::   *   *   **   **   ***   ***
\*****************************************************************************/

/* Additional Paradigm: distributed processing and storage possible in
   time and space */
/* at the beginning of each data file is prev and next filenames */

/* For determining appropriate output:
   forget sparks (artificial models of thought)
   instead, produce I/O models of the patterns in the real world and when
   the important parts of the model of the self seem to match the important
   parts of that model, I/O like that model. */

/*  : Connect Net :  */
/*      Thoughts     */
/* Connectnet is completely dynamic part so should be succinct as possible */
/* Because the kind of link does not separate its essence, links will need to
   have numbers assigned to them */
/* Note: similar links (an "a" and an "a" from different) will be separate
   unless some codelet comes along and finds that a long string is linked */
/* Ought to start my link numbers with 0; then I won't have to always be sub-
   tracting 1 -- then I will always have to have my #'s of records by 1 more
   than what I call that record (i.e. when I have 20 records, the last will
   be referred to as #19). No, better to keep it as it is. */
/* Draw together algorithm:
   Closer are to front, less likely to be randomly chosen to move.
   urgency / 255 is the degree to which the two should be drawn.
   Each time, recall urgency with a -1.  Then draw together 1/255 of the dist.
   each time until find that would make codelet of urgency 0, so don't */

/*       Format      */
/* <information location : LINK_NUM_LEN> */

/*  : Information :  */
/*      Thoughts     */
/* Everyone links to information and information links to everyone */
/* There are as many records in the connect net as there are in information
     which is the number of links so they will use the same number of bytes to
     describe a location, but different numbers: information will have a number
     for the current location of the link in the connect net, the connect net
     will always be moving a number for the location of the information */


/*       Format      */
/* <data : 1><link location : LINK_NUM_LEN><last bond loc. : BOND_NUM_LEN><summed strengths of bonds : BOND_NUM_LEN + 1> */

/*  : Bond Jumper :  */
/*      Thoughts     */
/* Bonds are not dynamic so I might as well only append to the end */
/* These include hyperlinks and all information that is needed (since doesn't
   need to be moved around).  Each one points to previous bond except first
   which has a null hyperlink signifying the last bond */
/* Use hyperlinks to find all bonds: w/in neural net just have
locations of info in info file; link file is appended to with links at every
location followed by info including where first bond is in bond file.  Bond
file has format <link-file-location: from><link-file-location: to><strength>
<next bond>.  Then when add new link, append to link file, add bond to some-
thing (time or next data/letter?), change link file data to point to first bond
+ add link file location to front of neural net.  When add new bond, append to
end of bond file, change previous bond (find by tracing hyper links) to point
to new bond */
/* Also, why am I lying the burden of checking for dupicate bonds on make bond,
   it has to be done everytime a bond is made, no matter the circumstances, so
   put it into add bond */
/* My sequence for forming a bond :
   Note: all links formed by template or sameness:

   H-E-L=L-O    H-E-L=L-O    H=E-L=L-O
   |   | |   => | | | | | => | | | | | ... Oops, this ought to be strengthening
   H-E-L-L-O    H-E-L-L-O    H-E=L=L=O

   I- -l-i-k-e- -f-r-o-g-s-.    I- -l-i-k-e- -f-r-o-g-s-.
   | | | | | | |         | | => | | | | | | | | | | | | | ... template building
   I- -l-i-k-e- -t-o-a-d-s-.    I- -l-i-k-e- -t-o-a-d-s-.

   So, check for sameness: if so, check for bond and form if need by, then look
                           for similar, non-sameness, sidebonds
			      if not, fizzle
   Depending on number and strengh of side bonds: If there is one set of
                           similar bonds in both but not all in both are
			      connected then begin to connect both
   If long row of similar bonds and everything similar is connected, suggest
                           dissimilar connections to continue a run.
       
   What is my salience?
     salience is a function of how close a link is to the front
                           and how many links it has (or their total strength)

   It makes no real sence to just randomly look around for any similarities --
     I would be looking everywhere and finding few.

   NOTE: when adding new data, reasonable to add a one-time codelet for its
         similars?

   That's a reasonable idea: post codelet for looking for similarities when new
                             data, but don't look randomly and don't revisit a
			          link unless at least some reason.

				       Moreover, with that one codelet, look around at
				              everything (skipping as go further from front?);
					             whenever find, post bond builder based, urgency
						            and later strength of bond based on salience
*/
/* Look like this for hitting to look at:
     X   X   X X X  X X X XX X XXXXX X X X  X XX X XXX
                                 ^Data               ^Front
     So, chance of hitting a piece related to distance from front and distance
     from spot. Could use squares, but would shrink too fast, so how about stat
     stuff from the headers?; hmm, guess I have to do it:
     y = (2*e^-(x / 16 - DataLoc) + e^-((x - FrontLoc) / 16)) / 2 */

/* Note: we want the whole "may check, may not" to be faster.  Rather than
     calculated rand again and again (must take a long time; why not use rand
     and the calculated probability to jump straight to next link to check */

/* Therefore... the amount to jump forward should be inversely porportional
     to the calculated probability, with changes dependent on random; ah!
     Probability is from 0 to 1.  1 - P is 0 to 1, then N * (1 - P) from 0 to N
     Then random of that, Okay.  We were going to go until chance was less that
     1 in 100.  So how about, jumping forward by 100 * (1 - P) * rand(). */
/* Ah-ha! Don't need a "from" location in the bond jumper records because the
   bonds are tied to a specific information slot/link which is the from! */
/* Compared to the number of links or the number of bonds (x 255)? */
/* Perfect score to the number of links means a bond to everything -- total
   coherence with what is known--very happy (but others probably are too) */
/* Perfect score to the number of bonds means that this links monopolizes all
   bonds--very happy (but everyone else is devistatingly sad) */
/* Note: I don't know if this is good or bad, but it does add more steps, which
   ought to be good, but when I am looking from the place of one link and that
   link makes a bond with another link, that other link won't know it and when
   I look at bonds from that link, I won't see it until is was made elsewhere.
   That fits in with the flirting, social analogy */
/* How about just say that every time that one link to another, suggest making
   opposite bond; not just for similars, but must have only 1 DRAW_TOGETHER */
/* AH!  That's it!
   First I thought, okay, well then why not post another make bond, but then
   would have another draw together unless I stopped it.
   Then I thought, why don't I just not worry about it and make both bonds in
   make bond and then they can be changed later
   Then I thought, "Ah!  Just make 1 bond, include both from and to, and have
   both links point to it!"
   Now I just thought about it again and I think I do want two bonds:  If
     I'm thinking about the word "barks" then that very much wants to be
     proceeded by the word "dog" but "dog", while it likes going to "barks"
     would be also happy with going to "lies down" or "ate the bone". */

/*       Format      */
/* <link 2 location : LINK_NUM_LEN><polarization : 1><strength : 1><prev. bond location : BOND_NUM_LEN> */

/*  :   Coderack  :  */
/*      Thoughts     */
/* Okay, so we need some way to choose which codelets to delete if there are
too many.  Their probability should be proporational to their age and inversely
proporational to their urgency, or it should be like CC's formula where their
probability is related to their score of Age * (Highest - Urgency).  Were it
totally by urgency, we could take a fraction of ((first_slot - 1) * max_pissi-
ble_urgency) and search though the codelets adding max_possible_urgency -
urgency for all but those but those with 0 urgency (no codelet).  Okay, but now
I need to adjust this value for those which are new without constant checking
who is new and who is not.  Suggestion - keep a coderack sized array filled w/
0 on hand for just such an occation.  I will put non-zero values in it and then
put back the 0's when I'm done.  For this, I will put in a number beginning at
1 at 255 slots back (or more, earlier if not that many slots), 2 at 254 slots
back, ..., 254 at 2 slots back, and 255 1 slot back (don't have to do checking
because lower numbers will be replaced with higher ones).  This number will be
subtracted from the modified urgency (I won't worry about it being too much,
because it will be making modifications to the summed urgency (which will have
to be signed) and the benefits will just carry a little. */
/* Note: I did the above modification array by just adding a "special" section
   to the regular coderack */
/* Note: the slothouse will not hold all locations.  If a given codelet were
placed in the 200 slot, then it is run when "first slot" is on 251, a 200 will
be put in the 250 slot and the 250 will no longer be in the slot house. It need
not be because it is not a open slot and will be run later */
/* Why not have just one "arguement" spot in a coderack records, with that spot
   as a pointer to all the information that codelet needs */

/*       Format      */
/* The coderack is just a list of codelet types and data.  Each time one wants
to select a codelet, take a fraction of the total urgency and then just search
through the codelets until the sum exceeds that fraction.  After much thought,
I must admit that no other solution presents itself */
/* Whenever a new codelet is added, it takes the slot shown in the slothouse as
the "first slot."  After it runs, the first slot spot moves forward but does
not delete previous data (no point).  Then, when a codelet runs, it is removed
from the coderack but data is deleted from the coderack so that a searcher can
know when it comes across a spent codelet.  Then the "first slot" spot moves
back a slot and overwrites previous data with the location of this new slot */
/* The data that was not overwritten above in the slothouse can be used as a
quick age checker.  Those just slots behind the "first slot" have recently been
filled and are therefore not very old. */
/* I must make absolutely certain a codelet never gets an urgency of 0 (through
for example a rounded down fraction below 1) because it will be by this that it
knows that no codelet exists there */
/* Coderack structure: use slots and slothouse for holding loc of unclaimed
   slots, but only 1 slot per codelet and add each time until more than num */
/* I say decrement it before putting slot into first slot, because it seems
   that slots are above first_slot, which is moved forward when one is used */
/* For the arguements array pointer in the coderack, just leave alone.  Don't
   0, just put what want there and call when need to.  */

/*  : Wider Ideas :  */
/* Significant sections: the goal of the program will always be to lower its
   "energy" - this will require it to think */
/* Other requirements: greed + addiction */
/* : Copycat Ideas : */
/* Sections: SLIPNET, WORKSPACE, CODERACK */
/* Structures: descriptions, bonds, groups, correspondences,
   rule, translated rule */
/* Bottom up: Noticers; Top Down: Lookers */
/* Urgency, activity */
/* Strength, Importance, Happiness, Salience */
/* Copycate Salience:
   Salience = f(importance, happiness)
   Importance = f(relavent descriptors, activity of descriptors)
   Happiness = f(incorporation of whole, stength of its structures) */
/* A formula that would work for adjusting randomness for temperature:
   Sum(i=0;n;v(Pi)+(1-v)avg) = t so I can change v for how much a probability
   should be pushed toward the average */

/* : Program style : */

/*
 * :: Put Title of major section here proceded and succeded by returns ::
 */

/*  :        Put Title of minor section here proceded by return        :  */
/*    Put command group title here preceded by a return or minor title    */
/* This is a command here */      /* Here is information here */
/* And another one */             /* And yet some more information */

/*    Put command group title here preceded by a return or minor title    */
/* This is a command here */      /* Here is information here */
/* And another one */             /* And yet some more information */

/* Functions versus macros?  I wanted speed, so macros just have to be the
   way to go, but let us be reasonable -- once difficult concepts are
   involved or comments very much needed, I really should stick to functions.
   Comprehensibility is at times more important than absolute ideal speed. */

/* ANSI CHARACTERS
IMMMMMMMMMMMMMMMMMMMMMMMMMQMMMMMMMMMMMMMMMMMMMMMMMQMMMMMMMMMMMMMMMMMMMMMMMMMMM;
                          @DDDDDDDDDDDDDDDDDDDDDDDY                           
:                                                                             :
HMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM<
*/

/* Need to have some sort of code for the numbers assigned to codelets:
             TYPE # _LEVEL1_ _LEVEL2_ _LEV3_ _LEV4_ _LEV5_ _LEV6_ _LEV7_ _LEV8_
     SENSORY   0    Keyboard 
       BONDS   1    Find sim formbond TmltSr
       LINKS   2    draw tog

       So have in base 16 (begin with 0x, and should be able to say "0x00") */


/* TO REMEMBER: */
/*   SPARKS: */
/* Use "sparks" that travel along bonds to find older data */
/* I think I like the sparks idea, even if sparks are nothing more than
   codelets.  Perhaps develope another area: the sparks box. */
/* Keep that idea close at hand, should it be useful */
/*   IMPORTANCE POLARIZATION: */
/* Also keep the other polarization type idea close should a use occur */
/* Idea: If one link notices another because that other link is important,
      and more important than the first, is that a polarization of sorts?
      If so, then a different kind; the kind that suggest that one link should
      be drawn to the other, not toward eachother.  So just say that the closer
      you are to the front, the less you have to move toward the other. */
/*   EXTRA RECORDS SPOT: */
/* Note: I don't need to keep track of both the number of information rec-
   ords and the number of links; they're the same. Can use one for diff. */

/* CODELETS: [codelets that it occurs to me I'll have to make]
             Break Bonds
	          Strengthen / Weaken Bonds (codelet?)
		  Template bond formers */


/* CURRENT THOUGHTS: ON TEMPLATES */

/* Heck, why not?  Each time an equivalent bond is formed, send out a template
   codelet with that bond as the arguement to see if there's anything to see */

/* Ignore polarity: see if there's a template and if there honestly is then
   the polarity, whatever it is, is part of that template.
   Even a similarity bond between two instances of exactly the same letter
   could be significant because it would suggest that such are good, unless
   it had a weak strength, in which case it would suggest that they're not */
/* If the search for templates will be so perliferative that it will note all
   sets of similarity bonds as templates of sorts, then such perlitivity should
   be everywhere */

/* But then want one that go through a lot to be shorter -- find by guess:
   say, this one has... 1 bonds, this has 0.  Then will go all though 0 for
   any bond in 1, but then update.  So finds that that has 7 bonds, so go all
   though other, but upon finding that that in fact has 9, go back */
/* Now have frombng and tobng: bng standing for Bond Number Guess */
/* Nah! more trouble than worth - just go for the one with smaller stsum */
/* ecb = Each: current bond */

/* A follow up codelet only needs to know: how long a line the template has
   formed as yet; what the last links were, so as not to go back on same
   paths; locations of last links to be added; and the first links in the
   chain, can use partly to make sure not form a circular template */

/* Further thought brings one to accept that I need each new codelet to know
   the entire path because a loop can form anywhere along the path. */

/* So what I need:
     how long chains are
     chains themselves (ends are last to be added) */

/* Another note that I seem to have lost: I would get far too many templates
     if each time one found two ways to go, a different one went each way.  I
     sort of decided that the best way to do it then was to start in all dir-
     ections, and from then on just choose randomly.  Then I thought, "Wait!
     many codelets are better, so just say that try one random direction and
     be done with it."  Now I reconsider.  To be consistand, I ought to go in
     all directions and then just leave it at that because I do a similar thing
     with my similar finder -- get all similars found and then have different
     codelet take each. */

/* Another thought: I wondered, "should every similar bond (and other bond)
   form all the time?  Why not throw some randomness into whether or not the
   bond will finally be formed, as well as the strength."  The strength random-
   ness is still a reasonable idea, but find similars already eliminates some
   randomly so shouldn't do that, but what I can do I just say that only a part
   of the time, the other, opposite bond gets formed. */


/* Sparks: I have many a thought on how to incorperate sparks and why on a dif-
   ferent paper.  Look there. */


/* TODO: Build randomness into strengths, opposite bond formations, etc... */
