// Creates group scout codelets for a group starting near position, of given size. private void SendGroupScoutsToArea(int position, int size) { if (size < 3) { if (size < 2) { return; } if (position < 0 || position + 1 >= workspace.measures.Count) { return; } ProximityGrouperCodelet pgc = new ProximityGrouperCodelet( 40, this, coderack, workspace, slipnet, workspace.measures[position], workspace.measures[position + 1]); coderack.AddCodelet(pgc); // Try to find measure link. MeasureLink link = workspace.FindMeasureLink(position, position + 1); if (link != null) { MeasureSamenessGrouperCodelet mgc = new MeasureSamenessGrouperCodelet( 60, this, coderack, workspace, slipnet, link); coderack.AddCodelet(mgc); } return; } int range = size / 2; for (int pos = position - range; pos <= position + range; pos++) { // Set urgency higher for an exact fit. int u = 30; if (pos == position) { u = 100; } Group g1 = null, g2 = null; bool foundBoth = false; // Try to divide into 2 subelements: find existing groups in range. for (int split = pos + 2; split <= pos + size - 2; split++) { foundBoth = TryToFindGroups(pos, split - 1, split, pos + size - 1, out g1, out g2); if (!foundBoth && pos == position) { if (g1 == null) { SendGroupScoutsToArea(pos, split - pos); } else { SendGroupScoutsToArea(split, pos + size - split + 1); } } if (foundBoth) { break; } } if (!foundBoth) { continue; } MetaGrouperCodelet mgc = new MetaGrouperCodelet(u, this, coderack, workspace, slipnet, g1, g2); coderack.AddCodelet(mgc); } }
public override void Run() { // If groups are not specified already, // look for two groups that are linked. if (ge1 == null || ge2 == null || !workspace.GroupElements.Contains(ge1) || !workspace.GroupElements.Contains(ge2)) { // Pick a link. Relationship r = workspace.PickRandomRelationshipByRecencyAndStrength(); if (r == null) { return; } ge1 = r.LHS; ge2 = r.RHS; // We prefer an analogy between parent groups containing the ends of this link. //Alternately, just try to find analogies when starting-relatinoships are found/ // If both have parents, spawn a codelet to look at that! // If they don't have parents, try to make groups including them. if (ge1.hasParent && ge2.hasParent) { if (ge1.parentGroup != ge2.parentGroup) { CreateAnalogyCodelet cac = new CreateAnalogyCodelet((int)this.rawUrgency, this, coderack, workspace, slipnet, ge1.parentGroup, ge2.parentGroup); coderack.AddCodelet(cac); } } else { MetaGrouperCodelet mgc1 = new MetaGrouperCodelet((int)this.rawUrgency, this, coderack, workspace, slipnet, ge1); MetaGrouperCodelet mgc2 = new MetaGrouperCodelet((int)this.rawUrgency, this, coderack, workspace, slipnet, ge2); coderack.AddCodelet(mgc1); coderack.AddCodelet(mgc2); } // Now try to work with this relationship as well, just in case it's at a good level and has good support. } if (ge1 == null || ge2 == null || ge1 == ge2 || !workspace.GroupElements.Contains(ge1) || !workspace.GroupElements.Contains(ge2)) { return; } if (ge1.Location > ge2.Location) { GroupElement tmp = ge1; ge1 = ge2; ge2 = tmp; } // Make analogies between single measures? if (Constants.MAKE_SINGLE_MEASURE_ANALOGIES) { if (!(ge1 is Group && ge2 is Group)) { return; } } // Check for redundant (identical) analogies! foreach (Analogy a2 in workspace.analogies) { if (a2.LHS == ge1 && a2.RHS == ge2) { return; } } // Make sure the 2 sides of the analogy span distinct time intervals (no mapping of m. 1-3 onto m.1-5, for instance) if (ge1.MaxLocation >= ge2.MinLocation) { return; } // Add to attention history. workspace.RecordCodeletAttentionHistory(this, ge1.MinLocation, ge1.MaxLocation); workspace.RecordCodeletAttentionHistory(this, ge2.MinLocation, ge2.MaxLocation); // So now we have 2 group elements, and we want to consider an analogy between them. // Look for a relationship between these elements (if bottom-level) or their subelements (if they have children) Analogy a = new Analogy(ge1, ge2, workspace); foreach (Relationship r in workspace.relationships) { // Check if this relatinoship is relevant. if (ge1 is Group) { Group g1 = (Group)ge1; if (!g1.GroupElements.Contains(r.LHS)) { continue; } } else { if (r.LHS != ge1) { continue; } } if (ge2 is Group) { Group g2 = (Group)ge2; if (!g2.GroupElements.Contains(r.RHS)) { continue; } } else { if (r.RHS != ge2) { continue; } } // Inside an analogy, we can only have one relationship (of normal similarity type) for each measure. For multiple ones, have them compete. // Compete against each conflicting relationship. Only add if it beats them all. bool won = true; List <Relationship> conflicting = a.FindConflictingRelationships(r); foreach (Relationship r2 in conflicting) { if (FightItOut(r, r2) == r2) { won = false; break; } } if (!won) { continue; } foreach (Relationship r2 in conflicting) { a.relationships.Remove(r2); } a.TryToAddRelationship(r); } // Make sure we were able to add something. if (a.relationships.Count == 0) { return; } // Create analogy if it's strong enough. Then other codelets will strengthen it and use it if necessary.. this // codelet just starts it up. double rnd = Utilities.rand.NextDouble() * 100; double score = a.Strength; if (rnd < score) { if (workspace.AddAnalogy(a)) { // Spawn more codelets to improve this analogy. AddRelationshipsToAnalogyCodelet arac = new AddRelationshipsToAnalogyCodelet(100, this, coderack, workspace, slipnet, a); // Consider a metagroup if the two items in the analogy are neighbors. if (ge1.MaxLocation + 1 == ge2.MinLocation) { MetaGrouperCodelet mgc = new MetaGrouperCodelet(100, this, coderack, workspace, slipnet, ge1, ge2, a); coderack.AddCodelet(mgc); } // Improve strength of subgroups. SpawnAnalogyReasonCodeletsRecur(ge1, a); SpawnAnalogyReasonCodeletsRecur(ge2, a); // Add contour analysis for LHS-RHS. LookForContourRelationshipCodelet lrc = new LookForContourRelationshipCodelet(100, this, coderack, workspace, slipnet, ge1, ge2); coderack.AddCodelet(lrc); AddRelationshipsToAnalogyCodelet arc = new AddRelationshipsToAnalogyCodelet(50, this, coderack, workspace, slipnet, a); coderack.AddCodelet(arc); } } }
/// <summary> /// Adds high-level codelets. /// This function provides top-down control by finding which structures are missing, and adding codelets /// to search for the missing structures. /// </summary> /// <param name="currentMeasureIndex">The index of the current (newest) measure, useful for focusing our attention</param> private static void AddHighLevelCodelets(int currentMeasureIndex) { // Add old link-breaker codelets for old analogies. This removes links that are irrelevant, where those measures // are already connected by anologies with good link/relationships. foreach (Analogy a in workspace.analogies) { if (a.Strength > 80 || a.MaxLocation < currentMeasureIndex - 4) { for (int j = 0; j < 5; j++) { OldMeasureLinkBreakerCodelet obc = new OldMeasureLinkBreakerCodelet(5, null, coderack, workspace, slipnet, a); coderack.AddCodelet(obc); } } } // Get happiness for each measure (taking into account a range before/after the measure. // Skip measures too far in past. for (int i = Math.Max(0, currentMeasureIndex - 8); i < workspace.measures.Count; i++) { int minMeasure; int maxMeasure; double happiness = workspace.GetHappinessStandardWindow(i, out minMeasure, out maxMeasure); double unhappiness = 100 - happiness; int urgency = (int)unhappiness; int linkUrgency = 0, groupUrgency = 0, analogyUrgency = 0; // Look for links at this measure. Do we need to search for more? double avgLinkStrength, maxLinkStrength; int numLinks = workspace.CountLinksToMeasure(i, out avgLinkStrength, out maxLinkStrength); if (numLinks < 1 || maxLinkStrength < 80 || avgLinkStrength < 50) { // Look for links. // TODO: how many to add? linkUrgency = (int)(100 - avgLinkStrength); for (int j = 0; j < 4; j++) { MeasureLinkerCodelet mlc = new MeasureLinkerCodelet(linkUrgency, null, coderack, workspace, slipnet, workspace.measures[i]); coderack.AddCodelet(mlc); } } // Look for Groups involving this measure. Do we need to search for more?. double avgGroupStrength, maxGroupStrength; int numGroups = workspace.CountGroupsInvolvingMeasure(i, out avgGroupStrength, out maxGroupStrength); if (numGroups < 1 || maxGroupStrength < 80 || avgGroupStrength < 50) { // Look for groups. // TODO: how many to add? for (int j = 0; j < 4; j++) { groupUrgency = Math.Max(5, (int)(100 - avgGroupStrength) - linkUrgency); MeasureSamenessGrouperCodelet msgc = new MeasureSamenessGrouperCodelet(groupUrgency, null, coderack, workspace, slipnet, workspace.PickMeasureLinkInRange(i, i)); coderack.AddCodelet(msgc); ProximityGrouperCodelet pgc = new ProximityGrouperCodelet(groupUrgency, null, coderack, workspace, slipnet, workspace.PickGroupElementInRange(i, i)); coderack.AddCodelet(pgc); MetaGrouperCodelet mgc = new MetaGrouperCodelet(groupUrgency, null, coderack, workspace, slipnet, workspace.PickGroupInRange(i, i)); coderack.AddCodelet(mgc); } } // Improve existing group scores. if (numGroups > 0 && maxGroupStrength < 75) { // TODO: how many to add? for (int j = 0; j < numGroups; j++) { Codelet codelet = new GroupReasonAnalogyComponentCodelet((int)(100 - maxGroupStrength), null, coderack, workspace, slipnet, workspace.PickGroupInRange(i, i)); coderack.AddCodelet(codelet); codelet = new GroupReasonComponentsSimilarCodelet((int)(100 - maxGroupStrength), null, coderack, workspace, slipnet, workspace.PickGroupInRange(i, i)); coderack.AddCodelet(codelet); codelet = new GroupReasonNumberComponentsCodelet((int)(100 - maxGroupStrength), null, coderack, workspace, slipnet, workspace.PickGroupInRange(i, i)); coderack.AddCodelet(codelet); codelet = new GroupReasonRhythmGapCodelet((int)(100 - maxGroupStrength), null, coderack, workspace, slipnet, workspace.PickGroupInRange(i, i)); coderack.AddCodelet(codelet); codelet = new GroupPenaltySubcomponentLengthCodelet((int)(100 - maxGroupStrength), null, coderack, workspace, slipnet, workspace.PickGroupInRange(i, i)); coderack.AddCodelet(codelet); } } // Look for Analogies involving this measure. Do we need to search for more?. double avgAnalogyStrength, maxAnalogyStrength; int numAnalogies = workspace.CountAnalogiesInvolvingMeasure(i, out avgAnalogyStrength, out maxAnalogyStrength); if (numAnalogies < 1 || maxAnalogyStrength < 80 || avgAnalogyStrength < 50) { // Look for analogies. // TODO: how many to add? for (int j = 0; j < 4; j++) { analogyUrgency = Math.Max(5, (int)(100 - avgAnalogyStrength) - groupUrgency - linkUrgency); CreateAnalogyCodelet cac = new CreateAnalogyCodelet(analogyUrgency, null, coderack, workspace, slipnet); coderack.AddCodelet(cac); } } // Add breakers and groupers. Add NUM_CODELETS_TILL_NEW_HIGH_LEVEL if we are super unhappy, less if happier. // TODO: how many to add? for (int j = 0; j < unhappiness / 100 * Constants.NUM_CODELETS_TILL_NEW_HIGH_LEVEL / 20; j++) { GroupBreakerCodelet gbc = new GroupBreakerCodelet(urgency, null, coderack, workspace, slipnet, workspace.PickGroupInRange(minMeasure, maxMeasure)); coderack.AddCodelet(gbc); /*MeasureSamenessGrouperCodelet msgc = new MeasureSamenessGrouperCodelet(urgency, null, coderack, workspace, slipnet, workspace.PickMeasureLinkInRange(minMeasure, maxMeasure)); * coderack.AddCodelet(msgc); * * ProximityGrouperCodelet pgc = new ProximityGrouperCodelet(urgency, null, coderack, workspace, slipnet, workspace.PickGroupElementInRange(minMeasure, maxMeasure)); * coderack.AddCodelet(pgc); * * MetaGrouperCodelet mgc = new MetaGrouperCodelet(urgency, null, coderack, workspace, slipnet, workspace.PickGroupInRange(minMeasure, maxMeasure)); * coderack.AddCodelet(mgc);*/ //CreateAnalogyCodelet cac = new CreateAnalogyCodelet(urgency, null, coderack, workspace, slipnet); //coderack.AddCodelet(cac); } //Generate/manage Expectations } }