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