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); }
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); }
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); }
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(); }
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); }
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(); } }
//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); }
//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); } } } } } } }
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) * }; * } * } * } */ }
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(); }