/// <summary> /// Adds a strong analogy to the list, cloning in memory any sub analogies/relationships necessary. i.e. we duplicate the tree structure. /// </summary> /// <param name="a"></param> public void AddAnalogy(Analogy a) { // First check if it already exists. Analogy found = FindAnalogy(a); // If it exists, update (by adding relationships, not taking away) if (found != null) { UpdateAnalogy(found, a); return; } // Otherwise, clone and store new version. GroupElement lhs = a.LHS.DeepCopy(); GroupElement rhs = a.RHS.DeepCopy(); Analogy newAnalogy = new Analogy(lhs, rhs, workspace); // Clone analogy relationships. newAnalogy.CloneRelationshipsFrom(a); analogies.Add(newAnalogy); analogyCompetitionStats[newAnalogy] = new CompetitionStats(); analogyCompetitionStats[newAnalogy].AddWin(); // start with default win. }
public override void Run() { if (analogy == null) { analogy = workspace.structureCollection.PickAnalogy(); } if (analogy == null) { return; } // Check if it already exists in the workspace. if (workspace.FindEquivalentAnalogy(analogy) != null) { return; } // Construct the new LHS and RHS, using existing groups in the workspace if they are there. If groups don't exist, try to add. // Also find conflicts. GroupElement lhs, rhs; bool foundLHS, foundRHS; List <Group> conflictGroups = new List <Group>(); lhs = ProcessAnalogyComponent(analogy.LHS, out foundLHS, conflictGroups); rhs = ProcessAnalogyComponent(analogy.RHS, out foundRHS, conflictGroups); // Find conflict Analogies. List <Analogy> conflictAnalogies = FindConflictAnalogies(conflictGroups); // Add to attention history. workspace.RecordCodeletAttentionHistory(this, analogy.LHS.MinLocation, analogy.LHS.MaxLocation); workspace.RecordCodeletAttentionHistory(this, analogy.RHS.MinLocation, analogy.RHS.MaxLocation); // Evaluate current workspaces conflict measures vs. the proposed recussitated version, in terms of happiness. // Find conflict measures. HashSet <int> conflictMeasures = UnionGroupRanges(conflictGroups); // Eval happiness for original version. double happinessOld = EvalHappiness(conflictMeasures); // Swap out groups/analogies and reeval happiness for new proposed version. workspace.DropGroups(conflictGroups); workspace.DropAnalogies(conflictAnalogies); // Put in the new pile of stuff. if (!foundLHS) { workspace.AddGroupAndSubgroupsNoChecks(lhs); } if (!foundRHS) { workspace.AddGroupAndSubgroupsNoChecks(rhs); } Analogy newAnalogy = new Analogy(lhs, rhs, workspace); workspace.AddAnalogy(newAnalogy); newAnalogy.CloneRelationshipsFrom(analogy); // Eval. double happinessNew = EvalHappiness(conflictMeasures); if (Utilities.FightItOut(happinessNew, happinessOld, workspace.Temperature)) { // New one won! // Update stats. workspace.structureCollection.analogyCompetitionStats[analogy].AddWin(); // Reify all temporary groups. if (newAnalogy.LHS is TemporaryGroup) { Group realLHS = ((TemporaryGroup)lhs).MakeRealGroup(); newAnalogy.LHS = realLHS; } if (newAnalogy.RHS is TemporaryGroup) { Group realRHS = ((TemporaryGroup)rhs).MakeRealGroup(); newAnalogy.RHS = realRHS; } // Remove left-over relationship stuff from dropped /analogoes workspace.CompleteDropGroups(conflictGroups); workspace.CompleteDropAnalogies(conflictAnalogies); } else { // Old one won! revert. // Update stats. workspace.structureCollection.analogyCompetitionStats[analogy].AddLoss(); workspace.DropGroupAndSubgroupsNoChecks(lhs); workspace.DropGroupAndSubgroupsNoChecks(rhs); workspace.DropAnalogyNoChecks(newAnalogy); workspace.AddGroupsNoChecks(conflictGroups); workspace.AddAnalogiesNoChecks(conflictAnalogies); } }