Example #1
0
        public Thing CreateLandmark(List <Thing> near)
        {
            //a landmark is a collection of nearby segments
            //these must be cloned so they can be fixed in position rather than being adjusted relative to Sallie's position
            ModuleUKSN UKS = (ModuleUKSN)FindModuleByType(typeof(ModuleUKSN));

            if (UKS is null)
            {
                return(null);
            }
            Thing newLandmark = UKS.AddThing("Lm" + landmarkCount++.ToString(), "Landmark");

            foreach (Thing t in near)
            {
                Segment s  = Module2DModel.SegmentFromUKSThing(t);
                Thing   P1 = UKS.AddThing("lmp" + pointCount++.ToString(), "Point"); //These points are not included in the model and do don't move with poin of view
                P1.V = s.P1.Clone();
                Thing P2 = UKS.AddThing("lmp" + pointCount++.ToString(), "Point");
                P2.V = s.P2.Clone();
                Thing S = UKS.AddThing("l" + t.Label.ToString(), "SSegment");
                S.AddReference(P1);
                S.AddReference(P2);
                S.AddReference(t.References[2].T);//the color
                newLandmark.AddReference(S);
            }

            return(newLandmark);
        }
Example #2
0
        public void AddOutcomePair(Thing Event, Thing theAction, Thing theOutcome)
        {
            ModuleUKSN UKS = (ModuleUKSN)FindModuleByType(typeof(ModuleUKSN));

            if (UKS is null)
            {
                return;
            }
            Thing newOutcomePair = UKS.AddThing("x" + pairCount++, Event); //creates new thing as it as a child

            newOutcomePair.AddReference(theAction);
            newOutcomePair.AddReference(theOutcome);
        }
Example #3
0
        public virtual Thing AddThing(string label, Thing[] parents, object value = null, Thing[] references = null)
        {
            Debug.WriteLine("AddThing: " + label + " (" + ArrayToString(parents) + ") (" + ArrayToString(references) + ")");
            Thing newThing = new Thing {
                Label = label, V = value
            };

            references = references ?? new Thing[0];
            for (int i = 0; i < parents.Length; i++)
            {
                if (parents[i] == null)
                {
                    return(null);
                }
                newThing.Parents.Add(parents[i]);
                parents[i].Children.Add(newThing);
            }

            for (int i = 0; i < references.Length; i++)
            {
                if (references[i] == null)
                {
                    return(null);
                }
                newThing.AddReference(references[i]);
            }

            UKS.Add(newThing);
            return(newThing);
        }
Example #4
0
        private Thing AddAngleandRelationship(float greatestLength, Thing nextAreaCorner, Thing newShapeCorner, int refIndex, Thing theShape, Thing nextShapeCorner = null)
        {
            //find the angle
            Angle a;

            ModuleBoundarySegments.Arc seg1;
            ModuleBoundarySegments.Arc seg2;
            if (nextAreaCorner.References.Count == 1)
            {
                a    = 0;
                seg1 = new ModuleBoundarySegments.Arc {
                    p1 = (Point)nextAreaCorner.Children[0].V, p2 = (Point)nextAreaCorner.Children[0].V
                };
                seg2 = new ModuleBoundarySegments.Arc {
                    p1 = (Point)nextAreaCorner.Children[0].V, p2 = (Point)nextAreaCorner.Children[0].V
                };
            }
            else
            {
                Point cnrPt = (Point)nextAreaCorner.Children[0].V;
                Point p1    = (Point)nextAreaCorner.References[0].T.Children[0].V;
                Point p2    = (Point)nextAreaCorner.References[1].T.Children[0].V;
                seg1 = new ModuleBoundarySegments.Arc {
                    p1 = cnrPt, p2 = p1
                };
                seg2 = new ModuleBoundarySegments.Arc {
                    p1 = cnrPt, p2 = p2
                };
                a = Angle.FromDegrees((float)Vector.AngleBetween(cnrPt - p1, cnrPt - p2));
                a = Math.Abs(a);
                a = Angle.FromDegrees((float)(Math.Round(a.ToDegrees() / 15) * 15));
            }
            string s     = "Ang" + (int)a.ToDegrees();
            Thing  value = uks.GetOrAddThing("Value", "Thing");

            newShapeCorner.AddReference(uks.GetOrAddThing(s, value));


            float lenToNextCorner;

            if (refIndex == 0)
            {
                lenToNextCorner = seg1.Length / greatestLength;  //normalize the lengths
            }
            else
            {
                lenToNextCorner = seg2.Length / greatestLength;  //normalize the lengths
            }
            lenToNextCorner = (float)Math.Round(lenToNextCorner, 1);
            s = "Len" + lenToNextCorner.ToString("f1");
            if (nextShapeCorner == null)
            {
                nextShapeCorner = uks.AddThing("Cnr*", theShape);
            }

            newShapeCorner.AddRelationship(nextShapeCorner, uks.GetOrAddThing(s, value));
            return(nextShapeCorner);
        }
        private void AddAtttention(Thing t)
        {
            Thing attn   = uks.GetOrAddThing("ATTN", "Thing");
            Thing parent = t.Parents[t.Parents.Count - 1];

            attn.RemoveReferencesWithAncestor(uks.Labeled("Visual"));
            attn.AddReference(t);
            currentAttention = t;
            UpdateDialog();
        }
