After many years of development,
Perl6 has finally been released
around the beginning of this new year 2016. We now position the
emerging AI
Perlmind as a killer app for the emerging
Perl6 programming language. Yesterday we uploaded the
Perl6 AI Manual to the Web for use with both P5 AI and
P6 AI.
Apparently both Perl5 and Perl6 will have problems in
accepting each single keystroke of input from a human user.
Therefore we should shift our AI input target away from
immediate human keyboard entry and towards the opening
and reading of computer files by the AI Mind. Since we
envision that a P6AI will sit quietly on a webserver and
ingest both local and remote computer files, it makes sense
now to channel input into the AI as a file rather than as
dynamic keyboard entry.
Today we have created C:\Strawberry\perl_tests\input.txt
as a textfile containing simply "boys play games john is a boy"
as its only content. Then we have copied the code-sequence of
AudInput() as FileInput() and we have made the necessary changes
to accept input from an input.txt file instead of from the keyboard.
2016 January 11:
Today we need to figure out how to read in each line of input.txt
and how to transfer each English word into quasi-auditory memory.
In the FileInput() subroutine of the mind0029.pl source, it looks
as though the WHILE loop for reading a file may be running through
completely before any individual line of input is extracted for
AI processing. We move the NewConcept() and AudMem() calls into
the WHILE loop so that each line of input is processed separately.
However, not just each line, but each word within a line, needs
to be processed separately.
2016 January 12:
A line of text input needs to be broken up into individual words.
First we learn from the PERL Black Book, page 568, that the
getc function lets us fetch each single character in
a line from our input.txt file. Therefore in the FileInput()
module of mind0031.pl we use the "#" symbol to comment out
the WHILE-loop that was transferring a whole message "$msg"
into AudMem(). Then we use getc in a new WHILE-loop
to transfer a series of incoming characters from input.txt
into AudMem(), where we comment out the string-reversing
and chopping code and we convert a do-loop into a simple
series of non-looping instructions, because the looping
is being done up in the FileInput() module. We see that
the program is now transferring individual input characters
into auditory memory. Later we will need to make the
transfers stop at the end of each input word, shown
by a blank space or punctuation or some other indicator.
The new code is messy, but we should upload it to the
Web and clean it up when we continue programming.
2016 January 13:
In the FileInput() module of the
mind0032.pl AI we are inserting
the call to NewConcept() so that AudMem() will show an incrementing
concept number for each word being stored in auditory memory.
Uh-oh, running the AI shows that each stored character is getting
its own concept number. Obviously, we will have to call NewConcept()
only when an entire new word is being stored, not each individual character.
We were able to test for a blank space (probably not enough) after
an input word in FileInput(), then order a "return" out of the
WHILE-loop. We had to put "{ return }" in brackets to avoid
crashing the program. Now the AI loads a first word "boys"
over and over into auditory memory, but we have made progress.
2016 January 14:
Let us see what happens if we run the Perl AI with no input.txt
available for the AI to read. We save input.txt elsewhere and
then we delete input.txt from the perl_tests directory. We run the
mind0033.pl AI program without an input.txt file available,
and it goes into an infinite loop. We change the FileInput()
code that opens the input.txt file by adding the "or die"
function to halt the program and issue an error message.
It works and we no longer get an infinite loop. Then we
add the input.txt file back into the directory.
Now we need to work on getting the AI to store the first word
of input and to move on to each succeeding word of input.
When we inspect the
MindForth code, we see that the AudInput
module first calls OldConcept at the end of a word, and
only calls NewConcept if the incoming word is not
recognized as an old concept. So we should create an
OldConcept() module in the Perl AI program.
In the FileInput() module, we might just wait for a
blank space-character and use it to initiate the saving
of the word and the calling of both OldConcept and
NewConcept(). Even if everything pauses to store
the word and either recognize it or create a new
concept, the reading of the input file should simply
resume and there should be no special need to keep
track of the position in the input-line.
In accordance with the MindForth code, any non-space
character coming in should go into AudMem(). An ASCII-32
space character does not get stored, but rather a
storage-space of one time-point gets skipped,
because MindForth AudInput increments time "t" for
all non-zero chararacters coming in. In other words,
skipping one time-point in auditory memory makes
it look as if a space-character were being stored.
It turns out that time "$t" was not yet being incremented
in the mind0033.pl AI, so we put an autoincrement into
the FileInput() module.
2016 January 15:
It is time in
mind0034.pl to create the
AudBuffer() module to be called by
AudInput() or FileInput() and
VerbGen(). The primitive coding may
be subject to criticism, since the module treats a series of variables
as a storage array, but the albeit primitive code not only serves its
purpose but is easily understandable by the AI coder or system
maintainer. For now we merely insert a stub of the AudBuffer() module.
After wondering where to place the AudBuffer() module, today
we re-arrange all the mind-modules to be in the same sequence as
MindForth has them, so that it will be easier in inspecting
code to move among the Forth and JavaScript and Perl AI programs.
MindForth compels a certain sequence because a module in a
Forth program can call only modules higher up in the code.
2016 January 16:
The mind0035.pl program is going to get extremely serious and
extremely complicated now, because for the first time in about
eighteen years we are going to change the format of the storage
of quasi-acoustic engrams in auditory memory. We are going to
change the six auditory panel-flags from "pho act pov beg ctu audpsi"
down to a group of only three: "pho" for the phoneme or character of
auditory input; "act" for the activation-level; and "audpsi" for
the concept number in the @psi conceptual memory array.
The point-of-view "pov" variable will no longer be stored in
auditory memory, and instead other functions of memory will have
to remember, if possible, who generated a sentence or a thought
stored in auditory memory. Over the years it has been helpful
to inspect the auditory memory array and to see whether a sentence
came from the AI itself or from an external source.
The flag-variables "beg" for beginning of a word and "ctu" for
continuation of a word served a purpose in the early AI Minds
but are now ready for extinction. The Perl language is so
powerful that it should simply detect the beginning or ending
of a word without relying on superfluous flags stored in
the engram itself. Removing obsolete flags makes the code
easier to understand and easier to develop further.
We should probably next code the EnVocab() module for
storing the fetch-tags of English vocabulary, because
the @psi concept array will need to direct pointers
into the @en array. In MindForth, EnVocab comes in between
InStantiate for "psi" concepts and EnParser for English
parts of speech. Oh, we already have a stub of EnVocab().
Then it is time to flesh out the module.
First we create the number-flag $num for grammatical
number, which is important for the retrieval of a stored word
in English or German or Russian. Then we create the
masculine-feminine-neuter flag mfn for tracking
the gender of a word in the @en English array.
We may now be able to discontinue the use of the fex
flag for "fiber-out" and fin for "fiber-in". These
flags were helpful for interpreting pronouns like "I" and
"me" as referring to the AI itself or to an external person.
The Perlmind should be able to use point-of-view "pov" code
to catch pronouns or verb-forms that need routing to the
correct concept.
We still need a part-of-speech pos flag to keep track
of words in the @en array. We also need the $aud flag
as an auditory recall-tag for activating engrams in the @aud
array, unless it conflicts with the @aud designation and
needs to be replaced with something like $rv for recall-vector.
The $nen flag is already incremented in NewConcept(), and
now we begin storing $nen during the operation of
EnVocab(). Then we had many problems because in TabulaRasa()
we had filled the @en English array with zeroes instead of
blank spaces.
2016 January 17:
In the mind0036.pl program we continue working on EnVocab() for
English vocabulary being stored in the @en array. Today we
create the variable $audbeg for auditory beginning
of an auditory word-engram stored in the @aud array. We also
create the variable $audnew to hold onto the value of
a recall-vector onset-tag for the start of a word in memory
while the rest of the word is still coming in. By setting
the $audnew flag only if it is at zero, we keep the
flag from changing its truly original value until the whole
word has been stored and the $audnew value has been
reset to zero for the sake of the next word coming in.
Today for a bug in the AI we kept getting a message something
like, "Use of unitialized value in concatenation <.> or string
at mind0036.pl line 295" at a point where we were trying to
show the contents of a row in the @en English lexical array.
In TabulaRasa() we solved the bug by declaring
$en[$trc] = "0,0,0,0,0,0,0"; with seven flags set to zero.
Apparently TabulaRasa() initializes all the items in the array.
2016 January 18:
In the
mind0037.pl AI Perlmind, let us see what happens at each stage
of reading an input.txt file.
The
MainLoop calls sensorium() which in turn calls the FileInput()
module. FileInput() goes into a WHILE-loop of reading with getc
(get character) for as long as the resulting $char remains
defined. As each character comes in, FileInput() calls
AudMem() to store the character in auditory memory.
Each time that $char becomes an empty non-letter
at the end of an input word, FileInput() increments the $onset
flag from $audnew and calls
NewConcept(), because the AI must learn each new word as
a new concept.
NewConcept() increments the number-of-English $nen lexical
identifier and calls the English vocabulary
EnVocab() module to set up a row of data in the @en array.
NewConcept() calls the stub of the English parser
EnParser() module. FileInput() calls the stub of the
OldConcept() module.
The
MainLoop module calls the Think() module which calls
Speech() to output a word as if it were a thought, but the
AI has not yet quickened and so the AI is not yet
truly thinking. At the end of the mind0037.pl program,
the MainLoop displays the contents of the experiential
memory for the sake of troubleshooting the AI.
2016 January 19:
The mind0038.pl program is ready to instantiate the
InStantiate() module for creating concepts in the @psi array of
the artificial Mind. Let us change the @psi array into the @psy
array so that a $psi variable will not conflict with the
name of the conceptual array.
2016 January 20:
With mind0039.pl we may need to remove the activation-flag
from the flag-panel of the @en English lexical array. In the
previous Forth and JavaScript AI Minds, we had "act" there
in case we needed it. Now it seems that in MindForth only
the KbSearch module uses "act" in the English array, and
the module could probably use @psy for searches instead of
the @en lexicon.
There is some question whether part-of-speech $pos should be
in the @psy conceptual array or in the @en lexical array. A search
for "6 en{" in the MindForth code of 24 July 2014 reveals that
no use seems to be made of part-of-speech "pos" in MindForth.
Apparently part-of-speech has already been dealt with during
the functions that use the Psi array, and therefore the English
array does not concern itself with part-of-speech. So part-of-speech
could be dropped from the @en English array.
It looks as though part-of-speech has to be assigned in the
@psy array before inflections are fetched in a lexical array.
If a person says, "I house you in a tent," then a word that
is normally a noun becomes a verb, "to house." The software
should override any knowledge of "house" as being a noun
and store the specific, one-time usage of "house" as a
verb. Then the AI robot can respond with "house" as a verb
to suit the occasion: "Please house me in a shed."
OldConcept() should not automatically insist that a
known word always has a particular part-of-speech.
In a German AI, VerbGen() should be called to create
verb-endings as needed, if not already stored in auditory
memory.
In the @psy concept array we should have seven flags:
psi, act, pos, jux, pre,
tkb, and seq. If we now change
the tqv variable from MindForth to $tkb in
the Perl AI, it clearly becomes "time-in-knowledge-base"
for Perl coders and AI maintainers.
It suddenly dawns on us that we no longer need an enx
flag in the @psy array. We may still need the $enx
variable for passing a fetch-value, but it looks like
the @psy concept number and the @en lexical number
will always be the same, since we coded MindForth
to find inflections for an unchanging concept number.
2016 January 21:
Now mind0040.pl invites us to make a drastic simplification by
merging the @psy array and the @en array, because any distinction
between the two arrays has gradually become redundant. The @psy
array has psi, act, pos, jux, pre,
tkb, seq flags. The @en array has
nen, num, mfn, dba, rv flags.
We could joint them together into one @psy conceptual array with
psi, act, pos, jux, pre,
tkb, seq, num, mfn, dba, rv
flags.
The first thing we do is in TabulaRasa(), where we fill each row
of the @psy array with eleven zeroes for the eleven flags. Next we
have the InStantiate() module store all eleven flags in the
combined flag-panel. We run the Perl AI and it makes no objections.
Then we have InStantiate() announce the values of all eleven flags
before storing them.
In the flag-panel of the @psy array, we should probably add
a human-language-code "hlc" so that an AI can detect English
or German or Russian and think in the indicated language.
2016 January 22:
In mind0042.pl where we have merged the @en array into the
@psy conceptual array, we gradually need to eliminate the
$nen variable. However, we need a replacement other
than the $psi variable so that the replacement
variable can hold steady and wait for each new word
being learned in English, German, Russian or whatever
human language is involved. Let us try using $nxt
as the next-word-to-be-learned.
2016 January 23:
In mind0043.pl we are now trying to code the AudRecog() module
taken from MindForth, although the timing may be premature.
As we began coding AudRecog() in the mind0043.pl AI, we discovered
that the primitive EnBoot() sequence did not contain enough English
words to serve as comparands with a word being processed in the
AudRecog() module, so we must suspend the AudRecog() coding
and fill up the EnBoot sequence properly before we resume coding
AudRecog().
Today we rename the English bootstrap EnBoot() sequence as
MindBoot() because the Perl AI with Unicode will not be limited
to thinking only in English, but will eventually be able to think
also in
German and in
Russian.
2016 January 24:
In mind0044.pl we are replacing the Think() module with EnThink() for
English thinking, and we are declaring DeThink() as a future German
thinking module and RuThink() as a future Russian thinking module.
Coding the AudRecog() module in Perl5, we move left-to-right
through the nested if-clauses. At the surface we test for a
matching $pho. Nested down one layer, we test for zero
activation on the matching $pho, because we do not want
a match-in-progress. At the second depth of nesting, we
test for the onset-character of a word. In the previous
AI Minds coded in Forth and JavaScript, we still had the
"beg(inning)" flag to fasten upon a beginning character
at the start of a comparand word in auditory memory.
Now in Perl killer app AI we must rely on the
$audnew variable which is set during FileInput()
but which we have apparently neglected to reset
to zero again. Let us try setting $audnew back
to zero just before we close the audinput.txt file.
Oh no, $audnew won't work here, because
$audnew applies only to the beginning of
an input word, not to the beginning of a word stored
in memory. Maybe we can try testing for not only a
zero-activation matching $pho but also for an adjacent
blank space.
Now, we are going backwards in memory from space-time $spt
down to $midway, which is set to zero in the primitive AI.
The $i variable is being decremented at each step backwards.
We would like to know if going one step further encounters
the space before a word. We might have to start searching
forwards through memory if we want to trap the occurrence
of an initial character in a stored word. If we go forwards
through memory, we could have a $penult variable that
would always hold the value of each preceding moment in time.
For the chain of activations resulting in recognition, it
should not matter if the sweep goes backwards or forwards.
2016 January 25:
Now in mind0045.pl we will stop searching backwards in AudRecog()
and search forwards so that it will be easier to find the beginning
of a comparand word stored in auditory memory.
As we debug the mind0045.pl AI, we notice that the MindBoot sequence
is not a subroutine, as EnBoot was in the previous AI Minds. We
should call MindBoot() as a one-time subroutine from the MainLoop.
We establish TabulaRasa() and MindBoot() as subroutines and we
give them a one-time call from the MainLoop.
Throughout many tests we were puzzled because AudRecog() was
not recognizing an initial "b" at zero activation preceded by
a zero $penult string. Finally it dawned on us that the
MindBoot() "BOY" was in uppercase, so for a test we switched
to lowercase "boy", and suddenly the proper recognition of
the initial character "b" was made. But we will need to
make input characters go into uppercase, so that AudRecog()
will not have to make distinctions.
2016 January 26:
Moving into mind0046.pl, we need to consult our Perl reference books
for how to shift input words into UPPERCASE. The index of
Perl by Example has no entry for "uppercase". None also
for "lowercase". However, the index of the Perl Black Book
says, "Uppercase, 341-342," BINGO! Mr. Steve Holzner
explains the "uc" function quite well on page 341. Let us turn
the page and see if we need any more info. Gee, page 342 says
that you can use "ucfirst" to capitalize only the first character
in a string sentence -- one more example of how powerful Perl is.
Resident webserver superintelligence, here we come.
Now let us try to use the "uc" function in the free Perl AI
source code of mind0046.pl as we continue. We had better look
into the FileInput() module first. Hmm, let us go back to
the index of Perl by Example, where in the index we
find "uc function, 702." Okay, let us try using
"uc $char" at the start of the input WHILE-loop in the
FileInput() module. Huh? It did not work. Uh-oh. Houston,
we have a problem. Our mission-critical Perl Supermind
is stuck in lowercase. Here we have been trying to learn
Perl, but we have never coded any Perl program other than
artificial intelligence. Even our very first "Hello world"
Perl program was a "mind.pl" program and we never did any
scratch-pad Perl coding. Meanwhile there are legions of
Perl coders waiting for us to finish the port of AI Minds
first into Perl5 and then into Perl6. Let us check the
Perl Black Book again. Let us try,
$char = "uc . $char"; in the FileInput() module.
We drag-and-drop the line of code from this journal
entry straight into the AI code. Then we issue the
MS-DOS command, "perl mind0046.pl" and take a look.
Oh no, the "uc" itself is going into memory as if it
were the input. Hey, it finally worked when we used
$char = uc $char; as the line of code. Now
the contents of auditory memory are being displayed
in uppercase. We can go back to coding the AudRecog()
module.
2016 January 27:
Although we have done away with the ctu-flag of MindForth in
the Perl AI, because we want to reduce the number of flags
stored in the @aud auditory memory, in AudRecog() we may
create a non-engram "ctu" or its equivalent by using the
split function to look ahead one array-row and see
whether a stored comparand word continues beyond any given
character.
2016 January 28:
In mind0050.pl we would like to have the FileInput() module
call the human-computer-interaction AudInput() module if
the input.txt file is not found. In that way, we can simply
remove input.txt to have a coding session of direct human
interaction with the AI Perlmind.
2016 January 29:
In mind0052.pl we are continuing to improve AudInput() towards
equal functionality as we developed in FileInput().
The line of input goes into a $msg string, which AudInput()
needs to process in the same way as FileInput() processes the
input.txt file, except that AudInput() only has to deal with
one line at a time, which is presumably one sentence or one
thought at a time.
2016 January 30:
Today in mind0053.pl we hope to fix a problem that we noticed
yesterday after we uploaded mind0052.pl to the Web. We had
carefully gone about sending the input $pho (phoneme) into
AudMem() and AudRecog(), but no word was being recognized
in AudRecog() -- which we had coded for six hours straight
three days ago. Then yesterday we saw that we had left a
"Temporary test for audrec" in the AudMem() module and that
the code was arbitrarily changing the $audpsi from
any recognized $audrec concept to the $nxt (next)
concept about to be named in the NewConcept() module. Now we
will comment out that pesky test code and see if AudRecog()
can recognize a word. Hmm, commenting out the code did
not seem to work.
We hate to debug the pristine Perl AudRecog() by inserting
diagnostic message triggers into it, but we start doing so,
and pretty soon we discover that we neglected to begin
AudRecog() with the activation-carrier $act set
to eight (8), as it is in the predecessor Mindforth AI.
So let us set $act to eight in the AudRecog() Perl
code and see what happens. Uh-oh, it still does not work.
But gradually we got AudRecog() to work. Now in the mind0054.pl
AI we are working on the AudMem() module. We want it to store
each $pho phoneme in the @ear array as $audpsi
if there has been an auditory recognition, and as simply
$nxt if only the next word from NewConcept() is being
stored.
The $audpsi shall be stored if the next time-point
is caught by the ($nxr[0] !~ /[A-Z]/) test as not
being a character of the alphabet.
2016 January 31:
Yesterday we got the
Perl AI to either recognize a known word
and store it in the @ear array with the correct $audpsi tag,
or instead to store a word as a new concept with the $nxt
identifier tag. However, in the @psy conceptual array, the Perlmind
is improperly incrementing the $nxt tag because we have
not yet figured out how to declare that a character flowing by
is the last character in a word. Bulbflash: Maybe
we can store the $nxt tag at the end of each @ear row,
erasing it when each successive character comes in, so that
only the last letter of the word will end up having the
$nxt tag.