Example #6
0
        public Thing CreateEvent(Thing newLandmark)
        {
            ModuleUKSN UKS = (ModuleUKSN)FindModuleByType(typeof(ModuleUKSN));

            if (UKS is null)
            {
                return(null);
            }
            Thing retVal = UKS.AddThing("E" + eventCount++.ToString(), "Event");

            retVal.AddReference(newLandmark);
            return(retVal);
        }
Example #7
0
        private void HandlePhonemes(ModuleUKS2 UKS)
        {
            List <Thing> phonemes = UKS.AnyChildrenFired(UKS.Labeled("Phoneme"), 1, 0, true, false);
            List <Thing> phrases  = UKS.GetChildren(UKS.Labeled("Phrase"));
            List <Thing> words    = UKS.GetChildren(UKS.Labeled("Word"));

            //add incoming phonemes to short-term memory and do more processing
            //if there is a new phoneme, add it to short-term memory
            //TODO: handle phonemes as they come in rather than waiting for a pause
            Debug.Assert(phonemes.Count < 2);
            if (phonemes.Count == 1)
            {
                Thing phoneme = phonemes[0];
                shortTermMemoryList.Add(phoneme);
            }

            if (phonemes.Count == 0 && shortTermMemoryList.Count > 0) //only process if the list isn't empty
            {
                if (talking)
                {
                    talking = false;
                    shortTermMemoryList.Clear();
                    return;
                }

                //  MakeWordOfShortInput(UKS, shortTermMemoryList, words);

                FindPossibleWords(UKS, shortTermMemoryList);

                List <Thing> bestPhrase = FindBestPhrase(UKS);

                ConvertUnmatchedPhonemesToWords(UKS, bestPhrase);

                ExtendWordsWithSinglePhonemes(UKS, bestPhrase, words);

                Thing phrase = AddPhrase(UKS, bestPhrase);

                //add a phrase to the text
                if (currentText != null && phrase != null)
                {
                    currentText.AddReference(phrase);
                }
                //are we matching a text we already know?

                possiblePhrases.Clear();
                shortTermMemoryList.Clear();
            }
        }
Example #8
0
        //get input from touch... accurate locations, no color
        public bool AddSegmentFromTouch(PointPlus P1, PointPlus P2, PointPlus motion, int arm)
        {
            //if conf=0, it's a known endpoint. conf=1, not an endpoint
            ModuleUKSN UKS = (ModuleUKSN)FindModuleByType(typeof(ModuleUKSN));

            if (UKS is null)
            {
                return(false);
            }
            if (UKSSegments is null)
            {
                return(false);
            }
            if (imagining)
            {
                return(false);
            }

            ColorInt theColor   = Utils.ColorToInt(Colors.Wheat);
            Segment  newSegment = new Segment()
            {
                P1 = P1, P2 = P2, theColor = theColor
            };
            //OrderSegment(newSegment);

            Thing t1 = GetNearestThing(newSegment.MidPoint.Theta, out float dist1);

            //TODO: for motion testing
            t1 = UKS.Labeled("s0");
            if (t1 == null)
            {
                //TODO: merge mutliple segments
                //                AddSegmentToUKS(P1, P2, theColor, motion); //don't store motion with the segment (yet)
                AddSegmentToUKS(P1, P2, theColor);
            }

            else if (dist1 < 1)
            {
                Segment   prevSegment  = SegmentFromUKSThing(t1);
                PointPlus prevMidpoint = prevSegment.MidPoint;
                Angle     oldM         = prevSegment.Angle;
                Angle     newM         = newSegment.Angle;
                PointPlus offset       = new PointPlus()
                {
                    R = prevSegment.Length, Theta = newM
                };
                if (P1.Conf == 0 && P2.Conf == 0) //we're given both endpoints
                {
                    prevSegment.P1.P = P1.P; prevSegment.P1.Conf = 0;
                    prevSegment.P2.P = P2.P; prevSegment.P2.Conf = 0;
                }
                else if (P1.Conf == 0)
                {
                    prevSegment.P1.P = P1.P; prevSegment.P1.Conf = 0;
                    prevSegment.P2.P = P1.P - offset.V;
                }
                else if (P2.Conf == 0)
                {
                    prevSegment.P1.P = P2.P; prevSegment.P2.Conf = 0;
                    prevSegment.P2.P = P2.P + offset.V;
                }
                else
                {
                    //we're not near an endpoint--match the modpoint as close as possible & preserve length
                    //make the segment match the two points
                    PointPlus newMidpoint1 = new PointPlus()
                    {
                        P = (Point)GetClosestPointOnLine(P1.V, P2.V, prevMidpoint.V),
                    };
                    //offset is the dietance from the midpoint to each end
                    offset.R = offset.R / 2;
                    PointPlus newP1 = new PointPlus()
                    {
                        P = newMidpoint1.P + offset.V
                    };
                    PointPlus newP2 = new PointPlus()
                    {
                        P = newMidpoint1.P - offset.V
                    };
                    prevSegment.P1.R = newP1.R; prevSegment.P1.Theta = newP1.Theta;
                    prevSegment.P2.R = newP2.R; prevSegment.P2.Theta = newP2.Theta;
                }
                PointPlus newMidpoint = prevSegment.MidPoint;
                newMidpoint.P = newMidpoint.P - prevMidpoint.V;
                if (newMidpoint.R > 0.01 && motion.R != 0)
                {
                    if (prevSegment.Motion == null)
                    {
                        prevSegment.Motion = new PointPlus();
                        Thing tMotion = UKS.AddThing("m" + mCount++, UKS.Labeled("Point"));
                        tMotion.V = prevSegment.Motion;
                        t1.AddReference(tMotion);
                    }
                    prevSegment.Motion.R     = motion.R;
                    prevSegment.Motion.Theta = motion.Theta;
                    prevSegment.Motion.Conf  = newM - oldM;
                }
            }

            UpdateDialog();
            return(false);
        }
Example #9
0
        //TODO: make this happen when new phrases are added
        private void PrunePhrases(ModuleUKS2 UKS)
        {
            //find phrases which differ by a single word...can this be a grammar exemplar?
            //find phrases which have phonemes in them and see if there are now words to put in them
            List <Thing> phrases = UKS.GetChildren(UKS.Labeled("Phrase"));
            List <Thing> words   = UKS.GetChildren(UKS.Labeled("Word"));

            //if a word is usually followed by another specific word, create a new bigger word out of two smaller ones.
            for (int i = 0; i < words.Count; i++)
            {
                Thing       word                = words[i];
                List <Link> followingWords      = new List <Link>();
                int         greatestWeight      = -1;
                int         greatestWeightIndex = -1;
                for (int j = 0; j < word.ReferencedBy.Count; j++)
                {
                    Thing phrase = word.ReferencedBy[j].T;
                    int   k      = phrase.References.FindIndex(x => x.T == word);
                    Debug.Assert(k >= 0);
                    if (k < phrase.References.Count - 1)
                    {
                        Thing followingWord = phrase.References[k + 1].T;

                        int index = followingWords.FindIndex(x => x.T == followingWord);
                        if (index != -1)
                        {
                            followingWords[index].weight++;
                            if (followingWords[index].weight > greatestWeight)
                            {
                                greatestWeight      = (int)followingWords[index].weight;
                                greatestWeightIndex = index;
                            }
                        }
                        else
                        {
                            followingWords.Add(new Link()
                            {
                                T = followingWord, weight = 0
                            });
                        }
                    }
                }
                if (greatestWeight > 3)
                {
                }
            }



            List <Thing> phrasesWithPhonemes = phrases.FindAll(x => x.References.Any(l => l.T.Parents[0] == UKS.Labeled("Phoneme")));

            foreach (Thing phrase in phrases)//hrasesWithPhonemes)
            {
                possiblePhrases.Clear();
                //convert phrase back to phonemes
                Thing expandedPhrase = new Thing();
                ExpandToClass(expandedPhrase, phrase, UKS.Labeled("Phoneme"));
                FindPossibleWords(UKS, expandedPhrase.ReferencesAsThings);
                List <Thing> bestPhrase = FindBestPhrase(UKS);
                ConvertUnmatchedPhonemesToWords(UKS, bestPhrase);
                ExtendWordsWithSinglePhonemes(UKS, bestPhrase, words);
                int newUseCount  = bestPhrase.Sum(x => x.useCount);
                int oldUseCount  = phrase.ReferencesAsThings.Sum(x => x.useCount);
                int newWordCount = GetWordCount(UKS, bestPhrase);
                int oldWordCount = GetWordCount(UKS, phrase.ReferencesAsThings);
                if (newWordCount == bestPhrase.Count || newWordCount < oldWordCount || newUseCount > oldUseCount)
                {
                    //replace the references in the phrase
                    while (phrase.References.Count > 0)
                    {
                        phrase.RemoveReference(phrase.References[0].T);
                    }
                    foreach (Thing t in bestPhrase)
                    {
                        phrase.AddReference(t);
                    }
                }
            }
            return;

            //find phrases which incorporate other phrases
#pragma warning disable CS0162 // Unreachable code detected
            for (int i = 0; i < phrases.Count; i++)
#pragma warning restore CS0162 // Unreachable code detected
            {
                Thing phrase1 = phrases[i];
                for (int j = i + 1; j < phrases.Count; j++)
                {
                    Thing phrase2 = phrases[j];
                    if (phrase1.References.Count < phrase2.References.Count)
                    {
                        int index = IndexOfSequence(phrase2.ReferencesAsThings, phrase1.ReferencesAsThings);
                        if (index > -1)
                        {
                            ReplaceReferences(phrase1, phrase2, index);
                        }
                    }
                    else if (phrase1.References.Count > phrase2.References.Count)
                    {
                        int index = IndexOfSequence(phrase1.ReferencesAsThings, phrase2.ReferencesAsThings);
                        if (index > -1)
                        {
                            phrase1.References[index].T = phrase2;
                            for (int k = 0; k < phrase2.References.Count - 1; k++)
                            {
                                phrase1.RemoveReferenceAt(index + 1);
                            }
                        }
                    }
                    else if (phrase1.References.Count == phrase2.References.Count)
                    {
                        int index = IndexOfSequence(phrase2.ReferencesAsThings, phrase1.ReferencesAsThings);
                        if (index > -1)
                        {
                            UKS.DeleteThing(phrase2);
                        }
                    }
                }
            }

            //search for common subsphrases and convert them into phrases
            //l is the length of commonality we're searching for
            for (int i = 0; i < phrases.Count; i++)
            {
                Thing phrase1 = phrases[i];
                for (int l = phrase1.References.Count - 1; l > 1; l--)
                {
                    for (int offset = 0; offset < phrase1.References.Count - l + 1; offset++)
                    {
                        List <Thing> subRange  = phrase1.ReferencesAsThings.GetRange(offset, l).ToList();
                        Thing        newPhrase = null;
                        for (int j = i + 1; j < phrases.Count; j++)
                        {
                            Thing phrase2 = phrases[j];
                            int   index   = IndexOfSequence(phrase2.ReferencesAsThings, subRange);
                            if (index > -1 && phrase2.References.Count > subRange.Count)
                            {
                                if (newPhrase == null)
                                {
                                    newPhrase = UKS.AddThing("ph" + phraseCount++, UKS.Labeled("Phrase"), null, subRange.ToArray());
                                    phrase1.References[offset].T = newPhrase;
                                    for (int k = 0; k < newPhrase.References.Count - 1; k++)
                                    {
                                        phrase1.RemoveReferenceAt(offset + 1);
                                    }
                                }
                                phrase2.References[index].T = newPhrase;
                                for (int k = 0; k < newPhrase.References.Count - 1; k++)
                                {
                                    phrase2.RemoveReferenceAt(index + 1);
                                }
                            }
                        }
                    }
                }
            }
        }
Example #10
0
        private void HandleTalking()
        {
            //hack to prevent mixed phrases
            if (activeSequences.Count != 0)
            {
                return;
            }
            if (Fired(Labeled("Say"), immediateMemory))
            {
                List <Thing> phrasesToSay = AnyChildrenFired(Labeled("Phrase"));
                if (phrasesToSay.Count != 0)
                {
                    Thing newUtterance = AddThing("uu" + EventCount++, new Thing[] { Labeled("Utterance") }, null, null);
                    foreach (Link l in phrasesToSay[0].References)
                    {
                        //if the link is to a word, get the pronunciation of the word
                        if (l.T.Parents[0] == Labeled("Word"))
                        {
                            foreach (Link l1 in l.T.References)
                            {
                                newUtterance.AddReference(l1.T);
                            }
                            //newUtterance.AddReference(FindBestReference(l1.T));
                        }
                        else
                        {
                            //if the link is to a phoneme, add it
                            newUtterance.AddReference(l.T);
                        }
                    }
                    ModuleSpeakPhonemes nm = (ModuleSpeakPhonemes)FindModuleByType(typeof(ModuleSpeakPhonemes));

                    //what's the closest phrase we can say based on the phonemes we've learned to say so we can speak the phrase
                    foreach (Link l in newUtterance.References)
                    {
                        Thing t = l.T;
                        if (t.References.Count == 0)
                        {
                            //we've heard a phoneme we haven't learned how to speak
                            float bestDist = 100;
                            Thing closest  = null;
                            foreach (Thing t1 in Labeled("Phoneme").Children)
                            {
                                if (t1.References.Count > 0)
                                {
                                    char  p1   = t.Label[2];
                                    char  p2   = t1.Label[2];
                                    float dist = nm.PhonemeDistance(p1, p2);
                                    if (dist > -1 && dist < bestDist)
                                    {
                                        closest  = t1;
                                        bestDist = dist;
                                    }
                                }
                            }
                            Thing t2 = FindBestReference(closest);
                            if (t2 != null)
                            {
                                l.T = t2;
                            }
                        }
                        else
                        {
                            l.T = FindBestReference(t);
                        }
                    }
                    newUtterance.AddReference(Labeled("End"));
                    activeSequences.Add(newUtterance);
                }
            }
            if (Fired(Labeled("SayRnd"), 0))
            {
                //say a random utterance  (there is a hack to handle combiners which is needed to work with TTS)
                List <Thing> vowels     = Labeled("Vowel").Children;
                List <Thing> consonants = Labeled("Consonant").Children;
                if (consonants.Count == 0)
                {
                    return;
                }
                Thing consonant = consonants[rand.Next(consonants.Count - 2)];
                Thing vowel1    = vowels[rand.Next(vowels.Count)];
                Thing combiner  = Labeled("spk\u0361");

                int useCombiner = rand.Next(20);

                int repeatCount = rand.Next(3);
                repeatCount++;

                Thing newUtterance = AddThing("uu" + EventCount++, new Thing[] { Labeled("Utterance") }, null, null);
                for (int i = 0; i < repeatCount; i++)
                {
                    if (useCombiner < ModuleSpeakPhonemes.combiners.Count)
                    {
                        string s = ModuleSpeakPhonemes.combiners[useCombiner];
                        if (useCombiner == 0)
                        {
                            newUtterance.AddReference(Labeled("spk" + s[0]));
                            newUtterance.AddReference(combiner);
                            newUtterance.AddReference(Labeled("spk" + s[2]));
                            newUtterance.AddReference(vowel1);
                        }
                        else
                        {
                            newUtterance.AddReference(consonant);
                            newUtterance.AddReference(Labeled("spk" + s[0]));
                            newUtterance.AddReference(combiner);
                            newUtterance.AddReference(Labeled("spk" + s[2]));
                        }
                    }
                    else
                    {
                        newUtterance.AddReference(consonant);
                        newUtterance.AddReference(vowel1);
                    }
                }
                newUtterance.AddReference(Labeled("End"));
                Forget(Labeled("Utterance"));
                activeSequences.Add(newUtterance);
                Fire(newUtterance);
            }

            /*//TODO select a phrase to say
             * //things you can say are children of "Say".  They can contain sequences of words OR word-parameters which are affected by the Event
             * List<Thing> sayPhrases = Labeled("Say").Children;
             * Thing bestPhrase = null;
             * foreach (Thing phrase in sayPhrases)
             * {
             *  if (Fired(phrase, immediateMemory))
             *  {
             *      bestPhrase = phrase;
             *      activeSequences.Add(new Thing())
             *      {
             *          References = bestPhrase.References
             *      };
             *      return;
             *  }
             * }
             * if (bestPhrase == null)
             * {
             *  //no good phrase exists, try to create a new one
             *  //did anything fire we know words for?
             *  List<Thing> colors = Labeled("Color").Children; //change this to all sensory inputs
             *  foreach (Thing color in colors)
             *  {
             *      if (Fired(color, immediateMemory)) //a sensory thing fired
             *      {
             *          //do we have a word associated?
             *          Thing word = color.MostLikelyReference(Thing.ReferenceDirection.referenceBy, Labeled("Word"));
             *
             *          { Fire(word, false);
             *          };
             *          word = word;
             *      }
             *  }
             *
             *  //}
             *  return;
             * if (lastPhraseHeard != null)
             * {
             *  List<Link> similarPhrases = lastPhraseHeard.FindSimilar(Labeled("Phrase").Children, false, 5);
             *  if (similarPhrases.Count > 0)
             *  {
             *      activeSequence = new Thing()
             *      {
             *          References = new List<Link>(similarPhrases[0].T.References)
             *      };
             *  }
             *  else
             *  {
             *      List<Thing> allPhrases = Labeled("Say").Children;
             *      Thing randomPhrase = allPhrases[r.Next(0, allPhrases.Count)];
             *      {
             *          activeSequence = new Thing()
             *          {
             *              References = new List<Link>(randomPhrase.References)
             *          };
             *      }
             *  }
             * }
             */
        }
Example #11
0
        private void CheckForPhrase()
        {
            //associate phonemes I've heard with phonemes I spoke 2 gens earlier
            BuildAssociation(Labeled("Phoneme"), Labeled("SpeakPhn"), 1, 1, 2);
            List <Thing> phonemes  = AnyChildrenFired(Labeled("Phoneme"), 0, 0, true);
            List <Thing> phrases   = GetChildren(Labeled("Phrase"));
            Thing        shortTerm = Labeled("phTemp");

            if (shortTerm == null)
            {
                return;
            }

            bool paused = true;

            foreach (Thing phoneme in phonemes)
            {
                if (shortTermMemoryList.Count == 0 || phoneme != shortTermMemoryList.LastOrDefault()) //can't duplicate a word in a phrase
                {
                    shortTermMemoryList.Add(phoneme);
                }
                shortTerm.AddReference(phoneme);
                paused = false;
                phoneme.useCount++;
            }
            if (paused && shortTermMemoryList.Count > 0)
            {
                //is this a phrase I just said or is it outside input?
                if (AnyChildrenFired(Labeled("SpeakPhn"), shortTermMemory, 0, true).Count > 0)
                {
                    Forget(Labeled("PhraseISpoke"), 10);
                    shortTermMemoryList.Clear();
                    shortTerm.References.Clear();
                    return;
                }

                //find any known words in the phrase
                List <Thing> words = GetChildren(Labeled("Word"));
                foreach (Thing word in words)
                {
                    if (word.References.Count > 0)
                    {
                        for (int i = 0; i < shortTermMemoryList.Count; i++)
                        {
                            bool match = true;
                            int  k     = i;
                            foreach (Link l in word.References)
                            {
                                if (k >= shortTermMemoryList.Count || shortTermMemoryList[k++] != l.T)
                                {
                                    match = false;
                                    break;
                                }
                            }
                            if (match)
                            {
                                word.useCount++;
                                shortTermMemoryList[i] = word;
                                shortTermMemoryList.RemoveRange(i + 1, word.References.Count - 1);
                            }
                        }
                    }
                }

                //anything which wasn't a word, convert to a word
                List <Thing> phonemesInWord = new List <Thing>();
                int          startOfNewWord = -1;
                for (int i = 0; i < shortTermMemoryList.Count; i++)
                {
                    if (shortTermMemoryList[i].Parents[0] == Labeled("Word"))
                    {
                        if (phonemesInWord.Count > 0)
                        {
                            Thing newWord = AddThing("w" + wordCount++, new Thing[] { Labeled("Word") }, null, phonemesInWord.ToArray());
                            phonemesInWord.Clear();
                            if (startOfNewWord != -1)
                            {
                                shortTermMemoryList[startOfNewWord] = newWord;
                                shortTermMemoryList.RemoveRange(startOfNewWord + 1, newWord.References.Count - 1);
                                startOfNewWord = -1;
                            }
                        }
                    }
                    else
                    {
                        if (startOfNewWord == -1)
                        {
                            startOfNewWord = i;
                        }
                        phonemesInWord.Add(shortTermMemoryList[i]);
                    }
                }
                if (phonemesInWord.Count > 0)
                {
                    Thing newWord = AddThing("w" + wordCount++, new Thing[] { Labeled("Word") }, null, phonemesInWord.ToArray());
                    shortTermMemoryList[startOfNewWord] = newWord;
                    shortTermMemoryList.RemoveRange(startOfNewWord + 1, newWord.References.Count - 1);
                    startOfNewWord = -1;
                }

                //Now add the phrase to the knowledge store
                Thing       possibleNewPhrase = AddThing("ph" + phraseCount++, new Thing[] { Labeled("Phrase") }, null, shortTermMemoryList.ToArray());
                List <Link> exitingPhrase     = possibleNewPhrase.FindSimilar(phrases, true, 1);
                if (exitingPhrase.Count == 1 && exitingPhrase[0].weight == 1)
                {
                    //existing phrase
                    DeleteThing(possibleNewPhrase);
                    Fire(exitingPhrase[0].T);
                }
                else
                {
                    //new phrase
                    Fire(possibleNewPhrase);
                }

                shortTermMemoryList.Clear();
                shortTerm.References.Clear();
                Fire(Labeled("Say"));
            }
        }
        //fill this method in with code which will execute
        //once for each cycle of the engine
        public override void Fire()
        {
            Init();  //be sure to leave this here

            ModuleView naSource = theNeuronArray.FindModuleByLabel("UKS");

            if (naSource == null)
            {
                return;
            }
            uks = (ModuleUKS)naSource.TheModule;

            ModuleView attnSource = theNeuronArray.FindModuleByLabel("Attention");

            if (attnSource == null)
            {
                return;
            }
            ModuleAttention m = (ModuleAttention)attnSource.TheModule;


            Thing mentalModelParent = uks.GetOrAddThing("MentalModel", "Visual");
            Thing wordParent        = uks.GetOrAddThing("Word", "Audible");
            Thing attn = uks.GetOrAddThing("ATTN", "Thing");

            if (words.Count > 0)
            {
                if (currentWord != "")
                {
                    attn.RemoveReferencesWithAncestor(wordParent);
                }
                currentWord = words[0];
                //is this a reference to a visible object? does it contain a digit?
                if (words[0].IndexOfAny(new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }) != -1)
                {
                    Thing t = uks.Labeled(words[0], mentalModelParent.Children);
                    if (t != null)
                    {
                        if (naSource != null)
                        {
                            m.SetAttention(t, -1);
                        }
                    }
                }
                else
                {
                    //process a single word & add it to the current phrase
                    currentWord = char.ToUpper(currentWord[0]) + currentWord.Substring(1);
                    Thing theWord = uks.GetOrAddThing("w" + currentWord, wordParent);
                    attn.AddReference(theWord);
                }
                //delete the word from the top of the list
                words.RemoveAt(0);
            }
            else
            {
                if (attn.HasReferenceWithParent(wordParent) != null)
                {
                    attn.RemoveReferencesWithAncestor(wordParent);
                    m.SetAttention(null, 0);
                }
            }



            InnerMonologue();

            //if you want the dlg to update, use the following code whenever any parameter changes
            UpdateDialog();
        }