From 1ca7f1839f8e79a64d208a17d70d39e78983c577 Mon Sep 17 00:00:00 2001 From: James Tauber Date: Fri, 30 Nov 2012 02:03:59 -0500 Subject: [PATCH 1/7] proper nouns don't take articles --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 588b853..073f78b 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ co.py.cat ========= -An implementation of the [Douglas Hofstadter](http://prelectur.stanford.edu/lecturers/hofstadter/)'s [copycat](https://en.wikipedia.org/wiki/Copycat_%28software%29) [algorithm](http://www.al-got-rhythm.net) +An implementation of [Douglas Hofstadter](http://prelectur.stanford.edu/lecturers/hofstadter/)'s [copycat](https://en.wikipedia.org/wiki/Copycat_%28software%29) [algorithm](http://www.al-got-rhythm.net) This implementation is a copycat of Scott Boland's [Java implementation](http://itee.uq.edu.au/~scottb/_Copycat/), but re-written into Python. It's not a direct translation - but based on his code. I did not carry over the GUI, as this version can more usefully be run from command line, or imported for use by other Python scripts. From cfaebd150ff47116efd074a622f65ffeee9578bd Mon Sep 17 00:00:00 2001 From: James Tauber Date: Fri, 30 Nov 2012 02:12:44 -0500 Subject: [PATCH 2/7] tabs to spaces --- copycat/bond.py | 312 +++---- copycat/codelet.py | 16 +- copycat/codeletMethods.py | 1438 ++++++++++++++++----------------- copycat/coderack.py | 578 ++++++------- copycat/coderackPressure.py | 234 +++--- copycat/conceptMapping.py | 224 ++--- copycat/copycat.py | 74 +- copycat/correspondence.py | 328 ++++---- copycat/description.py | 86 +- copycat/formulas.py | 210 ++--- copycat/group.py | 406 +++++----- copycat/grouprun.py | 18 +- copycat/letter.py | 78 +- copycat/main.py | 18 +- copycat/replacement.py | 10 +- copycat/rule.py | 238 +++--- copycat/sliplink.py | 42 +- copycat/slipnet.py | 436 +++++----- copycat/slipnode.py | 250 +++--- copycat/temperature.py | 28 +- copycat/utils.py | 210 ++--- copycat/workspace.py | 246 +++--- copycat/workspaceFormulas.py | 250 +++--- copycat/workspaceObject.py | 384 ++++----- copycat/workspaceString.py | 130 +-- copycat/workspaceStructure.py | 54 +- 26 files changed, 3149 insertions(+), 3149 deletions(-) diff --git a/copycat/bond.py b/copycat/bond.py index e850601..778c4f1 100644 --- a/copycat/bond.py +++ b/copycat/bond.py @@ -3,180 +3,180 @@ from slipnet import slipnet from workspace import workspace class Bond(WorkspaceStructure): - def __init__(self,source, destination, bondCategory, bondFacet, sourceDescriptor, destinationDescriptor): - WorkspaceStructure.__init__(self) - self.source = source - self.string = self.source.string - self.destination = destination - self.leftObject = self.source - self.rightObject = self.destination - self.directionCategory = slipnet.right - if self.source.leftStringPosition > self.destination.rightStringPosition: - self.leftObject = self.destination - self.rightObject = self.source - self.directionCategory = slipnet.left - self.facet = bondFacet - self.sourceDescriptor = sourceDescriptor - self.destinationDescriptor = destinationDescriptor - self.category = bondCategory + def __init__(self,source, destination, bondCategory, bondFacet, sourceDescriptor, destinationDescriptor): + WorkspaceStructure.__init__(self) + self.source = source + self.string = self.source.string + self.destination = destination + self.leftObject = self.source + self.rightObject = self.destination + self.directionCategory = slipnet.right + if self.source.leftStringPosition > self.destination.rightStringPosition: + self.leftObject = self.destination + self.rightObject = self.source + self.directionCategory = slipnet.left + self.facet = bondFacet + self.sourceDescriptor = sourceDescriptor + self.destinationDescriptor = destinationDescriptor + self.category = bondCategory - self.destinationIsOnRight = self.destination == self.rightObject - self.bidirectional = self.sourceDescriptor == self.destinationDescriptor - if self.bidirectional: - self.directionCategory = None + self.destinationIsOnRight = self.destination == self.rightObject + self.bidirectional = self.sourceDescriptor == self.destinationDescriptor + if self.bidirectional: + self.directionCategory = None - def flippedVersion(self): - """ + def flippedVersion(self): + """ - """ - return Bond( - self.destination, self.get_source(), self.category.getRelatedNode(slipnet.opposite), - self.facet, self.destinationDescriptor, self.sourceDescriptor - ) + """ + return Bond( + self.destination, self.get_source(), self.category.getRelatedNode(slipnet.opposite), + self.facet, self.destinationDescriptor, self.sourceDescriptor + ) - def __repr__(self): - return '' % self.__str__() + def __repr__(self): + return '' % self.__str__() - def __str__(self): - return '%s bond between %s and %s' % ( self.category.name, self.leftObject, self.rightObject) + def __str__(self): + return '%s bond between %s and %s' % ( self.category.name, self.leftObject, self.rightObject) - def buildBond(self): - workspace.structures += [ self ] - self.string.bonds += [ self ] - self.category.buffer = 100.0 - if self.directionCategory: - self.directionCategory.buffer = 100.0 - self.leftObject.rightBond = self - self.rightObject.leftBond = self - self.leftObject.bonds += [ self ] - self.rightObject.bonds += [ self ] + def buildBond(self): + workspace.structures += [ self ] + self.string.bonds += [ self ] + self.category.buffer = 100.0 + if self.directionCategory: + self.directionCategory.buffer = 100.0 + self.leftObject.rightBond = self + self.rightObject.leftBond = self + self.leftObject.bonds += [ self ] + self.rightObject.bonds += [ self ] - def break_the_structure(self): - self.breakBond() + def break_the_structure(self): + self.breakBond() - def breakBond(self): - if self in workspace.structures: - workspace.structures.remove(self) - if self in self.string.bonds: - self.string.bonds.remove(self) - self.leftObject.rightBond = None - self.rightObject.leftBond = None - if self in self.leftObject.bonds: - self.leftObject.bonds.remove(self) - if self in self.rightObject.bonds: - self.rightObject.bonds.remove(self) + def breakBond(self): + if self in workspace.structures: + workspace.structures.remove(self) + if self in self.string.bonds: + self.string.bonds.remove(self) + self.leftObject.rightBond = None + self.rightObject.leftBond = None + if self in self.leftObject.bonds: + self.leftObject.bonds.remove(self) + if self in self.rightObject.bonds: + self.rightObject.bonds.remove(self) - def getIncompatibleCorrespondences(self): - # returns a list of correspondences that are incompatible with - # self bond - incompatibles = [] - if self.leftObject.leftmost and self.leftObject.correspondence: - correspondence = self.leftObject.correspondence - if self.string == workspace.initial: - objekt = self.leftObject.correspondence.objectFromTarget - else: - objekt = self.leftObject.correspondence.objectFromInitial - if objekt.leftmost and objekt.rightBond: - if objekt.rightBond.directionCategory and objekt.rightBond.directionCategory != self.directionCategory: - incompatibles += [ correspondence ] - if self.rightObject.rightmost and self.rightObject.correspondence: - correspondence = self.rightObject.correspondence - if self.string == workspace.initial: - objekt = self.rightObject.correspondence.objectFromTarget - else: - objekt = self.rightObject.correspondence.objectFromInitial - if objekt.rightmost and objekt.leftBond: - if objekt.leftBond.directionCategory and objekt.leftBond.directionCategory != self.directionCategory: - incompatibles += [ correspondence ] - return incompatibles + def getIncompatibleCorrespondences(self): + # returns a list of correspondences that are incompatible with + # self bond + incompatibles = [] + if self.leftObject.leftmost and self.leftObject.correspondence: + correspondence = self.leftObject.correspondence + if self.string == workspace.initial: + objekt = self.leftObject.correspondence.objectFromTarget + else: + objekt = self.leftObject.correspondence.objectFromInitial + if objekt.leftmost and objekt.rightBond: + if objekt.rightBond.directionCategory and objekt.rightBond.directionCategory != self.directionCategory: + incompatibles += [ correspondence ] + if self.rightObject.rightmost and self.rightObject.correspondence: + correspondence = self.rightObject.correspondence + if self.string == workspace.initial: + objekt = self.rightObject.correspondence.objectFromTarget + else: + objekt = self.rightObject.correspondence.objectFromInitial + if objekt.rightmost and objekt.leftBond: + if objekt.leftBond.directionCategory and objekt.leftBond.directionCategory != self.directionCategory: + incompatibles += [ correspondence ] + return incompatibles - def updateInternalStrength(self): - # bonds between objects of same type(ie. letter or group) are - # stronger than bonds between different types - sourceGap = self.get_source().leftStringPosition != self.get_source().rightStringPosition - destinationGap = self.destination.leftStringPosition != self.destination.rightStringPosition - if sourceGap == destinationGap: - memberCompatibility = 1.0 - else: - memberCompatibility = 0.7 - # letter category bonds are stronger - if self.facet == slipnet.letterCategory: - facetFactor = 1.0 - else: - facetFactor = 0.7 - strength = min(100.0,memberCompatibility * facetFactor * self.category.bondDegreeOfAssociation()) - self.internalStrength = strength + def updateInternalStrength(self): + # bonds between objects of same type(ie. letter or group) are + # stronger than bonds between different types + sourceGap = self.get_source().leftStringPosition != self.get_source().rightStringPosition + destinationGap = self.destination.leftStringPosition != self.destination.rightStringPosition + if sourceGap == destinationGap: + memberCompatibility = 1.0 + else: + memberCompatibility = 0.7 + # letter category bonds are stronger + if self.facet == slipnet.letterCategory: + facetFactor = 1.0 + else: + facetFactor = 0.7 + strength = min(100.0,memberCompatibility * facetFactor * self.category.bondDegreeOfAssociation()) + self.internalStrength = strength - def updateExternalStrength(self): - self.externalStrength = 0.0 - supporters = self.numberOfLocalSupportingBonds() - if supporters > 0.0: - density = self.localDensity() / 100.0 - density = density ** 0.5 * 100.0 - supportFactor = 0.6 ** (1.0 / supporters ** 3) - supportFactor = max(1.0,supportFactor) - strength = supportFactor * density - self.externalStrength = strength + def updateExternalStrength(self): + self.externalStrength = 0.0 + supporters = self.numberOfLocalSupportingBonds() + if supporters > 0.0: + density = self.localDensity() / 100.0 + density = density ** 0.5 * 100.0 + supportFactor = 0.6 ** (1.0 / supporters ** 3) + supportFactor = max(1.0,supportFactor) + strength = supportFactor * density + self.externalStrength = strength - def numberOfLocalSupportingBonds(self): - return len([ b for b in self.string.bonds if b.string == self.get_source().string and - self.leftObject.letterDistance(b.leftObject) != 0 and - self.rightObject.letterDistance(b.rightObject) != 0 and - self.category == b.category and - self.directionCategory == b.directionCategory ]) + def numberOfLocalSupportingBonds(self): + return len([ b for b in self.string.bonds if b.string == self.get_source().string and + self.leftObject.letterDistance(b.leftObject) != 0 and + self.rightObject.letterDistance(b.rightObject) != 0 and + self.category == b.category and + self.directionCategory == b.directionCategory ]) - def sameCategories(self,other): - return self.category == other.category and self.directionCategory == other.directionCategory + def sameCategories(self,other): + return self.category == other.category and self.directionCategory == other.directionCategory - def myEnds(self,object1,object2): - if self.get_source() == object1 and self.destination == object2: - return True - return self.get_source() == object2 and self.destination == object1 + def myEnds(self,object1,object2): + if self.get_source() == object1 and self.destination == object2: + return True + return self.get_source() == object2 and self.destination == object1 - def localDensity(self): - # returns a rough measure of the density in the string - # of the same bond-category and the direction-category of - # the given bond - slotSum = supportSum = 0.0 - for object1 in workspace.objects: - if object1.string == self.string: - for object2 in workspace.objects: - if object1.beside(object2): - slotSum += 1.0 - for bond in self.string.bonds: - if bond != self and self.sameCategories(bond) and self.myEnds(object1,object2): - supportSum += 1.0 - if slotSum == 0.0: - return 0.0 - return 100.0 * supportSum / slotSum + def localDensity(self): + # returns a rough measure of the density in the string + # of the same bond-category and the direction-category of + # the given bond + slotSum = supportSum = 0.0 + for object1 in workspace.objects: + if object1.string == self.string: + for object2 in workspace.objects: + if object1.beside(object2): + slotSum += 1.0 + for bond in self.string.bonds: + if bond != self and self.sameCategories(bond) and self.myEnds(object1,object2): + supportSum += 1.0 + if slotSum == 0.0: + return 0.0 + return 100.0 * supportSum / slotSum - def sameNeighbours(self,other): - if self.leftObject == other.leftObject: - return True - return self.rightObject == other.rightObject + def sameNeighbours(self,other): + if self.leftObject == other.leftObject: + return True + return self.rightObject == other.rightObject - def getIncompatibleBonds(self): - return [ b for b in self.string.bonds if self.sameNeighbours(b) ] + def getIncompatibleBonds(self): + return [ b for b in self.string.bonds if self.sameNeighbours(b) ] - def get_source(self): - return self.source + def get_source(self): + return self.source - def set_source(self, value): - self.source = value + def set_source(self, value): + self.source = value def possibleGroupBonds(bondCategory, directionCategory, bondFacet, bonds): - result = [] - for bond in bonds: - if bond.category == bondCategory and bond.directionCategory == directionCategory: - result += [ bond ] - else: - # a modified bond might be made - if bondCategory == slipnet.sameness: - return None # a different bond cannot be made here - if bond.category == bondCategory or bond.directionCategory == directionCategory: - return None # a different bond cannot be made here - if bond.category == slipnet.sameness: - return None - bond = Bond(bond.destination, bond.get_source(), bondCategory, bondFacet, bond.destinationDescriptor, bond.sourceDescriptor) - result += [ bond ] - return result + result = [] + for bond in bonds: + if bond.category == bondCategory and bond.directionCategory == directionCategory: + result += [ bond ] + else: + # a modified bond might be made + if bondCategory == slipnet.sameness: + return None # a different bond cannot be made here + if bond.category == bondCategory or bond.directionCategory == directionCategory: + return None # a different bond cannot be made here + if bond.category == slipnet.sameness: + return None + bond = Bond(bond.destination, bond.get_source(), bondCategory, bondFacet, bond.destinationDescriptor, bond.sourceDescriptor) + result += [ bond ] + return result diff --git a/copycat/codelet.py b/copycat/codelet.py index 59fb8c1..65d4f94 100644 --- a/copycat/codelet.py +++ b/copycat/codelet.py @@ -1,10 +1,10 @@ class Codelet(object): - def __init__(self, name, urgency, timestamp): - self.name = name - self.urgency = urgency - self.arguments = [] - self.pressure = None - self.timeStamp = timestamp + def __init__(self, name, urgency, timestamp): + self.name = name + self.urgency = urgency + self.arguments = [] + self.pressure = None + self.timeStamp = timestamp - def __repr__(self): - return '' % self.name + def __repr__(self): + return '' % self.name diff --git a/copycat/codeletMethods.py b/copycat/codeletMethods.py index 138f96d..4de8dff 100644 --- a/copycat/codeletMethods.py +++ b/copycat/codeletMethods.py @@ -12,791 +12,791 @@ from correspondence import Correspondence # some methods common to the codelets def __showWhichStringObjectIsFrom(structure): - if not structure: - return - whence = 'other' - if isinstance(structure,WorkspaceObject): - whence='target' - if structure.string == workspace.initial: - whence='initial' - print 'object chosen = %s from %s string' % ( structure, whence ) + if not structure: + return + whence = 'other' + if isinstance(structure,WorkspaceObject): + whence='target' + if structure.string == workspace.initial: + whence='initial' + print 'object chosen = %s from %s string' % ( structure, whence ) def __getScoutSource(slipnode,relevanceMethod,typeName): - initialRelevance = relevanceMethod(workspace.initial,slipnode) - targetRelevance = relevanceMethod(workspace.target,slipnode) - initialUnhappiness = workspace.initial.intraStringUnhappiness - targetUnhappiness = workspace.target.intraStringUnhappiness - logging.info('initial : relevance = %d, unhappiness=%d' % (initialRelevance,int(initialUnhappiness)) ) - logging.info('target : relevance = %d, unhappiness=%d' % (targetRelevance,int(targetUnhappiness)) ) - string = workspace.initial - if utils.random() * (initialRelevance + initialUnhappiness+targetRelevance+targetUnhappiness) > (initialRelevance + initialUnhappiness): - string = workspace.target - logging.info('target string selected: %s for %s' % (workspace.target,typeName)) - else: - logging.info('initial string selected: %s for %s' % (workspace.initial,typeName)) - source = chooseUnmodifiedObject('intraStringSalience',string.objects) - return source + initialRelevance = relevanceMethod(workspace.initial,slipnode) + targetRelevance = relevanceMethod(workspace.target,slipnode) + initialUnhappiness = workspace.initial.intraStringUnhappiness + targetUnhappiness = workspace.target.intraStringUnhappiness + logging.info('initial : relevance = %d, unhappiness=%d' % (initialRelevance,int(initialUnhappiness)) ) + logging.info('target : relevance = %d, unhappiness=%d' % (targetRelevance,int(targetUnhappiness)) ) + string = workspace.initial + if utils.random() * (initialRelevance + initialUnhappiness+targetRelevance+targetUnhappiness) > (initialRelevance + initialUnhappiness): + string = workspace.target + logging.info('target string selected: %s for %s' % (workspace.target,typeName)) + else: + logging.info('initial string selected: %s for %s' % (workspace.initial,typeName)) + source = chooseUnmodifiedObject('intraStringSalience',string.objects) + return source def __getBondFacet(source,destination): - bondFacet = chooseBondFacet(source,destination) - assert bondFacet - return bondFacet + bondFacet = chooseBondFacet(source,destination) + assert bondFacet + return bondFacet def __getDescriptors(bondFacet,source,destination): - sourceDescriptor = source.getDescriptor(bondFacet) - destinationDescriptor = destination.getDescriptor(bondFacet) - assert sourceDescriptor and destinationDescriptor - return sourceDescriptor, destinationDescriptor + sourceDescriptor = source.getDescriptor(bondFacet) + destinationDescriptor = destination.getDescriptor(bondFacet) + assert sourceDescriptor and destinationDescriptor + return sourceDescriptor, destinationDescriptor def __allOppositeMappings(mappings): - return len([ m for m in mappings if m.label != slipnet.opposite ]) == 0 + return len([ m for m in mappings if m.label != slipnet.opposite ]) == 0 def __structureVsStructure(structure1,weight1,structure2,weight2): - structure1.updateStrength() - structure2.updateStrength() - weightedStrength1 = temperatureAdjustedValue(structure1.totalStrength * weight1) - weightedStrength2 = temperatureAdjustedValue(structure2.totalStrength * weight2) - rhs = (weightedStrength1 + weightedStrength2) * utils.random() - logging.info('%d > %d' % (weightedStrength1,rhs)) - return weightedStrength1 > rhs + structure1.updateStrength() + structure2.updateStrength() + weightedStrength1 = temperatureAdjustedValue(structure1.totalStrength * weight1) + weightedStrength2 = temperatureAdjustedValue(structure2.totalStrength * weight2) + rhs = (weightedStrength1 + weightedStrength2) * utils.random() + logging.info('%d > %d' % (weightedStrength1,rhs)) + return weightedStrength1 > rhs def __fightItOut(structure, structureWeight, incompatibles, incompatibleWeight): - if not (incompatibles and len(incompatibles)): - return True - for incompatible in incompatibles: - if not __structureVsStructure(structure, structureWeight, incompatible, incompatibleWeight): - logging.info('lost fight with %s' % incompatible) - return False - logging.info('won fight with %s' % incompatible) - return True + if not (incompatibles and len(incompatibles)): + return True + for incompatible in incompatibles: + if not __structureVsStructure(structure, structureWeight, incompatible, incompatibleWeight): + logging.info('lost fight with %s' % incompatible) + return False + logging.info('won fight with %s' % incompatible) + return True def __fightIncompatibles(incompatibles,structure,name,structureWeight,incompatibleWeight): - if len(incompatibles): - if __fightItOut(structure,structureWeight,incompatibles,incompatibleWeight): - logging.info('broke the %s' % name) - return True - logging.info('failed to break %s: Fizzle' % name) - return False - logging.info('no incompatible %s' % name) - return True + if len(incompatibles): + if __fightItOut(structure,structureWeight,incompatibles,incompatibleWeight): + logging.info('broke the %s' % name) + return True + logging.info('failed to break %s: Fizzle' % name) + return False + logging.info('no incompatible %s' % name) + return True def __slippability(conceptMappings): - for mapping in conceptMappings: - slippiness = mapping.slipability() / 100.0 - probabilityOfSlippage = temperatureAdjustedProbability(slippiness) - if formulas.coinFlip(probabilityOfSlippage): - return True - return False + for mapping in conceptMappings: + slippiness = mapping.slipability() / 100.0 + probabilityOfSlippage = temperatureAdjustedProbability(slippiness) + if formulas.coinFlip(probabilityOfSlippage): + return True + return False # start the actual codelets def breaker(): - probabilityOfFizzle = (100.0-Temperature)/100.0 - assert not coinFlip(probabilityOfFizzle) - # choose a structure at random - structures = [ s for s in workspace.structures if - isinstance(s,Group) or - isinstance(s,Bond) or - isinstance(s,Correspondence) ] - assert len(structures) - structure = utils.choice(structures) - __showWhichStringObjectIsFrom(structure) - breakObjects = [ structure ] - if isinstance(structure,Bond): - if structure.source.group and structure.source.group == structure.destination.group: - breakObjects += [ structure.source.group ] - # try to break all objects - for structure in breakObjects: - breakProbability = temperatureAdjustedProbability(structure.totalStrength/100.0) - if coinFlip(breakProbability): - return - for structure in breakObjects: - structure.break_the_structure() + probabilityOfFizzle = (100.0-Temperature)/100.0 + assert not coinFlip(probabilityOfFizzle) + # choose a structure at random + structures = [ s for s in workspace.structures if + isinstance(s,Group) or + isinstance(s,Bond) or + isinstance(s,Correspondence) ] + assert len(structures) + structure = utils.choice(structures) + __showWhichStringObjectIsFrom(structure) + breakObjects = [ structure ] + if isinstance(structure,Bond): + if structure.source.group and structure.source.group == structure.destination.group: + breakObjects += [ structure.source.group ] + # try to break all objects + for structure in breakObjects: + breakProbability = temperatureAdjustedProbability(structure.totalStrength/100.0) + if coinFlip(breakProbability): + return + for structure in breakObjects: + structure.break_the_structure() def bottom_up_description_scout(codelet): - chosenObject = chooseUnmodifiedObject('totalSalience',workspace.objects) - assert chosenObject - __showWhichStringObjectIsFrom(chosenObject) - description = chooseRelevantDescriptionByActivation(chosenObject) - assert description - sliplinks = similarPropertyLinks(description.descriptor) - assert sliplinks and len(sliplinks) - values = [ sliplink.degreeOfAssociation() * sliplink.destination.activation for sliplink in sliplinks ] - i = selectListPosition(values) - chosen = sliplinks[ i ] - chosenProperty = chosen.destination - coderack.proposeDescription(chosenObject,chosenProperty.category(),chosenProperty,codelet) + chosenObject = chooseUnmodifiedObject('totalSalience',workspace.objects) + assert chosenObject + __showWhichStringObjectIsFrom(chosenObject) + description = chooseRelevantDescriptionByActivation(chosenObject) + assert description + sliplinks = similarPropertyLinks(description.descriptor) + assert sliplinks and len(sliplinks) + values = [ sliplink.degreeOfAssociation() * sliplink.destination.activation for sliplink in sliplinks ] + i = selectListPosition(values) + chosen = sliplinks[ i ] + chosenProperty = chosen.destination + coderack.proposeDescription(chosenObject,chosenProperty.category(),chosenProperty,codelet) def top_down_description_scout(codelet): - descriptionType = codelet.arguments[0] - chosenObject = chooseUnmodifiedObject('totalSalience',workspace.objects) - assert chosenObject - __showWhichStringObjectIsFrom(chosenObject) - descriptions = chosenObject.getPossibleDescriptions(descriptionType) - assert descriptions and len(descriptions) - values = [ n.activation for n in descriptions ] - i = selectListPosition(values) - chosenProperty = descriptions[ i ] - coderack.proposeDescription(chosenObject,chosenProperty.category(), chosenProperty,codelet) + descriptionType = codelet.arguments[0] + chosenObject = chooseUnmodifiedObject('totalSalience',workspace.objects) + assert chosenObject + __showWhichStringObjectIsFrom(chosenObject) + descriptions = chosenObject.getPossibleDescriptions(descriptionType) + assert descriptions and len(descriptions) + values = [ n.activation for n in descriptions ] + i = selectListPosition(values) + chosenProperty = descriptions[ i ] + coderack.proposeDescription(chosenObject,chosenProperty.category(), chosenProperty,codelet) def description_strength_tester(codelet): - description = codelet.arguments[0] - description.descriptor.buffer = 100.0 - description.updateStrength() - strength = description.totalStrength - probability = temperatureAdjustedProbability(strength/100.0) - assert formulas.coinFlip(probability) - coderack.newCodelet('description-builder',codelet,strength) + description = codelet.arguments[0] + description.descriptor.buffer = 100.0 + description.updateStrength() + strength = description.totalStrength + probability = temperatureAdjustedProbability(strength/100.0) + assert formulas.coinFlip(probability) + coderack.newCodelet('description-builder',codelet,strength) def description_builder(codelet): - description = codelet.arguments[0] - assert description.object in workspace.objects - if description.object.hasDescription(description.descriptor): - description.descriptionType.buffer = 100.0 - description.descriptor.buffer = 100.0 - else: - description.build() + description = codelet.arguments[0] + assert description.object in workspace.objects + if description.object.hasDescription(description.descriptor): + description.descriptionType.buffer = 100.0 + description.descriptor.buffer = 100.0 + else: + description.build() def bottom_up_bond_scout(codelet): - source = chooseUnmodifiedObject('intraStringSalience',workspace.objects) - __showWhichStringObjectIsFrom(source) - destination = chooseNeighbour(source) - assert destination - logging.info('destination: %s' % destination) - bondFacet = __getBondFacet(source,destination) - logging.info('chosen bond facet: %s' % bondFacet.get_name()) - logging.info('Source: %s, destination: %s' % (source,destination)) - sourceDescriptor, destinationDescriptor = __getDescriptors(bondFacet,source,destination) - logging.info("source descriptor: " + sourceDescriptor.name.upper()) - logging.info("destination descriptior: " + destinationDescriptor.name.upper()) - category = sourceDescriptor.getBondCategory(destinationDescriptor) - assert category - if category == slipnet.identity: - category = slipnet.sameness - logging.info('proposing %s bond ' % category.name) - coderack.proposeBond(source,destination,category,bondFacet,sourceDescriptor,destinationDescriptor,codelet) + source = chooseUnmodifiedObject('intraStringSalience',workspace.objects) + __showWhichStringObjectIsFrom(source) + destination = chooseNeighbour(source) + assert destination + logging.info('destination: %s' % destination) + bondFacet = __getBondFacet(source,destination) + logging.info('chosen bond facet: %s' % bondFacet.get_name()) + logging.info('Source: %s, destination: %s' % (source,destination)) + sourceDescriptor, destinationDescriptor = __getDescriptors(bondFacet,source,destination) + logging.info("source descriptor: " + sourceDescriptor.name.upper()) + logging.info("destination descriptior: " + destinationDescriptor.name.upper()) + category = sourceDescriptor.getBondCategory(destinationDescriptor) + assert category + if category == slipnet.identity: + category = slipnet.sameness + logging.info('proposing %s bond ' % category.name) + coderack.proposeBond(source,destination,category,bondFacet,sourceDescriptor,destinationDescriptor,codelet) def rule_scout(codelet): - assert workspace.numberOfUnreplacedObjects() == 0 - changedObjects = [ o for o in workspace.initial.objects if o.changed ] - #assert len(changedObjects) < 2 - # if there are no changed objects, propose a rule with no changes - if not changedObjects: - return coderack.proposeRule(None,None,None,None,codelet) + assert workspace.numberOfUnreplacedObjects() == 0 + changedObjects = [ o for o in workspace.initial.objects if o.changed ] + #assert len(changedObjects) < 2 + # if there are no changed objects, propose a rule with no changes + if not changedObjects: + return coderack.proposeRule(None,None,None,None,codelet) - changed = changedObjects[-1] - # generate a list of distinguishing descriptions for the first object - # ie. string-position (leftmost,rightmost,middle or whole) or letter category - # if it is the only one of its type in the string - objectList = [] - position = changed.getDescriptor(slipnet.stringPositionCategory) - if position: - objectList += [ position ] - letter = changed.getDescriptor(slipnet.letterCategory) - otherObjectsOfSameLetter = [ o for o in workspace.initial.objects if not o != changed and o.getDescriptionType(letter) ] - if not len(otherObjectsOfSameLetter): # then the letter is a distinguishing feature - objectList += [ letter ] - # if this object corresponds to another object in the workspace - # objectList = the union of this and the distingushing descriptors - if changed.correspondence: - targetObject = changed.correspondence.objectFromTarget - newList = [] - slippages = workspace.slippages() - for node in objectList: - node = node.applySlippages(slippages) - if targetObject.hasDescription(node) and targetObject.distinguishingDescriptor(node): - newList += [ node ] - objectList = newList # XXX surely this should be += ("the union of this and the distinguishing descriptors") - assert objectList and len(objectList) - # use conceptual depth to choose a description - valueList = [] - for node in objectList: - depth = node.conceptualDepth - value = temperatureAdjustedValue(depth) - valueList += [ value ] - i = selectListPosition(valueList) - descriptor = objectList[ i ] - # choose the relation (change the letmost object to..xxxx) i.e. "successor" or "d" - objectList = [] - if changed.replacement.relation: - objectList += [ changed.replacement.relation ] - objectList += [ changed.replacement.objectFromModified.getDescriptor(slipnet.letterCategory) ] - # use conceptual depth to choose a relation - valueList = [] - for node in objectList: - depth = node.conceptualDepth - value = temperatureAdjustedValue(depth) - valueList += [ value ] - i = selectListPosition(valueList) - relation = objectList[ i ] - coderack.proposeRule(slipnet.letterCategory,descriptor,slipnet.letter,relation,codelet) + changed = changedObjects[-1] + # generate a list of distinguishing descriptions for the first object + # ie. string-position (leftmost,rightmost,middle or whole) or letter category + # if it is the only one of its type in the string + objectList = [] + position = changed.getDescriptor(slipnet.stringPositionCategory) + if position: + objectList += [ position ] + letter = changed.getDescriptor(slipnet.letterCategory) + otherObjectsOfSameLetter = [ o for o in workspace.initial.objects if not o != changed and o.getDescriptionType(letter) ] + if not len(otherObjectsOfSameLetter): # then the letter is a distinguishing feature + objectList += [ letter ] + # if this object corresponds to another object in the workspace + # objectList = the union of this and the distingushing descriptors + if changed.correspondence: + targetObject = changed.correspondence.objectFromTarget + newList = [] + slippages = workspace.slippages() + for node in objectList: + node = node.applySlippages(slippages) + if targetObject.hasDescription(node) and targetObject.distinguishingDescriptor(node): + newList += [ node ] + objectList = newList # XXX surely this should be += ("the union of this and the distinguishing descriptors") + assert objectList and len(objectList) + # use conceptual depth to choose a description + valueList = [] + for node in objectList: + depth = node.conceptualDepth + value = temperatureAdjustedValue(depth) + valueList += [ value ] + i = selectListPosition(valueList) + descriptor = objectList[ i ] + # choose the relation (change the letmost object to..xxxx) i.e. "successor" or "d" + objectList = [] + if changed.replacement.relation: + objectList += [ changed.replacement.relation ] + objectList += [ changed.replacement.objectFromModified.getDescriptor(slipnet.letterCategory) ] + # use conceptual depth to choose a relation + valueList = [] + for node in objectList: + depth = node.conceptualDepth + value = temperatureAdjustedValue(depth) + valueList += [ value ] + i = selectListPosition(valueList) + relation = objectList[ i ] + coderack.proposeRule(slipnet.letterCategory,descriptor,slipnet.letter,relation,codelet) def rule_strength_tester(codelet): - rule = codelet.arguments[0] - rule.updateStrength() - probability = temperatureAdjustedProbability(rule.totalStrength / 100.0) - assert utils.random() <= probability - coderack.newCodelet('rule-builder',codelet,rule.totalStrength,rule) + rule = codelet.arguments[0] + rule.updateStrength() + probability = temperatureAdjustedProbability(rule.totalStrength / 100.0) + assert utils.random() <= probability + coderack.newCodelet('rule-builder',codelet,rule.totalStrength,rule) def replacement_finder(): - # choose random letter in initial string - letters = [ o for o in workspace.initial.objects if isinstance(o,Letter) ] - letterOfInitialString = utils.choice(letters) - logging.info('selected letter in initial string = %s' % letterOfInitialString) - if letterOfInitialString.replacement: - logging.info("Replacement already found for %s, so fizzling" % letterOfInitialString) - return - position = letterOfInitialString.leftStringPosition - moreLetters = [ o for o in workspace.modified.objects if isinstance(o,Letter) and o.leftStringPosition == position ] - letterOfModifiedString = moreLetters and moreLetters[0] or None - assert letterOfModifiedString - position -= 1 - initialAscii = ord(workspace.initialString[position]) - modifiedAscii = ord(workspace.modifiedString[position]) - diff = initialAscii - modifiedAscii - if abs(diff) < 2: - relations = { 0:slipnet.sameness, -1:slipnet.successor, 1:slipnet.predecessor } - relation = relations[diff] - logging.info('Relation found: %s' % relation.name) - else: - relation = None - logging.info('no relation found') - letterOfInitialString.replacement = Replacement(letterOfInitialString,letterOfModifiedString,relation) - if relation != slipnet.sameness: - letterOfInitialString.changed = True - workspace.changedObject = letterOfInitialString - logging.info('building replacement') + # choose random letter in initial string + letters = [ o for o in workspace.initial.objects if isinstance(o,Letter) ] + letterOfInitialString = utils.choice(letters) + logging.info('selected letter in initial string = %s' % letterOfInitialString) + if letterOfInitialString.replacement: + logging.info("Replacement already found for %s, so fizzling" % letterOfInitialString) + return + position = letterOfInitialString.leftStringPosition + moreLetters = [ o for o in workspace.modified.objects if isinstance(o,Letter) and o.leftStringPosition == position ] + letterOfModifiedString = moreLetters and moreLetters[0] or None + assert letterOfModifiedString + position -= 1 + initialAscii = ord(workspace.initialString[position]) + modifiedAscii = ord(workspace.modifiedString[position]) + diff = initialAscii - modifiedAscii + if abs(diff) < 2: + relations = { 0:slipnet.sameness, -1:slipnet.successor, 1:slipnet.predecessor } + relation = relations[diff] + logging.info('Relation found: %s' % relation.name) + else: + relation = None + logging.info('no relation found') + letterOfInitialString.replacement = Replacement(letterOfInitialString,letterOfModifiedString,relation) + if relation != slipnet.sameness: + letterOfInitialString.changed = True + workspace.changedObject = letterOfInitialString + logging.info('building replacement') def top_down_bond_scout__category(codelet): - logging.info('top_down_bond_scout__category') - category = codelet.arguments[0] - source = __getScoutSource(category,localBondCategoryRelevance,'bond') - destination = chooseNeighbour(source) - logging.info('source: %s, destination: %s' % (source,destination)) - assert destination - bondFacet = __getBondFacet(source,destination) - sourceDescriptor, destinationDescriptor = __getDescriptors(bondFacet,source,destination) - forwardBond = sourceDescriptor.getBondCategory(destinationDescriptor) - if forwardBond == slipnet.identity: - forwardBond = slipnet.sameness - backwardBond = slipnet.sameness - else: - backwardBond = destinationDescriptor.getBondCategory(sourceDescriptor) - assert category == forwardBond or category == backwardBond - if category == forwardBond: - coderack.proposeBond(source,destination,category,bondFacet,sourceDescriptor, destinationDescriptor,codelet) - else: - coderack.proposeBond(destination,source,category,bondFacet,destinationDescriptor,sourceDescriptor,codelet) + logging.info('top_down_bond_scout__category') + category = codelet.arguments[0] + source = __getScoutSource(category,localBondCategoryRelevance,'bond') + destination = chooseNeighbour(source) + logging.info('source: %s, destination: %s' % (source,destination)) + assert destination + bondFacet = __getBondFacet(source,destination) + sourceDescriptor, destinationDescriptor = __getDescriptors(bondFacet,source,destination) + forwardBond = sourceDescriptor.getBondCategory(destinationDescriptor) + if forwardBond == slipnet.identity: + forwardBond = slipnet.sameness + backwardBond = slipnet.sameness + else: + backwardBond = destinationDescriptor.getBondCategory(sourceDescriptor) + assert category == forwardBond or category == backwardBond + if category == forwardBond: + coderack.proposeBond(source,destination,category,bondFacet,sourceDescriptor, destinationDescriptor,codelet) + else: + coderack.proposeBond(destination,source,category,bondFacet,destinationDescriptor,sourceDescriptor,codelet) def top_down_bond_scout__direction(codelet): - direction = codelet.arguments[0] - source = __getScoutSource(direction,localDirectionCategoryRelevance,'bond') - destination = chooseDirectedNeighbor(source,direction) - assert destination - logging.info('to object: %s' % destination) - bondFacet = __getBondFacet(source,destination) - sourceDescriptor, destinationDescriptor = __getDescriptors(bondFacet,source,destination) - category = sourceDescriptor.getBondCategory(destinationDescriptor) - assert category - if category == slipnet.identity: - category = slipnet.sameness - coderack.proposeBond(source,destination,category,bondFacet,sourceDescriptor, destinationDescriptor,codelet) + direction = codelet.arguments[0] + source = __getScoutSource(direction,localDirectionCategoryRelevance,'bond') + destination = chooseDirectedNeighbor(source,direction) + assert destination + logging.info('to object: %s' % destination) + bondFacet = __getBondFacet(source,destination) + sourceDescriptor, destinationDescriptor = __getDescriptors(bondFacet,source,destination) + category = sourceDescriptor.getBondCategory(destinationDescriptor) + assert category + if category == slipnet.identity: + category = slipnet.sameness + coderack.proposeBond(source,destination,category,bondFacet,sourceDescriptor, destinationDescriptor,codelet) def bond_strength_tester(codelet): - bond = codelet.arguments[0] - __showWhichStringObjectIsFrom(bond) - bond.updateStrength() - strength = bond.totalStrength - probability = temperatureAdjustedProbability(strength/100.0) - logging.info('bond strength = %d for %s' % (strength,bond)) - assert formulas.coinFlip(probability) - bond.facet.buffer = 100.0 - bond.sourceDescriptor.buffer = 100.0 - bond.destinationDescriptor.buffer = 100.0 - logging.info("succeeded: posting bond-builder") - coderack.newCodelet('bond-builder',codelet,strength) + bond = codelet.arguments[0] + __showWhichStringObjectIsFrom(bond) + bond.updateStrength() + strength = bond.totalStrength + probability = temperatureAdjustedProbability(strength/100.0) + logging.info('bond strength = %d for %s' % (strength,bond)) + assert formulas.coinFlip(probability) + bond.facet.buffer = 100.0 + bond.sourceDescriptor.buffer = 100.0 + bond.destinationDescriptor.buffer = 100.0 + logging.info("succeeded: posting bond-builder") + coderack.newCodelet('bond-builder',codelet,strength) def bond_builder(codelet): - bond = codelet.arguments[0] - __showWhichStringObjectIsFrom(bond) - bond.updateStrength() - assert (bond.source in workspace.objects or bond.destination in workspace.objects) - for stringBond in bond.string.bonds: - if bond.sameNeighbours(stringBond) and bond.sameCategories(stringBond): - if bond.directionCategory: - bond.directionCategory.buffer = 100.0 - bond.category.buffer = 100.0 - logging.info('already exists: activate descriptors & Fizzle') - return - incompatibleBonds = bond.getIncompatibleBonds() - logging.info('number of incompatibleBonds: %d' % len(incompatibleBonds)) - if len(incompatibleBonds): - logging.info('%s' % incompatibleBonds[0]) - assert __fightIncompatibles(incompatibleBonds,bond,'bonds',1.0,1.0) - incompatibleGroups = bond.source.getCommonGroups(bond.destination) - assert __fightIncompatibles(incompatibleGroups,bond,'groups',1.0,1.0) - # fight all incompatible correspondences - incompatibleCorrespondences = [] - if bond.leftObject.leftmost or bond.rightObject.rightmost: - if bond.directionCategory: - incompatibleCorrespondences = bond.getIncompatibleCorrespondences() - if incompatibleCorrespondences: - logging.info("trying to break incompatible correspondences") - assert __fightItOut(bond,2.0,incompatibleCorrespondences,3.0) - #assert __fightIncompatibles(incompatibleCorrespondences,bond,'correspondences',2.0,3.0) - for incompatible in incompatibleBonds: - incompatible.break_the_structure() - for incompatible in incompatibleGroups: - incompatible.break_the_structure() - for incompatible in incompatibleCorrespondences: - incompatible.break_the_structure() - logging.info('building bond %s' % bond) - bond.buildBond() + bond = codelet.arguments[0] + __showWhichStringObjectIsFrom(bond) + bond.updateStrength() + assert (bond.source in workspace.objects or bond.destination in workspace.objects) + for stringBond in bond.string.bonds: + if bond.sameNeighbours(stringBond) and bond.sameCategories(stringBond): + if bond.directionCategory: + bond.directionCategory.buffer = 100.0 + bond.category.buffer = 100.0 + logging.info('already exists: activate descriptors & Fizzle') + return + incompatibleBonds = bond.getIncompatibleBonds() + logging.info('number of incompatibleBonds: %d' % len(incompatibleBonds)) + if len(incompatibleBonds): + logging.info('%s' % incompatibleBonds[0]) + assert __fightIncompatibles(incompatibleBonds,bond,'bonds',1.0,1.0) + incompatibleGroups = bond.source.getCommonGroups(bond.destination) + assert __fightIncompatibles(incompatibleGroups,bond,'groups',1.0,1.0) + # fight all incompatible correspondences + incompatibleCorrespondences = [] + if bond.leftObject.leftmost or bond.rightObject.rightmost: + if bond.directionCategory: + incompatibleCorrespondences = bond.getIncompatibleCorrespondences() + if incompatibleCorrespondences: + logging.info("trying to break incompatible correspondences") + assert __fightItOut(bond,2.0,incompatibleCorrespondences,3.0) + #assert __fightIncompatibles(incompatibleCorrespondences,bond,'correspondences',2.0,3.0) + for incompatible in incompatibleBonds: + incompatible.break_the_structure() + for incompatible in incompatibleGroups: + incompatible.break_the_structure() + for incompatible in incompatibleCorrespondences: + incompatible.break_the_structure() + logging.info('building bond %s' % bond) + bond.buildBond() def top_down_group_scout__category(codelet): - groupCategory = codelet.arguments[0] - category = groupCategory.getRelatedNode(slipnet.bondCategory) - assert category - source = __getScoutSource(category,localBondCategoryRelevance,'group') - assert source and not source.spansString() - if source.leftmost: - direction = slipnet.right - elif source.rightmost: - direction = slipnet.left - else: - activations = [ slipnet.left.activation ] - activations += [ slipnet.right.activation ] - if not selectListPosition(activations): - direction = slipnet.left - else: - direction = slipnet.right - if direction == slipnet.left: - firstBond = source.leftBond - else: - firstBond = source.rightBond - if not firstBond or firstBond.category != category: - # check the other side of object - if direction == slipnet.right: - firstBond = source.leftBond - else: - firstBond = source.rightBond - if not firstBond or firstBond.category != category: - if category == slipnet.sameness and isinstance(source,Letter): - group = Group(source.string,slipnet.samenessGroup, None,slipnet.letterCategory, [ source ], []) - probability = group.singleLetterGroupProbability() - assert utils.random() >= probability - coderack.proposeSingleLetterGroup( source, codelet) - return - direction = firstBond.directionCategory - search = True - bondFacet = None - # find leftmost object in group with these bonds - while search: - search = False - if source.leftBond: - if source.leftBond.category == category: - if not source.leftBond.directionCategory or source.leftBond.directionCategory == direction: - if not bondFacet or bondFacet == source.leftBond.facet: - bondFacet = source.leftBond.facet - direction = source.leftBond.directionCategory - source = source.leftBond.leftObject - search = True - # find rightmost object in group with these bonds - search = True - destination = source - while search: - search = False - if destination.rightBond: - if destination.rightBond.category == category: - if not destination.rightBond.directionCategory or destination.rightBond.directionCategory == direction: - if not bondFacet or bondFacet == destination.rightBond.facet: - bondFacet = destination.rightBond.facet - direction = source.rightBond.directionCategory - destination = destination.rightBond.rightObject - search = True - assert destination != source - objects = [ source ] - bonds = [] - while source != destination: - bonds += [ source.rightBond ] - objects += [ source.rightBond.rightObject ] - source = source.rightBond.rightObject - coderack.proposeGroup(objects,bonds,groupCategory,direction,bondFacet,codelet) + groupCategory = codelet.arguments[0] + category = groupCategory.getRelatedNode(slipnet.bondCategory) + assert category + source = __getScoutSource(category,localBondCategoryRelevance,'group') + assert source and not source.spansString() + if source.leftmost: + direction = slipnet.right + elif source.rightmost: + direction = slipnet.left + else: + activations = [ slipnet.left.activation ] + activations += [ slipnet.right.activation ] + if not selectListPosition(activations): + direction = slipnet.left + else: + direction = slipnet.right + if direction == slipnet.left: + firstBond = source.leftBond + else: + firstBond = source.rightBond + if not firstBond or firstBond.category != category: + # check the other side of object + if direction == slipnet.right: + firstBond = source.leftBond + else: + firstBond = source.rightBond + if not firstBond or firstBond.category != category: + if category == slipnet.sameness and isinstance(source,Letter): + group = Group(source.string,slipnet.samenessGroup, None,slipnet.letterCategory, [ source ], []) + probability = group.singleLetterGroupProbability() + assert utils.random() >= probability + coderack.proposeSingleLetterGroup( source, codelet) + return + direction = firstBond.directionCategory + search = True + bondFacet = None + # find leftmost object in group with these bonds + while search: + search = False + if source.leftBond: + if source.leftBond.category == category: + if not source.leftBond.directionCategory or source.leftBond.directionCategory == direction: + if not bondFacet or bondFacet == source.leftBond.facet: + bondFacet = source.leftBond.facet + direction = source.leftBond.directionCategory + source = source.leftBond.leftObject + search = True + # find rightmost object in group with these bonds + search = True + destination = source + while search: + search = False + if destination.rightBond: + if destination.rightBond.category == category: + if not destination.rightBond.directionCategory or destination.rightBond.directionCategory == direction: + if not bondFacet or bondFacet == destination.rightBond.facet: + bondFacet = destination.rightBond.facet + direction = source.rightBond.directionCategory + destination = destination.rightBond.rightObject + search = True + assert destination != source + objects = [ source ] + bonds = [] + while source != destination: + bonds += [ source.rightBond ] + objects += [ source.rightBond.rightObject ] + source = source.rightBond.rightObject + coderack.proposeGroup(objects,bonds,groupCategory,direction,bondFacet,codelet) def top_down_group_scout__direction(codelet): - direction = codelet.arguments[0] - source = __getScoutSource(direction,localDirectionCategoryRelevance,'direction') - logging.info('source chosen = %s' % source) - assert not source.spansString() - if source.leftmost : - mydirection = slipnet.right - elif source.rightmost: - mydirection = slipnet.left - else: - activations = [ slipnet.left.activation ] - activations += [ slipnet.right.activation ] - if not selectListPosition(activations): - mydirection = slipnet.left - else: - mydirection = slipnet.right - if mydirection == slipnet.left: - firstBond = source.leftBond - else: - firstBond = source.rightBond - if not firstBond: - logging.info('no firstBond') - else: - logging.info('firstBond: %s' % firstBond) - if firstBond and not firstBond.directionCategory: - direction = None - if not firstBond or firstBond.directionCategory != direction: - if mydirection == slipnet.right: - firstBond = source.leftBond - else: - firstBond = source.rightBond - if not firstBond: - logging.info('no firstBond2') - else: - logging.info('firstBond2: %s' % firstBond) - if firstBond and not firstBond.directionCategory: - direction = None - assert firstBond and firstBond.directionCategory == direction - logging.info('possible group: %s' % firstBond) - category = firstBond.category - assert category - groupCategory = category.getRelatedNode(slipnet.groupCategory) - logging.info('trying from %s to %s' % (source,category.name) ) - bondFacet = None - # find leftmost object in group with these bonds - search = True - while search: - search = False - if source.leftBond: - if source.leftBond.category == category: - if not source.leftBond.directionCategory or source.leftBond.directionCategory == direction: - if not bondFacet or bondFacet == source.leftBond.facet: - bondFacet = source.leftBond.facet - direction = source.leftBond.directionCategory - source = source.leftBond.leftObject - search = True - destination = source - search = True - while search: - search = False - if destination.rightBond: - if destination.rightBond.category == category: - if not destination.rightBond.directionCategory or destination.rightBond.directionCategory == direction: - if not bondFacet or bondFacet == destination.rightBond.facet: - bondFacet = destination.rightBond.facet - direction = source.rightBond.directionCategory - destination = destination.rightBond.rightObject - search = True - assert destination != source - logging.info('proposing group from %s to %s' % (source,destination) ) - objects = [ source ] - bonds = [] - while source != destination: - bonds += [ source.rightBond ] - objects += [ source.rightBond.rightObject ] - source = source.rightBond.rightObject - coderack.proposeGroup(objects,bonds,groupCategory,direction,bondFacet,codelet) + direction = codelet.arguments[0] + source = __getScoutSource(direction,localDirectionCategoryRelevance,'direction') + logging.info('source chosen = %s' % source) + assert not source.spansString() + if source.leftmost : + mydirection = slipnet.right + elif source.rightmost: + mydirection = slipnet.left + else: + activations = [ slipnet.left.activation ] + activations += [ slipnet.right.activation ] + if not selectListPosition(activations): + mydirection = slipnet.left + else: + mydirection = slipnet.right + if mydirection == slipnet.left: + firstBond = source.leftBond + else: + firstBond = source.rightBond + if not firstBond: + logging.info('no firstBond') + else: + logging.info('firstBond: %s' % firstBond) + if firstBond and not firstBond.directionCategory: + direction = None + if not firstBond or firstBond.directionCategory != direction: + if mydirection == slipnet.right: + firstBond = source.leftBond + else: + firstBond = source.rightBond + if not firstBond: + logging.info('no firstBond2') + else: + logging.info('firstBond2: %s' % firstBond) + if firstBond and not firstBond.directionCategory: + direction = None + assert firstBond and firstBond.directionCategory == direction + logging.info('possible group: %s' % firstBond) + category = firstBond.category + assert category + groupCategory = category.getRelatedNode(slipnet.groupCategory) + logging.info('trying from %s to %s' % (source,category.name) ) + bondFacet = None + # find leftmost object in group with these bonds + search = True + while search: + search = False + if source.leftBond: + if source.leftBond.category == category: + if not source.leftBond.directionCategory or source.leftBond.directionCategory == direction: + if not bondFacet or bondFacet == source.leftBond.facet: + bondFacet = source.leftBond.facet + direction = source.leftBond.directionCategory + source = source.leftBond.leftObject + search = True + destination = source + search = True + while search: + search = False + if destination.rightBond: + if destination.rightBond.category == category: + if not destination.rightBond.directionCategory or destination.rightBond.directionCategory == direction: + if not bondFacet or bondFacet == destination.rightBond.facet: + bondFacet = destination.rightBond.facet + direction = source.rightBond.directionCategory + destination = destination.rightBond.rightObject + search = True + assert destination != source + logging.info('proposing group from %s to %s' % (source,destination) ) + objects = [ source ] + bonds = [] + while source != destination: + bonds += [ source.rightBond ] + objects += [ source.rightBond.rightObject ] + source = source.rightBond.rightObject + coderack.proposeGroup(objects,bonds,groupCategory,direction,bondFacet,codelet) #noinspection PyStringFormat def group_scout__whole_string(codelet): - string = workspace.initial - if utils.random() > 0.5: - string = workspace.target - logging.info('target string selected: %s' % workspace.target ) - else: - logging.info('initial string selected: %s' % workspace.initial ) - # find leftmost object & the highest group to which it belongs - leftmost = None - for objekt in string.objects: - if objekt.leftmost: - leftmost = objekt - while leftmost.group and leftmost.group.bondCategory == slipnet.sameness: - leftmost = leftmost.group - if leftmost.spansString(): - # the object already spans the string - propose this object - group = leftmost - coderack.proposeGroup(group.objectList, group.bondList,group.groupCategory,group.directionCategory, group.facet,codelet) - return - bonds = [] - objects = [ leftmost ] - while leftmost.rightBond: - bonds += [ leftmost.rightBond ] - leftmost = leftmost.rightBond.rightObject - objects += [ leftmost ] - assert leftmost.rightmost - # choose a random bond from list - chosenBond = utils.choice(bonds) - category = chosenBond.category - directionCategory = chosenBond.directionCategory - bondFacet = chosenBond.facet - bonds = possibleGroupBonds(category, directionCategory, bondFacet, bonds) - assert bonds - groupCategory = category.getRelatedNode(slipnet.groupCategory) - coderack.proposeGroup(objects,bonds,groupCategory,directionCategory,bondFacet,codelet) + string = workspace.initial + if utils.random() > 0.5: + string = workspace.target + logging.info('target string selected: %s' % workspace.target ) + else: + logging.info('initial string selected: %s' % workspace.initial ) + # find leftmost object & the highest group to which it belongs + leftmost = None + for objekt in string.objects: + if objekt.leftmost: + leftmost = objekt + while leftmost.group and leftmost.group.bondCategory == slipnet.sameness: + leftmost = leftmost.group + if leftmost.spansString(): + # the object already spans the string - propose this object + group = leftmost + coderack.proposeGroup(group.objectList, group.bondList,group.groupCategory,group.directionCategory, group.facet,codelet) + return + bonds = [] + objects = [ leftmost ] + while leftmost.rightBond: + bonds += [ leftmost.rightBond ] + leftmost = leftmost.rightBond.rightObject + objects += [ leftmost ] + assert leftmost.rightmost + # choose a random bond from list + chosenBond = utils.choice(bonds) + category = chosenBond.category + directionCategory = chosenBond.directionCategory + bondFacet = chosenBond.facet + bonds = possibleGroupBonds(category, directionCategory, bondFacet, bonds) + assert bonds + groupCategory = category.getRelatedNode(slipnet.groupCategory) + coderack.proposeGroup(objects,bonds,groupCategory,directionCategory,bondFacet,codelet) def group_strength_tester(codelet): - # update strength value of the group - group = codelet.arguments[0] - __showWhichStringObjectIsFrom(group) - group.updateStrength() - strength = group.totalStrength - probability = temperatureAdjustedProbability(strength/100.0) - assert utils.random() <= probability - # it is strong enough - post builder & activate nodes - group.groupCategory.getRelatedNode(slipnet.bondCategory).buffer = 100.0 - if group.directionCategory: - group.directionCategory.buffer=100.0 - coderack.newCodelet('group-builder',codelet,strength) + # update strength value of the group + group = codelet.arguments[0] + __showWhichStringObjectIsFrom(group) + group.updateStrength() + strength = group.totalStrength + probability = temperatureAdjustedProbability(strength/100.0) + assert utils.random() <= probability + # it is strong enough - post builder & activate nodes + group.groupCategory.getRelatedNode(slipnet.bondCategory).buffer = 100.0 + if group.directionCategory: + group.directionCategory.buffer=100.0 + coderack.newCodelet('group-builder',codelet,strength) def group_builder(codelet): - # update strength value of the group - group = codelet.arguments[0] - #print '%s' % group - __showWhichStringObjectIsFrom(group) - equivalent = group.string.equivalentGroup(group) - if equivalent : - logging.info('already exists...activate descriptors & fizzle') - group.activateDescriptions() - equivalent.addDescriptions(group.descriptions) - return - # check to see if all objects are still there - for o in group.objectList: - assert o in workspace.objects - # check to see if bonds are there of the same direction - incompatibleBonds = [] # incompatible bond list - if len(group.objectList) > 1: - previous = group.objectList[0] - for objekt in group.objectList[1:]: - #print 770 - leftBond = objekt.leftBond - if leftBond: - lefty = leftBond.leftObject - if lefty != previous or leftBond.directionCategory != group.directionCategory: - incompatibleBonds += [ leftBond ] - previous = objekt - next = group.objectList[-1] - for objekt in reversed(group.objectList[:-1]): - rightBond = objekt.rightBond - if rightBond: - righty = rightBond.rightObject - if righty != next or rightBond.directionCategory != group.directionCategory: - incompatibleBonds += [ rightBond ] - next = objekt - # if incompatible bonds exist - fight - group.updateStrength() - assert __fightIncompatibles(incompatibleBonds,group,'bonds',1.0,1.0) - # fight incompatible groups - # fight all groups containing these objects - incompatibleGroups = group.getIncompatibleGroups() - assert __fightIncompatibles(incompatibleGroups,group,'Groups',1.0,1.0) - for incompatible in incompatibleBonds: - incompatible.break_the_structure() - # create new bonds - group.bondList = [] - for i in range(1,len(group.objectList)): - #print 803 - object1 = group.objectList[i - 1] - object2 = group.objectList[i] - if not object1.rightBond: - if group.directionCategory == slipnet.right: - source = object1 - destination = object2 - else: - source = object2 - destination = object1 - category = group.groupCategory.getRelatedNode(slipnet.bondCategory) - facet = group.facet - newBond = Bond(source,destination,category,facet,source.getDescriptor(facet),destination.getDescriptor(facet)) - newBond.buildBond() - group.bondList += [ object1.rightBond ] - for incompatible in incompatibleGroups: - incompatible.break_the_structure() - group.buildGroup() - group.activateDescriptions() - logging.info('building group') + # update strength value of the group + group = codelet.arguments[0] + #print '%s' % group + __showWhichStringObjectIsFrom(group) + equivalent = group.string.equivalentGroup(group) + if equivalent : + logging.info('already exists...activate descriptors & fizzle') + group.activateDescriptions() + equivalent.addDescriptions(group.descriptions) + return + # check to see if all objects are still there + for o in group.objectList: + assert o in workspace.objects + # check to see if bonds are there of the same direction + incompatibleBonds = [] # incompatible bond list + if len(group.objectList) > 1: + previous = group.objectList[0] + for objekt in group.objectList[1:]: + #print 770 + leftBond = objekt.leftBond + if leftBond: + lefty = leftBond.leftObject + if lefty != previous or leftBond.directionCategory != group.directionCategory: + incompatibleBonds += [ leftBond ] + previous = objekt + next = group.objectList[-1] + for objekt in reversed(group.objectList[:-1]): + rightBond = objekt.rightBond + if rightBond: + righty = rightBond.rightObject + if righty != next or rightBond.directionCategory != group.directionCategory: + incompatibleBonds += [ rightBond ] + next = objekt + # if incompatible bonds exist - fight + group.updateStrength() + assert __fightIncompatibles(incompatibleBonds,group,'bonds',1.0,1.0) + # fight incompatible groups + # fight all groups containing these objects + incompatibleGroups = group.getIncompatibleGroups() + assert __fightIncompatibles(incompatibleGroups,group,'Groups',1.0,1.0) + for incompatible in incompatibleBonds: + incompatible.break_the_structure() + # create new bonds + group.bondList = [] + for i in range(1,len(group.objectList)): + #print 803 + object1 = group.objectList[i - 1] + object2 = group.objectList[i] + if not object1.rightBond: + if group.directionCategory == slipnet.right: + source = object1 + destination = object2 + else: + source = object2 + destination = object1 + category = group.groupCategory.getRelatedNode(slipnet.bondCategory) + facet = group.facet + newBond = Bond(source,destination,category,facet,source.getDescriptor(facet),destination.getDescriptor(facet)) + newBond.buildBond() + group.bondList += [ object1.rightBond ] + for incompatible in incompatibleGroups: + incompatible.break_the_structure() + group.buildGroup() + group.activateDescriptions() + logging.info('building group') def rule_builder(codelet): - rule = codelet.arguments[0] - if rule.ruleEqual(workspace.rule): - rule.activateRuleDescriptions() - return - rule.updateStrength() - assert rule.totalStrength - # fight against other rules - if workspace.rule: - assert __structureVsStructure(rule,1.0,workspace.rule,1.0) - workspace.buildRule(rule) + rule = codelet.arguments[0] + if rule.ruleEqual(workspace.rule): + rule.activateRuleDescriptions() + return + rule.updateStrength() + assert rule.totalStrength + # fight against other rules + if workspace.rule: + assert __structureVsStructure(rule,1.0,workspace.rule,1.0) + workspace.buildRule(rule) def __getCutOff(density): - if density > 0.8: - distribution = [ 5.0,150.0,5.0,2.0,1.0,1.0,1.0,1.0,1.0,1.0 ] - elif density > 0.6: - distribution = [ 2.0,5.0,150.0,5.0,2.0,1.0,1.0,1.0,1.0,1.0 ] - elif density > 0.4: - distribution = [ 1.0,2.0,5.0,150.0,5.0,2.0,1.0,1.0,1.0,1.0 ] - elif density > 0.2: - distribution = [ 1.0,1.0,2.0,5.0,150.0,5.0,2.0,1.0,1.0,1.0 ] - else: - distribution = [ 1.0,1.0,1.0,2.0,5.0,150.0,5.0,2.0,1.0,1.0 ] - stop = sum(distribution) * utils.random() - total = 0.0 - for i in range(0,len(distribution)): - total += distribution[i] - if total >= stop: - return i + 1 - return len(distribution) + if density > 0.8: + distribution = [ 5.0,150.0,5.0,2.0,1.0,1.0,1.0,1.0,1.0,1.0 ] + elif density > 0.6: + distribution = [ 2.0,5.0,150.0,5.0,2.0,1.0,1.0,1.0,1.0,1.0 ] + elif density > 0.4: + distribution = [ 1.0,2.0,5.0,150.0,5.0,2.0,1.0,1.0,1.0,1.0 ] + elif density > 0.2: + distribution = [ 1.0,1.0,2.0,5.0,150.0,5.0,2.0,1.0,1.0,1.0 ] + else: + distribution = [ 1.0,1.0,1.0,2.0,5.0,150.0,5.0,2.0,1.0,1.0 ] + stop = sum(distribution) * utils.random() + total = 0.0 + for i in range(0,len(distribution)): + total += distribution[i] + if total >= stop: + return i + 1 + return len(distribution) def rule_translator(): - assert workspace.rule - if len(workspace.initial) == 1 and len(workspace.target) == 1: - bondDensity = 1.0 - else: - numberOfBonds = len(workspace.initial.bonds) + len(workspace.target.bonds) - nearlyTotalLength = len(workspace.initial) + len(workspace.target) - 2 - bondDensity = numberOfBonds / nearlyTotalLength - if bondDensity>1.0: - bondDensity = 1.0 - cutoff = __getCutOff(bondDensity) * 10.0 - assert cutoff >= formulas.actualTemperature - if workspace.rule.buildTranslatedRule(): - workspace.foundAnswer = True - else: - temperature.clampTime = coderack.codeletsRun + 100 - temperature.clamped = True - formulas.Temperature = 100.0 + assert workspace.rule + if len(workspace.initial) == 1 and len(workspace.target) == 1: + bondDensity = 1.0 + else: + numberOfBonds = len(workspace.initial.bonds) + len(workspace.target.bonds) + nearlyTotalLength = len(workspace.initial) + len(workspace.target) - 2 + bondDensity = numberOfBonds / nearlyTotalLength + if bondDensity>1.0: + bondDensity = 1.0 + cutoff = __getCutOff(bondDensity) * 10.0 + assert cutoff >= formulas.actualTemperature + if workspace.rule.buildTranslatedRule(): + workspace.foundAnswer = True + else: + temperature.clampTime = coderack.codeletsRun + 100 + temperature.clamped = True + formulas.Temperature = 100.0 def bottom_up_correspondence_scout(codelet): - objectFromInitial = chooseUnmodifiedObject('interStringSalience',workspace.initial.objects) - objectFromTarget = chooseUnmodifiedObject('interStringSalience',workspace.target.objects) - assert objectFromInitial.spansString() == objectFromTarget.spansString() - # get the posible concept mappings - conceptMappings = getMappings( objectFromInitial, objectFromTarget, objectFromInitial.relevantDescriptions(), objectFromTarget.relevantDescriptions()) - assert conceptMappings and __slippability(conceptMappings) - #find out if any are distinguishing - distinguishingMappings = [ m for m in conceptMappings if m.distinguishing() ] - assert distinguishingMappings - # if both objects span the strings, check to see if the - # string description needs to be flipped - oppositeMappings = [ m for m in distinguishingMappings - if m.initialDescriptionType == slipnet.stringPositionCategory and - m.initialDescriptionType != slipnet.bondFacet ] - initialDescriptionTypes = [ m.initialDescriptionType for m in oppositeMappings ] - flipTargetObject = False - if objectFromInitial.spansString() and objectFromTarget.spansString() and slipnet.directionCategory in initialDescriptionTypes and __allOppositeMappings(oppositeMappings) and slipnet.opposite.activation != 100.0: - objectFromTarget = objectFromTarget.flippedVersion() - conceptMappings = getMappings( objectFromInitial, objectFromTarget, objectFromInitial.relevantDescriptions(), objectFromTarget.relevantDescriptions()) - flipTargetObject = True - coderack.proposeCorrespondence(objectFromInitial,objectFromTarget,conceptMappings,flipTargetObject,codelet) + objectFromInitial = chooseUnmodifiedObject('interStringSalience',workspace.initial.objects) + objectFromTarget = chooseUnmodifiedObject('interStringSalience',workspace.target.objects) + assert objectFromInitial.spansString() == objectFromTarget.spansString() + # get the posible concept mappings + conceptMappings = getMappings( objectFromInitial, objectFromTarget, objectFromInitial.relevantDescriptions(), objectFromTarget.relevantDescriptions()) + assert conceptMappings and __slippability(conceptMappings) + #find out if any are distinguishing + distinguishingMappings = [ m for m in conceptMappings if m.distinguishing() ] + assert distinguishingMappings + # if both objects span the strings, check to see if the + # string description needs to be flipped + oppositeMappings = [ m for m in distinguishingMappings + if m.initialDescriptionType == slipnet.stringPositionCategory and + m.initialDescriptionType != slipnet.bondFacet ] + initialDescriptionTypes = [ m.initialDescriptionType for m in oppositeMappings ] + flipTargetObject = False + if objectFromInitial.spansString() and objectFromTarget.spansString() and slipnet.directionCategory in initialDescriptionTypes and __allOppositeMappings(oppositeMappings) and slipnet.opposite.activation != 100.0: + objectFromTarget = objectFromTarget.flippedVersion() + conceptMappings = getMappings( objectFromInitial, objectFromTarget, objectFromInitial.relevantDescriptions(), objectFromTarget.relevantDescriptions()) + flipTargetObject = True + coderack.proposeCorrespondence(objectFromInitial,objectFromTarget,conceptMappings,flipTargetObject,codelet) def important_object_correspondence_scout(codelet): - objectFromInitial = chooseUnmodifiedObject('relativeImportance',workspace.initial.objects) - descriptors = objectFromInitial.relevantDistinguishingDescriptors() - slipnode = chooseSlipnodeByConceptualDepth(descriptors) - assert slipnode - initialDescriptor = slipnode - for mapping in workspace.slippages(): - if mapping.initialDescriptor == slipnode: - initialDescriptor = mapping.targetDescriptor - targetCandidates = [] - for objekt in workspace.target.objects: - for description in objekt.relevantDescriptions(): - if description.descriptor == initialDescriptor: - targetCandidates += [ objekt ] - assert targetCandidates - objectFromTarget = chooseUnmodifiedObject('interStringSalience',targetCandidates) - assert objectFromInitial.spansString() == objectFromTarget.spansString() - # get the posible concept mappings - conceptMappings = getMappings( objectFromInitial, objectFromTarget, objectFromInitial.relevantDescriptions(), objectFromTarget.relevantDescriptions()) - assert conceptMappings and __slippability(conceptMappings) - #find out if any are distinguishing - distinguishingMappings = [ m for m in conceptMappings if m.distinguishing() ] - assert distinguishingMappings - # if both objects span the strings, check to see if the - # string description needs to be flipped - oppositeMappings = [ m for m in distinguishingMappings if m.initialDescriptionType == slipnet.stringPositionCategory and m.initialDescriptionType != slipnet.bondFacet ] - initialDescriptionTypes = [ m.initialDescriptionType for m in oppositeMappings ] - flipTargetObject = False - if objectFromInitial.spansString() and objectFromTarget.spansString() and slipnet.directionCategory in initialDescriptionTypes and __allOppositeMappings(oppositeMappings) and slipnet.opposite.activation != 100.0: - objectFromTarget = objectFromTarget.flippedVersion() - conceptMappings = getMappings( objectFromInitial, objectFromTarget,objectFromInitial.relevantDescriptions(), objectFromTarget.relevantDescriptions()) - flipTargetObject = True - coderack.proposeCorrespondence(objectFromInitial,objectFromTarget,conceptMappings,flipTargetObject,codelet) + objectFromInitial = chooseUnmodifiedObject('relativeImportance',workspace.initial.objects) + descriptors = objectFromInitial.relevantDistinguishingDescriptors() + slipnode = chooseSlipnodeByConceptualDepth(descriptors) + assert slipnode + initialDescriptor = slipnode + for mapping in workspace.slippages(): + if mapping.initialDescriptor == slipnode: + initialDescriptor = mapping.targetDescriptor + targetCandidates = [] + for objekt in workspace.target.objects: + for description in objekt.relevantDescriptions(): + if description.descriptor == initialDescriptor: + targetCandidates += [ objekt ] + assert targetCandidates + objectFromTarget = chooseUnmodifiedObject('interStringSalience',targetCandidates) + assert objectFromInitial.spansString() == objectFromTarget.spansString() + # get the posible concept mappings + conceptMappings = getMappings( objectFromInitial, objectFromTarget, objectFromInitial.relevantDescriptions(), objectFromTarget.relevantDescriptions()) + assert conceptMappings and __slippability(conceptMappings) + #find out if any are distinguishing + distinguishingMappings = [ m for m in conceptMappings if m.distinguishing() ] + assert distinguishingMappings + # if both objects span the strings, check to see if the + # string description needs to be flipped + oppositeMappings = [ m for m in distinguishingMappings if m.initialDescriptionType == slipnet.stringPositionCategory and m.initialDescriptionType != slipnet.bondFacet ] + initialDescriptionTypes = [ m.initialDescriptionType for m in oppositeMappings ] + flipTargetObject = False + if objectFromInitial.spansString() and objectFromTarget.spansString() and slipnet.directionCategory in initialDescriptionTypes and __allOppositeMappings(oppositeMappings) and slipnet.opposite.activation != 100.0: + objectFromTarget = objectFromTarget.flippedVersion() + conceptMappings = getMappings( objectFromInitial, objectFromTarget,objectFromInitial.relevantDescriptions(), objectFromTarget.relevantDescriptions()) + flipTargetObject = True + coderack.proposeCorrespondence(objectFromInitial,objectFromTarget,conceptMappings,flipTargetObject,codelet) def correspondence_strength_tester(codelet): - correspondence = codelet.arguments[0] - objectFromInitial = correspondence.objectFromInitial - objectFromTarget = correspondence.objectFromTarget - assert objectFromInitial in workspace.objects and (objectFromTarget in workspace.objects or correspondence.flipTargetObject and not workspace.target.equivalentGroup(objectFromTarget.flipped_version())) - correspondence.updateStrength() - strength = correspondence.totalStrength - probability = temperatureAdjustedProbability(strength/100.0) - assert utils.random() <= probability - # activate some concepts - for mapping in correspondence.conceptMappings: - mapping.initialDescriptionType.buffer = 100.0 - mapping.initialDescriptor.buffer = 100.0 - mapping.targetDescriptionType.buffer = 100.0 - mapping.targetDescriptor.buffer = 100.0 - coderack.newCodelet('correspondence-builder',codelet,strength,correspondence) + correspondence = codelet.arguments[0] + objectFromInitial = correspondence.objectFromInitial + objectFromTarget = correspondence.objectFromTarget + assert objectFromInitial in workspace.objects and (objectFromTarget in workspace.objects or correspondence.flipTargetObject and not workspace.target.equivalentGroup(objectFromTarget.flipped_version())) + correspondence.updateStrength() + strength = correspondence.totalStrength + probability = temperatureAdjustedProbability(strength/100.0) + assert utils.random() <= probability + # activate some concepts + for mapping in correspondence.conceptMappings: + mapping.initialDescriptionType.buffer = 100.0 + mapping.initialDescriptor.buffer = 100.0 + mapping.targetDescriptionType.buffer = 100.0 + mapping.targetDescriptor.buffer = 100.0 + coderack.newCodelet('correspondence-builder',codelet,strength,correspondence) def correspondence_builder(codelet): - correspondence = codelet.arguments[0] - objectFromInitial = correspondence.objectFromInitial - objectFromTarget = correspondence.objectFromTarget - wantFlip = correspondence.flipTargetObject - if wantFlip: - flipper = objectFromTarget.flippedVersion() - targetNotFlipped = not workspace.target.equivalentGroup(flipper) - else: - targetNotFlipped = False - initialInObjects = objectFromInitial in workspace.objects - targetInObjects = objectFromTarget in workspace.objects - assert (initialInObjects or (not targetInObjects and (not (wantFlip and targetNotFlipped)))) - if correspondence.reflexive(): - # if the correspondence exists, activate concept mappings - # and add new ones to the existing corr. - existing = correspondence.objectFromInitial.correspondence - for mapping in correspondence.conceptMappings: - if mapping.label: - mapping.label.buffer = 100.0 - if not mapping.isContainedBy(existing.conceptMappings): - existing.conceptMappings += [ mapping ] - return - incompatibleCorrespondences = correspondence.getIncompatibleCorrespondences() - # fight against all correspondences - if incompatibleCorrespondences: - correspondenceSpans = correspondence.objectFromInitial.letterSpan() + correspondence.objectFromTarget.letterSpan() - for incompatible in incompatibleCorrespondences: - incompatibleSpans = incompatible.objectFromInitial.letterSpan() + incompatible.objectFromTarget.letterSpan() - assert __structureVsStructure(correspondence,correspondenceSpans,incompatible,incompatibleSpans) - incompatibleBond = None - incompatibleGroup = None - # if there is an incompatible bond then fight against it - if correspondence.objectFromInitial.leftmost or correspondence.objectFromInitial.rightmost and correspondence.objectFromTarget.leftmost or correspondence.objectFromTarget.rightmost: - # search for the incompatible bond - incompatibleBond = correspondence.getIncompatibleBond() - if incompatibleBond: - # bond found - fight against it - assert __structureVsStructure(correspondence,3.0,incompatibleBond,2.0) - # won against incompatible bond - incompatibleGroup = correspondence.objectFromTarget.group - if incompatibleGroup: - assert __structureVsStructure(correspondence,1.0,incompatibleGroup,1.0) - # if there is an incompatible rule, fight against it - incompatibleRule = None - if workspace.rule and workspace.rule.incompatibleRuleCorrespondence(correspondence): - incompatibleRule = workspace.rule - assert __structureVsStructure( correspondence,1.0,incompatibleRule,1.0) - for incompatible in incompatibleCorrespondences: - incompatible.break_the_structure() - # break incompatible group and bond if they exist - if incompatibleBond: - incompatibleBond.break_the_structure() - if incompatibleGroup: - incompatibleGroup.break_the_structure() - if incompatibleRule: - workspace.breakRule() - correspondence.buildCorrespondence() + correspondence = codelet.arguments[0] + objectFromInitial = correspondence.objectFromInitial + objectFromTarget = correspondence.objectFromTarget + wantFlip = correspondence.flipTargetObject + if wantFlip: + flipper = objectFromTarget.flippedVersion() + targetNotFlipped = not workspace.target.equivalentGroup(flipper) + else: + targetNotFlipped = False + initialInObjects = objectFromInitial in workspace.objects + targetInObjects = objectFromTarget in workspace.objects + assert (initialInObjects or (not targetInObjects and (not (wantFlip and targetNotFlipped)))) + if correspondence.reflexive(): + # if the correspondence exists, activate concept mappings + # and add new ones to the existing corr. + existing = correspondence.objectFromInitial.correspondence + for mapping in correspondence.conceptMappings: + if mapping.label: + mapping.label.buffer = 100.0 + if not mapping.isContainedBy(existing.conceptMappings): + existing.conceptMappings += [ mapping ] + return + incompatibleCorrespondences = correspondence.getIncompatibleCorrespondences() + # fight against all correspondences + if incompatibleCorrespondences: + correspondenceSpans = correspondence.objectFromInitial.letterSpan() + correspondence.objectFromTarget.letterSpan() + for incompatible in incompatibleCorrespondences: + incompatibleSpans = incompatible.objectFromInitial.letterSpan() + incompatible.objectFromTarget.letterSpan() + assert __structureVsStructure(correspondence,correspondenceSpans,incompatible,incompatibleSpans) + incompatibleBond = None + incompatibleGroup = None + # if there is an incompatible bond then fight against it + if correspondence.objectFromInitial.leftmost or correspondence.objectFromInitial.rightmost and correspondence.objectFromTarget.leftmost or correspondence.objectFromTarget.rightmost: + # search for the incompatible bond + incompatibleBond = correspondence.getIncompatibleBond() + if incompatibleBond: + # bond found - fight against it + assert __structureVsStructure(correspondence,3.0,incompatibleBond,2.0) + # won against incompatible bond + incompatibleGroup = correspondence.objectFromTarget.group + if incompatibleGroup: + assert __structureVsStructure(correspondence,1.0,incompatibleGroup,1.0) + # if there is an incompatible rule, fight against it + incompatibleRule = None + if workspace.rule and workspace.rule.incompatibleRuleCorrespondence(correspondence): + incompatibleRule = workspace.rule + assert __structureVsStructure( correspondence,1.0,incompatibleRule,1.0) + for incompatible in incompatibleCorrespondences: + incompatible.break_the_structure() + # break incompatible group and bond if they exist + if incompatibleBond: + incompatibleBond.break_the_structure() + if incompatibleGroup: + incompatibleGroup.break_the_structure() + if incompatibleRule: + workspace.breakRule() + correspondence.buildCorrespondence() diff --git a/copycat/coderack.py b/copycat/coderack.py index 8cc55d0..f5e1c01 100644 --- a/copycat/coderack.py +++ b/copycat/coderack.py @@ -13,326 +13,326 @@ MAX_NUMBER_OF_CODELETS = 100 codeletsUsed = {} class CodeRack(object): - def __init__(self): - #logging.debug('coderack.__init__()') - self.speedUpBonds = False - self.removeBreakerCodelets = False - self.removeTerracedScan = False - self.pressures = CoderackPressures() - self.pressures.initialisePressures() - self.reset() - self.initialCodeletNames = ( 'bottom-up-bond-scout', 'replacement-finder', 'bottom-up-correspondence-scout' ) - self.codeletMethodsDir = None - self.runCodelets = {} - self.postings = {} + def __init__(self): + #logging.debug('coderack.__init__()') + self.speedUpBonds = False + self.removeBreakerCodelets = False + self.removeTerracedScan = False + self.pressures = CoderackPressures() + self.pressures.initialisePressures() + self.reset() + self.initialCodeletNames = ( 'bottom-up-bond-scout', 'replacement-finder', 'bottom-up-correspondence-scout' ) + self.codeletMethodsDir = None + self.runCodelets = {} + self.postings = {} - def reset(self): - #logging.debug('coderack.reset()') - from temperature import temperature + def reset(self): + #logging.debug('coderack.reset()') + from temperature import temperature - self.codelets = [] - self.codeletsRun = 0 - temperature.clamped = True - self.pressures.reset() + self.codelets = [] + self.codeletsRun = 0 + temperature.clamped = True + self.pressures.reset() - def updateCodelets(self): - if self.codeletsRun > 0: - self.postTopDownCodelets() - self.postBottomUpCodelets() + def updateCodelets(self): + if self.codeletsRun > 0: + self.postTopDownCodelets() + self.postBottomUpCodelets() - def getUrgencyBin(self, urgency): - bin = int(urgency) * NUMBER_OF_BINS - bin /= 100 - if bin >= NUMBER_OF_BINS: - bin = NUMBER_OF_BINS - 1 - return bin + 1 + def getUrgencyBin(self, urgency): + bin = int(urgency) * NUMBER_OF_BINS + bin /= 100 + if bin >= NUMBER_OF_BINS: + bin = NUMBER_OF_BINS - 1 + return bin + 1 - def post(self, codelet): - #logging.info('Posting codelet called: %s, with urgency %f' % (codelet.name,codelet.urgency)) - self.postings[codelet.name] = self.postings.get(codelet.name, 0) + 1 - self.pressures.addCodelet(codelet) - self.codelets += [codelet] - if len(self.codelets) > 100: - oldCodelet = self.chooseOldCodelet() - self.removeCodelet(oldCodelet) + def post(self, codelet): + #logging.info('Posting codelet called: %s, with urgency %f' % (codelet.name,codelet.urgency)) + self.postings[codelet.name] = self.postings.get(codelet.name, 0) + 1 + self.pressures.addCodelet(codelet) + self.codelets += [codelet] + if len(self.codelets) > 100: + oldCodelet = self.chooseOldCodelet() + self.removeCodelet(oldCodelet) - def postTopDownCodelets(self): - for node in slipnet.slipnodes: - #logging.info('Trying slipnode: %s' % node.get_name()) - if node.activation == 100.0: - #logging.info('using slipnode: %s' % node.get_name()) - for codeletName in node.codelets: - probability = workspaceFormulas.probabilityOfPosting(codeletName) - howMany = workspaceFormulas.howManyToPost(codeletName) - #print '%s:%d' % (codeletName,howMany) - for unused in range(0, howMany): - if utils.random() < probability: - urgency = self.getUrgencyBin(node.activation * node.conceptualDepth / 100.0) - codelet = Codelet(codeletName, urgency, self.codeletsRun) - codelet.arguments += [node] - logging.info('Post top down: %s, with urgency: %d' % (codelet.name, urgency)) - #logging.info("From slipnode %s, activation: %s, depth: %s" %(node.get_name(),node.activation,node.conceptual_depth) ) - self.post(codelet) + def postTopDownCodelets(self): + for node in slipnet.slipnodes: + #logging.info('Trying slipnode: %s' % node.get_name()) + if node.activation == 100.0: + #logging.info('using slipnode: %s' % node.get_name()) + for codeletName in node.codelets: + probability = workspaceFormulas.probabilityOfPosting(codeletName) + howMany = workspaceFormulas.howManyToPost(codeletName) + #print '%s:%d' % (codeletName,howMany) + for unused in range(0, howMany): + if utils.random() < probability: + urgency = self.getUrgencyBin(node.activation * node.conceptualDepth / 100.0) + codelet = Codelet(codeletName, urgency, self.codeletsRun) + codelet.arguments += [node] + logging.info('Post top down: %s, with urgency: %d' % (codelet.name, urgency)) + #logging.info("From slipnode %s, activation: %s, depth: %s" %(node.get_name(),node.activation,node.conceptual_depth) ) + self.post(codelet) - def postBottomUpCodelets(self): - logging.info("posting bottom up codelets") - self.__postBottomUpCodelets('bottom-up-description-scout') - self.__postBottomUpCodelets('bottom-up-bond-scout') - self.__postBottomUpCodelets('group-scout--whole-string') - self.__postBottomUpCodelets('bottom-up-correspondence-scout') - self.__postBottomUpCodelets('important-object-correspondence-scout') - self.__postBottomUpCodelets('replacement-finder') - self.__postBottomUpCodelets('rule-scout') - self.__postBottomUpCodelets('rule-translator') - if not self.removeBreakerCodelets: - self.__postBottomUpCodelets('breaker') + def postBottomUpCodelets(self): + logging.info("posting bottom up codelets") + self.__postBottomUpCodelets('bottom-up-description-scout') + self.__postBottomUpCodelets('bottom-up-bond-scout') + self.__postBottomUpCodelets('group-scout--whole-string') + self.__postBottomUpCodelets('bottom-up-correspondence-scout') + self.__postBottomUpCodelets('important-object-correspondence-scout') + self.__postBottomUpCodelets('replacement-finder') + self.__postBottomUpCodelets('rule-scout') + self.__postBottomUpCodelets('rule-translator') + if not self.removeBreakerCodelets: + self.__postBottomUpCodelets('breaker') - def __postBottomUpCodelets(self, codeletName): - probability = workspaceFormulas.probabilityOfPosting(codeletName) - howMany = workspaceFormulas.howManyToPost(codeletName) - #if codeletName == 'bottom-up-bond-scout': - # print 'post --> %f:%d' % (probability,howMany) - if self.speedUpBonds: - if 'bond' in codeletName or 'group' in codeletName: - howMany *= 3 - urgency = 3 - if codeletName == 'breaker': - urgency = 1 - if formulas.Temperature < 25.0 and 'translator' in codeletName: - urgency = 5 - for unused in range(0, howMany): - if utils.random() < probability: - codelet = Codelet(codeletName, urgency, self.codeletsRun) - self.post(codelet) + def __postBottomUpCodelets(self, codeletName): + probability = workspaceFormulas.probabilityOfPosting(codeletName) + howMany = workspaceFormulas.howManyToPost(codeletName) + #if codeletName == 'bottom-up-bond-scout': + # print 'post --> %f:%d' % (probability,howMany) + if self.speedUpBonds: + if 'bond' in codeletName or 'group' in codeletName: + howMany *= 3 + urgency = 3 + if codeletName == 'breaker': + urgency = 1 + if formulas.Temperature < 25.0 and 'translator' in codeletName: + urgency = 5 + for unused in range(0, howMany): + if utils.random() < probability: + codelet = Codelet(codeletName, urgency, self.codeletsRun) + self.post(codelet) - def removeCodelet(self, codelet): - self.codelets.remove(codelet) - self.pressures.removeCodelet(codelet) + def removeCodelet(self, codelet): + self.codelets.remove(codelet) + self.pressures.removeCodelet(codelet) - def newCodelet(self, name, oldCodelet, strength, arguments=None): - #logging.debug('Posting new codelet called %s' % name) - urgency = self.getUrgencyBin(strength) - newCodelet = Codelet(name, urgency, self.codeletsRun) - if arguments: - newCodelet.arguments = [arguments] - else: - newCodelet.arguments = oldCodelet.arguments - newCodelet.pressure = oldCodelet.pressure - self.tryRun(newCodelet) + def newCodelet(self, name, oldCodelet, strength, arguments=None): + #logging.debug('Posting new codelet called %s' % name) + urgency = self.getUrgencyBin(strength) + newCodelet = Codelet(name, urgency, self.codeletsRun) + if arguments: + newCodelet.arguments = [arguments] + else: + newCodelet.arguments = oldCodelet.arguments + newCodelet.pressure = oldCodelet.pressure + self.tryRun(newCodelet) - def proposeRule(self, facet, description, category, relation, oldCodelet): - """Creates a proposed rule, and posts a rule-strength-tester codelet. + def proposeRule(self, facet, description, category, relation, oldCodelet): + """Creates a proposed rule, and posts a rule-strength-tester codelet. - The new codelet has urgency a function of the degree of conceptual-depth of the descriptions in the rule - """ - from rule import Rule + The new codelet has urgency a function of the degree of conceptual-depth of the descriptions in the rule + """ + from rule import Rule - rule = Rule(facet, description, category, relation) - rule.updateStrength() - if description and relation: - depths = description.conceptualDepth + relation.conceptualDepth - depths /= 200.0 - urgency = math.sqrt(depths) * 100.0 - else: - urgency = 0 - self.newCodelet('rule-strength-tester', oldCodelet, urgency, rule) + rule = Rule(facet, description, category, relation) + rule.updateStrength() + if description and relation: + depths = description.conceptualDepth + relation.conceptualDepth + depths /= 200.0 + urgency = math.sqrt(depths) * 100.0 + else: + urgency = 0 + self.newCodelet('rule-strength-tester', oldCodelet, urgency, rule) - def proposeCorrespondence(self, initialObject, targetObject, conceptMappings, flipTargetObject, oldCodelet): - from correspondence import Correspondence + def proposeCorrespondence(self, initialObject, targetObject, conceptMappings, flipTargetObject, oldCodelet): + from correspondence import Correspondence - correspondence = Correspondence(initialObject, targetObject, conceptMappings, flipTargetObject) - for mapping in conceptMappings: - mapping.initialDescriptionType.buffer = 100.0 - mapping.initialDescriptor.buffer = 100.0 - mapping.targetDescriptionType.buffer = 100.0 - mapping.targetDescriptor.buffer = 100.0 - mappings = correspondence.distinguishingConceptMappings() - urgency = sum([mapping.strength() for mapping in mappings]) - numberOfMappings = len(mappings) - if urgency: - urgency /= numberOfMappings - bin = self.getUrgencyBin(urgency) - logging.info('urgency: %s, number: %d, bin: %d' % (urgency, numberOfMappings, bin)) - self.newCodelet('correspondence-strength-tester', oldCodelet, urgency, correspondence) + correspondence = Correspondence(initialObject, targetObject, conceptMappings, flipTargetObject) + for mapping in conceptMappings: + mapping.initialDescriptionType.buffer = 100.0 + mapping.initialDescriptor.buffer = 100.0 + mapping.targetDescriptionType.buffer = 100.0 + mapping.targetDescriptor.buffer = 100.0 + mappings = correspondence.distinguishingConceptMappings() + urgency = sum([mapping.strength() for mapping in mappings]) + numberOfMappings = len(mappings) + if urgency: + urgency /= numberOfMappings + bin = self.getUrgencyBin(urgency) + logging.info('urgency: %s, number: %d, bin: %d' % (urgency, numberOfMappings, bin)) + self.newCodelet('correspondence-strength-tester', oldCodelet, urgency, correspondence) - def proposeDescription(self, objekt, descriptionType, descriptor, oldCodelet): - from description import Description + def proposeDescription(self, objekt, descriptionType, descriptor, oldCodelet): + from description import Description - description = Description(objekt, descriptionType, descriptor) - descriptor.buffer = 100.0 - urgency = descriptionType.activation - self.newCodelet('description-strength-tester', oldCodelet, urgency, description) + description = Description(objekt, descriptionType, descriptor) + descriptor.buffer = 100.0 + urgency = descriptionType.activation + self.newCodelet('description-strength-tester', oldCodelet, urgency, description) - def proposeSingleLetterGroup(self, source, codelet): - self.proposeGroup([source], [], slipnet.samenessGroup, None, slipnet.letterCategory, codelet) + def proposeSingleLetterGroup(self, source, codelet): + self.proposeGroup([source], [], slipnet.samenessGroup, None, slipnet.letterCategory, codelet) - def proposeGroup(self, objects, bondList, groupCategory, directionCategory, bondFacet, oldCodelet ): - from group import Group + def proposeGroup(self, objects, bondList, groupCategory, directionCategory, bondFacet, oldCodelet ): + from group import Group - bondCategory = groupCategory.getRelatedNode(slipnet.bondCategory) - bondCategory.buffer = 100.0 - if directionCategory: - directionCategory.buffer = 100.0 - group = Group(objects[0].string, groupCategory, directionCategory, bondFacet, objects, bondList) - urgency = bondCategory.bondDegreeOfAssociation() - self.newCodelet('group-strength-tester', oldCodelet, urgency, group) + bondCategory = groupCategory.getRelatedNode(slipnet.bondCategory) + bondCategory.buffer = 100.0 + if directionCategory: + directionCategory.buffer = 100.0 + group = Group(objects[0].string, groupCategory, directionCategory, bondFacet, objects, bondList) + urgency = bondCategory.bondDegreeOfAssociation() + self.newCodelet('group-strength-tester', oldCodelet, urgency, group) - def proposeBond(self, source, destination, bondCategory, bondFacet, sourceDescriptor, destinationDescriptor, oldCodelet ): - from bond import Bond + def proposeBond(self, source, destination, bondCategory, bondFacet, sourceDescriptor, destinationDescriptor, oldCodelet ): + from bond import Bond - bondFacet.buffer = 100.0 - sourceDescriptor.buffer = 100.0 - destinationDescriptor.buffer = 100.0 - bond = Bond(source, destination, bondCategory, bondFacet, sourceDescriptor, destinationDescriptor) - urgency = bondCategory.bondDegreeOfAssociation() - self.newCodelet('bond-strength-tester', oldCodelet, urgency, bond) + bondFacet.buffer = 100.0 + sourceDescriptor.buffer = 100.0 + destinationDescriptor.buffer = 100.0 + bond = Bond(source, destination, bondCategory, bondFacet, sourceDescriptor, destinationDescriptor) + urgency = bondCategory.bondDegreeOfAssociation() + self.newCodelet('bond-strength-tester', oldCodelet, urgency, bond) - def chooseOldCodelet(self): - # selects an old codelet to remove from the coderack - # more likely to select lower urgency codelets - if not len(self.codelets): - return None - urgencies = [] - for codelet in self.codelets: - urgency = (coderack.codeletsRun - codelet.timeStamp) * (7.5 - codelet.urgency) - urgencies += [urgency] - threshold = utils.random() * sum(urgencies) - sumOfUrgencies = 0.0 - for i in range(0, len(self.codelets)): - sumOfUrgencies += urgencies[i] - if sumOfUrgencies > threshold: - return self.codelets[i] - return self.codelets[0] + def chooseOldCodelet(self): + # selects an old codelet to remove from the coderack + # more likely to select lower urgency codelets + if not len(self.codelets): + return None + urgencies = [] + for codelet in self.codelets: + urgency = (coderack.codeletsRun - codelet.timeStamp) * (7.5 - codelet.urgency) + urgencies += [urgency] + threshold = utils.random() * sum(urgencies) + sumOfUrgencies = 0.0 + for i in range(0, len(self.codelets)): + sumOfUrgencies += urgencies[i] + if sumOfUrgencies > threshold: + return self.codelets[i] + return self.codelets[0] - def postInitialCodelets(self): - #logging.debug('Posting initial codelets') - #logging.debug('Number of inital codelets: %d' % len(self.initialCodeletNames)) - #logging.debug('Number of workspaceObjects: %d' % workspace.numberOfObjects()) - for name in self.initialCodeletNames: - for unused in range(0, workspaceFormulas.numberOfObjects()): - codelet = Codelet(name, 1, self.codeletsRun) - self.post(codelet) - codelet2 = Codelet(name, 1, self.codeletsRun) - self.post(codelet2) + def postInitialCodelets(self): + #logging.debug('Posting initial codelets') + #logging.debug('Number of inital codelets: %d' % len(self.initialCodeletNames)) + #logging.debug('Number of workspaceObjects: %d' % workspace.numberOfObjects()) + for name in self.initialCodeletNames: + for unused in range(0, workspaceFormulas.numberOfObjects()): + codelet = Codelet(name, 1, self.codeletsRun) + self.post(codelet) + codelet2 = Codelet(name, 1, self.codeletsRun) + self.post(codelet2) - def tryRun(self, newCodelet): - if self.removeTerracedScan: - self.run(newCodelet) - else: - self.post(newCodelet) + def tryRun(self, newCodelet): + if self.removeTerracedScan: + self.run(newCodelet) + else: + self.post(newCodelet) - def getCodeletmethods(self): - import codeletMethods + def getCodeletmethods(self): + import codeletMethods - self.codeletMethodsDir = dir(codeletMethods) - knownCodeletNames = ( - 'breaker', - 'bottom-up-description-scout', - 'top-down-description-scout', - 'description-strength-tester', - 'description-builder', - 'bottom-up-bond-scout', - 'top-down-bond-scout--category', - 'top-down-bond-scout--direction', - 'bond-strength-tester', - 'bond-builder', - 'top-down-group-scout--category', - 'top-down-group-scout--direction', - 'group-scout--whole-string', - 'group-strength-tester', - 'group-builder', - 'replacement-finder', - 'rule-scout', - 'rule-strength-tester', - 'rule-builder', - 'rule-translator', - 'bottom-up-correspondence-scout', - 'important-object-correspondence-scout', - 'correspondence-strength-tester', - 'correspondence-builder', - ) - self.methods = {} - for codeletName in knownCodeletNames: - methodName = re.sub('[ -]', '_', codeletName) - if methodName not in self.codeletMethodsDir: - raise NotImplementedError, 'Cannot find %s in codeletMethods' % methodName - method = getattr(codeletMethods, methodName) - self.methods[methodName] = method + self.codeletMethodsDir = dir(codeletMethods) + knownCodeletNames = ( + 'breaker', + 'bottom-up-description-scout', + 'top-down-description-scout', + 'description-strength-tester', + 'description-builder', + 'bottom-up-bond-scout', + 'top-down-bond-scout--category', + 'top-down-bond-scout--direction', + 'bond-strength-tester', + 'bond-builder', + 'top-down-group-scout--category', + 'top-down-group-scout--direction', + 'group-scout--whole-string', + 'group-strength-tester', + 'group-builder', + 'replacement-finder', + 'rule-scout', + 'rule-strength-tester', + 'rule-builder', + 'rule-translator', + 'bottom-up-correspondence-scout', + 'important-object-correspondence-scout', + 'correspondence-strength-tester', + 'correspondence-builder', + ) + self.methods = {} + for codeletName in knownCodeletNames: + methodName = re.sub('[ -]', '_', codeletName) + if methodName not in self.codeletMethodsDir: + raise NotImplementedError, 'Cannot find %s in codeletMethods' % methodName + method = getattr(codeletMethods, methodName) + self.methods[methodName] = method - def chooseAndRunCodelet(self): - if not len(coderack.codelets): - coderack.postInitialCodelets() - codelet = self.chooseCodeletToRun() - if codelet: - self.run(codelet) + def chooseAndRunCodelet(self): + if not len(coderack.codelets): + coderack.postInitialCodelets() + codelet = self.chooseCodeletToRun() + if codelet: + self.run(codelet) - def chooseCodeletToRun(self): - if not self.codelets: - return None - temp = formulas.Temperature - scale = ( 100.0 - temp + 10.0 ) / 15.0 - # threshold = sum( [ c.urgency ** scale for c in self.codelets ] ) * utils.random() - urgsum = 0.0 - for codelet in self.codelets: - urg = codelet.urgency ** scale - urgsum += urg - r = utils.random() - threshold = r * urgsum - chosen = None - urgencySum = 0.0 - logging.info('temperature: %f' % formulas.Temperature) - logging.info('actualTemperature: %f' % formulas.actualTemperature) - logging.info('Slipnet:') - for node in slipnet.slipnodes: - logging.info("\tnode %s, activation: %d, buffer: %d, depth: %s" % (node.get_name(), node.activation, node.buffer, node.conceptualDepth)) - logging.info('Coderack:') - for codelet in self.codelets: - logging.info('\t%s, %d' % (codelet.name, codelet.urgency)) - from workspace import workspace + def chooseCodeletToRun(self): + if not self.codelets: + return None + temp = formulas.Temperature + scale = ( 100.0 - temp + 10.0 ) / 15.0 + # threshold = sum( [ c.urgency ** scale for c in self.codelets ] ) * utils.random() + urgsum = 0.0 + for codelet in self.codelets: + urg = codelet.urgency ** scale + urgsum += urg + r = utils.random() + threshold = r * urgsum + chosen = None + urgencySum = 0.0 + logging.info('temperature: %f' % formulas.Temperature) + logging.info('actualTemperature: %f' % formulas.actualTemperature) + logging.info('Slipnet:') + for node in slipnet.slipnodes: + logging.info("\tnode %s, activation: %d, buffer: %d, depth: %s" % (node.get_name(), node.activation, node.buffer, node.conceptualDepth)) + logging.info('Coderack:') + for codelet in self.codelets: + logging.info('\t%s, %d' % (codelet.name, codelet.urgency)) + from workspace import workspace - workspace.initial.log("Initial: ") - workspace.target.log("Target: ") - for codelet in self.codelets: - urgencySum += codelet.urgency ** scale - if not chosen and urgencySum > threshold: - chosen = codelet - break - if not chosen: - chosen = self.codelets[0] - self.removeCodelet(chosen) - logging.info('chosen codelet\n\t%s, urgency = %s' % (chosen.name, chosen.urgency)) - return chosen + workspace.initial.log("Initial: ") + workspace.target.log("Target: ") + for codelet in self.codelets: + urgencySum += codelet.urgency ** scale + if not chosen and urgencySum > threshold: + chosen = codelet + break + if not chosen: + chosen = self.codelets[0] + self.removeCodelet(chosen) + logging.info('chosen codelet\n\t%s, urgency = %s' % (chosen.name, chosen.urgency)) + return chosen - def run(self, codelet): - methodName = re.sub('[ -]', '_', codelet.name) - self.codeletsRun += 1 - self.runCodelets[methodName] = self.runCodelets.get(methodName, 0) + 1 + def run(self, codelet): + methodName = re.sub('[ -]', '_', codelet.name) + self.codeletsRun += 1 + self.runCodelets[methodName] = self.runCodelets.get(methodName, 0) + 1 - #if self.codeletsRun > 2000: - #import sys - #print "running too many codelets" - #for name,count in self.postings.iteritems(): - #print '%d:%s' % (count,name) - #raise ValueError - #else: - # print 'running %d' % self.codeletsRun - if not self.codeletMethodsDir: - self.getCodeletmethods() - #if not self.codeletMethodsDir: - method = self.methods[methodName] - if not method: - raise ValueError, 'Found %s in codeletMethods, but cannot get it' % methodName - if not callable(method): - raise RuntimeError, 'Cannot call %s()' % methodName - args, varargs, varkw, defaults = inspect.getargspec(method) - #global codeletsUsed - #codeletsUsed[methodName] = codeletsUsed.get(methodName,0) + 1 - try: - if 'codelet' in args: - method(codelet) - else: - method() - except AssertionError: - pass + #if self.codeletsRun > 2000: + #import sys + #print "running too many codelets" + #for name,count in self.postings.iteritems(): + #print '%d:%s' % (count,name) + #raise ValueError + #else: + # print 'running %d' % self.codeletsRun + if not self.codeletMethodsDir: + self.getCodeletmethods() + #if not self.codeletMethodsDir: + method = self.methods[methodName] + if not method: + raise ValueError, 'Found %s in codeletMethods, but cannot get it' % methodName + if not callable(method): + raise RuntimeError, 'Cannot call %s()' % methodName + args, varargs, varkw, defaults = inspect.getargspec(method) + #global codeletsUsed + #codeletsUsed[methodName] = codeletsUsed.get(methodName,0) + 1 + try: + if 'codelet' in args: + method(codelet) + else: + method() + except AssertionError: + pass coderack = CodeRack() diff --git a/copycat/coderackPressure.py b/copycat/coderackPressure.py index 4b925f6..ed85da1 100644 --- a/copycat/coderackPressure.py +++ b/copycat/coderackPressure.py @@ -3,131 +3,131 @@ from formulas import Temperature from slipnet import slipnet class CoderackPressure(object): - def __init__(self, name): - self.name = name + def __init__(self, name): + self.name = name - def reset(self): - self.unmodifedValues = [] - self.values = [] - self.codelets = [] + def reset(self): + self.unmodifedValues = [] + self.values = [] + self.codelets = [] class CoderackPressures(object): - def __init__(self): - #logging.debug('coderackPressures.__init__()') - self.initialisePressures() - self.reset() + def __init__(self): + #logging.debug('coderackPressures.__init__()') + self.initialisePressures() + self.reset() - def initialisePressures(self): - #logging.debug('coderackPressures.initialisePressures()') - self.pressures = [] - self.pressures += [CoderackPressure('Bottom Up Bonds')] - self.pressures += [CoderackPressure('Top Down Successor Bonds')] - self.pressures += [CoderackPressure('Top Down Predecessor Bonds')] - self.pressures += [CoderackPressure('Top Down Sameness Bonds')] - self.pressures += [CoderackPressure('Top Down Left Bonds')] - self.pressures += [CoderackPressure('Top Down Right Bonds')] - self.pressures += [CoderackPressure('Top Down Successor Group')] - self.pressures += [CoderackPressure('Top Down Predecessor Group')] - self.pressures += [CoderackPressure('Top Down Sameness Group')] - self.pressures += [CoderackPressure('Top Down Left Group')] - self.pressures += [CoderackPressure('Top Down Right Group')] - self.pressures += [CoderackPressure('Bottom Up Whole Group')] - self.pressures += [CoderackPressure('Replacement Finder')] - self.pressures += [CoderackPressure('Rule Codelets')] - self.pressures += [CoderackPressure('Rule Translator')] - self.pressures += [CoderackPressure('Bottom Up Correspondences')] - self.pressures += [CoderackPressure('Important Object Correspondences')] - self.pressures += [CoderackPressure('Breakers')] + def initialisePressures(self): + #logging.debug('coderackPressures.initialisePressures()') + self.pressures = [] + self.pressures += [CoderackPressure('Bottom Up Bonds')] + self.pressures += [CoderackPressure('Top Down Successor Bonds')] + self.pressures += [CoderackPressure('Top Down Predecessor Bonds')] + self.pressures += [CoderackPressure('Top Down Sameness Bonds')] + self.pressures += [CoderackPressure('Top Down Left Bonds')] + self.pressures += [CoderackPressure('Top Down Right Bonds')] + self.pressures += [CoderackPressure('Top Down Successor Group')] + self.pressures += [CoderackPressure('Top Down Predecessor Group')] + self.pressures += [CoderackPressure('Top Down Sameness Group')] + self.pressures += [CoderackPressure('Top Down Left Group')] + self.pressures += [CoderackPressure('Top Down Right Group')] + self.pressures += [CoderackPressure('Bottom Up Whole Group')] + self.pressures += [CoderackPressure('Replacement Finder')] + self.pressures += [CoderackPressure('Rule Codelets')] + self.pressures += [CoderackPressure('Rule Translator')] + self.pressures += [CoderackPressure('Bottom Up Correspondences')] + self.pressures += [CoderackPressure('Important Object Correspondences')] + self.pressures += [CoderackPressure('Breakers')] - def calculatePressures(self): - #logging.debug('coderackPressures.calculatePressures()') - scale = ( 100.0 - Temperature + 10.0 ) / 15.0 - values = [] - for pressure in self.pressures: - value = sum([c.urgency ** scale for c in pressure.codelets]) - values += [value] - totalValue = sum(values) - if not totalValue: - totalValue = 1.0 - values = [value / totalValue for value in values] - self.maxValue = max(values) - for pressure, value in zip(self.pressures, values): - pressure.values += [value * 100.0] - for codelet in self.removedCodelets: - if codelet.pressure: - codelet.pressure.codelets.removeElement(codelet) - self.removedCodelets = [] + def calculatePressures(self): + #logging.debug('coderackPressures.calculatePressures()') + scale = ( 100.0 - Temperature + 10.0 ) / 15.0 + values = [] + for pressure in self.pressures: + value = sum([c.urgency ** scale for c in pressure.codelets]) + values += [value] + totalValue = sum(values) + if not totalValue: + totalValue = 1.0 + values = [value / totalValue for value in values] + self.maxValue = max(values) + for pressure, value in zip(self.pressures, values): + pressure.values += [value * 100.0] + for codelet in self.removedCodelets: + if codelet.pressure: + codelet.pressure.codelets.removeElement(codelet) + self.removedCodelets = [] - def reset(self): - #logging.debug('coderackPressures.reset()') - self.maxValue = 0.001 - for pressure in self.pressures: - pressure.reset() - self.removedCodelets = [] + def reset(self): + #logging.debug('coderackPressures.reset()') + self.maxValue = 0.001 + for pressure in self.pressures: + pressure.reset() + self.removedCodelets = [] - def addCodelet(self, codelet): - node = None - i = -1 - if codelet.name == 'bottom-up-bond-scout': - i = 0 - if codelet.name == 'top-down-bond-scout--category': - node = codelet.arguments[0] - if node == slipnet.successor: - i = 1 - elif node == slipnet.predecessor: - i = 2 - else: - i = 3 - if codelet.name == 'top-down-bond-scout--direction': - node = codelet.arguments[0] - if node == slipnet.left: - i = 4 - elif node == slipnet.right: - i = 5 - else: - i = 3 - if codelet.name == 'top-down-group-scout--category': - node = codelet.arguments[0] - if node == slipnet.successorGroup: - i = 6 - elif node == slipnet.predecessorGroup: - i = 7 - else: - i = 8 - if codelet.name == 'top-down-group-scout--direction': - node = codelet.arguments[0] - if node == slipnet.left: - i = 9 - elif node == slipnet.right: - i = 10 - if codelet.name == 'group-scout--whole-string': - i = 11 - if codelet.name == 'replacement-finder': - i = 12 - if codelet.name == 'rule-scout': - i = 13 - if codelet.name == 'rule-translator': - i = 14 - if codelet.name == 'bottom-up-correspondence-scout': - i = 15 - if codelet.name == 'important-object-correspondence-scout': - i = 16 - if codelet.name == 'breaker': - i = 17 - if i >= 0: - self.pressures[i].codelets += [codelet] - if codelet.pressure: - codelet.pressure.codelets += [codelet] # XXX why do this - if i >= 0: - codelet.pressure = self.pressures[i] # when following with this ? - logging.info('Add %s: %d' % (codelet.name, i)) - if node: - logging.info('Node: %s' % node.name) + def addCodelet(self, codelet): + node = None + i = -1 + if codelet.name == 'bottom-up-bond-scout': + i = 0 + if codelet.name == 'top-down-bond-scout--category': + node = codelet.arguments[0] + if node == slipnet.successor: + i = 1 + elif node == slipnet.predecessor: + i = 2 + else: + i = 3 + if codelet.name == 'top-down-bond-scout--direction': + node = codelet.arguments[0] + if node == slipnet.left: + i = 4 + elif node == slipnet.right: + i = 5 + else: + i = 3 + if codelet.name == 'top-down-group-scout--category': + node = codelet.arguments[0] + if node == slipnet.successorGroup: + i = 6 + elif node == slipnet.predecessorGroup: + i = 7 + else: + i = 8 + if codelet.name == 'top-down-group-scout--direction': + node = codelet.arguments[0] + if node == slipnet.left: + i = 9 + elif node == slipnet.right: + i = 10 + if codelet.name == 'group-scout--whole-string': + i = 11 + if codelet.name == 'replacement-finder': + i = 12 + if codelet.name == 'rule-scout': + i = 13 + if codelet.name == 'rule-translator': + i = 14 + if codelet.name == 'bottom-up-correspondence-scout': + i = 15 + if codelet.name == 'important-object-correspondence-scout': + i = 16 + if codelet.name == 'breaker': + i = 17 + if i >= 0: + self.pressures[i].codelets += [codelet] + if codelet.pressure: + codelet.pressure.codelets += [codelet] # XXX why do this + if i >= 0: + codelet.pressure = self.pressures[i] # when following with this ? + logging.info('Add %s: %d' % (codelet.name, i)) + if node: + logging.info('Node: %s' % node.name) - def removeCodelet(self, codelet): - self.removedCodelets += [codelet] + def removeCodelet(self, codelet): + self.removedCodelets += [codelet] - def numberOfPressures(self): - return len(self.pressures) + def numberOfPressures(self): + return len(self.pressures) coderackPressures = CoderackPressures() diff --git a/copycat/conceptMapping.py b/copycat/conceptMapping.py index 4f861e2..acbda95 100644 --- a/copycat/conceptMapping.py +++ b/copycat/conceptMapping.py @@ -2,141 +2,141 @@ import logging from slipnet import slipnet class ConceptMapping(object): - def __init__(self, initialDescriptionType, targetDescriptionType, initialDescriptor, targetDescriptor, initialObject, targetObject): - logging.info('make a map: %s-%s' % (initialDescriptionType.get_name(), targetDescriptionType.get_name())) - self.initialDescriptionType = initialDescriptionType - self.targetDescriptionType = targetDescriptionType - self.initialDescriptor = initialDescriptor - self.targetDescriptor = targetDescriptor - self.initialObject = initialObject - self.targetObject = targetObject - self.label = initialDescriptor.getBondCategory(targetDescriptor) + def __init__(self, initialDescriptionType, targetDescriptionType, initialDescriptor, targetDescriptor, initialObject, targetObject): + logging.info('make a map: %s-%s' % (initialDescriptionType.get_name(), targetDescriptionType.get_name())) + self.initialDescriptionType = initialDescriptionType + self.targetDescriptionType = targetDescriptionType + self.initialDescriptor = initialDescriptor + self.targetDescriptor = targetDescriptor + self.initialObject = initialObject + self.targetObject = targetObject + self.label = initialDescriptor.getBondCategory(targetDescriptor) - def __repr__(self): - return '' % (self.__str__(), self.initialDescriptor, self.targetDescriptor) + def __repr__(self): + return '' % (self.__str__(), self.initialDescriptor, self.targetDescriptor) - def __str__(self): - return self.label and self.label.name or 'anonymous' + def __str__(self): + return self.label and self.label.name or 'anonymous' - def slipability(self): - association = self.__degreeOfAssociation() - if association == 100.0: - return 100.0 - depth = self.__conceptualDepth() / 100.0 - return association * ( 1 - depth * depth ) + def slipability(self): + association = self.__degreeOfAssociation() + if association == 100.0: + return 100.0 + depth = self.__conceptualDepth() / 100.0 + return association * ( 1 - depth * depth ) - def __degreeOfAssociation(self): - #assumes the 2 descriptors are connected in the slipnet by at most 1 link - if self.initialDescriptor == self.targetDescriptor: - return 100.0 - for link in self.initialDescriptor.lateralSlipLinks: - if link.destination == self.targetDescriptor: - return link.degreeOfAssociation() - return 0.0 + def __degreeOfAssociation(self): + #assumes the 2 descriptors are connected in the slipnet by at most 1 link + if self.initialDescriptor == self.targetDescriptor: + return 100.0 + for link in self.initialDescriptor.lateralSlipLinks: + if link.destination == self.targetDescriptor: + return link.degreeOfAssociation() + return 0.0 - def strength(self): - association = self.__degreeOfAssociation() - if association == 100.0: - return 100.0 - depth = self.__conceptualDepth() / 100.0 - return association * ( 1 + depth * depth ) + def strength(self): + association = self.__degreeOfAssociation() + if association == 100.0: + return 100.0 + depth = self.__conceptualDepth() / 100.0 + return association * ( 1 + depth * depth ) - def __conceptualDepth(self): - return (self.initialDescriptor.conceptualDepth + self.targetDescriptor.conceptualDepth ) / 2.0 + def __conceptualDepth(self): + return (self.initialDescriptor.conceptualDepth + self.targetDescriptor.conceptualDepth ) / 2.0 - def distinguishing(self): - if self.initialDescriptor == slipnet.whole and self.targetDescriptor == slipnet.whole: - return False - if not self.initialObject.distinguishingDescriptor(self.initialDescriptor): - return False - return self.targetObject.distinguishingDescriptor(self.targetDescriptor) + def distinguishing(self): + if self.initialDescriptor == slipnet.whole and self.targetDescriptor == slipnet.whole: + return False + if not self.initialObject.distinguishingDescriptor(self.initialDescriptor): + return False + return self.targetObject.distinguishingDescriptor(self.targetDescriptor) - def sameInitialType(self, other): - return self.initialDescriptionType == other.initialDescriptionType + def sameInitialType(self, other): + return self.initialDescriptionType == other.initialDescriptionType - def sameTargetType(self, other): - return self.targetDescriptionType == other.targetDescriptionType + def sameTargetType(self, other): + return self.targetDescriptionType == other.targetDescriptionType - def sameTypes(self, other): - return self.sameInitialType(other) and self.sameTargetType(other) + def sameTypes(self, other): + return self.sameInitialType(other) and self.sameTargetType(other) - def sameInitialDescriptor(self, other): - return self.initialDescriptor == other.initialDescriptor + def sameInitialDescriptor(self, other): + return self.initialDescriptor == other.initialDescriptor - def sameTargetDescriptor(self, other): - return self.targetDescriptor == other.targetDescriptor + def sameTargetDescriptor(self, other): + return self.targetDescriptor == other.targetDescriptor - def sameDescriptors(self, other): - return self.sameInitialDescriptor(other) and self.sameTargetDescriptor(other) + def sameDescriptors(self, other): + return self.sameInitialDescriptor(other) and self.sameTargetDescriptor(other) - def sameKind(self, other): - return self.sameTypes(other) and self.sameDescriptors(other) + def sameKind(self, other): + return self.sameTypes(other) and self.sameDescriptors(other) - def nearlySameKind(self, other): - return self.sameTypes(other) and self.sameInitialDescriptor(other) + def nearlySameKind(self, other): + return self.sameTypes(other) and self.sameInitialDescriptor(other) - def isContainedBy(self, mappings): - return any([self.sameKind(mapping) for mapping in mappings]) + def isContainedBy(self, mappings): + return any([self.sameKind(mapping) for mapping in mappings]) - def isNearlyContainedBy(self, mappings): - return any([self.nearlySameKind(mapping) for mapping in mappings]) + def isNearlyContainedBy(self, mappings): + return any([self.nearlySameKind(mapping) for mapping in mappings]) - def related(self, other): - if self.initialDescriptor.related(other.initialDescriptor): - return True - return self.targetDescriptor.related(other.targetDescriptor) + def related(self, other): + if self.initialDescriptor.related(other.initialDescriptor): + return True + return self.targetDescriptor.related(other.targetDescriptor) - def incompatible(self, other): - # Concept-mappings (a -> b) and (c -> d) are incompatible if a is - # related to c or if b is related to d, and the a -> b relationship is - # different from the c -> d relationship. E.g., rightmost -> leftmost - # is incompatible with right -> right, since rightmost is linked - # to right, but the relationships (opposite and identity) are different. - # Notice that slipnet distances are not looked at, only slipnet links. This - # should be changed eventually. - if not self.related(other): - return False - if not self.label or not other.label: - return False - return self.label != other.label + def incompatible(self, other): + # Concept-mappings (a -> b) and (c -> d) are incompatible if a is + # related to c or if b is related to d, and the a -> b relationship is + # different from the c -> d relationship. E.g., rightmost -> leftmost + # is incompatible with right -> right, since rightmost is linked + # to right, but the relationships (opposite and identity) are different. + # Notice that slipnet distances are not looked at, only slipnet links. This + # should be changed eventually. + if not self.related(other): + return False + if not self.label or not other.label: + return False + return self.label != other.label - def supports(self, other): - # Concept-mappings (a -> b) and (c -> d) support each other if a is related - # to c and if b is related to d and the a -> b relationship is the same as the - # c -> d relationship. E.g., rightmost -> rightmost supports right -> right - # and leftmost -> leftmost. Notice that slipnet distances are not looked - # at, only slipnet links. This should be changed eventually. + def supports(self, other): + # Concept-mappings (a -> b) and (c -> d) support each other if a is related + # to c and if b is related to d and the a -> b relationship is the same as the + # c -> d relationship. E.g., rightmost -> rightmost supports right -> right + # and leftmost -> leftmost. Notice that slipnet distances are not looked + # at, only slipnet links. This should be changed eventually. - # If the two concept-mappings are the same, then return t. This - # means that letter->group supports letter->group, even though these - # concept-mappings have no label. + # If the two concept-mappings are the same, then return t. This + # means that letter->group supports letter->group, even though these + # concept-mappings have no label. - if self.initialDescriptor == other.initialDescriptor and self.targetDescriptor == other.targetDescriptor: - return True - # if the descriptors are not related return false - if not self.related(other): - return False - if not self.label or not other.label: - return False - return self.label == other.label + if self.initialDescriptor == other.initialDescriptor and self.targetDescriptor == other.targetDescriptor: + return True + # if the descriptors are not related return false + if not self.related(other): + return False + if not self.label or not other.label: + return False + return self.label == other.label - def relevant(self): - return self.initialDescriptionType.fully_active() and self.targetDescriptionType.fully_active() + def relevant(self): + return self.initialDescriptionType.fully_active() and self.targetDescriptionType.fully_active() - def slippage(self): - return self.label != slipnet.sameness and self.label != slipnet.identity + def slippage(self): + return self.label != slipnet.sameness and self.label != slipnet.identity - def symmetricVersion(self): - if not self.slippage(): - return self - if self.targetDescriptor.getBondCategory(self.initialDescriptor) == self.label: - return self - return ConceptMapping( - self.targetDescriptionType, - self.initialDescriptionType, - self.targetDescriptor, - self.initialDescriptor1, - self.initialObject, - self.targetObject - ) + def symmetricVersion(self): + if not self.slippage(): + return self + if self.targetDescriptor.getBondCategory(self.initialDescriptor) == self.label: + return self + return ConceptMapping( + self.targetDescriptionType, + self.initialDescriptionType, + self.targetDescriptor, + self.initialDescriptor1, + self.initialObject, + self.targetObject + ) diff --git a/copycat/copycat.py b/copycat/copycat.py index d58f33d..ff75ea4 100644 --- a/copycat/copycat.py +++ b/copycat/copycat.py @@ -1,10 +1,10 @@ import logging logging.basicConfig( - level=logging.INFO, - #format='%(asctime)s %(filename)s:%(lineno)d %(message)s', - format='%(message)s', - filename='./copycat.log', - filemode='w' + level=logging.INFO, + #format='%(asctime)s %(filename)s:%(lineno)d %(message)s', + format='%(message)s', + filename='./copycat.log', + filemode='w' ) @@ -16,43 +16,43 @@ from coderack import coderack from coderackPressure import coderackPressures def updateEverything(): - workspace.updateEverything() - coderack.updateCodelets() - slipnet.update() - workspaceFormulas.updateTemperature() - coderackPressures.calculatePressures() + workspace.updateEverything() + coderack.updateCodelets() + slipnet.update() + workspaceFormulas.updateTemperature() + coderackPressures.calculatePressures() def mainLoop(lastUpdate): - temperature.tryUnclamp() - result = lastUpdate - if coderack.codeletsRun - lastUpdate >= slipnet.timeStepLength or not coderack.codeletsRun: - updateEverything() - result = coderack.codeletsRun - logging.debug('Number of codelets: %d' % len(coderack.codelets)) - coderack.chooseAndRunCodelet() - return result + temperature.tryUnclamp() + result = lastUpdate + if coderack.codeletsRun - lastUpdate >= slipnet.timeStepLength or not coderack.codeletsRun: + updateEverything() + result = coderack.codeletsRun + logging.debug('Number of codelets: %d' % len(coderack.codelets)) + coderack.chooseAndRunCodelet() + return result def runTrial(): - """Run a trial of the copycat algorithm""" - answers = {} - slipnet.reset() - workspace.reset() - coderack.reset() - lastUpdate = 0 - while not workspace.foundAnswer: - lastUpdate = mainLoop(lastUpdate) - if workspace.rule: - answer = workspace.rule.finalAnswer - else: - answer = None - print '%d: %s' % (coderack.codeletsRun, answer) - answers[answer] = answers.get(answer, 0) + 1 - logging.debug('codelets used:') - for answer, count in answers.iteritems(): - print '%s:%d' % (answer, count) + """Run a trial of the copycat algorithm""" + answers = {} + slipnet.reset() + workspace.reset() + coderack.reset() + lastUpdate = 0 + while not workspace.foundAnswer: + lastUpdate = mainLoop(lastUpdate) + if workspace.rule: + answer = workspace.rule.finalAnswer + else: + answer = None + print '%d: %s' % (coderack.codeletsRun, answer) + answers[answer] = answers.get(answer, 0) + 1 + logging.debug('codelets used:') + for answer, count in answers.iteritems(): + print '%s:%d' % (answer, count) def run(initial, modified, target): - workspace.setStrings(initial, modified, target) - runTrial() + workspace.setStrings(initial, modified, target) + runTrial() diff --git a/copycat/correspondence.py b/copycat/correspondence.py index b3e6c7c..3e7d0d7 100644 --- a/copycat/correspondence.py +++ b/copycat/correspondence.py @@ -3,187 +3,187 @@ from workspaceStructure import WorkspaceStructure from formulas import getMappings class Correspondence(WorkspaceStructure): - def __init__(self,objectFromInitial,objectFromTarget,conceptMappings,flipTargetObject): - WorkspaceStructure.__init__(self) - self.objectFromInitial = objectFromInitial - self.objectFromTarget = objectFromTarget - self.conceptMappings = conceptMappings - self.flipTargetObject = flipTargetObject - self.accessoryConceptMappings = [] + def __init__(self,objectFromInitial,objectFromTarget,conceptMappings,flipTargetObject): + WorkspaceStructure.__init__(self) + self.objectFromInitial = objectFromInitial + self.objectFromTarget = objectFromTarget + self.conceptMappings = conceptMappings + self.flipTargetObject = flipTargetObject + self.accessoryConceptMappings = [] - def __repr__(self): - return '<%s>' % self.__str__() + def __repr__(self): + return '<%s>' % self.__str__() - def __str__(self): - return 'Correspondence between %s and %s' % (self.objectFromInitial,self.objectFromTarget) + def __str__(self): + return 'Correspondence between %s and %s' % (self.objectFromInitial,self.objectFromTarget) - def distinguishingConceptMappings(self): - return [ m for m in self.conceptMappings if m.distinguishing() ] + def distinguishingConceptMappings(self): + return [ m for m in self.conceptMappings if m.distinguishing() ] - def relevantDistinguishingConceptMappings(self): - return [ m for m in self.conceptMappings if m.distinguishing() and m.relevant() ] + def relevantDistinguishingConceptMappings(self): + return [ m for m in self.conceptMappings if m.distinguishing() and m.relevant() ] - def extract_target_bond(self): - targetBond = False - if self.objectFromTarget.leftmost: - targetBond = self.objectFromTarget.rightBond - elif self.objectFromTarget.rightmost: - targetBond = self.objectFromTarget.leftBond - return targetBond + def extract_target_bond(self): + targetBond = False + if self.objectFromTarget.leftmost: + targetBond = self.objectFromTarget.rightBond + elif self.objectFromTarget.rightmost: + targetBond = self.objectFromTarget.leftBond + return targetBond - def extract_initial_bond(self): - initialBond = False - if self.objectFromInitial.leftmost: - initialBond = self.objectFromInitial.rightBond - elif self.objectFromInitial.rightmost: - initialBond = self.objectFromInitial.leftBond - return initialBond + def extract_initial_bond(self): + initialBond = False + if self.objectFromInitial.leftmost: + initialBond = self.objectFromInitial.rightBond + elif self.objectFromInitial.rightmost: + initialBond = self.objectFromInitial.leftBond + return initialBond - def getIncompatibleBond(self): - initialBond = self.extract_initial_bond() - if not initialBond: - return None - targetBond = self.extract_target_bond() - if not targetBond: - return None - from conceptMapping import ConceptMapping - from slipnet import slipnet - if initialBond.directionCategory and targetBond.directionCategory: - mapping = ConceptMapping( - slipnet.directionCategory, - slipnet.directionCategory, - initialBond.directionCategory, - targetBond.directionCategory, - None, - None - ) - for m in self.conceptMappings: - if m.incompatible(mapping): - return targetBond - return None + def getIncompatibleBond(self): + initialBond = self.extract_initial_bond() + if not initialBond: + return None + targetBond = self.extract_target_bond() + if not targetBond: + return None + from conceptMapping import ConceptMapping + from slipnet import slipnet + if initialBond.directionCategory and targetBond.directionCategory: + mapping = ConceptMapping( + slipnet.directionCategory, + slipnet.directionCategory, + initialBond.directionCategory, + targetBond.directionCategory, + None, + None + ) + for m in self.conceptMappings: + if m.incompatible(mapping): + return targetBond + return None - def getIncompatibleCorrespondences(self): - return [ o.correspondence for o in workspace.initial.objects if o and self.incompatible(o.correspondence) ] + def getIncompatibleCorrespondences(self): + return [ o.correspondence for o in workspace.initial.objects if o and self.incompatible(o.correspondence) ] - def incompatible(self,other): - if not other: - return False - if self.objectFromInitial == other.objectFromInitial: - return True - if self.objectFromTarget == other.objectFromTarget: - return True - for mapping in self.conceptMappings: - for otherMapping in other.conceptMappings: - if mapping.incompatible(otherMapping): - return True - return False + def incompatible(self,other): + if not other: + return False + if self.objectFromInitial == other.objectFromInitial: + return True + if self.objectFromTarget == other.objectFromTarget: + return True + for mapping in self.conceptMappings: + for otherMapping in other.conceptMappings: + if mapping.incompatible(otherMapping): + return True + return False - def supporting(self,other): - if self == other: - return False - if self.objectFromInitial == other.objectFromInitial: - return False - if self.objectFromTarget == other.objectFromTarget: - return False - if self.incompatible(other): - return False - for mapping in self.distinguishingConceptMappings(): - for otherMapping in other.distinguishingConceptMappings(): - if mapping.supports(otherMapping): - return True - return False + def supporting(self,other): + if self == other: + return False + if self.objectFromInitial == other.objectFromInitial: + return False + if self.objectFromTarget == other.objectFromTarget: + return False + if self.incompatible(other): + return False + for mapping in self.distinguishingConceptMappings(): + for otherMapping in other.distinguishingConceptMappings(): + if mapping.supports(otherMapping): + return True + return False - def support(self): - from letter import Letter - if isinstance(self.objectFromInitial,Letter) and self.objectFromInitial.spansString(): - return 100.0 - if isinstance(self.objectFromTarget,Letter) and self.objectFromTarget.spansString(): - return 100.0 - total = sum([ c.totalStrength for c in workspace.correspondences() if self.supporting(c) ]) - total = min(total,100.0) - return total + def support(self): + from letter import Letter + if isinstance(self.objectFromInitial,Letter) and self.objectFromInitial.spansString(): + return 100.0 + if isinstance(self.objectFromTarget,Letter) and self.objectFromTarget.spansString(): + return 100.0 + total = sum([ c.totalStrength for c in workspace.correspondences() if self.supporting(c) ]) + total = min(total,100.0) + return total - def updateInternalStrength(self): - """A function of how many conceptMappings there are, their strength and how well they cohere""" - relevantDistinguishingMappings = self.relevantDistinguishingConceptMappings() - numberOfConceptMappings = len(relevantDistinguishingMappings) - if numberOfConceptMappings < 1: - self.internalStrength = 0.0 - return - totalStrength = sum([ m.strength() for m in relevantDistinguishingMappings ]) - averageStrength = totalStrength / numberOfConceptMappings - if numberOfConceptMappings == 1.0: - numberOfConceptMappingsFactor = 0.8 - elif numberOfConceptMappings == 2.0: - numberOfConceptMappingsFactor = 1.2 - else: - numberOfConceptMappingsFactor = 1.6 - if self.internallyCoherent(): - internalCoherenceFactor = 2.5 - else: - internalCoherenceFactor = 1.0 - internalStrength = averageStrength * internalCoherenceFactor * numberOfConceptMappingsFactor - self.internalStrength = min(internalStrength,100.0) + def updateInternalStrength(self): + """A function of how many conceptMappings there are, their strength and how well they cohere""" + relevantDistinguishingMappings = self.relevantDistinguishingConceptMappings() + numberOfConceptMappings = len(relevantDistinguishingMappings) + if numberOfConceptMappings < 1: + self.internalStrength = 0.0 + return + totalStrength = sum([ m.strength() for m in relevantDistinguishingMappings ]) + averageStrength = totalStrength / numberOfConceptMappings + if numberOfConceptMappings == 1.0: + numberOfConceptMappingsFactor = 0.8 + elif numberOfConceptMappings == 2.0: + numberOfConceptMappingsFactor = 1.2 + else: + numberOfConceptMappingsFactor = 1.6 + if self.internallyCoherent(): + internalCoherenceFactor = 2.5 + else: + internalCoherenceFactor = 1.0 + internalStrength = averageStrength * internalCoherenceFactor * numberOfConceptMappingsFactor + self.internalStrength = min(internalStrength,100.0) - def updateExternalStrength(self): - self.externalStrength = self.support() + def updateExternalStrength(self): + self.externalStrength = self.support() - def internallyCoherent(self): - """Whether any pair of relevant distinguishing mappings support each other""" - mappings = self.relevantDistinguishingConceptMappings() - for i in range(0,len(mappings)): - for j in range(0,len(mappings)): - if i != j: - if mappings[i].supports(mappings[j]): - return True - return False + def internallyCoherent(self): + """Whether any pair of relevant distinguishing mappings support each other""" + mappings = self.relevantDistinguishingConceptMappings() + for i in range(0,len(mappings)): + for j in range(0,len(mappings)): + if i != j: + if mappings[i].supports(mappings[j]): + return True + return False - def slippages(self): - mappings = [ m for m in self.conceptMappings if m.slippage() ] - mappings += [ m for m in self.accessoryConceptMappings if m.slippage() ] - return mappings + def slippages(self): + mappings = [ m for m in self.conceptMappings if m.slippage() ] + mappings += [ m for m in self.accessoryConceptMappings if m.slippage() ] + return mappings - def reflexive(self): - if not self.objectFromInitial.correspondence: - return False - if self.objectFromInitial.correspondence.objectFromTarget == self.objectFromTarget: - return True - return False + def reflexive(self): + if not self.objectFromInitial.correspondence: + return False + if self.objectFromInitial.correspondence.objectFromTarget == self.objectFromTarget: + return True + return False - def buildCorrespondence(self): - workspace.structures += [ self ] - if self.objectFromInitial.correspondence: - self.objectFromInitial.correspondence.breakCorrespondence() - if self.objectFromTarget.correspondence: - self.objectFromTarget.correspondence.breakCorrespondence() - self.objectFromInitial.correspondence = self - self.objectFromTarget.correspondence = self - # add mappings to accessory-concept-mapping-list - relevantMappings = self.relevantDistinguishingConceptMappings() - for mapping in relevantMappings: - if mapping.slippage(): - self.accessoryConceptMappings += [ mapping.symmetricVersion() ] - from group import Group - if isinstance(self.objectFromInitial,Group) and isinstance(self.objectFromTarget,Group): - bondMappings = getMappings( - self.objectFromInitial, - self.objectFromTarget, - self.objectFromInitial.bondDescriptions, - self.objectFromTarget.bondDescriptions - ) - for mapping in bondMappings: - self.accessoryConceptMappings += [ mapping ] - if mapping.slippage(): - self.accessoryConceptMappings += [ mapping.symmetricVersion() ] - for mapping in self.conceptMappings: - if mapping.label: - mapping.label.activation = 100.0 + def buildCorrespondence(self): + workspace.structures += [ self ] + if self.objectFromInitial.correspondence: + self.objectFromInitial.correspondence.breakCorrespondence() + if self.objectFromTarget.correspondence: + self.objectFromTarget.correspondence.breakCorrespondence() + self.objectFromInitial.correspondence = self + self.objectFromTarget.correspondence = self + # add mappings to accessory-concept-mapping-list + relevantMappings = self.relevantDistinguishingConceptMappings() + for mapping in relevantMappings: + if mapping.slippage(): + self.accessoryConceptMappings += [ mapping.symmetricVersion() ] + from group import Group + if isinstance(self.objectFromInitial,Group) and isinstance(self.objectFromTarget,Group): + bondMappings = getMappings( + self.objectFromInitial, + self.objectFromTarget, + self.objectFromInitial.bondDescriptions, + self.objectFromTarget.bondDescriptions + ) + for mapping in bondMappings: + self.accessoryConceptMappings += [ mapping ] + if mapping.slippage(): + self.accessoryConceptMappings += [ mapping.symmetricVersion() ] + for mapping in self.conceptMappings: + if mapping.label: + mapping.label.activation = 100.0 - def break_the_structure(self): - self.breakCorrespondence() + def break_the_structure(self): + self.breakCorrespondence() - def breakCorrespondence(self): - workspace.structures.remove(self) - self.objectFromInitial.correspondence = None - self.objectFromTarget.correspondence = None + def breakCorrespondence(self): + workspace.structures.remove(self) + self.objectFromInitial.correspondence = None + self.objectFromTarget.correspondence = None diff --git a/copycat/description.py b/copycat/description.py index b8b30bf..879d0c1 100644 --- a/copycat/description.py +++ b/copycat/description.py @@ -2,55 +2,55 @@ import logging from workspaceStructure import WorkspaceStructure class Description(WorkspaceStructure): - def __init__(self,workspaceObject,descriptionType,descriptor): - WorkspaceStructure.__init__(self) - self.object = workspaceObject - self.string = workspaceObject.string - self.descriptionType = descriptionType - self.descriptor = descriptor + def __init__(self,workspaceObject,descriptionType,descriptor): + WorkspaceStructure.__init__(self) + self.object = workspaceObject + self.string = workspaceObject.string + self.descriptionType = descriptionType + self.descriptor = descriptor - def __repr__(self): - return '' % self.__str__() + def __repr__(self): + return '' % self.__str__() - def __str__(self): - s = 'description(%s) of %s' % (self.descriptor.get_name(),self.object) - from workspace import workspace - if self.object.string == workspace.initial: - s += ' in initial string' - else: - s += ' in target string' - return s + def __str__(self): + s = 'description(%s) of %s' % (self.descriptor.get_name(),self.object) + from workspace import workspace + if self.object.string == workspace.initial: + s += ' in initial string' + else: + s += ' in target string' + return s - def updateInternalStrength(self): - self.internalStrength = self.descriptor.conceptualDepth + def updateInternalStrength(self): + self.internalStrength = self.descriptor.conceptualDepth - def updateExternalStrength(self): - self.externalStrength = (self.localSupport() + self.descriptionType.activation) / 2 + def updateExternalStrength(self): + self.externalStrength = (self.localSupport() + self.descriptionType.activation) / 2 - def localSupport(self): - from workspace import workspace - supporters = 0 # number of objects in the string with a descriptionType like self - for other in workspace.otherObjects(self.object): - if not ( self.object.isWithin(other) or other.isWithin(self.object) ): - for description in other.descriptions: - if description.descriptionType == self.descriptionType: - supporters += 1 - results = { 0:0.0, 1:20.0, 2:60.0, 3:90.0 } - if supporters in results: - return results[supporters] - return 100.0 + def localSupport(self): + from workspace import workspace + supporters = 0 # number of objects in the string with a descriptionType like self + for other in workspace.otherObjects(self.object): + if not ( self.object.isWithin(other) or other.isWithin(self.object) ): + for description in other.descriptions: + if description.descriptionType == self.descriptionType: + supporters += 1 + results = { 0:0.0, 1:20.0, 2:60.0, 3:90.0 } + if supporters in results: + return results[supporters] + return 100.0 - def build(self): - self.descriptionType.buffer = 100.0 - self.descriptor.buffer = 100.0 - if not self.object.hasDescription(self.descriptor): - logging.info('Add %s to descriptions' % self) - self.object.descriptions += [ self ] + def build(self): + self.descriptionType.buffer = 100.0 + self.descriptor.buffer = 100.0 + if not self.object.hasDescription(self.descriptor): + logging.info('Add %s to descriptions' % self) + self.object.descriptions += [ self ] - def breakDescription(self): - from workspace import workspace - if self in workspace.structures: - workspace.structures.remove(self) - self.object.descriptions.remove(self) + def breakDescription(self): + from workspace import workspace + if self in workspace.structures: + workspace.structures.remove(self) + self.object.descriptions.remove(self) diff --git a/copycat/formulas.py b/copycat/formulas.py index 2ac26a2..8fe4789 100644 --- a/copycat/formulas.py +++ b/copycat/formulas.py @@ -8,139 +8,139 @@ from temperature import temperature actualTemperature = Temperature = 100.0 def selectListPosition(probabilities): - total = sum(probabilities) - #logging.info('total: %s' % total) - r = utils.random() - stopPosition = total * r - #logging.info('stopPosition: %s' % stopPosition) - total = 0 - index = 0 - for probability in probabilities: - total += probability - if total > stopPosition: - return index - index += 1 - return 0 + total = sum(probabilities) + #logging.info('total: %s' % total) + r = utils.random() + stopPosition = total * r + #logging.info('stopPosition: %s' % stopPosition) + total = 0 + index = 0 + for probability in probabilities: + total += probability + if total > stopPosition: + return index + index += 1 + return 0 def weightedAverage(values): - total = 0.0 - totalWeights = 0.0 - for value,weight in values: - total += value * weight - totalWeights += weight - if not totalWeights: - return 0.0 - return total / totalWeights + total = 0.0 + totalWeights = 0.0 + for value,weight in values: + total += value * weight + totalWeights += weight + if not totalWeights: + return 0.0 + return total / totalWeights def temperatureAdjustedValue(value): - #logging.info('Temperature: %s' % Temperature) - #logging.info('actualTemperature: %s' % actualTemperature) - return value ** (((100.0-Temperature)/30.0)+0.5) + #logging.info('Temperature: %s' % Temperature) + #logging.info('actualTemperature: %s' % actualTemperature) + return value ** (((100.0-Temperature)/30.0)+0.5) def temperatureAdjustedProbability(value): - if not value or value == 0.5 or not temperature.value: - return value - if value < 0.5: - return 1.0 - temperatureAdjustedProbability(1.0 - value) - coldness = 100.0 - temperature.value - a = math.sqrt(coldness) - b = 10.0 - a - c = b / 100 - d = c * ( 1.0 - ( 1.0 - value ) ) # aka c * value, but we're following the java - e = ( 1.0 - value ) + d - f = 1.0 - e - return max(f,0.5) + if not value or value == 0.5 or not temperature.value: + return value + if value < 0.5: + return 1.0 - temperatureAdjustedProbability(1.0 - value) + coldness = 100.0 - temperature.value + a = math.sqrt(coldness) + b = 10.0 - a + c = b / 100 + d = c * ( 1.0 - ( 1.0 - value ) ) # aka c * value, but we're following the java + e = ( 1.0 - value ) + d + f = 1.0 - e + return max(f,0.5) def coinFlip(chance=0.5): - return utils.random() < chance + return utils.random() < chance def blur(value): - root = math.sqrt(value) - if coinFlip(): - return value + root - return value - root + root = math.sqrt(value) + if coinFlip(): + return value + root + return value - root def chooseObjectFromList(objects,attribute): - if not objects: - return None - probabilities = [] - for object in objects: - value = getattr(object,attribute) - probability = temperatureAdjustedValue(value) - logging.info('Object: %s, value: %d, probability: %d' % (object,value,probability)) - probabilities += [ probability ] - index = selectListPosition(probabilities) - logging.info("Selected: %d" % index) - return objects[index] + if not objects: + return None + probabilities = [] + for object in objects: + value = getattr(object,attribute) + probability = temperatureAdjustedValue(value) + logging.info('Object: %s, value: %d, probability: %d' % (object,value,probability)) + probabilities += [ probability ] + index = selectListPosition(probabilities) + logging.info("Selected: %d" % index) + return objects[index] def chooseRelevantDescriptionByActivation(workspaceObject): - descriptions = workspaceObject.relevantDescriptions() - if not descriptions: - return None - activations = [ description.descriptor.activation for description in descriptions ] - index = selectListPosition(activations) - return descriptions[ index ] + descriptions = workspaceObject.relevantDescriptions() + if not descriptions: + return None + activations = [ description.descriptor.activation for description in descriptions ] + index = selectListPosition(activations) + return descriptions[ index ] def similarPropertyLinks(slip_node): - result = [] - for slip_link in slip_node.propertyLinks: - association = slip_link.degreeOfAssociation() / 100.0 - probability = temperatureAdjustedProbability( association ) - if coinFlip(probability): - result += [ slip_link ] - return result + result = [] + for slip_link in slip_node.propertyLinks: + association = slip_link.degreeOfAssociation() / 100.0 + probability = temperatureAdjustedProbability( association ) + if coinFlip(probability): + result += [ slip_link ] + return result def chooseSlipnodeByConceptualDepth(slip_nodes): - if not slip_nodes: - return None - depths = [ temperatureAdjustedValue(n.conceptualDepth) for n in slip_nodes ] - i = selectListPosition(depths) - return slip_nodes[ i ] + if not slip_nodes: + return None + depths = [ temperatureAdjustedValue(n.conceptualDepth) for n in slip_nodes ] + i = selectListPosition(depths) + return slip_nodes[ i ] def __relevantCategory(objekt,slipnode): - return objekt.rightBond and objekt.rightBond.category == slipnode + return objekt.rightBond and objekt.rightBond.category == slipnode def __relevantDirection(objekt,slipnode): - return objekt.rightBond and objekt.rightBond.directionCategory == slipnode + return objekt.rightBond and objekt.rightBond.directionCategory == slipnode def __localRelevance(string,slipnode,relevance): - numberOfObjectsNotSpanning = numberOfMatches = 0.0 - #logging.info("find relevance for a string: %s" % string); - for objekt in string.objects: - #logging.info('object: %s' % objekt) - if not objekt.spansString(): - #logging.info('non spanner: %s' % objekt) - numberOfObjectsNotSpanning += 1.0 - if relevance(objekt,slipnode): - numberOfMatches += 1.0 - #logging.info("matches: %d, not spanning: %d" % (numberOfMatches,numberOfObjectsNotSpanning)) - if numberOfObjectsNotSpanning == 1: - return 100.0 * numberOfMatches - return 100.0 * numberOfMatches / (numberOfObjectsNotSpanning - 1.0) + numberOfObjectsNotSpanning = numberOfMatches = 0.0 + #logging.info("find relevance for a string: %s" % string); + for objekt in string.objects: + #logging.info('object: %s' % objekt) + if not objekt.spansString(): + #logging.info('non spanner: %s' % objekt) + numberOfObjectsNotSpanning += 1.0 + if relevance(objekt,slipnode): + numberOfMatches += 1.0 + #logging.info("matches: %d, not spanning: %d" % (numberOfMatches,numberOfObjectsNotSpanning)) + if numberOfObjectsNotSpanning == 1: + return 100.0 * numberOfMatches + return 100.0 * numberOfMatches / (numberOfObjectsNotSpanning - 1.0) def localBondCategoryRelevance(string, category): - if len(string.objects) == 1: - return 0.0 - return __localRelevance(string,category,__relevantCategory) + if len(string.objects) == 1: + return 0.0 + return __localRelevance(string,category,__relevantCategory) def localDirectionCategoryRelevance(string, direction): - return __localRelevance(string,direction,__relevantDirection) + return __localRelevance(string,direction,__relevantDirection) def getMappings(objectFromInitial,objectFromTarget, initialDescriptions, targetDescriptions): - mappings = [] - from conceptMapping import ConceptMapping - for initialDescription in initialDescriptions: - for targetDescription in targetDescriptions: - if initialDescription.descriptionType == targetDescription.descriptionType: - if initialDescription.descriptor == targetDescription.descriptor or initialDescription.descriptor.slipLinked(targetDescription.descriptor): - mapping = ConceptMapping( - initialDescription.descriptionType, - targetDescription.descriptionType, - initialDescription.descriptor, - targetDescription.descriptor, - objectFromInitial, - objectFromTarget - ) - mappings += [ mapping ] - return mappings + mappings = [] + from conceptMapping import ConceptMapping + for initialDescription in initialDescriptions: + for targetDescription in targetDescriptions: + if initialDescription.descriptionType == targetDescription.descriptionType: + if initialDescription.descriptor == targetDescription.descriptor or initialDescription.descriptor.slipLinked(targetDescription.descriptor): + mapping = ConceptMapping( + initialDescription.descriptionType, + targetDescription.descriptionType, + initialDescription.descriptor, + targetDescription.descriptor, + objectFromInitial, + objectFromTarget + ) + mappings += [ mapping ] + return mappings diff --git a/copycat/group.py b/copycat/group.py index 9244866..98dc071 100644 --- a/copycat/group.py +++ b/copycat/group.py @@ -6,232 +6,232 @@ from slipnet import slipnet import formulas class Group(WorkspaceObject): - def __init__(self,string,groupCategory,directionCategory,facet,objectList,bondList): - WorkspaceObject.__init__(self,string) - self.groupCategory = groupCategory - self.directionCategory = directionCategory - self.facet = facet - self.objectList = objectList - self.bondList = bondList - self.bondCategory = self.groupCategory.getRelatedNode(slipnet.bondCategory) + def __init__(self,string,groupCategory,directionCategory,facet,objectList,bondList): + WorkspaceObject.__init__(self,string) + self.groupCategory = groupCategory + self.directionCategory = directionCategory + self.facet = facet + self.objectList = objectList + self.bondList = bondList + self.bondCategory = self.groupCategory.getRelatedNode(slipnet.bondCategory) - leftObject = objectList[0] - rightObject = objectList[-1] - self.leftStringPosition = leftObject.leftStringPosition - self.leftmost = self.leftStringPosition == 1 - self.rightStringPosition = rightObject.rightStringPosition - self.rightmost = self.rightStringPosition == len(self.string) + leftObject = objectList[0] + rightObject = objectList[-1] + self.leftStringPosition = leftObject.leftStringPosition + self.leftmost = self.leftStringPosition == 1 + self.rightStringPosition = rightObject.rightStringPosition + self.rightmost = self.rightStringPosition == len(self.string) - self.descriptions = [] - self.bondDescriptions = [] - self.extrinsicDescriptions = [] - self.outgoingBonds = [] - self.incomingBonds = [] - self.bonds = [] - self.leftBond = None - self.rightBond = None - self.correspondence = None - self.changed = False - self.newAnswerLetter = False - self.clampSalience = False - self.name = '' + self.descriptions = [] + self.bondDescriptions = [] + self.extrinsicDescriptions = [] + self.outgoingBonds = [] + self.incomingBonds = [] + self.bonds = [] + self.leftBond = None + self.rightBond = None + self.correspondence = None + self.changed = False + self.newAnswerLetter = False + self.clampSalience = False + self.name = '' - from description import Description - if self.bondList and len(self.bondList): - firstFacet = self.bondList[0].facet - self.addBondDescription(Description(self, slipnet.bondFacet, firstFacet)) - self.addBondDescription(Description(self, slipnet.bondCategory, self.bondCategory)) + from description import Description + if self.bondList and len(self.bondList): + firstFacet = self.bondList[0].facet + self.addBondDescription(Description(self, slipnet.bondFacet, firstFacet)) + self.addBondDescription(Description(self, slipnet.bondCategory, self.bondCategory)) - self.addDescription(slipnet.objectCategory, slipnet.group) - self.addDescription(slipnet.groupCategory, self.groupCategory) - if not self.directionCategory: - # sameness group - find letterCategory - letter = self.objectList[0].getDescriptor(self.facet) - self.addDescription(self.facet, letter) - if self.directionCategory: - self.addDescription(slipnet.directionCategory, self.directionCategory) - if self.spansString(): - self.addDescription(slipnet.stringPositionCategory, slipnet.whole) - elif self.leftStringPosition == 1: - self.addDescription(slipnet.stringPositionCategory, slipnet.leftmost) - elif self.rightStringPosition == self.string.length: - self.addDescription(slipnet.stringPositionCategory, slipnet.rightmost) - elif self.middleObject(): - self.addDescription(slipnet.stringPositionCategory, slipnet.middle) + self.addDescription(slipnet.objectCategory, slipnet.group) + self.addDescription(slipnet.groupCategory, self.groupCategory) + if not self.directionCategory: + # sameness group - find letterCategory + letter = self.objectList[0].getDescriptor(self.facet) + self.addDescription(self.facet, letter) + if self.directionCategory: + self.addDescription(slipnet.directionCategory, self.directionCategory) + if self.spansString(): + self.addDescription(slipnet.stringPositionCategory, slipnet.whole) + elif self.leftStringPosition == 1: + self.addDescription(slipnet.stringPositionCategory, slipnet.leftmost) + elif self.rightStringPosition == self.string.length: + self.addDescription(slipnet.stringPositionCategory, slipnet.rightmost) + elif self.middleObject(): + self.addDescription(slipnet.stringPositionCategory, slipnet.middle) - #check whether or not to add length description category - probability = self.lengthDescriptionProbability() - if utils.random() < probability: - length = len(self.objectList) - if length < 6: - self.addDescription(slipnet.length, slipnet.numbers[length - 1]) + #check whether or not to add length description category + probability = self.lengthDescriptionProbability() + if utils.random() < probability: + length = len(self.objectList) + if length < 6: + self.addDescription(slipnet.length, slipnet.numbers[length - 1]) - def __str__(self): - s = self.string.__str__() - l = self.leftStringPosition - 1 - r = self.rightStringPosition - return 'group[%d:%d] == %s' % ( l, r - 1, s[l: r ]) + def __str__(self): + s = self.string.__str__() + l = self.leftStringPosition - 1 + r = self.rightStringPosition + return 'group[%d:%d] == %s' % ( l, r - 1, s[l: r ]) - def getIncompatibleGroups(self): - result = [] - for objekt in self.objectList: - while objekt.group: - result += [ objekt.group ] - objekt = objekt.group - return result + def getIncompatibleGroups(self): + result = [] + for objekt in self.objectList: + while objekt.group: + result += [ objekt.group ] + objekt = objekt.group + return result - def addBondDescription(self,description): - self.bondDescriptions += [ description ] + def addBondDescription(self,description): + self.bondDescriptions += [ description ] - def singleLetterGroupProbability(self): - numberOfSupporters = self.numberOfLocalSupportingGroups() - if not numberOfSupporters: - return 0.0 - if numberOfSupporters == 1: - exp = 4.0 - elif numberOfSupporters == 2: - exp = 2.0 - else: - exp = 1.0 - support = self.localSupport() / 100.0 - activation = slipnet.length.activation / 100.0 - supportedActivation = (support * activation) ** exp - return formulas.temperatureAdjustedProbability(supportedActivation) + def singleLetterGroupProbability(self): + numberOfSupporters = self.numberOfLocalSupportingGroups() + if not numberOfSupporters: + return 0.0 + if numberOfSupporters == 1: + exp = 4.0 + elif numberOfSupporters == 2: + exp = 2.0 + else: + exp = 1.0 + support = self.localSupport() / 100.0 + activation = slipnet.length.activation / 100.0 + supportedActivation = (support * activation) ** exp + return formulas.temperatureAdjustedProbability(supportedActivation) - def flippedVersion(self): - flippedBonds = [ b.flippedversion() for b in self.bondList ] - flippedGroup = self.groupCategory.getRelatedNode(slipnet.flipped) - flippedDirection = self.directionCategory.getRelatedNode(slipnet.flipped) - return Group(self.string, flippedGroup, flippedDirection, self.facet, self.objectList, flippedBonds) + def flippedVersion(self): + flippedBonds = [ b.flippedversion() for b in self.bondList ] + flippedGroup = self.groupCategory.getRelatedNode(slipnet.flipped) + flippedDirection = self.directionCategory.getRelatedNode(slipnet.flipped) + return Group(self.string, flippedGroup, flippedDirection, self.facet, self.objectList, flippedBonds) - def buildGroup(self): - workspace.objects += [ self ] - workspace.structures += [ self ] - self.string.objects += [ self ] - for objekt in self.objectList: - objekt.group = self - workspace.buildDescriptions(self) - self.activateDescriptions() + def buildGroup(self): + workspace.objects += [ self ] + workspace.structures += [ self ] + self.string.objects += [ self ] + for objekt in self.objectList: + objekt.group = self + workspace.buildDescriptions(self) + self.activateDescriptions() - def activateDescriptions(self): - for description in self.descriptions: - logging.info('Activate: %s' % description) - description.descriptor.buffer = 100.0 + def activateDescriptions(self): + for description in self.descriptions: + logging.info('Activate: %s' % description) + description.descriptor.buffer = 100.0 - def lengthDescriptionProbability(self): - length = len(self.objectList) - if length > 5: - return 0.0 - cubedlength = length ** 3 - fred = cubedlength * (100.0 - slipnet.length.activation) / 100.0 - probability = 0.5 ** fred - value = formulas.temperatureAdjustedProbability(probability) - if value < 0.06: - value = 0.0 # otherwise 1/20 chance always - return value + def lengthDescriptionProbability(self): + length = len(self.objectList) + if length > 5: + return 0.0 + cubedlength = length ** 3 + fred = cubedlength * (100.0 - slipnet.length.activation) / 100.0 + probability = 0.5 ** fred + value = formulas.temperatureAdjustedProbability(probability) + if value < 0.06: + value = 0.0 # otherwise 1/20 chance always + return value - def break_the_structure(self): - self.breakGroup() + def break_the_structure(self): + self.breakGroup() - def breakGroup(self): - while len(self.descriptions): - description = self.descriptions[-1] - description.breakDescription() - for objekt in self.objectList: - objekt.group = None - if self.group: - self.group.breakGroup() - if self in workspace.structures: - workspace.structures.remove(self) - if self in workspace.objects: - workspace.objects.remove(self) - if self in self.string.objects: - self.string.objects.remove(self) - if self.correspondence: - self.correspondence.breakCorrespondence() - if self.leftBond: - self.leftBond.breakBond() - if self.rightBond: - self.rightBond.breakBond() + def breakGroup(self): + while len(self.descriptions): + description = self.descriptions[-1] + description.breakDescription() + for objekt in self.objectList: + objekt.group = None + if self.group: + self.group.breakGroup() + if self in workspace.structures: + workspace.structures.remove(self) + if self in workspace.objects: + workspace.objects.remove(self) + if self in self.string.objects: + self.string.objects.remove(self) + if self.correspondence: + self.correspondence.breakCorrespondence() + if self.leftBond: + self.leftBond.breakBond() + if self.rightBond: + self.rightBond.breakBond() - def updateInternalStrength(self): - relatedBondAssociation = self.groupCategory.getRelatedNode(slipnet.bondCategory).degreeOfAssociation() - bondWeight = relatedBondAssociation ** 0.98 - length = len(self.objectList) - if length == 1: - lengthFactor = 5.0 - elif length == 2: - lengthFactor = 20.0 - elif length == 3: - lengthFactor = 60.0 - else: - lengthFactor = 90.0 - lengthWeight = 100.0 - bondWeight - weightList = ( (relatedBondAssociation, bondWeight), (lengthFactor, lengthWeight) ) - self.internalStrength = formulas.weightedAverage(weightList) + def updateInternalStrength(self): + relatedBondAssociation = self.groupCategory.getRelatedNode(slipnet.bondCategory).degreeOfAssociation() + bondWeight = relatedBondAssociation ** 0.98 + length = len(self.objectList) + if length == 1: + lengthFactor = 5.0 + elif length == 2: + lengthFactor = 20.0 + elif length == 3: + lengthFactor = 60.0 + else: + lengthFactor = 90.0 + lengthWeight = 100.0 - bondWeight + weightList = ( (relatedBondAssociation, bondWeight), (lengthFactor, lengthWeight) ) + self.internalStrength = formulas.weightedAverage(weightList) - def updateExternalStrength(self): - if self.spansString(): - self.externalStrength = 100.0 - else: - self.externalStrength = self.localSupport() + def updateExternalStrength(self): + if self.spansString(): + self.externalStrength = 100.0 + else: + self.externalStrength = self.localSupport() - def localSupport(self): - numberOfSupporters = self.numberOfLocalSupportingGroups() - if numberOfSupporters == 0.0: - return 0.0 - supportFactor = min(1.0,0.6 ** (1 / (numberOfSupporters ** 3 ))) - densityFactor = 100.0 * ((self.localDensity() / 100.0) ** 0.5) - return densityFactor * supportFactor + def localSupport(self): + numberOfSupporters = self.numberOfLocalSupportingGroups() + if numberOfSupporters == 0.0: + return 0.0 + supportFactor = min(1.0,0.6 ** (1 / (numberOfSupporters ** 3 ))) + densityFactor = 100.0 * ((self.localDensity() / 100.0) ** 0.5) + return densityFactor * supportFactor - def numberOfLocalSupportingGroups(self): - count = 0 - for objekt in self.string.objects: - if isinstance(objekt,Group): - if objekt.rightStringPosition < self.leftStringPosition or objekt.leftStringPosition > self.rightStringPosition: - if objekt.groupCategory == self.groupCategory and objekt.directionCategory == self.directionCategory: - count += 1 - return count + def numberOfLocalSupportingGroups(self): + count = 0 + for objekt in self.string.objects: + if isinstance(objekt,Group): + if objekt.rightStringPosition < self.leftStringPosition or objekt.leftStringPosition > self.rightStringPosition: + if objekt.groupCategory == self.groupCategory and objekt.directionCategory == self.directionCategory: + count += 1 + return count - def localDensity(self): - numberOfSupporters = self.numberOfLocalSupportingGroups() - halfLength = len(self.string) / 2.0 - return 100.0 * numberOfSupporters / halfLength + def localDensity(self): + numberOfSupporters = self.numberOfLocalSupportingGroups() + halfLength = len(self.string) / 2.0 + return 100.0 * numberOfSupporters / halfLength - def sameGroup(self,other): - if self.leftStringPosition != other.leftStringPosition: - return False - if self.rightStringPosition != other.rightStringPosition: - return False - if self.groupCategory != other.groupCategory: - return False - if self.directionCategory != other.directionCategory: - return False - if self.facet != other.facet: - return False - return True + def sameGroup(self,other): + if self.leftStringPosition != other.leftStringPosition: + return False + if self.rightStringPosition != other.rightStringPosition: + return False + if self.groupCategory != other.groupCategory: + return False + if self.directionCategory != other.directionCategory: + return False + if self.facet != other.facet: + return False + return True - def morePossibleDescriptions(self,node): - result = [] - i = 1 - for number in slipnet.numbers: - if node == number and len(self.objects) == i: - result += [ node ] - i += 1 - return result + def morePossibleDescriptions(self,node): + result = [] + i = 1 + for number in slipnet.numbers: + if node == number and len(self.objects) == i: + result += [ node ] + i += 1 + return result - def distinguishingDescriptor(self,descriptor): - """Whether no other object of the same type (group) has the same descriptor""" - if not WorkspaceObject.distinguishingDescriptor(self,descriptor): - return False - for objekt in self.string.objects: - # check to see if they are of the same type - if isinstance(objekt,Group) and objekt != self: - # check all descriptions for the descriptor - for description in objekt.descriptions: - if description.descriptor == descriptor: - return False - return True + def distinguishingDescriptor(self,descriptor): + """Whether no other object of the same type (group) has the same descriptor""" + if not WorkspaceObject.distinguishingDescriptor(self,descriptor): + return False + for objekt in self.string.objects: + # check to see if they are of the same type + if isinstance(objekt,Group) and objekt != self: + # check all descriptions for the descriptor + for description in objekt.descriptions: + if description.descriptor == descriptor: + return False + return True diff --git a/copycat/grouprun.py b/copycat/grouprun.py index a7f5395..df4e554 100644 --- a/copycat/grouprun.py +++ b/copycat/grouprun.py @@ -1,14 +1,14 @@ from workspace import workspace class GroupRun(object): - def __init__(self): - self.name = 'xxx' - self.maximumNumberOfRuns = 1000 - self.runStrings = [] - self.answers = [] - self.scores = [0] * 100 - self.initial = workspace.initial - self.modified = workspace.modified - self.target = workspace.target + def __init__(self): + self.name = 'xxx' + self.maximumNumberOfRuns = 1000 + self.runStrings = [] + self.answers = [] + self.scores = [0] * 100 + self.initial = workspace.initial + self.modified = workspace.modified + self.target = workspace.target groupRun = GroupRun() diff --git a/copycat/letter.py b/copycat/letter.py index 55d8898..8dd91e4 100644 --- a/copycat/letter.py +++ b/copycat/letter.py @@ -2,47 +2,47 @@ from workspaceObject import WorkspaceObject from slipnet import slipnet class Letter(WorkspaceObject): - def __init__(self,string,position,length): - WorkspaceObject.__init__(self,string) - from workspace import workspace - workspace.objects += [ self ] - string.objects += [self ] - self.leftStringPosition = position - self.leftmost = self.leftStringPosition == 1 - self.rightStringPosition = position - self.rightmost = self.rightStringPosition == length + def __init__(self,string,position,length): + WorkspaceObject.__init__(self,string) + from workspace import workspace + workspace.objects += [ self ] + string.objects += [self ] + self.leftStringPosition = position + self.leftmost = self.leftStringPosition == 1 + self.rightStringPosition = position + self.rightmost = self.rightStringPosition == length - def describe(self,position,length): - if length == 1: - self.addDescription(slipnet.stringPositionCategory,slipnet.single) - if self.leftmost and length > 1: # ? why check length ? - self.addDescription(slipnet.stringPositionCategory,slipnet.leftmost) - if self.rightmost and length > 1: # ? why check length ? - self.addDescription(slipnet.stringPositionCategory,slipnet.rightmost) - if length > 2 and position * 2 == length + 1: - self.addDescription(slipnet.stringPositionCategory,slipnet.middle) + def describe(self,position,length): + if length == 1: + self.addDescription(slipnet.stringPositionCategory,slipnet.single) + if self.leftmost and length > 1: # ? why check length ? + self.addDescription(slipnet.stringPositionCategory,slipnet.leftmost) + if self.rightmost and length > 1: # ? why check length ? + self.addDescription(slipnet.stringPositionCategory,slipnet.rightmost) + if length > 2 and position * 2 == length + 1: + self.addDescription(slipnet.stringPositionCategory,slipnet.middle) - def __repr__(self): - return '' % self.__str__() + def __repr__(self): + return '' % self.__str__() - def __str__(self): - if not self.string: - return '' - i = self.leftStringPosition - 1 - if len(self.string) <= i: - raise ValueError, 'len(self.string) <= self.leftStringPosition :: %d <= %d' % (len(self.string),self.leftStringPosition) - return self.string[ i ] + def __str__(self): + if not self.string: + return '' + i = self.leftStringPosition - 1 + if len(self.string) <= i: + raise ValueError, 'len(self.string) <= self.leftStringPosition :: %d <= %d' % (len(self.string),self.leftStringPosition) + return self.string[ i ] - def distinguishingDescriptor(self,descriptor): - """Whether no other object of the same type (letter) has the same descriptor""" - if not WorkspaceObject.distinguishingDescriptor(self,descriptor): - return False - for objekt in self.string.objects: - # check to see if they are of the same type - if isinstance(objekt,Letter) and objekt != self: - # check all descriptions for the descriptor - for description in objekt.descriptions: - if description.descriptor == descriptor: - return False - return True + def distinguishingDescriptor(self,descriptor): + """Whether no other object of the same type (letter) has the same descriptor""" + if not WorkspaceObject.distinguishingDescriptor(self,descriptor): + return False + for objekt in self.string.objects: + # check to see if they are of the same type + if isinstance(objekt,Letter) and objekt != self: + # check all descriptions for the descriptor + for description in objekt.descriptions: + if description.descriptor == descriptor: + return False + return True diff --git a/copycat/main.py b/copycat/main.py index fe38ebe..034c398 100644 --- a/copycat/main.py +++ b/copycat/main.py @@ -7,15 +7,15 @@ import copycat def main(program, args): - """Run the program""" - try: - initial, modified, target = args - copycat.run(initial, modified, target) - return 0 - except ValueError: - print >> sys.stderr, 'Usage: %s initial modified target' % program - return 1 + """Run the program""" + try: + initial, modified, target = args + copycat.run(initial, modified, target) + return 0 + except ValueError: + print >> sys.stderr, 'Usage: %s initial modified target' % program + return 1 if __name__ == '__main__': - sys.exit(main(sys.argv[0], sys.argv[1:])) + sys.exit(main(sys.argv[0], sys.argv[1:])) diff --git a/copycat/replacement.py b/copycat/replacement.py index ea65a75..a06ca45 100644 --- a/copycat/replacement.py +++ b/copycat/replacement.py @@ -1,9 +1,9 @@ from workspaceStructure import WorkspaceStructure class Replacement(WorkspaceStructure): - def __init__(self, objectFromInitial, objectFromModified, relation): - WorkspaceStructure.__init__(self) - self.objectFromInitial = objectFromInitial - self.objectFromModified = objectFromModified - self.relation = relation + def __init__(self, objectFromInitial, objectFromModified, relation): + WorkspaceStructure.__init__(self) + self.objectFromInitial = objectFromInitial + self.objectFromModified = objectFromModified + self.relation = relation diff --git a/copycat/rule.py b/copycat/rule.py index 8eca725..c9ea5c4 100644 --- a/copycat/rule.py +++ b/copycat/rule.py @@ -4,131 +4,131 @@ from workspaceStructure import WorkspaceStructure from formulas import * class Rule(WorkspaceStructure): - def __init__(self,facet,descriptor,category,relation): - WorkspaceStructure.__init__(self) - self.facet = facet - self.descriptor = descriptor - self.category = category - self.relation = relation + def __init__(self,facet,descriptor,category,relation): + WorkspaceStructure.__init__(self) + self.facet = facet + self.descriptor = descriptor + self.category = category + self.relation = relation - def __str__(self): - if not self.facet: - return 'Empty rule' - return 'replace %s of %s %s by %s' % (self.facet.name, self.descriptor.name, self.category.name, self.relation.name) + def __str__(self): + if not self.facet: + return 'Empty rule' + return 'replace %s of %s %s by %s' % (self.facet.name, self.descriptor.name, self.category.name, self.relation.name) - def updateExternalStrength(self): - self.externalStrength = self.internalStrength + def updateExternalStrength(self): + self.externalStrength = self.internalStrength - def updateInternalStrength(self): - if not ( self.descriptor and self.relation ): - self.internalStrength = 0.0 - return - averageDepth = ( self.descriptor.conceptualDepth + self.relation.conceptualDepth ) / 2.0 - averageDepth **= 1.1 - # see if the object corresponds to an object - # if so, see if the descriptor is present (modulo slippages) in the - # corresponding object - changedObjects = [ o for o in workspace.initial.objects if o.changed ] - changed = changedObjects[0] - sharedDescriptorTerm = 0.0 - if changed and changed.correspondence: - targetObject = changed.correspondence.objectFromTarget - slippages = workspace.slippages() - slipnode = self.descriptor.applySlippages(slippages) - if not targetObject.hasDescription(slipnode): - self.internalStrength = 0.0 - return - sharedDescriptorTerm = 100.0 - sharedDescriptorWeight = ((100.0 - self.descriptor.conceptualDepth) / 10.0) ** 1.4 - depthDifference = 100.0 - abs(self.descriptor.conceptualDepth - self.relation.conceptualDepth) - weights = ( (depthDifference,12), (averageDepth,18), (sharedDescriptorTerm,sharedDescriptorWeight) ) - self.internalStrength = weightedAverage( weights ) - if self.internalStrength > 100.0: - self.internalStrength = 100.0 + def updateInternalStrength(self): + if not ( self.descriptor and self.relation ): + self.internalStrength = 0.0 + return + averageDepth = ( self.descriptor.conceptualDepth + self.relation.conceptualDepth ) / 2.0 + averageDepth **= 1.1 + # see if the object corresponds to an object + # if so, see if the descriptor is present (modulo slippages) in the + # corresponding object + changedObjects = [ o for o in workspace.initial.objects if o.changed ] + changed = changedObjects[0] + sharedDescriptorTerm = 0.0 + if changed and changed.correspondence: + targetObject = changed.correspondence.objectFromTarget + slippages = workspace.slippages() + slipnode = self.descriptor.applySlippages(slippages) + if not targetObject.hasDescription(slipnode): + self.internalStrength = 0.0 + return + sharedDescriptorTerm = 100.0 + sharedDescriptorWeight = ((100.0 - self.descriptor.conceptualDepth) / 10.0) ** 1.4 + depthDifference = 100.0 - abs(self.descriptor.conceptualDepth - self.relation.conceptualDepth) + weights = ( (depthDifference,12), (averageDepth,18), (sharedDescriptorTerm,sharedDescriptorWeight) ) + self.internalStrength = weightedAverage( weights ) + if self.internalStrength > 100.0: + self.internalStrength = 100.0 - def ruleEqual(self,other): - if not other: - return False - if self.relation != other.relation: - return False - if self.facet != other.facet: - return False - if self.category != other.category: - return False - if self.descriptor != other.descriptor: - return False - return True + def ruleEqual(self,other): + if not other: + return False + if self.relation != other.relation: + return False + if self.facet != other.facet: + return False + if self.category != other.category: + return False + if self.descriptor != other.descriptor: + return False + return True - def activateRuleDescriptions(self): - if self.relation: - self.relation.buffer = 100.0 - if self.facet: - self.facet.buffer = 100.0 - if self.category: - self.category.buffer = 100.0 - if self.descriptor: - self.descriptor.buffer = 100.0 + def activateRuleDescriptions(self): + if self.relation: + self.relation.buffer = 100.0 + if self.facet: + self.facet.buffer = 100.0 + if self.category: + self.category.buffer = 100.0 + if self.descriptor: + self.descriptor.buffer = 100.0 - def incompatibleRuleCorrespondence(self, correspondence): - if not correspondence: - return False - # find changed object - changeds = [ o for o in workspace.initial.objects if o.changed ] - if not changeds: - return False - changed = changeds[0] - if correspondence.objectFromInitial != changed: - return False - # it is incompatible if the rule descriptor is not in the mapping list - if len([ m for m in correspondence.conceptMappings if m.initialDescriptor == self.descriptor ]): - return False - return True + def incompatibleRuleCorrespondence(self, correspondence): + if not correspondence: + return False + # find changed object + changeds = [ o for o in workspace.initial.objects if o.changed ] + if not changeds: + return False + changed = changeds[0] + if correspondence.objectFromInitial != changed: + return False + # it is incompatible if the rule descriptor is not in the mapping list + if len([ m for m in correspondence.conceptMappings if m.initialDescriptor == self.descriptor ]): + return False + return True - def __changeString(self,string): - # applies the changes to self string ie. successor - if self.facet == slipnet.length: - if self.relation == slipnet.predecessor: - return string[0:-1] - if self.relation == slipnet.successor: - return string + string[0:1] - return string - # apply character changes - if self.relation == slipnet.predecessor: - if 'a' in string: - return None - return ''.join([ chr(ord(c) - 1) for c in string]) - elif self.relation == slipnet.successor: - if 'z' in string: - return None - return ''.join([ chr(ord(c) + 1) for c in string]) - else: - return self.relation.name.lower() + def __changeString(self,string): + # applies the changes to self string ie. successor + if self.facet == slipnet.length: + if self.relation == slipnet.predecessor: + return string[0:-1] + if self.relation == slipnet.successor: + return string + string[0:1] + return string + # apply character changes + if self.relation == slipnet.predecessor: + if 'a' in string: + return None + return ''.join([ chr(ord(c) - 1) for c in string]) + elif self.relation == slipnet.successor: + if 'z' in string: + return None + return ''.join([ chr(ord(c) + 1) for c in string]) + else: + return self.relation.name.lower() - def buildTranslatedRule(self): - slippages = workspace.slippages() - self.category = self.category.applySlippages(slippages) - self.facet = self.facet.applySlippages(slippages) - self.descriptor = self.descriptor.applySlippages(slippages) - self.relation = self.relation.applySlippages(slippages) - # generate the final string - self.finalAnswer = workspace.targetString - changeds = [ o for o in workspace.target.objects if - o.hasDescription(self.descriptor) and - o.hasDescription(self.category) ] - changed = changeds and changeds[0] or None - logging.debug('changed object = %s' % changed) - if changed: - left = changed.leftStringPosition - startString = '' - if left > 1: - startString = self.finalAnswer[0: left - 1] - right = changed.rightStringPosition - middleString = self.__changeString(self.finalAnswer[left - 1: right]) - if not middleString: - return False - endString = '' - if right < len(self.finalAnswer): - endString = self.finalAnswer[right:] - self.finalAnswer = startString + middleString + endString - return True + def buildTranslatedRule(self): + slippages = workspace.slippages() + self.category = self.category.applySlippages(slippages) + self.facet = self.facet.applySlippages(slippages) + self.descriptor = self.descriptor.applySlippages(slippages) + self.relation = self.relation.applySlippages(slippages) + # generate the final string + self.finalAnswer = workspace.targetString + changeds = [ o for o in workspace.target.objects if + o.hasDescription(self.descriptor) and + o.hasDescription(self.category) ] + changed = changeds and changeds[0] or None + logging.debug('changed object = %s' % changed) + if changed: + left = changed.leftStringPosition + startString = '' + if left > 1: + startString = self.finalAnswer[0: left - 1] + right = changed.rightStringPosition + middleString = self.__changeString(self.finalAnswer[left - 1: right]) + if not middleString: + return False + endString = '' + if right < len(self.finalAnswer): + endString = self.finalAnswer[right:] + self.finalAnswer = startString + middleString + endString + return True diff --git a/copycat/sliplink.py b/copycat/sliplink.py index 81a5afa..fa08802 100644 --- a/copycat/sliplink.py +++ b/copycat/sliplink.py @@ -1,28 +1,28 @@ #from slipnode import Slipnode class Sliplink(object): - def __init__(self, source, destination, label=None, length=0.0): - self.source = source - self.destination = destination - self.label = label - self.fixedLength = length - source.outgoingLinks += [self] - destination.incomingLinks += [self] + def __init__(self, source, destination, label=None, length=0.0): + self.source = source + self.destination = destination + self.label = label + self.fixedLength = length + source.outgoingLinks += [self] + destination.incomingLinks += [self] - def degreeOfAssociation(self): - if self.fixedLength > 0 or not self.label: - return 100.0 - self.fixedLength - return self.label.degreeOfAssociation() + def degreeOfAssociation(self): + if self.fixedLength > 0 or not self.label: + return 100.0 - self.fixedLength + return self.label.degreeOfAssociation() - def intrinsicDegreeOfAssociation(self): - if self.fixedLength > 1: - return 100.0 - self.fixedLength - if self.label: - return 100.0 - self.label.intrinsicLinkLength - return 0.0 + def intrinsicDegreeOfAssociation(self): + if self.fixedLength > 1: + return 100.0 - self.fixedLength + if self.label: + return 100.0 - self.label.intrinsicLinkLength + return 0.0 - def spread_activation(self): - self.destination.buffer += self.intrinsicDegreeOfAssociation() + def spread_activation(self): + self.destination.buffer += self.intrinsicDegreeOfAssociation() - def points_at(self, other): - return self.destination == other \ No newline at end of file + def points_at(self, other): + return self.destination == other \ No newline at end of file diff --git a/copycat/slipnet.py b/copycat/slipnet.py index 4c9b348..b8710fb 100644 --- a/copycat/slipnet.py +++ b/copycat/slipnet.py @@ -4,249 +4,249 @@ from slipnode import Slipnode from sliplink import Sliplink class SlipNet(object): - def __init__(self): - logging.debug("SlipNet.__init__()") - self.initiallyClampedSlipnodes = [] - self.slipnodes = [] - self.sliplinks = [] - self.bondFacets = [] - self.timeStepLength = 15 - self.numberOfUpdates = 0 - self.__addInitialNodes() - self.__addInitialLinks() - self.predecessor = None + def __init__(self): + logging.debug("SlipNet.__init__()") + self.initiallyClampedSlipnodes = [] + self.slipnodes = [] + self.sliplinks = [] + self.bondFacets = [] + self.timeStepLength = 15 + self.numberOfUpdates = 0 + self.__addInitialNodes() + self.__addInitialLinks() + self.predecessor = None - def __repr__(self): - return '' + def __repr__(self): + return '' - def setConceptualDepths(self, depth): - logging.debug('slipnet set all depths to %f' % depth) - [node.setConceptualDepth(depth) for node in self.slipnodes] + def setConceptualDepths(self, depth): + logging.debug('slipnet set all depths to %f' % depth) + [node.setConceptualDepth(depth) for node in self.slipnodes] - def reset(self): - logging.debug('slipnet.reset()') - self.numberOfUpdates = 0 - for node in self.slipnodes: - node.reset() - if node in self.initiallyClampedSlipnodes: - node.clampHigh() + def reset(self): + logging.debug('slipnet.reset()') + self.numberOfUpdates = 0 + for node in self.slipnodes: + node.reset() + if node in self.initiallyClampedSlipnodes: + node.clampHigh() - def update(self): - logging.debug('slipnet.update()') - self.numberOfUpdates += 1 - if self.numberOfUpdates == 50: - [node.unclamp() for node in self.initiallyClampedSlipnodes] - [node.update() for node in self.slipnodes] - # Note - spreadActivation() affects more than one node, so the following - # cannot go in a general "for node" loop with the other node actions - for node in self.slipnodes: - node.spread_activation() - for node in self.slipnodes: - node.addBuffer() - node.jump() - node.buffer = 0.0 + def update(self): + logging.debug('slipnet.update()') + self.numberOfUpdates += 1 + if self.numberOfUpdates == 50: + [node.unclamp() for node in self.initiallyClampedSlipnodes] + [node.update() for node in self.slipnodes] + # Note - spreadActivation() affects more than one node, so the following + # cannot go in a general "for node" loop with the other node actions + for node in self.slipnodes: + node.spread_activation() + for node in self.slipnodes: + node.addBuffer() + node.jump() + node.buffer = 0.0 - def __addInitialNodes(self): - self.slipnodes = [] - self.letters = [] - for c in 'abcdefghijklmnopqrstuvwxyz': - slipnode = self.__addNode(c, 10.0) - self.letters += [slipnode] - self.numbers = [] - for c in '12345': - slipnode = self.__addNode(c, 30.0) - self.numbers += [slipnode] + def __addInitialNodes(self): + self.slipnodes = [] + self.letters = [] + for c in 'abcdefghijklmnopqrstuvwxyz': + slipnode = self.__addNode(c, 10.0) + self.letters += [slipnode] + self.numbers = [] + for c in '12345': + slipnode = self.__addNode(c, 30.0) + self.numbers += [slipnode] - # string positions - self.leftmost = self.__addNode('leftmost', 40.0) - self.rightmost = self.__addNode('rightmost', 40.0) - self.middle = self.__addNode('middle', 40.0) - self.single = self.__addNode('single', 40.0) - self.whole = self.__addNode('whole', 40.0) + # string positions + self.leftmost = self.__addNode('leftmost', 40.0) + self.rightmost = self.__addNode('rightmost', 40.0) + self.middle = self.__addNode('middle', 40.0) + self.single = self.__addNode('single', 40.0) + self.whole = self.__addNode('whole', 40.0) - # alphabetic positions - self.first = self.__addNode('first', 60.0) - self.last = self.__addNode('last', 60.0) + # alphabetic positions + self.first = self.__addNode('first', 60.0) + self.last = self.__addNode('last', 60.0) - # directions - self.left = self.__addNode('left', 40.0) - self.left.codelets += ['top-down-bond-scout--direction'] - self.left.codelets += ['top-down-group-scout--direction'] - self.right = self.__addNode('right', 40.0) - self.right.codelets += ['top-down-bond-scout--direction'] - self.right.codelets += ['top-down-group-scout--direction'] + # directions + self.left = self.__addNode('left', 40.0) + self.left.codelets += ['top-down-bond-scout--direction'] + self.left.codelets += ['top-down-group-scout--direction'] + self.right = self.__addNode('right', 40.0) + self.right.codelets += ['top-down-bond-scout--direction'] + self.right.codelets += ['top-down-group-scout--direction'] - # bond types - self.predecessor = self.__addNode('predecessor', 50.0, 60.0) - self.predecessor.codelets += ['top-down-bond-scout--category'] - self.successor = self.__addNode('successor', 50.0, 60.0) - self.successor.codelets += ['top-down-bond-scout--category'] - self.sameness = self.__addNode('sameness', 80.0) - self.sameness.codelets += ['top-down-bond-scout--category'] + # bond types + self.predecessor = self.__addNode('predecessor', 50.0, 60.0) + self.predecessor.codelets += ['top-down-bond-scout--category'] + self.successor = self.__addNode('successor', 50.0, 60.0) + self.successor.codelets += ['top-down-bond-scout--category'] + self.sameness = self.__addNode('sameness', 80.0) + self.sameness.codelets += ['top-down-bond-scout--category'] - # group types - self.predecessorGroup = self.__addNode('predecessorGroup', 50.0) - self.predecessorGroup.codelets += ['top-down-group-scout--category'] - self.successorGroup = self.__addNode('successorGroup', 50.0) - self.successorGroup.codelets += ['top-down-group-scout--category'] - self.samenessGroup = self.__addNode('samenessGroup', 80.0) - self.samenessGroup.codelets += ['top-down-group-scout--category'] + # group types + self.predecessorGroup = self.__addNode('predecessorGroup', 50.0) + self.predecessorGroup.codelets += ['top-down-group-scout--category'] + self.successorGroup = self.__addNode('successorGroup', 50.0) + self.successorGroup.codelets += ['top-down-group-scout--category'] + self.samenessGroup = self.__addNode('samenessGroup', 80.0) + self.samenessGroup.codelets += ['top-down-group-scout--category'] - # other relations - self.identity = self.__addNode('identity', 90.0) - self.opposite = self.__addNode('opposite', 90.0, 80.0) + # other relations + self.identity = self.__addNode('identity', 90.0) + self.opposite = self.__addNode('opposite', 90.0, 80.0) - # objects - self.letter = self.__addNode('letter', 20.0) - self.group = self.__addNode('group', 80.0) + # objects + self.letter = self.__addNode('letter', 20.0) + self.group = self.__addNode('group', 80.0) - # categories - self.letterCategory = self.__addNode('letterCategory', 30.0) - self.stringPositionCategory = self.__addNode('stringPositionCategory', 70.0) - self.stringPositionCategory.codelets += ['top-down-description-scout'] - self.alphabeticPositionCategory = self.__addNode('alphabeticPositionCategory', 80.0) - self.alphabeticPositionCategory.codelets += ['top-down-description-scout'] - self.directionCategory = self.__addNode('directionCategory', 70.0) - self.bondCategory = self.__addNode('bondCategory', 80.0) - self.groupCategory = self.__addNode('groupCategory', 80.0) - self.length = self.__addNode('length', 60.0) - self.objectCategory = self.__addNode('objectCategory', 90.0) - self.bondFacet = self.__addNode('bondFacet', 90.0) + # categories + self.letterCategory = self.__addNode('letterCategory', 30.0) + self.stringPositionCategory = self.__addNode('stringPositionCategory', 70.0) + self.stringPositionCategory.codelets += ['top-down-description-scout'] + self.alphabeticPositionCategory = self.__addNode('alphabeticPositionCategory', 80.0) + self.alphabeticPositionCategory.codelets += ['top-down-description-scout'] + self.directionCategory = self.__addNode('directionCategory', 70.0) + self.bondCategory = self.__addNode('bondCategory', 80.0) + self.groupCategory = self.__addNode('groupCategory', 80.0) + self.length = self.__addNode('length', 60.0) + self.objectCategory = self.__addNode('objectCategory', 90.0) + self.bondFacet = self.__addNode('bondFacet', 90.0) - # specify the descriptor types that bonds can form between - self.bondFacets += [self.letterCategory] - self.bondFacets += [self.length] + # specify the descriptor types that bonds can form between + self.bondFacets += [self.letterCategory] + self.bondFacets += [self.length] - # - self.initiallyClampedSlipnodes += [self.letterCategory] - self.letterCategory.clamped = True - self.initiallyClampedSlipnodes += [self.stringPositionCategory] - self.stringPositionCategory.clamped = True + # + self.initiallyClampedSlipnodes += [self.letterCategory] + self.letterCategory.clamped = True + self.initiallyClampedSlipnodes += [self.stringPositionCategory] + self.stringPositionCategory.clamped = True - def __addInitialLinks(self): - self.sliplinks = [] - self.__link_items_to_their_neighbours(self.letters) - self.__link_items_to_their_neighbours(self.numbers) - # letter categories - for letter in self.letters: - self.__addInstanceLink(self.letterCategory, letter, 97.0) - self.__addCategoryLink(self.samenessGroup, self.letterCategory, 50.0) - # lengths - for number in self.numbers: - self.__addInstanceLink(self.length, number, 100.0) - self.__addNonSlipLink(self.predecessorGroup, self.length, length=95.0) - self.__addNonSlipLink(self.successorGroup, self.length, length=95.0) - self.__addNonSlipLink(self.samenessGroup, self.length, length=95.0) - # opposites - self.__addOppositeLink(self.first, self.last) - self.__addOppositeLink(self.leftmost, self.rightmost) - self.__addOppositeLink(self.left, self.right) - self.__addOppositeLink(self.successor, self.predecessor) - self.__addOppositeLink(self.successorGroup, self.predecessorGroup) - # properties - self.__addPropertyLink(self.letters[0], self.first, 75.0) - self.__addPropertyLink(self.letters[-1], self.last, 75.0) - # object categories - self.__addInstanceLink(self.objectCategory, self.letter, 100.0) - self.__addInstanceLink(self.objectCategory, self.group, 100.0) - # string positions - self.__addInstanceLink(self.stringPositionCategory, self.leftmost, 100.0) - self.__addInstanceLink(self.stringPositionCategory, self.rightmost, 100.0) - self.__addInstanceLink(self.stringPositionCategory, self.middle, 100.0) - self.__addInstanceLink(self.stringPositionCategory, self.single, 100.0) - self.__addInstanceLink(self.stringPositionCategory, self.whole, 100.0) - # alphabetic positions - self.__addInstanceLink(self.alphabeticPositionCategory, self.first, 100.0) - self.__addInstanceLink(self.alphabeticPositionCategory, self.last, 100.0) - # direction categories - self.__addInstanceLink(self.directionCategory, self.left, 100.0) - self.__addInstanceLink(self.directionCategory, self.right, 100.0) - # bond categories - self.__addInstanceLink(self.bondCategory, self.predecessor, 100.0) - self.__addInstanceLink(self.bondCategory, self.successor, 100.0) - self.__addInstanceLink(self.bondCategory, self.sameness, 100.0) - # group categories - self.__addInstanceLink(self.groupCategory, self.predecessorGroup, 100.0) - self.__addInstanceLink(self.groupCategory, self.successorGroup, 100.0) - self.__addInstanceLink(self.groupCategory, self.samenessGroup, 100.0) - # link bonds to their groups - self.__addNonSlipLink(self.sameness, self.samenessGroup, label=self.groupCategory, length=30.0) - self.__addNonSlipLink(self.successor, self.successorGroup, label=self.groupCategory, length=60.0) - self.__addNonSlipLink(self.predecessor, self.predecessorGroup, label=self.groupCategory, length=60.0) - # link bond groups to their bonds - self.__addNonSlipLink(self.samenessGroup, self.sameness, label=self.bondCategory, length=90.0) - self.__addNonSlipLink(self.successorGroup, self.successor, label=self.bondCategory, length=90.0) - self.__addNonSlipLink(self.predecessorGroup, self.predecessor, label=self.bondCategory, length=90.0) - # bond facets - self.__addInstanceLink(self.bondFacet, self.letterCategory, 100.0) - self.__addInstanceLink(self.bondFacet, self.length, 100.0) - # letter category to length - self.__addSlipLink(self.letterCategory, self.length, length=95.0) - self.__addSlipLink(self.length, self.letterCategory, length=95.0) - # letter to group - self.__addSlipLink(self.letter, self.group, length=90.0) - self.__addSlipLink(self.group, self.letter, length=90.0) - # direction-position, direction-neighbour, position-neighbour - self.__addBidirectionalLink(self.left, self.leftmost, 90.0) - self.__addBidirectionalLink(self.right, self.rightmost, 90.0) - self.__addBidirectionalLink(self.right, self.leftmost, 100.0) - self.__addBidirectionalLink(self.left, self.rightmost, 100.0) - self.__addBidirectionalLink(self.leftmost, self.first, 100.0) - self.__addBidirectionalLink(self.rightmost, self.first, 100.0) - self.__addBidirectionalLink(self.leftmost, self.last, 100.0) - self.__addBidirectionalLink(self.rightmost, self.last, 100.0) - # other - self.__addSlipLink(self.single, self.whole, length=90.0) - self.__addSlipLink(self.whole, self.single, length=90.0) + def __addInitialLinks(self): + self.sliplinks = [] + self.__link_items_to_their_neighbours(self.letters) + self.__link_items_to_their_neighbours(self.numbers) + # letter categories + for letter in self.letters: + self.__addInstanceLink(self.letterCategory, letter, 97.0) + self.__addCategoryLink(self.samenessGroup, self.letterCategory, 50.0) + # lengths + for number in self.numbers: + self.__addInstanceLink(self.length, number, 100.0) + self.__addNonSlipLink(self.predecessorGroup, self.length, length=95.0) + self.__addNonSlipLink(self.successorGroup, self.length, length=95.0) + self.__addNonSlipLink(self.samenessGroup, self.length, length=95.0) + # opposites + self.__addOppositeLink(self.first, self.last) + self.__addOppositeLink(self.leftmost, self.rightmost) + self.__addOppositeLink(self.left, self.right) + self.__addOppositeLink(self.successor, self.predecessor) + self.__addOppositeLink(self.successorGroup, self.predecessorGroup) + # properties + self.__addPropertyLink(self.letters[0], self.first, 75.0) + self.__addPropertyLink(self.letters[-1], self.last, 75.0) + # object categories + self.__addInstanceLink(self.objectCategory, self.letter, 100.0) + self.__addInstanceLink(self.objectCategory, self.group, 100.0) + # string positions + self.__addInstanceLink(self.stringPositionCategory, self.leftmost, 100.0) + self.__addInstanceLink(self.stringPositionCategory, self.rightmost, 100.0) + self.__addInstanceLink(self.stringPositionCategory, self.middle, 100.0) + self.__addInstanceLink(self.stringPositionCategory, self.single, 100.0) + self.__addInstanceLink(self.stringPositionCategory, self.whole, 100.0) + # alphabetic positions + self.__addInstanceLink(self.alphabeticPositionCategory, self.first, 100.0) + self.__addInstanceLink(self.alphabeticPositionCategory, self.last, 100.0) + # direction categories + self.__addInstanceLink(self.directionCategory, self.left, 100.0) + self.__addInstanceLink(self.directionCategory, self.right, 100.0) + # bond categories + self.__addInstanceLink(self.bondCategory, self.predecessor, 100.0) + self.__addInstanceLink(self.bondCategory, self.successor, 100.0) + self.__addInstanceLink(self.bondCategory, self.sameness, 100.0) + # group categories + self.__addInstanceLink(self.groupCategory, self.predecessorGroup, 100.0) + self.__addInstanceLink(self.groupCategory, self.successorGroup, 100.0) + self.__addInstanceLink(self.groupCategory, self.samenessGroup, 100.0) + # link bonds to their groups + self.__addNonSlipLink(self.sameness, self.samenessGroup, label=self.groupCategory, length=30.0) + self.__addNonSlipLink(self.successor, self.successorGroup, label=self.groupCategory, length=60.0) + self.__addNonSlipLink(self.predecessor, self.predecessorGroup, label=self.groupCategory, length=60.0) + # link bond groups to their bonds + self.__addNonSlipLink(self.samenessGroup, self.sameness, label=self.bondCategory, length=90.0) + self.__addNonSlipLink(self.successorGroup, self.successor, label=self.bondCategory, length=90.0) + self.__addNonSlipLink(self.predecessorGroup, self.predecessor, label=self.bondCategory, length=90.0) + # bond facets + self.__addInstanceLink(self.bondFacet, self.letterCategory, 100.0) + self.__addInstanceLink(self.bondFacet, self.length, 100.0) + # letter category to length + self.__addSlipLink(self.letterCategory, self.length, length=95.0) + self.__addSlipLink(self.length, self.letterCategory, length=95.0) + # letter to group + self.__addSlipLink(self.letter, self.group, length=90.0) + self.__addSlipLink(self.group, self.letter, length=90.0) + # direction-position, direction-neighbour, position-neighbour + self.__addBidirectionalLink(self.left, self.leftmost, 90.0) + self.__addBidirectionalLink(self.right, self.rightmost, 90.0) + self.__addBidirectionalLink(self.right, self.leftmost, 100.0) + self.__addBidirectionalLink(self.left, self.rightmost, 100.0) + self.__addBidirectionalLink(self.leftmost, self.first, 100.0) + self.__addBidirectionalLink(self.rightmost, self.first, 100.0) + self.__addBidirectionalLink(self.leftmost, self.last, 100.0) + self.__addBidirectionalLink(self.rightmost, self.last, 100.0) + # other + self.__addSlipLink(self.single, self.whole, length=90.0) + self.__addSlipLink(self.whole, self.single, length=90.0) - def __addLink(self, source, destination, label=None, length=0.0): - link = Sliplink(source, destination, label=label, length=length) - self.sliplinks += [link] - return link + def __addLink(self, source, destination, label=None, length=0.0): + link = Sliplink(source, destination, label=label, length=length) + self.sliplinks += [link] + return link - def __addSlipLink(self, source, destination, label=None, length=0.0): - link = self.__addLink(source, destination, label, length) - source.lateralSlipLinks += [link] + def __addSlipLink(self, source, destination, label=None, length=0.0): + link = self.__addLink(source, destination, label, length) + source.lateralSlipLinks += [link] - def __addNonSlipLink(self, source, destination, label=None, length=0.0): - link = self.__addLink(source, destination, label, length) - source.lateralNonSlipLinks += [link] + def __addNonSlipLink(self, source, destination, label=None, length=0.0): + link = self.__addLink(source, destination, label, length) + source.lateralNonSlipLinks += [link] - def __addBidirectionalLink(self, source, destination, length): - self.__addNonSlipLink(source, destination, length=length) - self.__addNonSlipLink(destination, source, length=length) + def __addBidirectionalLink(self, source, destination, length): + self.__addNonSlipLink(source, destination, length=length) + self.__addNonSlipLink(destination, source, length=length) - def __addCategoryLink(self, source, destination, length): - #noinspection PyArgumentEqualDefault - link = self.__addLink(source, destination, None, length) - source.categoryLinks += [link] + def __addCategoryLink(self, source, destination, length): + #noinspection PyArgumentEqualDefault + link = self.__addLink(source, destination, None, length) + source.categoryLinks += [link] - def __addInstanceLink(self, source, destination, length): - categoryLength = source.conceptualDepth - destination.conceptualDepth - self.__addCategoryLink(destination, source, categoryLength) - #noinspection PyArgumentEqualDefault - link = self.__addLink(source, destination, None, length) - source.instanceLinks += [link] + def __addInstanceLink(self, source, destination, length): + categoryLength = source.conceptualDepth - destination.conceptualDepth + self.__addCategoryLink(destination, source, categoryLength) + #noinspection PyArgumentEqualDefault + link = self.__addLink(source, destination, None, length) + source.instanceLinks += [link] - def __addPropertyLink(self, source, destination, length): - #noinspection PyArgumentEqualDefault - link = self.__addLink(source, destination, None, length) - source.propertyLinks += [link] + def __addPropertyLink(self, source, destination, length): + #noinspection PyArgumentEqualDefault + link = self.__addLink(source, destination, None, length) + source.propertyLinks += [link] - def __addOppositeLink(self, source, destination): - self.__addSlipLink(source, destination, label=self.opposite) - self.__addSlipLink(destination, source, label=self.opposite) + def __addOppositeLink(self, source, destination): + self.__addSlipLink(source, destination, label=self.opposite) + self.__addSlipLink(destination, source, label=self.opposite) - def __addNode(self, name, depth, length=0): - slipnode = Slipnode(name, depth, length) - self.slipnodes += [slipnode] - return slipnode + def __addNode(self, name, depth, length=0): + slipnode = Slipnode(name, depth, length) + self.slipnodes += [slipnode] + return slipnode - def __link_items_to_their_neighbours(self,items): - previous = items[0] - for item in items[1:]: - self.__addNonSlipLink(previous, item, label=self.successor) - self.__addNonSlipLink(item, previous, label=self.predecessor) - previous = item + def __link_items_to_their_neighbours(self,items): + previous = items[0] + for item in items[1:]: + self.__addNonSlipLink(previous, item, label=self.successor) + self.__addNonSlipLink(item, previous, label=self.predecessor) + previous = item slipnet = SlipNet() diff --git a/copycat/slipnode.py b/copycat/slipnode.py index 7d596f2..38cf542 100644 --- a/copycat/slipnode.py +++ b/copycat/slipnode.py @@ -3,159 +3,159 @@ import utils import logging def full_activation(): - return 100 + return 100 def jump_threshold(): - return 55.0 + return 55.0 class Slipnode(object): - def __init__(self, name, depth, length=0.0): - # logging.info('depth to %s for %s' % (depth,name)) - self.conceptual_depth = depth - self.usualConceptualDepth = depth - self.name = name - self.intrinsicLinkLength = length - self.shrunkLinkLength = length * 0.4 + def __init__(self, name, depth, length=0.0): + # logging.info('depth to %s for %s' % (depth,name)) + self.conceptual_depth = depth + self.usualConceptualDepth = depth + self.name = name + self.intrinsicLinkLength = length + self.shrunkLinkLength = length * 0.4 - self.activation = 0.0 - self.buffer = 0.0 - self.clamped = False - self.bondFacetFactor = 0.0 - self.categoryLinks = [] - self.instanceLinks = [] - self.propertyLinks = [] - self.lateralSlipLinks = [] - self.lateralNonSlipLinks = [] - self.incomingLinks = [] - self.outgoingLinks = [] - self.codelets = [] - self.clampBondDegreeOfAssociation = False + self.activation = 0.0 + self.buffer = 0.0 + self.clamped = False + self.bondFacetFactor = 0.0 + self.categoryLinks = [] + self.instanceLinks = [] + self.propertyLinks = [] + self.lateralSlipLinks = [] + self.lateralNonSlipLinks = [] + self.incomingLinks = [] + self.outgoingLinks = [] + self.codelets = [] + self.clampBondDegreeOfAssociation = False - def __repr__(self): - return '' % self.name + def __repr__(self): + return '' % self.name - def reset(self): - self.buffer = 0.0 - self.activation = 0.0 + def reset(self): + self.buffer = 0.0 + self.activation = 0.0 - def clampHigh(self): - self.clamped = True - self.activation = 100.0 + def clampHigh(self): + self.clamped = True + self.activation = 100.0 - def unclamp(self): - self.clamped = False + def unclamp(self): + self.clamped = False - def setConceptualDepth(self, depth): - logging.info('set depth to %s for %s' % (depth, self.name)) - self.conceptual_depth = depth + def setConceptualDepth(self, depth): + logging.info('set depth to %s for %s' % (depth, self.name)) + self.conceptual_depth = depth - def category(self): - if not len(self.categoryLinks): - return None - link = self.categoryLinks[0] - return link.destination + def category(self): + if not len(self.categoryLinks): + return None + link = self.categoryLinks[0] + return link.destination - def fully_active(self): - """Whether this node has full activation""" - return self.activation > full_activation() - 0.00001 # allow a little leeway for floats + def fully_active(self): + """Whether this node has full activation""" + return self.activation > full_activation() - 0.00001 # allow a little leeway for floats - def activate_fully(self): - """Make this node fully active""" - self.activation = full_activation() + def activate_fully(self): + """Make this node fully active""" + self.activation = full_activation() - def bondDegreeOfAssociation(self): - linkLength = self.intrinsicLinkLength - if (not self.clampBondDegreeOfAssociation) and self.fully_active(): - linkLength = self.shrunkLinkLength - result = math.sqrt(100 - linkLength) * 11.0 - return min(100.0, result) + def bondDegreeOfAssociation(self): + linkLength = self.intrinsicLinkLength + if (not self.clampBondDegreeOfAssociation) and self.fully_active(): + linkLength = self.shrunkLinkLength + result = math.sqrt(100 - linkLength) * 11.0 + return min(100.0, result) - def degreeOfAssociation(self): - linkLength = self.intrinsicLinkLength - if self.fully_active(): - linkLength = self.shrunkLinkLength - return 100.0 - linkLength + def degreeOfAssociation(self): + linkLength = self.intrinsicLinkLength + if self.fully_active(): + linkLength = self.shrunkLinkLength + return 100.0 - linkLength - def update(self): - act = self.activation - self.oldActivation = act - self.buffer -= self.activation * ( 100.0 - self.conceptual_depth) / 100.0 + def update(self): + act = self.activation + self.oldActivation = act + self.buffer -= self.activation * ( 100.0 - self.conceptual_depth) / 100.0 - def linked(self, other): - """Whether the other is among the outgoing links""" - return self.points_at(self.outgoingLinks, other) + def linked(self, other): + """Whether the other is among the outgoing links""" + return self.points_at(self.outgoingLinks, other) - def slipLinked(self, other): - """Whether the other is among the lateral links""" - return self.points_at(self.lateralSlipLinks, other) + def slipLinked(self, other): + """Whether the other is among the lateral links""" + return self.points_at(self.lateralSlipLinks, other) - def points_at(self, links, other): - """Whether any of the links points at the other""" - return any([l.points_at(other) for l in links]) + def points_at(self, links, other): + """Whether any of the links points at the other""" + return any([l.points_at(other) for l in links]) - def related(self, other): - """Same or linked""" - return self == other or self.linked(other) + def related(self, other): + """Same or linked""" + return self == other or self.linked(other) - def applySlippages(self, slippages): - for slippage in slippages: - if self == slippage.initialDescriptor: - return slippage.targetDescriptor - return self + def applySlippages(self, slippages): + for slippage in slippages: + if self == slippage.initialDescriptor: + return slippage.targetDescriptor + return self - def getRelatedNode(self, relation): - """Return the node that is linked to this node via this relation. + def getRelatedNode(self, relation): + """Return the node that is linked to this node via this relation. - If no linked node is found, return None - """ - from slipnet import slipnet + If no linked node is found, return None + """ + from slipnet import slipnet - if relation == slipnet.identity: - return self - destinations = [l.destination for l in self.outgoingLinks if l.label == relation] - if destinations: - return destinations[0] - node = None - return node + if relation == slipnet.identity: + return self + destinations = [l.destination for l in self.outgoingLinks if l.label == relation] + if destinations: + return destinations[0] + node = None + return node - def getBondCategory(self, destination): - """Return the label of the link between these nodes if it exists. + def getBondCategory(self, destination): + """Return the label of the link between these nodes if it exists. - If it does not exist return None - """ - from slipnet import slipnet + If it does not exist return None + """ + from slipnet import slipnet - result = None - if self == destination: - result = slipnet.identity - else: - for link in self.outgoingLinks: - if link.destination == destination: - result = link.label - break - if result: - logging.info('Got bond: %s' % result.name) - else: - logging.info('Got no bond') - return result + result = None + if self == destination: + result = slipnet.identity + else: + for link in self.outgoingLinks: + if link.destination == destination: + result = link.label + break + if result: + logging.info('Got bond: %s' % result.name) + else: + logging.info('Got no bond') + return result - def spread_activation(self): - if self.fully_active(): - [ link.spread_activation() for link in self.outgoingLinks ] + def spread_activation(self): + if self.fully_active(): + [ link.spread_activation() for link in self.outgoingLinks ] - def addBuffer(self): - if not self.clamped: - self.activation += self.buffer - self.activation = min(self.activation, 100) - self.activation = max(self.activation, 0) + def addBuffer(self): + if not self.clamped: + self.activation += self.buffer + self.activation = min(self.activation, 100) + self.activation = max(self.activation, 0) - def jump(self): - value = (self.activation / 100.0) ** 3 - #logging.info('jumping for %s at activation %s' % (self.name,self.activation)) - if self.activation > jump_threshold() and utils.random() < value and not self.clamped: - self.activate_fully() + def jump(self): + value = (self.activation / 100.0) ** 3 + #logging.info('jumping for %s at activation %s' % (self.name,self.activation)) + if self.activation > jump_threshold() and utils.random() < value and not self.clamped: + self.activate_fully() - def get_name(self): - if len(self.name) == 1: - return self.name.upper() - return self.name + def get_name(self): + if len(self.name) == 1: + return self.name.upper() + return self.name diff --git a/copycat/temperature.py b/copycat/temperature.py index 6cc2e4d..6e17b4b 100644 --- a/copycat/temperature.py +++ b/copycat/temperature.py @@ -1,23 +1,23 @@ import logging class Temperature(object): - def __init__(self): - self.value = 100.0 - self.clamped = True - self.clampTime = 30 + def __init__(self): + self.value = 100.0 + self.clamped = True + self.clampTime = 30 - def update(self, value): - logging.debug('update to %s' % value) - self.value = value + def update(self, value): + logging.debug('update to %s' % value) + self.value = value - def tryUnclamp(self): - from coderack import coderack + def tryUnclamp(self): + from coderack import coderack - if self.clamped and coderack.codeletsRun >= self.clampTime: - logging.info('unclamp temperature at %d' % coderack.codeletsRun) - self.clamped = False + if self.clamped and coderack.codeletsRun >= self.clampTime: + logging.info('unclamp temperature at %d' % coderack.codeletsRun) + self.clamped = False - def log(self): - logging.debug('temperature.value: %f' % self.value) + def log(self): + logging.debug('temperature.value: %f' % self.value) temperature = Temperature() diff --git a/copycat/utils.py b/copycat/utils.py index 3a4cb43..1c3a946 100644 --- a/copycat/utils.py +++ b/copycat/utils.py @@ -1,113 +1,113 @@ def any(things): - """Return True if any of the things are True. + """Return True if any of the things are True. - things should be iterable. + things should be iterable. - If the things are empty, then we can't say any are True - >>> any([]) - False + If the things are empty, then we can't say any are True + >>> any([]) + False - If all the things are False, then we can't say any are True - >>> any([False,False,False]) - False + If all the things are False, then we can't say any are True + >>> any([False,False,False]) + False - If all the things are equivalent to False, then we can't say any are True - >>> any([0,[],'']) - False + If all the things are equivalent to False, then we can't say any are True + >>> any([0,[],'']) + False - The type of the true thing should not matter - >>> any([1,[],'']) - True - >>> any([0,(2,),'']) - True - >>> any([0,[],'foo']) - True - >>> any([0,[],True,'']) - True + The type of the true thing should not matter + >>> any([1,[],'']) + True + >>> any([0,(2,),'']) + True + >>> any([0,[],'foo']) + True + >>> any([0,[],True,'']) + True - It should not matter where the True thing is - >>> any((True,False,False,False,False,)) - True - >>> any((False,False,True,False,False,)) - True - >>> any((False,False,False,False,True,)) - True + It should not matter where the True thing is + >>> any((True,False,False,False,False,)) + True + >>> any((False,False,True,False,False,)) + True + >>> any((False,False,False,False,True,)) + True - The size of the sequence should not matter - >>> True == any((True,)) == any((True,True,)) == any((True,True,True,True,)) - True + The size of the sequence should not matter + >>> True == any((True,)) == any((True,True,)) == any((True,True,True,True,)) + True - Any string is True - >>> any('foo') - True + Any string is True + >>> any('foo') + True - Except an empty string - >>> any('') - False + Except an empty string + >>> any('') + False - The function cannot be applied to ints - >>> any(7) - Traceback (most recent call last): - ... - TypeError: iteration over non-sequence - """ - for thing in things: - if thing: - return True - return False + The function cannot be applied to ints + >>> any(7) + Traceback (most recent call last): + ... + TypeError: iteration over non-sequence + """ + for thing in things: + if thing: + return True + return False def all(things): - """Return True if all of the things are True. + """Return True if all of the things are True. - things should be iterable. + things should be iterable. - If the things are empty, then we can't say all are True - >>> all([]) - False + If the things are empty, then we can't say all are True + >>> all([]) + False - If all the things are False, then we can't say all are True - >>> all([False,False,False]) - False + If all the things are False, then we can't say all are True + >>> all([False,False,False]) + False - If all the things are equivalent to False, then we can't say all are True - >>> all([0,[],'']) - False + If all the things are equivalent to False, then we can't say all are True + >>> all([0,[],'']) + False - The type of the false thing should not matter - >>> all([0,True,True,]) - False - >>> all([True,(),True,]) - False - >>> all([True,True,'',]) - False + The type of the false thing should not matter + >>> all([0,True,True,]) + False + >>> all([True,(),True,]) + False + >>> all([True,True,'',]) + False - Position of the false thing should not matter - >>> all((False,True,True,)) - False - >>> all((True,False,True,)) - False - >>> all((True,True,False,)) - False + Position of the false thing should not matter + >>> all((False,True,True,)) + False + >>> all((True,False,True,)) + False + >>> all((True,True,False,)) + False - any string is True - >>> all('foo') - True + any string is True + >>> all('foo') + True - Except an empty string - >>> all('') - False + Except an empty string + >>> all('') + False - The function cannot be applied to ints - >>> all(7) - Traceback (most recent call last): - ... - TypeError: iteration over non-sequence - """ - for thing in things: - if not thing: - return False - return len(things) > 0 + The function cannot be applied to ints + >>> all(7) + Traceback (most recent call last): + ... + TypeError: iteration over non-sequence + """ + for thing in things: + if not thing: + return False + return len(things) > 0 import logging @@ -115,26 +115,26 @@ seed = 999.0 count = 0 testably_random = True def random(): - global testably_random - if testably_random: - from random import random - return random() - global seed - global count - seed += 1.0 - count += 1 - if seed > 1999: - seed = 0.0 - logging.info("count: %d" % count) - #if seed == 998: - # sys.exit(1) - return seed / 2000.0 + global testably_random + if testably_random: + from random import random + return random() + global seed + global count + seed += 1.0 + count += 1 + if seed > 1999: + seed = 0.0 + logging.info("count: %d" % count) + #if seed == 998: + # sys.exit(1) + return seed / 2000.0 def choice(aList): - i = int(random() * len(aList)) - return aList[i] + i = int(random() * len(aList)) + return aList[i] if __name__ == '__main__': - import doctest - doctest.testmod() + import doctest + doctest.testmod() diff --git a/copycat/workspace.py b/copycat/workspace.py index 9279336..e952e01 100644 --- a/copycat/workspace.py +++ b/copycat/workspace.py @@ -5,153 +5,153 @@ from workspaceString import WorkspaceString unknownAnswer = '?' class Workspace(object): - def __init__(self): - #logging.debug('workspace.__init__()') - self.setStrings('', '', '') - self.reset() - self.totalUnhappiness = 0.0 - self.intraStringUnhappiness = 0.0 - self.interStringUnhappiness = 0.0 + def __init__(self): + #logging.debug('workspace.__init__()') + self.setStrings('', '', '') + self.reset() + self.totalUnhappiness = 0.0 + self.intraStringUnhappiness = 0.0 + self.interStringUnhappiness = 0.0 - def __repr__(self): - return '' % (self.initialString, self.modifiedString, self.targetString) + def __repr__(self): + return '' % (self.initialString, self.modifiedString, self.targetString) - def setStrings(self, initial, modified, target): - self.targetString = target - self.initialString = initial - self.modifiedString = modified + def setStrings(self, initial, modified, target): + self.targetString = target + self.initialString = initial + self.modifiedString = modified - def reset(self): - #logging.debug('workspace.reset()') - self.foundAnswer = False - self.changedObject = None - self.objects = [] - self.structures = [] - self.rule = None - self.initial = WorkspaceString(self.initialString) - self.modified = WorkspaceString(self.modifiedString) - self.target = WorkspaceString(self.targetString) + def reset(self): + #logging.debug('workspace.reset()') + self.foundAnswer = False + self.changedObject = None + self.objects = [] + self.structures = [] + self.rule = None + self.initial = WorkspaceString(self.initialString) + self.modified = WorkspaceString(self.modifiedString) + self.target = WorkspaceString(self.targetString) - def __adjustUnhappiness(self, values): - result = sum(values) / 2 - if result > 100.0: - result = 100.0 - return result + def __adjustUnhappiness(self, values): + result = sum(values) / 2 + if result > 100.0: + result = 100.0 + return result - def assessUnhappiness(self): - self.intraStringUnhappiness = self.__adjustUnhappiness([o.relativeImportance * o.intraStringUnhappiness for o in self.objects]) - self.interStringUnhappiness = self.__adjustUnhappiness([o.relativeImportance * o.interStringUnhappiness for o in self.objects]) - self.totalUnhappiness = self.__adjustUnhappiness([o.relativeImportance * o.totalUnhappiness for o in self.objects]) + def assessUnhappiness(self): + self.intraStringUnhappiness = self.__adjustUnhappiness([o.relativeImportance * o.intraStringUnhappiness for o in self.objects]) + self.interStringUnhappiness = self.__adjustUnhappiness([o.relativeImportance * o.interStringUnhappiness for o in self.objects]) + self.totalUnhappiness = self.__adjustUnhappiness([o.relativeImportance * o.totalUnhappiness for o in self.objects]) - def assessTemperature(self): - self.calculateIntraStringUnhappiness() - self.calculateInterStringUnhappiness() - self.calculateTotalUnhappiness() + def assessTemperature(self): + self.calculateIntraStringUnhappiness() + self.calculateInterStringUnhappiness() + self.calculateTotalUnhappiness() - def calculateIntraStringUnhappiness(self): - values = [o.relativeImportance * o.intraStringUnhappiness for o in self.objects] - value = sum(values) / 2.0 - self.intraStringUnhappiness = min(value, 100.0) + def calculateIntraStringUnhappiness(self): + values = [o.relativeImportance * o.intraStringUnhappiness for o in self.objects] + value = sum(values) / 2.0 + self.intraStringUnhappiness = min(value, 100.0) - def calculateInterStringUnhappiness(self): - values = [o.relativeImportance * o.interStringUnhappiness for o in self.objects] - value = sum(values) / 2.0 - self.interStringUnhappiness = min(value, 100.0) + def calculateInterStringUnhappiness(self): + values = [o.relativeImportance * o.interStringUnhappiness for o in self.objects] + value = sum(values) / 2.0 + self.interStringUnhappiness = min(value, 100.0) - def calculateTotalUnhappiness(self): - for o in self.objects: - logging.info("object: %s, totalUnhappiness: %d, relativeImportance: %d" % ( - o, o.totalUnhappiness, o.relativeImportance * 1000)) - values = [o.relativeImportance * o.totalUnhappiness for o in self.objects] - value = sum(values) / 2.0 - self.totalUnhappiness = min(value, 100.0) + def calculateTotalUnhappiness(self): + for o in self.objects: + logging.info("object: %s, totalUnhappiness: %d, relativeImportance: %d" % ( + o, o.totalUnhappiness, o.relativeImportance * 1000)) + values = [o.relativeImportance * o.totalUnhappiness for o in self.objects] + value = sum(values) / 2.0 + self.totalUnhappiness = min(value, 100.0) - def updateEverything(self): - for structure in self.structures: - structure.updateStrength() - for obj in self.objects: - obj.updateValue() - self.initial.updateRelativeImportance() - self.target.updateRelativeImportance() - self.initial.updateIntraStringUnhappiness() - self.target.updateIntraStringUnhappiness() + def updateEverything(self): + for structure in self.structures: + structure.updateStrength() + for obj in self.objects: + obj.updateValue() + self.initial.updateRelativeImportance() + self.target.updateRelativeImportance() + self.initial.updateIntraStringUnhappiness() + self.target.updateIntraStringUnhappiness() - def otherObjects(self, anObject): - return [o for o in self.objects if o != anObject] + def otherObjects(self, anObject): + return [o for o in self.objects if o != anObject] - def numberOfUnrelatedObjects(self): - """A list of all objects in the workspace that have at least one bond slot open.""" - objects = [o for o in self.objects if o.string == self.initial or o.string == self.target] - #print 'A: %d' % len(objects) - objects = [o for o in objects if not o.spansString()] - #print 'B: %d' % len(objects) - objects = [o for o in objects if (not o.leftBond and not o.leftmost) or (not o.rightBond and not o.rightmost)] - #print 'C: %d' % len(objects) - #objects = [ o for o in objects if ] - #print 'D: %d' % len(objects) - return len(objects) + def numberOfUnrelatedObjects(self): + """A list of all objects in the workspace that have at least one bond slot open.""" + objects = [o for o in self.objects if o.string == self.initial or o.string == self.target] + #print 'A: %d' % len(objects) + objects = [o for o in objects if not o.spansString()] + #print 'B: %d' % len(objects) + objects = [o for o in objects if (not o.leftBond and not o.leftmost) or (not o.rightBond and not o.rightmost)] + #print 'C: %d' % len(objects) + #objects = [ o for o in objects if ] + #print 'D: %d' % len(objects) + return len(objects) - def numberOfUngroupedObjects(self): - """A list of all objects in the workspace that have no group.""" - objects = [o for o in self.objects if o.string == self.initial or o.string == self.target] - objects = [o for o in objects if not o.spansString()] - objects = [o for o in objects if not o.group] - return len(objects) + def numberOfUngroupedObjects(self): + """A list of all objects in the workspace that have no group.""" + objects = [o for o in self.objects if o.string == self.initial or o.string == self.target] + objects = [o for o in objects if not o.spansString()] + objects = [o for o in objects if not o.group] + return len(objects) - def numberOfUnreplacedObjects(self): - """A list of all objects in the inital string that have not been replaced.""" - from letter import Letter + def numberOfUnreplacedObjects(self): + """A list of all objects in the inital string that have not been replaced.""" + from letter import Letter - objects = [o for o in self.objects if o.string == self.initial and isinstance(o, Letter)] - objects = [o for o in objects if not o.replacement] - return len(objects) + objects = [o for o in self.objects if o.string == self.initial and isinstance(o, Letter)] + objects = [o for o in objects if not o.replacement] + return len(objects) - def numberOfUncorrespondingObjects(self): - """A list of all objects in the inital string that have not been replaced.""" - objects = [o for o in self.objects if o.string == self.initial or o.string == self.target] - objects = [o for o in objects if not o.correspondence] - return len(objects) + def numberOfUncorrespondingObjects(self): + """A list of all objects in the inital string that have not been replaced.""" + objects = [o for o in self.objects if o.string == self.initial or o.string == self.target] + objects = [o for o in objects if not o.correspondence] + return len(objects) - def numberOfBonds(self): - """The number of bonds in the workspace""" - from bond import Bond + def numberOfBonds(self): + """The number of bonds in the workspace""" + from bond import Bond - return len([o for o in self.structures if isinstance(o, Bond)]) + return len([o for o in self.structures if isinstance(o, Bond)]) - def correspondences(self): - from correspondence import Correspondence + def correspondences(self): + from correspondence import Correspondence - return [s for s in self.structures if isinstance(s, Correspondence)] + return [s for s in self.structures if isinstance(s, Correspondence)] - def slippages(self): - result = [] - if self.changedObject and self.changedObject.correspondence: - result = [m for m in self.changedObject.correspondence.conceptMappings] - for objekt in workspace.initial.objects: - if objekt.correspondence: - for mapping in objekt.correspondence.slippages(): - if not mapping.isNearlyContainedBy(result): - result += [mapping] - return result + def slippages(self): + result = [] + if self.changedObject and self.changedObject.correspondence: + result = [m for m in self.changedObject.correspondence.conceptMappings] + for objekt in workspace.initial.objects: + if objekt.correspondence: + for mapping in objekt.correspondence.slippages(): + if not mapping.isNearlyContainedBy(result): + result += [mapping] + return result - def buildRule(self, rule): - if self.rule: - self.structures.remove(self.rule) - self.rule = rule - self.structures += [rule] - rule.activateRuleDescriptions() + def buildRule(self, rule): + if self.rule: + self.structures.remove(self.rule) + self.rule = rule + self.structures += [rule] + rule.activateRuleDescriptions() - def breakRule(self): - self.rule = None + def breakRule(self): + self.rule = None - def buildDescriptions(self, objekt): - for description in objekt.descriptions: - description.descriptionType.buffer = 100.0 - #logging.info("Set buffer to 100 for " + description.descriptionType.get_name()); - description.descriptor.buffer = 100.0 - #logging.info("Set buffer to 100 for " + description.descriptor.get_name()); - if description not in self.structures: - self.structures += [description] + def buildDescriptions(self, objekt): + for description in objekt.descriptions: + description.descriptionType.buffer = 100.0 + #logging.info("Set buffer to 100 for " + description.descriptionType.get_name()); + description.descriptor.buffer = 100.0 + #logging.info("Set buffer to 100 for " + description.descriptor.get_name()); + if description not in self.structures: + self.structures += [description] workspace = Workspace() diff --git a/copycat/workspaceFormulas.py b/copycat/workspaceFormulas.py index ca504c2..cfd14a3 100644 --- a/copycat/workspaceFormulas.py +++ b/copycat/workspaceFormulas.py @@ -6,155 +6,155 @@ from slipnet import slipnet import formulas class WorkspaceFormulas(object): - def __init__(self): - self.clampTemperature = False + def __init__(self): + self.clampTemperature = False - def updateTemperature(self): - logging.debug('updateTemperature') - workspace.assessTemperature() - ruleWeakness = 100.0 - if workspace.rule: - workspace.rule.updateStrength() - ruleWeakness = 100.0 - workspace.rule.totalStrength - values = ( (workspace.totalUnhappiness, 0.8), (ruleWeakness, 0.2), ) - slightly_above_actual_temperature = formulas.actualTemperature + 0.001 - logging.info('actualTemperature: %f' % slightly_above_actual_temperature) - formulas.actualTemperature = formulas.weightedAverage(values) - logging.info('unhappiness: %f, weakness: %f, actualTemperature: %f' % ( - workspace.totalUnhappiness + 0.001, ruleWeakness + 0.001, formulas.actualTemperature + 0.001)) - if temperature.clamped: - formulas.actualTemperature = 100.0 - logging.info('actualTemperature: %f' % (formulas.actualTemperature + 0.001)) - temperature.update(formulas.actualTemperature) - if not self.clampTemperature: - formulas.Temperature = formulas.actualTemperature - temperature.update(formulas.Temperature) + def updateTemperature(self): + logging.debug('updateTemperature') + workspace.assessTemperature() + ruleWeakness = 100.0 + if workspace.rule: + workspace.rule.updateStrength() + ruleWeakness = 100.0 - workspace.rule.totalStrength + values = ( (workspace.totalUnhappiness, 0.8), (ruleWeakness, 0.2), ) + slightly_above_actual_temperature = formulas.actualTemperature + 0.001 + logging.info('actualTemperature: %f' % slightly_above_actual_temperature) + formulas.actualTemperature = formulas.weightedAverage(values) + logging.info('unhappiness: %f, weakness: %f, actualTemperature: %f' % ( + workspace.totalUnhappiness + 0.001, ruleWeakness + 0.001, formulas.actualTemperature + 0.001)) + if temperature.clamped: + formulas.actualTemperature = 100.0 + logging.info('actualTemperature: %f' % (formulas.actualTemperature + 0.001)) + temperature.update(formulas.actualTemperature) + if not self.clampTemperature: + formulas.Temperature = formulas.actualTemperature + temperature.update(formulas.Temperature) workspaceFormulas = WorkspaceFormulas() def numberOfObjects(): - return len(workspace.objects) + return len(workspace.objects) def chooseUnmodifiedObject(attribute,inObjects): - objects = [ o for o in inObjects if o.string != workspace.modified ] - if not len(objects): - print 'no objects available in initial or target strings' - return formulas.chooseObjectFromList(objects,attribute) + objects = [ o for o in inObjects if o.string != workspace.modified ] + if not len(objects): + print 'no objects available in initial or target strings' + return formulas.chooseObjectFromList(objects,attribute) def chooseNeighbour(source): - objects = [] - for objekt in workspace.objects: - if objekt.string != source.string: - continue - if objekt.leftStringPosition == source.rightStringPosition + 1: - objects += [ objekt ] - elif source.leftStringPosition == objekt.rightStringPosition + 1: - objects += [ objekt ] - return formulas.chooseObjectFromList(objects,"intraStringSalience") + objects = [] + for objekt in workspace.objects: + if objekt.string != source.string: + continue + if objekt.leftStringPosition == source.rightStringPosition + 1: + objects += [ objekt ] + elif source.leftStringPosition == objekt.rightStringPosition + 1: + objects += [ objekt ] + return formulas.chooseObjectFromList(objects,"intraStringSalience") def chooseDirectedNeighbor(source,direction): - if direction == slipnet.left: - logging.info('Left') - return __chooseLeftNeighbor(source) - logging.info('Right') - return __chooseRightNeighbor(source) + if direction == slipnet.left: + logging.info('Left') + return __chooseLeftNeighbor(source) + logging.info('Right') + return __chooseRightNeighbor(source) def __chooseLeftNeighbor(source): - objects = [] - for o in workspace.objects: - if o.string == source.string : - if source.leftStringPosition == o.rightStringPosition + 1: - logging.info('%s is on left of %s' % (o,source)) - objects += [ o ] - else: - logging.info('%s is not on left of %s' % (o,source)) - logging.info('Number of left objects: %s' % len(objects)) - return formulas.chooseObjectFromList(objects,'intraStringSalience') + objects = [] + for o in workspace.objects: + if o.string == source.string : + if source.leftStringPosition == o.rightStringPosition + 1: + logging.info('%s is on left of %s' % (o,source)) + objects += [ o ] + else: + logging.info('%s is not on left of %s' % (o,source)) + logging.info('Number of left objects: %s' % len(objects)) + return formulas.chooseObjectFromList(objects,'intraStringSalience') def __chooseRightNeighbor(source): - objects = [ o for o in workspace.objects if - o.string == source.string and - o.leftStringPosition == source.rightStringPosition + 1 - ] - return formulas.chooseObjectFromList(objects,'intraStringSalience') + objects = [ o for o in workspace.objects if + o.string == source.string and + o.leftStringPosition == source.rightStringPosition + 1 + ] + return formulas.chooseObjectFromList(objects,'intraStringSalience') def chooseBondFacet(source, destination): - sourceFacets = [ d.descriptionType for d in source.descriptions if d.descriptionType in slipnet.bondFacets ] - bondFacets = [ d.descriptionType for d in destination.descriptions if d.descriptionType in sourceFacets ] - if not bondFacets: - return None - supports = [ __supportForDescriptionType(f,source.string) for f in bondFacets ] - i = formulas.selectListPosition(supports) - return bondFacets[ i ] + sourceFacets = [ d.descriptionType for d in source.descriptions if d.descriptionType in slipnet.bondFacets ] + bondFacets = [ d.descriptionType for d in destination.descriptions if d.descriptionType in sourceFacets ] + if not bondFacets: + return None + supports = [ __supportForDescriptionType(f,source.string) for f in bondFacets ] + i = formulas.selectListPosition(supports) + return bondFacets[ i ] def __supportForDescriptionType(descriptionType,string): - return ( descriptionType.activation + __descriptionTypeSupport(descriptionType,string) ) / 2 + return ( descriptionType.activation + __descriptionTypeSupport(descriptionType,string) ) / 2 def __descriptionTypeSupport(descriptionType,string): - """The proportion of objects in the string that have a description with this descriptionType""" - numberOfObjects = totalNumberOfObjects = 0.0 - for objekt in workspace.objects: - if objekt.string == string: - totalNumberOfObjects += 1.0 - for description in objekt.descriptions: - if description.descriptionType == descriptionType: - numberOfObjects += 1.0 - return numberOfObjects / totalNumberOfObjects + """The proportion of objects in the string that have a description with this descriptionType""" + numberOfObjects = totalNumberOfObjects = 0.0 + for objekt in workspace.objects: + if objekt.string == string: + totalNumberOfObjects += 1.0 + for description in objekt.descriptions: + if description.descriptionType == descriptionType: + numberOfObjects += 1.0 + return numberOfObjects / totalNumberOfObjects def probabilityOfPosting(codeletName): - if codeletName == 'breaker': - return 1.0 - if 'description' in codeletName: - result = ( formulas.Temperature / 100.0 ) ** 2 - else: - result = workspace.intraStringUnhappiness / 100.0 - if 'correspondence' in codeletName: - result = workspace.interStringUnhappiness / 100.0 - if 'replacement' in codeletName: - if workspace.numberOfUnreplacedObjects() > 0: - return 1.0 - return 0.0 - if 'rule' in codeletName: - if not workspace.rule: - return 1.0 - return workspace.rule.totalWeakness() / 100.0 - if 'translator' in codeletName: - if not workspace.rule: - assert 0 - return 0.0 - assert 0 - return 1.0 - return result + if codeletName == 'breaker': + return 1.0 + if 'description' in codeletName: + result = ( formulas.Temperature / 100.0 ) ** 2 + else: + result = workspace.intraStringUnhappiness / 100.0 + if 'correspondence' in codeletName: + result = workspace.interStringUnhappiness / 100.0 + if 'replacement' in codeletName: + if workspace.numberOfUnreplacedObjects() > 0: + return 1.0 + return 0.0 + if 'rule' in codeletName: + if not workspace.rule: + return 1.0 + return workspace.rule.totalWeakness() / 100.0 + if 'translator' in codeletName: + if not workspace.rule: + assert 0 + return 0.0 + assert 0 + return 1.0 + return result def howManyToPost(codeletName): - if codeletName == 'breaker': - return 1 - if 'description' in codeletName: - return 1 - if 'translator' in codeletName: - if not workspace.rule: - return 0 - return 1 - if 'rule' in codeletName: - return 2 - if 'group' in codeletName and not workspace.numberOfBonds(): - return 0 - if 'replacement' in codeletName and workspace.rule: - return 0 - number = 0 - if 'bond' in codeletName: - number = workspace.numberOfUnrelatedObjects() -# print 'post number of unrelated: %d, objects: %d' % (number,len(workspace.objects)) - if 'group' in codeletName: - number = workspace.numberOfUngroupedObjects() - if 'replacement' in codeletName: - number = workspace.numberOfUnreplacedObjects() - if 'correspondence' in codeletName: - number = workspace.numberOfUncorrespondingObjects() - if number < formulas.blur(2.0): - return 1 - if number < formulas.blur(4.0): - return 2 - return 3 + if codeletName == 'breaker': + return 1 + if 'description' in codeletName: + return 1 + if 'translator' in codeletName: + if not workspace.rule: + return 0 + return 1 + if 'rule' in codeletName: + return 2 + if 'group' in codeletName and not workspace.numberOfBonds(): + return 0 + if 'replacement' in codeletName and workspace.rule: + return 0 + number = 0 + if 'bond' in codeletName: + number = workspace.numberOfUnrelatedObjects() +# print 'post number of unrelated: %d, objects: %d' % (number,len(workspace.objects)) + if 'group' in codeletName: + number = workspace.numberOfUngroupedObjects() + if 'replacement' in codeletName: + number = workspace.numberOfUnreplacedObjects() + if 'correspondence' in codeletName: + number = workspace.numberOfUncorrespondingObjects() + if number < formulas.blur(2.0): + return 1 + if number < formulas.blur(4.0): + return 2 + return 3 diff --git a/copycat/workspaceObject.py b/copycat/workspaceObject.py index 235b357..79d7360 100644 --- a/copycat/workspaceObject.py +++ b/copycat/workspaceObject.py @@ -5,222 +5,222 @@ from slipnet import slipnet from workspaceStructure import WorkspaceStructure class WorkspaceObject(WorkspaceStructure): - def __init__(self,workspaceString): - WorkspaceStructure.__init__(self) - self.string = workspaceString - #self.string.objects += [ self ] - self.descriptions = [] - self.extrinsicDescriptions = [] - self.incomingBonds = [] - self.outgoingBonds = [] - self.bonds = [] - self.group = None - self.changed = None - self.correspondence = None - self.clampSalience = False - self.rawImportance = 0.0 - self.relativeImportance = 0.0 - self.leftBond = None - self.rightBond = None - self.newAnswerLetter = False - self.name = '' - self.replacement = None - self.rightStringPosition = 0 - self.leftStringPosition = 0 - self.leftmost = False - self.rightmost = False - self.intraStringSalience = 0.0 - self.interStringSalience = 0.0 - self.totalSalience = 0.0 - self.intraStringUnhappiness = 0.0 - self.interStringUnhappiness = 0.0 - self.totalUnhappiness = 0.0 + def __init__(self,workspaceString): + WorkspaceStructure.__init__(self) + self.string = workspaceString + #self.string.objects += [ self ] + self.descriptions = [] + self.extrinsicDescriptions = [] + self.incomingBonds = [] + self.outgoingBonds = [] + self.bonds = [] + self.group = None + self.changed = None + self.correspondence = None + self.clampSalience = False + self.rawImportance = 0.0 + self.relativeImportance = 0.0 + self.leftBond = None + self.rightBond = None + self.newAnswerLetter = False + self.name = '' + self.replacement = None + self.rightStringPosition = 0 + self.leftStringPosition = 0 + self.leftmost = False + self.rightmost = False + self.intraStringSalience = 0.0 + self.interStringSalience = 0.0 + self.totalSalience = 0.0 + self.intraStringUnhappiness = 0.0 + self.interStringUnhappiness = 0.0 + self.totalUnhappiness = 0.0 - def __str__(self): - return 'object' + def __str__(self): + return 'object' - def spansString(self): - return self.leftmost and self.rightmost + def spansString(self): + return self.leftmost and self.rightmost - def addDescription(self,descriptionType,descriptor): - description = Description(self,descriptionType,descriptor) - logging.info("Adding description: %s to %s" % (description,self)) - self.descriptions += [ description ] + def addDescription(self,descriptionType,descriptor): + description = Description(self,descriptionType,descriptor) + logging.info("Adding description: %s to %s" % (description,self)) + self.descriptions += [ description ] - def addDescriptions(self,descriptions): - #print 'addDescriptions 1' - #print 'add %d to %d of %s' % (len(descriptions),len(self.descriptions), self.string.string) - copy = descriptions[:] # in case we add to our own descriptions, which turns the loop infinite - for description in copy: - #print '%d addDescriptions 2 %s ' % (len(descriptions),description) - logging.info('might add: %s' % description) - if not self.containsDescription(description): - #print '%d addDescriptions 3 %s ' % (len(descriptions),description) - self.addDescription(description.descriptionType,description.descriptor) - #print '%d addDescriptions 4 %s ' % (len(descriptions),description) - else: - logging.info("Won't add it") - #print '%d added, have %d ' % (len(descriptions),len(self.descriptions)) - from workspace import workspace - workspace.buildDescriptions(self) + def addDescriptions(self,descriptions): + #print 'addDescriptions 1' + #print 'add %d to %d of %s' % (len(descriptions),len(self.descriptions), self.string.string) + copy = descriptions[:] # in case we add to our own descriptions, which turns the loop infinite + for description in copy: + #print '%d addDescriptions 2 %s ' % (len(descriptions),description) + logging.info('might add: %s' % description) + if not self.containsDescription(description): + #print '%d addDescriptions 3 %s ' % (len(descriptions),description) + self.addDescription(description.descriptionType,description.descriptor) + #print '%d addDescriptions 4 %s ' % (len(descriptions),description) + else: + logging.info("Won't add it") + #print '%d added, have %d ' % (len(descriptions),len(self.descriptions)) + from workspace import workspace + workspace.buildDescriptions(self) - def __calculateIntraStringHappiness(self): - if self.spansString(): - return 100.0 - if self.group: - return self.group.totalStrength - bondStrength = 0.0 - for bond in self.bonds: - bondStrength += bond.totalStrength - divisor = 6.0 - if self.spansString(): # XXX then we have already returned - divisor = 3.0 - return bondStrength / divisor + def __calculateIntraStringHappiness(self): + if self.spansString(): + return 100.0 + if self.group: + return self.group.totalStrength + bondStrength = 0.0 + for bond in self.bonds: + bondStrength += bond.totalStrength + divisor = 6.0 + if self.spansString(): # XXX then we have already returned + divisor = 3.0 + return bondStrength / divisor - def __calculateRawImportance(self): - """Calculate the raw importance of this object. + def __calculateRawImportance(self): + """Calculate the raw importance of this object. - Which is the sum of all relevant descriptions""" - result = 0.0 - for description in self.descriptions: - if description.descriptionType.fully_active(): - result += description.descriptor.activation - else: - result += description.descriptor.activation / 20.0 - if self.group: - result *= 2.0 / 3.0 - if self.changed: - result *= 2.0 - return result + Which is the sum of all relevant descriptions""" + result = 0.0 + for description in self.descriptions: + if description.descriptionType.fully_active(): + result += description.descriptor.activation + else: + result += description.descriptor.activation / 20.0 + if self.group: + result *= 2.0 / 3.0 + if self.changed: + result *= 2.0 + return result - def updateValue(self): - self.rawImportance = self.__calculateRawImportance() - intraStringHappiness = self.__calculateIntraStringHappiness() - self.intraStringUnhappiness = 100.0 - intraStringHappiness + def updateValue(self): + self.rawImportance = self.__calculateRawImportance() + intraStringHappiness = self.__calculateIntraStringHappiness() + self.intraStringUnhappiness = 100.0 - intraStringHappiness - interStringHappiness = 0.0 - if self.correspondence: - interStringHappiness = self.correspondence.totalStrength - self.interStringUnhappiness = 100.0 - interStringHappiness - #logging.info("Unhappy: %s"%self.interStringUnhappiness) + interStringHappiness = 0.0 + if self.correspondence: + interStringHappiness = self.correspondence.totalStrength + self.interStringUnhappiness = 100.0 - interStringHappiness + #logging.info("Unhappy: %s"%self.interStringUnhappiness) - averageHappiness = ( intraStringHappiness + interStringHappiness ) / 2 - self.totalUnhappiness = 100.0 - averageHappiness + averageHappiness = ( intraStringHappiness + interStringHappiness ) / 2 + self.totalUnhappiness = 100.0 - averageHappiness - if self.clampSalience: - self.intraStringSalience = 100.0 - self.interStringSalience = 100.0 - else: - from formulas import weightedAverage - self.intraStringSalience = weightedAverage( ((self.relativeImportance,0.2), (self.intraStringUnhappiness,0.8)) ) - self.interStringSalience = weightedAverage( ((self.relativeImportance,0.8), (self.interStringUnhappiness,0.2)) ) - self.totalSalience = (self.intraStringSalience + self.interStringSalience) / 2.0 - logging.info('Set salience of %s to %f = (%f + %f)/2' % ( - self.__str__(),self.totalSalience, self.intraStringSalience, self.interStringSalience)) + if self.clampSalience: + self.intraStringSalience = 100.0 + self.interStringSalience = 100.0 + else: + from formulas import weightedAverage + self.intraStringSalience = weightedAverage( ((self.relativeImportance,0.2), (self.intraStringUnhappiness,0.8)) ) + self.interStringSalience = weightedAverage( ((self.relativeImportance,0.8), (self.interStringUnhappiness,0.2)) ) + self.totalSalience = (self.intraStringSalience + self.interStringSalience) / 2.0 + logging.info('Set salience of %s to %f = (%f + %f)/2' % ( + self.__str__(),self.totalSalience, self.intraStringSalience, self.interStringSalience)) - def isWithin(self,other): - return self.leftStringPosition >= other.leftStringPosition and self.rightStringPosition <= other.rightStringPosition + def isWithin(self,other): + return self.leftStringPosition >= other.leftStringPosition and self.rightStringPosition <= other.rightStringPosition - def relevantDescriptions(self): - return [ d for d in self.descriptions if d.descriptionType.fully_active() ] + def relevantDescriptions(self): + return [ d for d in self.descriptions if d.descriptionType.fully_active() ] - def morePossibleDescriptions(self,node): - return [] + def morePossibleDescriptions(self,node): + return [] - def getPossibleDescriptions(self,descriptionType): - logging.info('getting possible descriptions for %s' % self) - descriptions = [ ] - from group import Group - for link in descriptionType.instanceLinks: - node = link.destination - if node == slipnet.first and self.hasDescription(slipnet.letters[0]): - descriptions += [ node ] - if node == slipnet.last and self.hasDescription(slipnet.letters[-1]): - descriptions += [ node ] - i = 1 - for number in slipnet.numbers: - if node == number and isinstance(self,Group) and len(self.objectList) == i: - descriptions += [ node ] - i += 1 - if node == slipnet.middle and self.middleObject(): - descriptions += [ node ] - s = '' - for d in descriptions: - s = '%s, %s' % (s,d.get_name()) - logging.info(s) - return descriptions + def getPossibleDescriptions(self,descriptionType): + logging.info('getting possible descriptions for %s' % self) + descriptions = [ ] + from group import Group + for link in descriptionType.instanceLinks: + node = link.destination + if node == slipnet.first and self.hasDescription(slipnet.letters[0]): + descriptions += [ node ] + if node == slipnet.last and self.hasDescription(slipnet.letters[-1]): + descriptions += [ node ] + i = 1 + for number in slipnet.numbers: + if node == number and isinstance(self,Group) and len(self.objectList) == i: + descriptions += [ node ] + i += 1 + if node == slipnet.middle and self.middleObject(): + descriptions += [ node ] + s = '' + for d in descriptions: + s = '%s, %s' % (s,d.get_name()) + logging.info(s) + return descriptions - def containsDescription(self,sought): - soughtType = sought.descriptionType - soughtDescriptor = sought.descriptor - for d in self.descriptions: - if soughtType == d.descriptionType and soughtDescriptor == d.descriptor: - return True - return False + def containsDescription(self,sought): + soughtType = sought.descriptionType + soughtDescriptor = sought.descriptor + for d in self.descriptions: + if soughtType == d.descriptionType and soughtDescriptor == d.descriptor: + return True + return False - def hasDescription(self,slipnode): - return [ d for d in self.descriptions if d.descriptor == slipnode ] and True or False + def hasDescription(self,slipnode): + return [ d for d in self.descriptions if d.descriptor == slipnode ] and True or False - def middleObject(self): - # XXX only works if string is 3 chars long - # as we have access to the string, why not just " == len / 2" ? - objectOnMyRightIsRightmost = objectOnMyLeftIsLeftmost = False - for objekt in self.string.objects: - if objekt.leftmost and objekt.rightStringPosition == self.leftStringPosition - 1: - objectOnMyLeftIsLeftmost = True - if objekt.rightmost and objekt.leftStringPosition == self.rightStringPosition + 1: - objectOnMyRightIsRightmost = True - return objectOnMyRightIsRightmost and objectOnMyLeftIsLeftmost + def middleObject(self): + # XXX only works if string is 3 chars long + # as we have access to the string, why not just " == len / 2" ? + objectOnMyRightIsRightmost = objectOnMyLeftIsLeftmost = False + for objekt in self.string.objects: + if objekt.leftmost and objekt.rightStringPosition == self.leftStringPosition - 1: + objectOnMyLeftIsLeftmost = True + if objekt.rightmost and objekt.leftStringPosition == self.rightStringPosition + 1: + objectOnMyRightIsRightmost = True + return objectOnMyRightIsRightmost and objectOnMyLeftIsLeftmost - def distinguishingDescriptor(self,descriptor): - """Whether no other object of the same type (ie. letter or group) has the same descriptor""" - if descriptor == slipnet.letter: - return False - if descriptor == slipnet.group: - return False - for number in slipnet.numbers: - if number == descriptor: - return False - return True + def distinguishingDescriptor(self,descriptor): + """Whether no other object of the same type (ie. letter or group) has the same descriptor""" + if descriptor == slipnet.letter: + return False + if descriptor == slipnet.group: + return False + for number in slipnet.numbers: + if number == descriptor: + return False + return True - def relevantDistinguishingDescriptors(self): - return [ d.descriptor for d in self.relevantDescriptions() if self.distinguishingDescriptor(d.descriptor) ] + def relevantDistinguishingDescriptors(self): + return [ d.descriptor for d in self.relevantDescriptions() if self.distinguishingDescriptor(d.descriptor) ] - def getDescriptor(self,descriptionType): - """The description attached to this object of the specified description type.""" - descriptor = None - logging.info("\nIn %s, trying for type: %s" % (self,descriptionType.get_name())) - for description in self.descriptions: - logging.info("Trying description: %s" % description) - if description.descriptionType == descriptionType: - return description.descriptor - return descriptor + def getDescriptor(self,descriptionType): + """The description attached to this object of the specified description type.""" + descriptor = None + logging.info("\nIn %s, trying for type: %s" % (self,descriptionType.get_name())) + for description in self.descriptions: + logging.info("Trying description: %s" % description) + if description.descriptionType == descriptionType: + return description.descriptor + return descriptor - def getDescriptionType(self,sought_description): - """The description_type attached to this object of the specified description""" - for description in self.descriptions: - if description.descriptor == sought_description: - return description.descriptionType - description = None - return description + def getDescriptionType(self,sought_description): + """The description_type attached to this object of the specified description""" + for description in self.descriptions: + if description.descriptor == sought_description: + return description.descriptionType + description = None + return description - def getCommonGroups(self,other): - return [ o for o in self.string.objects if self.isWithin(o) and other.isWithin(o) ] + def getCommonGroups(self,other): + return [ o for o in self.string.objects if self.isWithin(o) and other.isWithin(o) ] - def letterDistance(self,other): - if other.leftStringPosition > self.rightStringPosition: - return other.leftStringPosition - self.rightStringPosition - if self.leftStringPosition > other.rightStringPosition: - return self.leftStringPosition - other.rightStringPosition - return 0 + def letterDistance(self,other): + if other.leftStringPosition > self.rightStringPosition: + return other.leftStringPosition - self.rightStringPosition + if self.leftStringPosition > other.rightStringPosition: + return self.leftStringPosition - other.rightStringPosition + return 0 - def letterSpan(self): - return self.rightStringPosition - self.leftStringPosition + 1 + def letterSpan(self): + return self.rightStringPosition - self.leftStringPosition + 1 - def beside(self,other): - if self.string != other.string: - return False - if self.leftStringPosition == other.rightStringPosition + 1: - return True - return other.leftStringPosition == self.rightStringPosition + 1 + def beside(self,other): + if self.string != other.string: + return False + if self.leftStringPosition == other.rightStringPosition + 1: + return True + return other.leftStringPosition == self.rightStringPosition + 1 diff --git a/copycat/workspaceString.py b/copycat/workspaceString.py index 53f26f7..ea68d01 100644 --- a/copycat/workspaceString.py +++ b/copycat/workspaceString.py @@ -3,78 +3,78 @@ from letter import Letter from slipnet import slipnet class WorkspaceString(object): - def __init__(self, s): - self.string = s - self.bonds = [] - self.objects = [] - self.letters = [] - self.length = len(s) - self.intraStringUnhappiness = 0.0 - if not self.length: - return - position = 0 - from workspace import workspace + def __init__(self, s): + self.string = s + self.bonds = [] + self.objects = [] + self.letters = [] + self.length = len(s) + self.intraStringUnhappiness = 0.0 + if not self.length: + return + position = 0 + from workspace import workspace - for c in self.string.upper(): - value = ord(c) - ord('A') - letter = Letter(self, position + 1, self.length) - letter.workspaceString = self - letter.addDescription(slipnet.objectCategory, slipnet.letter) - letter.addDescription(slipnet.letterCategory, slipnet.letters[value]) - letter.describe(position + 1, self.length) - workspace.buildDescriptions(letter) - self.letters += [letter] - position += 1 + for c in self.string.upper(): + value = ord(c) - ord('A') + letter = Letter(self, position + 1, self.length) + letter.workspaceString = self + letter.addDescription(slipnet.objectCategory, slipnet.letter) + letter.addDescription(slipnet.letterCategory, slipnet.letters[value]) + letter.describe(position + 1, self.length) + workspace.buildDescriptions(letter) + self.letters += [letter] + position += 1 - def __repr__(self): - return '' % self.string + def __repr__(self): + return '' % self.string - def __str__(self): - return '%s with %d letters, %d objects, %d bonds' % (self.string, len(self.letters), len(self.objects), len(self.bonds)) + def __str__(self): + return '%s with %d letters, %d objects, %d bonds' % (self.string, len(self.letters), len(self.objects), len(self.bonds)) - def log(self, heading): - s = '%s: %s - ' % (heading, self) - for l in self.letters: - s += ' %s' % l - s += '; ' - for o in self.objects: - s += ' %s' % o - s += '; ' - for b in self.bonds: - s += ' %s' % b - s += '.' - logging.info(s) + def log(self, heading): + s = '%s: %s - ' % (heading, self) + for l in self.letters: + s += ' %s' % l + s += '; ' + for o in self.objects: + s += ' %s' % o + s += '; ' + for b in self.bonds: + s += ' %s' % b + s += '.' + logging.info(s) - def __len__(self): - return len(self.string) + def __len__(self): + return len(self.string) - def __getitem__(self, i): - return self.string[i] + def __getitem__(self, i): + return self.string[i] - def updateRelativeImportance(self): - """Update the normalised importance of all objects in the string""" - total = sum([o.rawImportance for o in self.objects]) - if not total: - for o in self.objects: - o.relativeImportance = 0.0 - else: - for o in self.objects: - logging.info('object: %s, relative: %d = raw: %d / total: %d' % ( - o, o.relativeImportance * 1000, o.rawImportance, total )) - o.relativeImportance = o.rawImportance / total + def updateRelativeImportance(self): + """Update the normalised importance of all objects in the string""" + total = sum([o.rawImportance for o in self.objects]) + if not total: + for o in self.objects: + o.relativeImportance = 0.0 + else: + for o in self.objects: + logging.info('object: %s, relative: %d = raw: %d / total: %d' % ( + o, o.relativeImportance * 1000, o.rawImportance, total )) + o.relativeImportance = o.rawImportance / total - def updateIntraStringUnhappiness(self): - if not len(self.objects): - self.intraStringUnhappiness = 0.0 - return - total = sum([o.intraStringUnhappiness for o in self.objects]) - self.intraStringUnhappiness = total / len(self.objects) + def updateIntraStringUnhappiness(self): + if not len(self.objects): + self.intraStringUnhappiness = 0.0 + return + total = sum([o.intraStringUnhappiness for o in self.objects]) + self.intraStringUnhappiness = total / len(self.objects) - def equivalentGroup(self, sought): - from group import Group + def equivalentGroup(self, sought): + from group import Group - for objekt in self.objects: - if isinstance(objekt, Group): - if objekt.sameGroup(sought): - return objekt - return None + for objekt in self.objects: + if isinstance(objekt, Group): + if objekt.sameGroup(sought): + return objekt + return None diff --git a/copycat/workspaceStructure.py b/copycat/workspaceStructure.py index 0b41260..107e16b 100644 --- a/copycat/workspaceStructure.py +++ b/copycat/workspaceStructure.py @@ -1,37 +1,37 @@ import formulas class WorkspaceStructure(object): - def __init__(self): - self.string = None - self.internalStrength = 0.0 - self.externalStrength = 0.0 - self.totalStrength = 0.0 + def __init__(self): + self.string = None + self.internalStrength = 0.0 + self.externalStrength = 0.0 + self.totalStrength = 0.0 - def updateStrength(self): - self.updateInternalStrength() - self.updateExternalStrength() - self.updateTotalStrength() + def updateStrength(self): + self.updateInternalStrength() + self.updateExternalStrength() + self.updateTotalStrength() - def updateTotalStrength(self): - """Recalculate the total strength based on internal and external strengths""" - weights = ( (self.internalStrength, self.internalStrength), (self.externalStrength, 100 - self.internalStrength) ) - strength = formulas.weightedAverage(weights) - self.totalStrength = strength + def updateTotalStrength(self): + """Recalculate the total strength based on internal and external strengths""" + weights = ( (self.internalStrength, self.internalStrength), (self.externalStrength, 100 - self.internalStrength) ) + strength = formulas.weightedAverage(weights) + self.totalStrength = strength - def totalWeakness(self): - """The total weakness is derived from total strength""" - return 100 - self.totalStrength ** 0.95 + def totalWeakness(self): + """The total weakness is derived from total strength""" + return 100 - self.totalStrength ** 0.95 - def updateInternalStrength(self): - """How internally cohesive the structure is""" - raise NotImplementedError, 'call of abstract method: WorkspaceStructure.updateInternalStrength()' + def updateInternalStrength(self): + """How internally cohesive the structure is""" + raise NotImplementedError, 'call of abstract method: WorkspaceStructure.updateInternalStrength()' - def updateExternalStrength(self): - raise NotImplementedError, 'call of abstract method: WorkspaceStructure.updateExternalStrength()' + def updateExternalStrength(self): + raise NotImplementedError, 'call of abstract method: WorkspaceStructure.updateExternalStrength()' - def break_the_structure(self): - """Break this workspace structure + def break_the_structure(self): + """Break this workspace structure - Exactly what is broken depends on sub-class - """ - raise NotImplementedError, 'call of abstract method: WorkspaceStructure.break_the_structure()' + Exactly what is broken depends on sub-class + """ + raise NotImplementedError, 'call of abstract method: WorkspaceStructure.break_the_structure()' From 33cf41b585c656dc12a08fc55c156199b47bf05f Mon Sep 17 00:00:00 2001 From: James Tauber Date: Sat, 1 Dec 2012 02:00:03 -0500 Subject: [PATCH 3/7] fix linter errors and warnings --- copycat/bond.py | 44 ++--- copycat/codeletMethods.py | 342 +++++++++++++++++++--------------- copycat/coderack.py | 20 +- copycat/coderackPressure.py | 6 +- copycat/conceptMapping.py | 7 +- copycat/copycat.py | 2 + copycat/correspondence.py | 46 ++--- copycat/description.py | 15 +- copycat/formulas.py | 65 ++++--- copycat/group.py | 47 +++-- copycat/grouprun.py | 1 + copycat/letter.py | 34 ++-- copycat/replacement.py | 2 +- copycat/rule.py | 32 ++-- copycat/sliplink.py | 3 +- copycat/slipnet.py | 3 +- copycat/slipnode.py | 9 +- copycat/temperature.py | 1 + copycat/utils.py | 6 +- copycat/workspace.py | 2 +- copycat/workspaceFormulas.py | 60 +++--- copycat/workspaceObject.py | 74 ++++---- copycat/workspaceString.py | 3 +- copycat/workspaceStructure.py | 9 +- 24 files changed, 456 insertions(+), 377 deletions(-) diff --git a/copycat/bond.py b/copycat/bond.py index 778c4f1..666e466 100644 --- a/copycat/bond.py +++ b/copycat/bond.py @@ -2,8 +2,9 @@ from workspaceStructure import WorkspaceStructure from slipnet import slipnet from workspace import workspace + class Bond(WorkspaceStructure): - def __init__(self,source, destination, bondCategory, bondFacet, sourceDescriptor, destinationDescriptor): + def __init__(self, source, destination, bondCategory, bondFacet, sourceDescriptor, destinationDescriptor): WorkspaceStructure.__init__(self) self.source = source self.string = self.source.string @@ -38,18 +39,18 @@ class Bond(WorkspaceStructure): return '' % self.__str__() def __str__(self): - return '%s bond between %s and %s' % ( self.category.name, self.leftObject, self.rightObject) + return '%s bond between %s and %s' % (self.category.name, self.leftObject, self.rightObject) def buildBond(self): - workspace.structures += [ self ] - self.string.bonds += [ self ] + workspace.structures += [self] + self.string.bonds += [self] self.category.buffer = 100.0 if self.directionCategory: self.directionCategory.buffer = 100.0 self.leftObject.rightBond = self self.rightObject.leftBond = self - self.leftObject.bonds += [ self ] - self.rightObject.bonds += [ self ] + self.leftObject.bonds += [self] + self.rightObject.bonds += [self] def break_the_structure(self): self.breakBond() @@ -78,7 +79,7 @@ class Bond(WorkspaceStructure): objekt = self.leftObject.correspondence.objectFromInitial if objekt.leftmost and objekt.rightBond: if objekt.rightBond.directionCategory and objekt.rightBond.directionCategory != self.directionCategory: - incompatibles += [ correspondence ] + incompatibles += [correspondence] if self.rightObject.rightmost and self.rightObject.correspondence: correspondence = self.rightObject.correspondence if self.string == workspace.initial: @@ -87,7 +88,7 @@ class Bond(WorkspaceStructure): objekt = self.rightObject.correspondence.objectFromInitial if objekt.rightmost and objekt.leftBond: if objekt.leftBond.directionCategory and objekt.leftBond.directionCategory != self.directionCategory: - incompatibles += [ correspondence ] + incompatibles += [correspondence] return incompatibles def updateInternalStrength(self): @@ -104,7 +105,7 @@ class Bond(WorkspaceStructure): facetFactor = 1.0 else: facetFactor = 0.7 - strength = min(100.0,memberCompatibility * facetFactor * self.category.bondDegreeOfAssociation()) + strength = min(100.0, memberCompatibility * facetFactor * self.category.bondDegreeOfAssociation()) self.internalStrength = strength def updateExternalStrength(self): @@ -114,21 +115,21 @@ class Bond(WorkspaceStructure): density = self.localDensity() / 100.0 density = density ** 0.5 * 100.0 supportFactor = 0.6 ** (1.0 / supporters ** 3) - supportFactor = max(1.0,supportFactor) + supportFactor = max(1.0, supportFactor) strength = supportFactor * density self.externalStrength = strength def numberOfLocalSupportingBonds(self): - return len([ b for b in self.string.bonds if b.string == self.get_source().string and + return len([b for b in self.string.bonds if b.string == self.get_source().string and self.leftObject.letterDistance(b.leftObject) != 0 and self.rightObject.letterDistance(b.rightObject) != 0 and self.category == b.category and - self.directionCategory == b.directionCategory ]) + self.directionCategory == b.directionCategory]) - def sameCategories(self,other): + def sameCategories(self, other): return self.category == other.category and self.directionCategory == other.directionCategory - def myEnds(self,object1,object2): + def myEnds(self, object1, object2): if self.get_source() == object1 and self.destination == object2: return True return self.get_source() == object2 and self.destination == object1 @@ -144,19 +145,19 @@ class Bond(WorkspaceStructure): if object1.beside(object2): slotSum += 1.0 for bond in self.string.bonds: - if bond != self and self.sameCategories(bond) and self.myEnds(object1,object2): + if bond != self and self.sameCategories(bond) and self.myEnds(object1, object2): supportSum += 1.0 if slotSum == 0.0: return 0.0 return 100.0 * supportSum / slotSum - def sameNeighbours(self,other): + def sameNeighbours(self, other): if self.leftObject == other.leftObject: return True return self.rightObject == other.rightObject def getIncompatibleBonds(self): - return [ b for b in self.string.bonds if self.sameNeighbours(b) ] + return [b for b in self.string.bonds if self.sameNeighbours(b)] def get_source(self): return self.source @@ -164,19 +165,20 @@ class Bond(WorkspaceStructure): def set_source(self, value): self.source = value + def possibleGroupBonds(bondCategory, directionCategory, bondFacet, bonds): result = [] for bond in bonds: if bond.category == bondCategory and bond.directionCategory == directionCategory: - result += [ bond ] + result += [bond] else: # a modified bond might be made if bondCategory == slipnet.sameness: - return None # a different bond cannot be made here + return None # a different bond cannot be made here if bond.category == bondCategory or bond.directionCategory == directionCategory: - return None # a different bond cannot be made here + return None # a different bond cannot be made here if bond.category == slipnet.sameness: return None bond = Bond(bond.destination, bond.get_source(), bondCategory, bondFacet, bond.destinationDescriptor, bond.sourceDescriptor) - result += [ bond ] + result += [bond] return result diff --git a/copycat/codeletMethods.py b/copycat/codeletMethods.py index 4de8dff..f618add 100644 --- a/copycat/codeletMethods.py +++ b/copycat/codeletMethods.py @@ -10,56 +10,63 @@ from group import Group from bond import Bond, possibleGroupBonds from correspondence import Correspondence + # some methods common to the codelets def __showWhichStringObjectIsFrom(structure): if not structure: return whence = 'other' - if isinstance(structure,WorkspaceObject): - whence='target' + if isinstance(structure, WorkspaceObject): + whence = 'target' if structure.string == workspace.initial: - whence='initial' - print 'object chosen = %s from %s string' % ( structure, whence ) + whence = 'initial' + print 'object chosen = %s from %s string' % (structure, whence) -def __getScoutSource(slipnode,relevanceMethod,typeName): - initialRelevance = relevanceMethod(workspace.initial,slipnode) - targetRelevance = relevanceMethod(workspace.target,slipnode) + +def __getScoutSource(slipnode, relevanceMethod, typeName): + initialRelevance = relevanceMethod(workspace.initial, slipnode) + targetRelevance = relevanceMethod(workspace.target, slipnode) initialUnhappiness = workspace.initial.intraStringUnhappiness targetUnhappiness = workspace.target.intraStringUnhappiness - logging.info('initial : relevance = %d, unhappiness=%d' % (initialRelevance,int(initialUnhappiness)) ) - logging.info('target : relevance = %d, unhappiness=%d' % (targetRelevance,int(targetUnhappiness)) ) + logging.info('initial : relevance = %d, unhappiness=%d' % (initialRelevance, int(initialUnhappiness))) + logging.info('target : relevance = %d, unhappiness=%d' % (targetRelevance, int(targetUnhappiness))) string = workspace.initial - if utils.random() * (initialRelevance + initialUnhappiness+targetRelevance+targetUnhappiness) > (initialRelevance + initialUnhappiness): + if utils.random() * (initialRelevance + initialUnhappiness + targetRelevance + targetUnhappiness) > (initialRelevance + initialUnhappiness): string = workspace.target - logging.info('target string selected: %s for %s' % (workspace.target,typeName)) + logging.info('target string selected: %s for %s' % (workspace.target, typeName)) else: - logging.info('initial string selected: %s for %s' % (workspace.initial,typeName)) - source = chooseUnmodifiedObject('intraStringSalience',string.objects) + logging.info('initial string selected: %s for %s' % (workspace.initial, typeName)) + source = chooseUnmodifiedObject('intraStringSalience', string.objects) return source -def __getBondFacet(source,destination): - bondFacet = chooseBondFacet(source,destination) + +def __getBondFacet(source, destination): + bondFacet = chooseBondFacet(source, destination) assert bondFacet return bondFacet -def __getDescriptors(bondFacet,source,destination): + +def __getDescriptors(bondFacet, source, destination): sourceDescriptor = source.getDescriptor(bondFacet) destinationDescriptor = destination.getDescriptor(bondFacet) assert sourceDescriptor and destinationDescriptor return sourceDescriptor, destinationDescriptor -def __allOppositeMappings(mappings): - return len([ m for m in mappings if m.label != slipnet.opposite ]) == 0 -def __structureVsStructure(structure1,weight1,structure2,weight2): +def __allOppositeMappings(mappings): + return len([m for m in mappings if m.label != slipnet.opposite]) == 0 + + +def __structureVsStructure(structure1, weight1, structure2, weight2): structure1.updateStrength() structure2.updateStrength() weightedStrength1 = temperatureAdjustedValue(structure1.totalStrength * weight1) weightedStrength2 = temperatureAdjustedValue(structure2.totalStrength * weight2) rhs = (weightedStrength1 + weightedStrength2) * utils.random() - logging.info('%d > %d' % (weightedStrength1,rhs)) + logging.info('%d > %d' % (weightedStrength1, rhs)) return weightedStrength1 > rhs + def __fightItOut(structure, structureWeight, incompatibles, incompatibleWeight): if not (incompatibles and len(incompatibles)): return True @@ -70,9 +77,10 @@ def __fightItOut(structure, structureWeight, incompatibles, incompatibleWeight): logging.info('won fight with %s' % incompatible) return True -def __fightIncompatibles(incompatibles,structure,name,structureWeight,incompatibleWeight): + +def __fightIncompatibles(incompatibles, structure, name, structureWeight, incompatibleWeight): if len(incompatibles): - if __fightItOut(structure,structureWeight,incompatibles,incompatibleWeight): + if __fightItOut(structure, structureWeight, incompatibles, incompatibleWeight): logging.info('broke the %s' % name) return True logging.info('failed to break %s: Fizzle' % name) @@ -80,6 +88,7 @@ def __fightIncompatibles(incompatibles,structure,name,structureWeight,incompatib logging.info('no incompatible %s' % name) return True + def __slippability(conceptMappings): for mapping in conceptMappings: slippiness = mapping.slipability() / 100.0 @@ -88,64 +97,69 @@ def __slippability(conceptMappings): return True return False + # start the actual codelets def breaker(): - probabilityOfFizzle = (100.0-Temperature)/100.0 + probabilityOfFizzle = (100.0 - Temperature) / 100.0 assert not coinFlip(probabilityOfFizzle) # choose a structure at random - structures = [ s for s in workspace.structures if - isinstance(s,Group) or - isinstance(s,Bond) or - isinstance(s,Correspondence) ] + structures = [s for s in workspace.structures if + isinstance(s, Group) or + isinstance(s, Bond) or + isinstance(s, Correspondence)] assert len(structures) structure = utils.choice(structures) __showWhichStringObjectIsFrom(structure) - breakObjects = [ structure ] - if isinstance(structure,Bond): + breakObjects = [structure] + if isinstance(structure, Bond): if structure.source.group and structure.source.group == structure.destination.group: - breakObjects += [ structure.source.group ] + breakObjects += [structure.source.group] # try to break all objects for structure in breakObjects: - breakProbability = temperatureAdjustedProbability(structure.totalStrength/100.0) + breakProbability = temperatureAdjustedProbability(structure.totalStrength / 100.0) if coinFlip(breakProbability): return for structure in breakObjects: structure.break_the_structure() + def bottom_up_description_scout(codelet): - chosenObject = chooseUnmodifiedObject('totalSalience',workspace.objects) + chosenObject = chooseUnmodifiedObject('totalSalience', workspace.objects) assert chosenObject __showWhichStringObjectIsFrom(chosenObject) description = chooseRelevantDescriptionByActivation(chosenObject) assert description sliplinks = similarPropertyLinks(description.descriptor) assert sliplinks and len(sliplinks) - values = [ sliplink.degreeOfAssociation() * sliplink.destination.activation for sliplink in sliplinks ] + values = [sliplink.degreeOfAssociation() * sliplink.destination.activation for sliplink in sliplinks] i = selectListPosition(values) - chosen = sliplinks[ i ] + chosen = sliplinks[i] chosenProperty = chosen.destination - coderack.proposeDescription(chosenObject,chosenProperty.category(),chosenProperty,codelet) + coderack.proposeDescription(chosenObject, chosenProperty.category(), chosenProperty, codelet) + def top_down_description_scout(codelet): descriptionType = codelet.arguments[0] - chosenObject = chooseUnmodifiedObject('totalSalience',workspace.objects) + chosenObject = chooseUnmodifiedObject('totalSalience', workspace.objects) assert chosenObject __showWhichStringObjectIsFrom(chosenObject) descriptions = chosenObject.getPossibleDescriptions(descriptionType) assert descriptions and len(descriptions) - values = [ n.activation for n in descriptions ] + values = [n.activation for n in descriptions] i = selectListPosition(values) - chosenProperty = descriptions[ i ] - coderack.proposeDescription(chosenObject,chosenProperty.category(), chosenProperty,codelet) + chosenProperty = descriptions[i] + coderack.proposeDescription(chosenObject, chosenProperty.category(), chosenProperty, codelet) + def description_strength_tester(codelet): description = codelet.arguments[0] description.descriptor.buffer = 100.0 description.updateStrength() strength = description.totalStrength - probability = temperatureAdjustedProbability(strength/100.0) + probability = temperatureAdjustedProbability(strength / 100.0) assert formulas.coinFlip(probability) - coderack.newCodelet('description-builder',codelet,strength) + coderack.newCodelet('description-builder', codelet, strength) + def description_builder(codelet): description = codelet.arguments[0] @@ -156,16 +170,17 @@ def description_builder(codelet): else: description.build() + def bottom_up_bond_scout(codelet): - source = chooseUnmodifiedObject('intraStringSalience',workspace.objects) + source = chooseUnmodifiedObject('intraStringSalience', workspace.objects) __showWhichStringObjectIsFrom(source) destination = chooseNeighbour(source) assert destination logging.info('destination: %s' % destination) - bondFacet = __getBondFacet(source,destination) + bondFacet = __getBondFacet(source, destination) logging.info('chosen bond facet: %s' % bondFacet.get_name()) - logging.info('Source: %s, destination: %s' % (source,destination)) - sourceDescriptor, destinationDescriptor = __getDescriptors(bondFacet,source,destination) + logging.info('Source: %s, destination: %s' % (source, destination)) + sourceDescriptor, destinationDescriptor = __getDescriptors(bondFacet, source, destination) logging.info("source descriptor: " + sourceDescriptor.name.upper()) logging.info("destination descriptior: " + destinationDescriptor.name.upper()) category = sourceDescriptor.getBondCategory(destinationDescriptor) @@ -173,15 +188,16 @@ def bottom_up_bond_scout(codelet): if category == slipnet.identity: category = slipnet.sameness logging.info('proposing %s bond ' % category.name) - coderack.proposeBond(source,destination,category,bondFacet,sourceDescriptor,destinationDescriptor,codelet) + coderack.proposeBond(source, destination, category, bondFacet, sourceDescriptor, destinationDescriptor, codelet) + def rule_scout(codelet): assert workspace.numberOfUnreplacedObjects() == 0 - changedObjects = [ o for o in workspace.initial.objects if o.changed ] + changedObjects = [o for o in workspace.initial.objects if o.changed] #assert len(changedObjects) < 2 # if there are no changed objects, propose a rule with no changes if not changedObjects: - return coderack.proposeRule(None,None,None,None,codelet) + return coderack.proposeRule(None, None, None, None, codelet) changed = changedObjects[-1] # generate a list of distinguishing descriptions for the first object @@ -190,11 +206,11 @@ def rule_scout(codelet): objectList = [] position = changed.getDescriptor(slipnet.stringPositionCategory) if position: - objectList += [ position ] + objectList += [position] letter = changed.getDescriptor(slipnet.letterCategory) - otherObjectsOfSameLetter = [ o for o in workspace.initial.objects if not o != changed and o.getDescriptionType(letter) ] - if not len(otherObjectsOfSameLetter): # then the letter is a distinguishing feature - objectList += [ letter ] + otherObjectsOfSameLetter = [o for o in workspace.initial.objects if not o != changed and o.getDescriptionType(letter)] + if not len(otherObjectsOfSameLetter): # then the letter is a distinguishing feature + objectList += [letter] # if this object corresponds to another object in the workspace # objectList = the union of this and the distingushing descriptors if changed.correspondence: @@ -204,49 +220,51 @@ def rule_scout(codelet): for node in objectList: node = node.applySlippages(slippages) if targetObject.hasDescription(node) and targetObject.distinguishingDescriptor(node): - newList += [ node ] - objectList = newList # XXX surely this should be += ("the union of this and the distinguishing descriptors") + newList += [node] + objectList = newList # XXX surely this should be += ("the union of this and the distinguishing descriptors") assert objectList and len(objectList) # use conceptual depth to choose a description valueList = [] for node in objectList: depth = node.conceptualDepth value = temperatureAdjustedValue(depth) - valueList += [ value ] + valueList += [value] i = selectListPosition(valueList) - descriptor = objectList[ i ] + descriptor = objectList[i] # choose the relation (change the letmost object to..xxxx) i.e. "successor" or "d" objectList = [] if changed.replacement.relation: - objectList += [ changed.replacement.relation ] - objectList += [ changed.replacement.objectFromModified.getDescriptor(slipnet.letterCategory) ] + objectList += [changed.replacement.relation] + objectList += [changed.replacement.objectFromModified.getDescriptor(slipnet.letterCategory)] # use conceptual depth to choose a relation valueList = [] for node in objectList: depth = node.conceptualDepth value = temperatureAdjustedValue(depth) - valueList += [ value ] + valueList += [value] i = selectListPosition(valueList) - relation = objectList[ i ] - coderack.proposeRule(slipnet.letterCategory,descriptor,slipnet.letter,relation,codelet) + relation = objectList[i] + coderack.proposeRule(slipnet.letterCategory, descriptor, slipnet.letter, relation, codelet) + def rule_strength_tester(codelet): rule = codelet.arguments[0] rule.updateStrength() probability = temperatureAdjustedProbability(rule.totalStrength / 100.0) assert utils.random() <= probability - coderack.newCodelet('rule-builder',codelet,rule.totalStrength,rule) + coderack.newCodelet('rule-builder', codelet, rule.totalStrength, rule) + def replacement_finder(): # choose random letter in initial string - letters = [ o for o in workspace.initial.objects if isinstance(o,Letter) ] + letters = [o for o in workspace.initial.objects if isinstance(o, Letter)] letterOfInitialString = utils.choice(letters) logging.info('selected letter in initial string = %s' % letterOfInitialString) if letterOfInitialString.replacement: logging.info("Replacement already found for %s, so fizzling" % letterOfInitialString) return position = letterOfInitialString.leftStringPosition - moreLetters = [ o for o in workspace.modified.objects if isinstance(o,Letter) and o.leftStringPosition == position ] + moreLetters = [o for o in workspace.modified.objects if isinstance(o, Letter) and o.leftStringPosition == position] letterOfModifiedString = moreLetters and moreLetters[0] or None assert letterOfModifiedString position -= 1 @@ -254,27 +272,28 @@ def replacement_finder(): modifiedAscii = ord(workspace.modifiedString[position]) diff = initialAscii - modifiedAscii if abs(diff) < 2: - relations = { 0:slipnet.sameness, -1:slipnet.successor, 1:slipnet.predecessor } + relations = {0: slipnet.sameness, -1: slipnet.successor, 1: slipnet.predecessor} relation = relations[diff] logging.info('Relation found: %s' % relation.name) else: relation = None logging.info('no relation found') - letterOfInitialString.replacement = Replacement(letterOfInitialString,letterOfModifiedString,relation) + letterOfInitialString.replacement = Replacement(letterOfInitialString, letterOfModifiedString, relation) if relation != slipnet.sameness: letterOfInitialString.changed = True workspace.changedObject = letterOfInitialString logging.info('building replacement') + def top_down_bond_scout__category(codelet): logging.info('top_down_bond_scout__category') category = codelet.arguments[0] - source = __getScoutSource(category,localBondCategoryRelevance,'bond') + source = __getScoutSource(category, localBondCategoryRelevance, 'bond') destination = chooseNeighbour(source) - logging.info('source: %s, destination: %s' % (source,destination)) + logging.info('source: %s, destination: %s' % (source, destination)) assert destination - bondFacet = __getBondFacet(source,destination) - sourceDescriptor, destinationDescriptor = __getDescriptors(bondFacet,source,destination) + bondFacet = __getBondFacet(source, destination) + sourceDescriptor, destinationDescriptor = __getDescriptors(bondFacet, source, destination) forwardBond = sourceDescriptor.getBondCategory(destinationDescriptor) if forwardBond == slipnet.identity: forwardBond = slipnet.sameness @@ -283,37 +302,40 @@ def top_down_bond_scout__category(codelet): backwardBond = destinationDescriptor.getBondCategory(sourceDescriptor) assert category == forwardBond or category == backwardBond if category == forwardBond: - coderack.proposeBond(source,destination,category,bondFacet,sourceDescriptor, destinationDescriptor,codelet) + coderack.proposeBond(source, destination, category, bondFacet, sourceDescriptor, destinationDescriptor, codelet) else: - coderack.proposeBond(destination,source,category,bondFacet,destinationDescriptor,sourceDescriptor,codelet) + coderack.proposeBond(destination, source, category, bondFacet, destinationDescriptor, sourceDescriptor, codelet) + def top_down_bond_scout__direction(codelet): direction = codelet.arguments[0] - source = __getScoutSource(direction,localDirectionCategoryRelevance,'bond') - destination = chooseDirectedNeighbor(source,direction) + source = __getScoutSource(direction, localDirectionCategoryRelevance, 'bond') + destination = chooseDirectedNeighbor(source, direction) assert destination logging.info('to object: %s' % destination) - bondFacet = __getBondFacet(source,destination) - sourceDescriptor, destinationDescriptor = __getDescriptors(bondFacet,source,destination) + bondFacet = __getBondFacet(source, destination) + sourceDescriptor, destinationDescriptor = __getDescriptors(bondFacet, source, destination) category = sourceDescriptor.getBondCategory(destinationDescriptor) assert category if category == slipnet.identity: category = slipnet.sameness - coderack.proposeBond(source,destination,category,bondFacet,sourceDescriptor, destinationDescriptor,codelet) + coderack.proposeBond(source, destination, category, bondFacet, sourceDescriptor, destinationDescriptor, codelet) + def bond_strength_tester(codelet): bond = codelet.arguments[0] __showWhichStringObjectIsFrom(bond) bond.updateStrength() strength = bond.totalStrength - probability = temperatureAdjustedProbability(strength/100.0) - logging.info('bond strength = %d for %s' % (strength,bond)) + probability = temperatureAdjustedProbability(strength / 100.0) + logging.info('bond strength = %d for %s' % (strength, bond)) assert formulas.coinFlip(probability) bond.facet.buffer = 100.0 bond.sourceDescriptor.buffer = 100.0 bond.destinationDescriptor.buffer = 100.0 logging.info("succeeded: posting bond-builder") - coderack.newCodelet('bond-builder',codelet,strength) + coderack.newCodelet('bond-builder', codelet, strength) + def bond_builder(codelet): bond = codelet.arguments[0] @@ -331,9 +353,9 @@ def bond_builder(codelet): logging.info('number of incompatibleBonds: %d' % len(incompatibleBonds)) if len(incompatibleBonds): logging.info('%s' % incompatibleBonds[0]) - assert __fightIncompatibles(incompatibleBonds,bond,'bonds',1.0,1.0) + assert __fightIncompatibles(incompatibleBonds, bond, 'bonds', 1.0, 1.0) incompatibleGroups = bond.source.getCommonGroups(bond.destination) - assert __fightIncompatibles(incompatibleGroups,bond,'groups',1.0,1.0) + assert __fightIncompatibles(incompatibleGroups, bond, 'groups', 1.0, 1.0) # fight all incompatible correspondences incompatibleCorrespondences = [] if bond.leftObject.leftmost or bond.rightObject.rightmost: @@ -341,7 +363,7 @@ def bond_builder(codelet): incompatibleCorrespondences = bond.getIncompatibleCorrespondences() if incompatibleCorrespondences: logging.info("trying to break incompatible correspondences") - assert __fightItOut(bond,2.0,incompatibleCorrespondences,3.0) + assert __fightItOut(bond, 2.0, incompatibleCorrespondences, 3.0) #assert __fightIncompatibles(incompatibleCorrespondences,bond,'correspondences',2.0,3.0) for incompatible in incompatibleBonds: incompatible.break_the_structure() @@ -352,19 +374,20 @@ def bond_builder(codelet): logging.info('building bond %s' % bond) bond.buildBond() + def top_down_group_scout__category(codelet): groupCategory = codelet.arguments[0] category = groupCategory.getRelatedNode(slipnet.bondCategory) assert category - source = __getScoutSource(category,localBondCategoryRelevance,'group') + source = __getScoutSource(category, localBondCategoryRelevance, 'group') assert source and not source.spansString() if source.leftmost: direction = slipnet.right elif source.rightmost: direction = slipnet.left else: - activations = [ slipnet.left.activation ] - activations += [ slipnet.right.activation ] + activations = [slipnet.left.activation] + activations += [slipnet.right.activation] if not selectListPosition(activations): direction = slipnet.left else: @@ -380,11 +403,11 @@ def top_down_group_scout__category(codelet): else: firstBond = source.rightBond if not firstBond or firstBond.category != category: - if category == slipnet.sameness and isinstance(source,Letter): - group = Group(source.string,slipnet.samenessGroup, None,slipnet.letterCategory, [ source ], []) + if category == slipnet.sameness and isinstance(source, Letter): + group = Group(source.string, slipnet.samenessGroup, None, slipnet.letterCategory, [source], []) probability = group.singleLetterGroupProbability() assert utils.random() >= probability - coderack.proposeSingleLetterGroup( source, codelet) + coderack.proposeSingleLetterGroup(source, codelet) return direction = firstBond.directionCategory search = True @@ -414,26 +437,27 @@ def top_down_group_scout__category(codelet): destination = destination.rightBond.rightObject search = True assert destination != source - objects = [ source ] + objects = [source] bonds = [] while source != destination: - bonds += [ source.rightBond ] - objects += [ source.rightBond.rightObject ] + bonds += [source.rightBond] + objects += [source.rightBond.rightObject] source = source.rightBond.rightObject - coderack.proposeGroup(objects,bonds,groupCategory,direction,bondFacet,codelet) + coderack.proposeGroup(objects, bonds, groupCategory, direction, bondFacet, codelet) + def top_down_group_scout__direction(codelet): direction = codelet.arguments[0] - source = __getScoutSource(direction,localDirectionCategoryRelevance,'direction') + source = __getScoutSource(direction, localDirectionCategoryRelevance, 'direction') logging.info('source chosen = %s' % source) assert not source.spansString() - if source.leftmost : + if source.leftmost: mydirection = slipnet.right elif source.rightmost: mydirection = slipnet.left else: - activations = [ slipnet.left.activation ] - activations += [ slipnet.right.activation ] + activations = [slipnet.left.activation] + activations += [slipnet.right.activation] if not selectListPosition(activations): mydirection = slipnet.left else: @@ -464,7 +488,7 @@ def top_down_group_scout__direction(codelet): category = firstBond.category assert category groupCategory = category.getRelatedNode(slipnet.groupCategory) - logging.info('trying from %s to %s' % (source,category.name) ) + logging.info('trying from %s to %s' % (source, category.name)) bondFacet = None # find leftmost object in group with these bonds search = True @@ -491,23 +515,24 @@ def top_down_group_scout__direction(codelet): destination = destination.rightBond.rightObject search = True assert destination != source - logging.info('proposing group from %s to %s' % (source,destination) ) - objects = [ source ] + logging.info('proposing group from %s to %s' % (source, destination)) + objects = [source] bonds = [] while source != destination: - bonds += [ source.rightBond ] - objects += [ source.rightBond.rightObject ] + bonds += [source.rightBond] + objects += [source.rightBond.rightObject] source = source.rightBond.rightObject - coderack.proposeGroup(objects,bonds,groupCategory,direction,bondFacet,codelet) + coderack.proposeGroup(objects, bonds, groupCategory, direction, bondFacet, codelet) + #noinspection PyStringFormat def group_scout__whole_string(codelet): string = workspace.initial if utils.random() > 0.5: string = workspace.target - logging.info('target string selected: %s' % workspace.target ) + logging.info('target string selected: %s' % workspace.target) else: - logging.info('initial string selected: %s' % workspace.initial ) + logging.info('initial string selected: %s' % workspace.initial) # find leftmost object & the highest group to which it belongs leftmost = None for objekt in string.objects: @@ -518,14 +543,14 @@ def group_scout__whole_string(codelet): if leftmost.spansString(): # the object already spans the string - propose this object group = leftmost - coderack.proposeGroup(group.objectList, group.bondList,group.groupCategory,group.directionCategory, group.facet,codelet) + coderack.proposeGroup(group.objectList, group.bondList, group.groupCategory, group.directionCategory, group.facet, codelet) return bonds = [] - objects = [ leftmost ] + objects = [leftmost] while leftmost.rightBond: - bonds += [ leftmost.rightBond ] + bonds += [leftmost.rightBond] leftmost = leftmost.rightBond.rightObject - objects += [ leftmost ] + objects += [leftmost] assert leftmost.rightmost # choose a random bond from list chosenBond = utils.choice(bonds) @@ -535,7 +560,8 @@ def group_scout__whole_string(codelet): bonds = possibleGroupBonds(category, directionCategory, bondFacet, bonds) assert bonds groupCategory = category.getRelatedNode(slipnet.groupCategory) - coderack.proposeGroup(objects,bonds,groupCategory,directionCategory,bondFacet,codelet) + coderack.proposeGroup(objects, bonds, groupCategory, directionCategory, bondFacet, codelet) + def group_strength_tester(codelet): # update strength value of the group @@ -543,13 +569,14 @@ def group_strength_tester(codelet): __showWhichStringObjectIsFrom(group) group.updateStrength() strength = group.totalStrength - probability = temperatureAdjustedProbability(strength/100.0) + probability = temperatureAdjustedProbability(strength / 100.0) assert utils.random() <= probability # it is strong enough - post builder & activate nodes group.groupCategory.getRelatedNode(slipnet.bondCategory).buffer = 100.0 if group.directionCategory: - group.directionCategory.buffer=100.0 - coderack.newCodelet('group-builder',codelet,strength) + group.directionCategory.buffer = 100.0 + coderack.newCodelet('group-builder', codelet, strength) + def group_builder(codelet): # update strength value of the group @@ -557,7 +584,7 @@ def group_builder(codelet): #print '%s' % group __showWhichStringObjectIsFrom(group) equivalent = group.string.equivalentGroup(group) - if equivalent : + if equivalent: logging.info('already exists...activate descriptors & fizzle') group.activateDescriptions() equivalent.addDescriptions(group.descriptions) @@ -575,7 +602,7 @@ def group_builder(codelet): if leftBond: lefty = leftBond.leftObject if lefty != previous or leftBond.directionCategory != group.directionCategory: - incompatibleBonds += [ leftBond ] + incompatibleBonds += [leftBond] previous = objekt next = group.objectList[-1] for objekt in reversed(group.objectList[:-1]): @@ -583,20 +610,20 @@ def group_builder(codelet): if rightBond: righty = rightBond.rightObject if righty != next or rightBond.directionCategory != group.directionCategory: - incompatibleBonds += [ rightBond ] + incompatibleBonds += [rightBond] next = objekt # if incompatible bonds exist - fight group.updateStrength() - assert __fightIncompatibles(incompatibleBonds,group,'bonds',1.0,1.0) + assert __fightIncompatibles(incompatibleBonds, group, 'bonds', 1.0, 1.0) # fight incompatible groups # fight all groups containing these objects incompatibleGroups = group.getIncompatibleGroups() - assert __fightIncompatibles(incompatibleGroups,group,'Groups',1.0,1.0) + assert __fightIncompatibles(incompatibleGroups, group, 'Groups', 1.0, 1.0) for incompatible in incompatibleBonds: incompatible.break_the_structure() # create new bonds group.bondList = [] - for i in range(1,len(group.objectList)): + for i in range(1, len(group.objectList)): #print 803 object1 = group.objectList[i - 1] object2 = group.objectList[i] @@ -609,15 +636,16 @@ def group_builder(codelet): destination = object1 category = group.groupCategory.getRelatedNode(slipnet.bondCategory) facet = group.facet - newBond = Bond(source,destination,category,facet,source.getDescriptor(facet),destination.getDescriptor(facet)) + newBond = Bond(source, destination, category, facet, source.getDescriptor(facet), destination.getDescriptor(facet)) newBond.buildBond() - group.bondList += [ object1.rightBond ] + group.bondList += [object1.rightBond] for incompatible in incompatibleGroups: incompatible.break_the_structure() group.buildGroup() group.activateDescriptions() logging.info('building group') + def rule_builder(codelet): rule = codelet.arguments[0] if rule.ruleEqual(workspace.rule): @@ -627,28 +655,30 @@ def rule_builder(codelet): assert rule.totalStrength # fight against other rules if workspace.rule: - assert __structureVsStructure(rule,1.0,workspace.rule,1.0) + assert __structureVsStructure(rule, 1.0, workspace.rule, 1.0) workspace.buildRule(rule) + def __getCutOff(density): if density > 0.8: - distribution = [ 5.0,150.0,5.0,2.0,1.0,1.0,1.0,1.0,1.0,1.0 ] + distribution = [5.0, 150.0, 5.0, 2.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] elif density > 0.6: - distribution = [ 2.0,5.0,150.0,5.0,2.0,1.0,1.0,1.0,1.0,1.0 ] + distribution = [2.0, 5.0, 150.0, 5.0, 2.0, 1.0, 1.0, 1.0, 1.0, 1.0] elif density > 0.4: - distribution = [ 1.0,2.0,5.0,150.0,5.0,2.0,1.0,1.0,1.0,1.0 ] + distribution = [1.0, 2.0, 5.0, 150.0, 5.0, 2.0, 1.0, 1.0, 1.0, 1.0] elif density > 0.2: - distribution = [ 1.0,1.0,2.0,5.0,150.0,5.0,2.0,1.0,1.0,1.0 ] + distribution = [1.0, 1.0, 2.0, 5.0, 150.0, 5.0, 2.0, 1.0, 1.0, 1.0] else: - distribution = [ 1.0,1.0,1.0,2.0,5.0,150.0,5.0,2.0,1.0,1.0 ] + distribution = [1.0, 1.0, 1.0, 2.0, 5.0, 150.0, 5.0, 2.0, 1.0, 1.0] stop = sum(distribution) * utils.random() total = 0.0 - for i in range(0,len(distribution)): + for i in range(0, len(distribution)): total += distribution[i] if total >= stop: return i + 1 return len(distribution) + def rule_translator(): assert workspace.rule if len(workspace.initial) == 1 and len(workspace.target) == 1: @@ -657,7 +687,7 @@ def rule_translator(): numberOfBonds = len(workspace.initial.bonds) + len(workspace.target.bonds) nearlyTotalLength = len(workspace.initial) + len(workspace.target) - 2 bondDensity = numberOfBonds / nearlyTotalLength - if bondDensity>1.0: + if bondDensity > 1.0: bondDensity = 1.0 cutoff = __getCutOff(bondDensity) * 10.0 assert cutoff >= formulas.actualTemperature @@ -668,31 +698,33 @@ def rule_translator(): temperature.clamped = True formulas.Temperature = 100.0 + def bottom_up_correspondence_scout(codelet): - objectFromInitial = chooseUnmodifiedObject('interStringSalience',workspace.initial.objects) - objectFromTarget = chooseUnmodifiedObject('interStringSalience',workspace.target.objects) + objectFromInitial = chooseUnmodifiedObject('interStringSalience', workspace.initial.objects) + objectFromTarget = chooseUnmodifiedObject('interStringSalience', workspace.target.objects) assert objectFromInitial.spansString() == objectFromTarget.spansString() # get the posible concept mappings - conceptMappings = getMappings( objectFromInitial, objectFromTarget, objectFromInitial.relevantDescriptions(), objectFromTarget.relevantDescriptions()) + conceptMappings = getMappings(objectFromInitial, objectFromTarget, objectFromInitial.relevantDescriptions(), objectFromTarget.relevantDescriptions()) assert conceptMappings and __slippability(conceptMappings) #find out if any are distinguishing - distinguishingMappings = [ m for m in conceptMappings if m.distinguishing() ] + distinguishingMappings = [m for m in conceptMappings if m.distinguishing()] assert distinguishingMappings # if both objects span the strings, check to see if the # string description needs to be flipped - oppositeMappings = [ m for m in distinguishingMappings + oppositeMappings = [m for m in distinguishingMappings if m.initialDescriptionType == slipnet.stringPositionCategory and - m.initialDescriptionType != slipnet.bondFacet ] - initialDescriptionTypes = [ m.initialDescriptionType for m in oppositeMappings ] + m.initialDescriptionType != slipnet.bondFacet] + initialDescriptionTypes = [m.initialDescriptionType for m in oppositeMappings] flipTargetObject = False if objectFromInitial.spansString() and objectFromTarget.spansString() and slipnet.directionCategory in initialDescriptionTypes and __allOppositeMappings(oppositeMappings) and slipnet.opposite.activation != 100.0: objectFromTarget = objectFromTarget.flippedVersion() - conceptMappings = getMappings( objectFromInitial, objectFromTarget, objectFromInitial.relevantDescriptions(), objectFromTarget.relevantDescriptions()) + conceptMappings = getMappings(objectFromInitial, objectFromTarget, objectFromInitial.relevantDescriptions(), objectFromTarget.relevantDescriptions()) flipTargetObject = True - coderack.proposeCorrespondence(objectFromInitial,objectFromTarget,conceptMappings,flipTargetObject,codelet) + coderack.proposeCorrespondence(objectFromInitial, objectFromTarget, conceptMappings, flipTargetObject, codelet) + def important_object_correspondence_scout(codelet): - objectFromInitial = chooseUnmodifiedObject('relativeImportance',workspace.initial.objects) + objectFromInitial = chooseUnmodifiedObject('relativeImportance', workspace.initial.objects) descriptors = objectFromInitial.relevantDistinguishingDescriptors() slipnode = chooseSlipnodeByConceptualDepth(descriptors) assert slipnode @@ -704,26 +736,27 @@ def important_object_correspondence_scout(codelet): for objekt in workspace.target.objects: for description in objekt.relevantDescriptions(): if description.descriptor == initialDescriptor: - targetCandidates += [ objekt ] + targetCandidates += [objekt] assert targetCandidates - objectFromTarget = chooseUnmodifiedObject('interStringSalience',targetCandidates) + objectFromTarget = chooseUnmodifiedObject('interStringSalience', targetCandidates) assert objectFromInitial.spansString() == objectFromTarget.spansString() # get the posible concept mappings - conceptMappings = getMappings( objectFromInitial, objectFromTarget, objectFromInitial.relevantDescriptions(), objectFromTarget.relevantDescriptions()) + conceptMappings = getMappings(objectFromInitial, objectFromTarget, objectFromInitial.relevantDescriptions(), objectFromTarget.relevantDescriptions()) assert conceptMappings and __slippability(conceptMappings) #find out if any are distinguishing - distinguishingMappings = [ m for m in conceptMappings if m.distinguishing() ] + distinguishingMappings = [m for m in conceptMappings if m.distinguishing()] assert distinguishingMappings # if both objects span the strings, check to see if the # string description needs to be flipped - oppositeMappings = [ m for m in distinguishingMappings if m.initialDescriptionType == slipnet.stringPositionCategory and m.initialDescriptionType != slipnet.bondFacet ] - initialDescriptionTypes = [ m.initialDescriptionType for m in oppositeMappings ] + oppositeMappings = [m for m in distinguishingMappings if m.initialDescriptionType == slipnet.stringPositionCategory and m.initialDescriptionType != slipnet.bondFacet] + initialDescriptionTypes = [m.initialDescriptionType for m in oppositeMappings] flipTargetObject = False if objectFromInitial.spansString() and objectFromTarget.spansString() and slipnet.directionCategory in initialDescriptionTypes and __allOppositeMappings(oppositeMappings) and slipnet.opposite.activation != 100.0: objectFromTarget = objectFromTarget.flippedVersion() - conceptMappings = getMappings( objectFromInitial, objectFromTarget,objectFromInitial.relevantDescriptions(), objectFromTarget.relevantDescriptions()) + conceptMappings = getMappings(objectFromInitial, objectFromTarget, objectFromInitial.relevantDescriptions(), objectFromTarget.relevantDescriptions()) flipTargetObject = True - coderack.proposeCorrespondence(objectFromInitial,objectFromTarget,conceptMappings,flipTargetObject,codelet) + coderack.proposeCorrespondence(objectFromInitial, objectFromTarget, conceptMappings, flipTargetObject, codelet) + def correspondence_strength_tester(codelet): correspondence = codelet.arguments[0] @@ -732,7 +765,7 @@ def correspondence_strength_tester(codelet): assert objectFromInitial in workspace.objects and (objectFromTarget in workspace.objects or correspondence.flipTargetObject and not workspace.target.equivalentGroup(objectFromTarget.flipped_version())) correspondence.updateStrength() strength = correspondence.totalStrength - probability = temperatureAdjustedProbability(strength/100.0) + probability = temperatureAdjustedProbability(strength / 100.0) assert utils.random() <= probability # activate some concepts for mapping in correspondence.conceptMappings: @@ -740,7 +773,8 @@ def correspondence_strength_tester(codelet): mapping.initialDescriptor.buffer = 100.0 mapping.targetDescriptionType.buffer = 100.0 mapping.targetDescriptor.buffer = 100.0 - coderack.newCodelet('correspondence-builder',codelet,strength,correspondence) + coderack.newCodelet('correspondence-builder', codelet, strength, correspondence) + def correspondence_builder(codelet): correspondence = codelet.arguments[0] @@ -763,7 +797,7 @@ def correspondence_builder(codelet): if mapping.label: mapping.label.buffer = 100.0 if not mapping.isContainedBy(existing.conceptMappings): - existing.conceptMappings += [ mapping ] + existing.conceptMappings += [mapping] return incompatibleCorrespondences = correspondence.getIncompatibleCorrespondences() # fight against all correspondences @@ -771,7 +805,7 @@ def correspondence_builder(codelet): correspondenceSpans = correspondence.objectFromInitial.letterSpan() + correspondence.objectFromTarget.letterSpan() for incompatible in incompatibleCorrespondences: incompatibleSpans = incompatible.objectFromInitial.letterSpan() + incompatible.objectFromTarget.letterSpan() - assert __structureVsStructure(correspondence,correspondenceSpans,incompatible,incompatibleSpans) + assert __structureVsStructure(correspondence, correspondenceSpans, incompatible, incompatibleSpans) incompatibleBond = None incompatibleGroup = None # if there is an incompatible bond then fight against it @@ -780,16 +814,16 @@ def correspondence_builder(codelet): incompatibleBond = correspondence.getIncompatibleBond() if incompatibleBond: # bond found - fight against it - assert __structureVsStructure(correspondence,3.0,incompatibleBond,2.0) + assert __structureVsStructure(correspondence, 3.0, incompatibleBond, 2.0) # won against incompatible bond incompatibleGroup = correspondence.objectFromTarget.group if incompatibleGroup: - assert __structureVsStructure(correspondence,1.0,incompatibleGroup,1.0) + assert __structureVsStructure(correspondence, 1.0, incompatibleGroup, 1.0) # if there is an incompatible rule, fight against it incompatibleRule = None if workspace.rule and workspace.rule.incompatibleRuleCorrespondence(correspondence): incompatibleRule = workspace.rule - assert __structureVsStructure( correspondence,1.0,incompatibleRule,1.0) + assert __structureVsStructure(correspondence, 1.0, incompatibleRule, 1.0) for incompatible in incompatibleCorrespondences: incompatible.break_the_structure() # break incompatible group and bond if they exist diff --git a/copycat/coderack.py b/copycat/coderack.py index f5e1c01..c0b7fcf 100644 --- a/copycat/coderack.py +++ b/copycat/coderack.py @@ -1,4 +1,7 @@ -import re, inspect, math, logging +import re +import inspect +import math +import logging import utils import formulas @@ -12,6 +15,7 @@ MAX_NUMBER_OF_CODELETS = 100 codeletsUsed = {} + class CodeRack(object): def __init__(self): #logging.debug('coderack.__init__()') @@ -21,7 +25,7 @@ class CodeRack(object): self.pressures = CoderackPressures() self.pressures.initialisePressures() self.reset() - self.initialCodeletNames = ( 'bottom-up-bond-scout', 'replacement-finder', 'bottom-up-correspondence-scout' ) + self.initialCodeletNames = ('bottom-up-bond-scout', 'replacement-finder', 'bottom-up-correspondence-scout') self.codeletMethodsDir = None self.runCodelets = {} self.postings = {} @@ -166,7 +170,7 @@ class CodeRack(object): def proposeSingleLetterGroup(self, source, codelet): self.proposeGroup([source], [], slipnet.samenessGroup, None, slipnet.letterCategory, codelet) - def proposeGroup(self, objects, bondList, groupCategory, directionCategory, bondFacet, oldCodelet ): + def proposeGroup(self, objects, bondList, groupCategory, directionCategory, bondFacet, oldCodelet): from group import Group bondCategory = groupCategory.getRelatedNode(slipnet.bondCategory) @@ -177,7 +181,7 @@ class CodeRack(object): urgency = bondCategory.bondDegreeOfAssociation() self.newCodelet('group-strength-tester', oldCodelet, urgency, group) - def proposeBond(self, source, destination, bondCategory, bondFacet, sourceDescriptor, destinationDescriptor, oldCodelet ): + def proposeBond(self, source, destination, bondCategory, bondFacet, sourceDescriptor, destinationDescriptor, oldCodelet): from bond import Bond bondFacet.buffer = 100.0 @@ -255,7 +259,7 @@ class CodeRack(object): for codeletName in knownCodeletNames: methodName = re.sub('[ -]', '_', codeletName) if methodName not in self.codeletMethodsDir: - raise NotImplementedError, 'Cannot find %s in codeletMethods' % methodName + raise NotImplementedError('Cannot find %s in codeletMethods' % methodName) method = getattr(codeletMethods, methodName) self.methods[methodName] = method @@ -270,7 +274,7 @@ class CodeRack(object): if not self.codelets: return None temp = formulas.Temperature - scale = ( 100.0 - temp + 10.0 ) / 15.0 + scale = (100.0 - temp + 10.0) / 15.0 # threshold = sum( [ c.urgency ** scale for c in self.codelets ] ) * utils.random() urgsum = 0.0 for codelet in self.codelets: @@ -321,9 +325,9 @@ class CodeRack(object): #if not self.codeletMethodsDir: method = self.methods[methodName] if not method: - raise ValueError, 'Found %s in codeletMethods, but cannot get it' % methodName + raise ValueError('Found %s in codeletMethods, but cannot get it' % methodName) if not callable(method): - raise RuntimeError, 'Cannot call %s()' % methodName + raise RuntimeError('Cannot call %s()' % methodName) args, varargs, varkw, defaults = inspect.getargspec(method) #global codeletsUsed #codeletsUsed[methodName] = codeletsUsed.get(methodName,0) + 1 diff --git a/copycat/coderackPressure.py b/copycat/coderackPressure.py index ed85da1..042cbc7 100644 --- a/copycat/coderackPressure.py +++ b/copycat/coderackPressure.py @@ -2,6 +2,7 @@ import logging from formulas import Temperature from slipnet import slipnet + class CoderackPressure(object): def __init__(self, name): self.name = name @@ -11,6 +12,7 @@ class CoderackPressure(object): self.values = [] self.codelets = [] + class CoderackPressures(object): def __init__(self): #logging.debug('coderackPressures.__init__()') @@ -41,7 +43,7 @@ class CoderackPressures(object): def calculatePressures(self): #logging.debug('coderackPressures.calculatePressures()') - scale = ( 100.0 - Temperature + 10.0 ) / 15.0 + scale = (100.0 - Temperature + 10.0) / 15.0 values = [] for pressure in self.pressures: value = sum([c.urgency ** scale for c in pressure.codelets]) @@ -117,7 +119,7 @@ class CoderackPressures(object): if i >= 0: self.pressures[i].codelets += [codelet] if codelet.pressure: - codelet.pressure.codelets += [codelet] # XXX why do this + codelet.pressure.codelets += [codelet] # XXX why do this if i >= 0: codelet.pressure = self.pressures[i] # when following with this ? logging.info('Add %s: %d' % (codelet.name, i)) diff --git a/copycat/conceptMapping.py b/copycat/conceptMapping.py index acbda95..5699582 100644 --- a/copycat/conceptMapping.py +++ b/copycat/conceptMapping.py @@ -1,6 +1,7 @@ import logging from slipnet import slipnet + class ConceptMapping(object): def __init__(self, initialDescriptionType, targetDescriptionType, initialDescriptor, targetDescriptor, initialObject, targetObject): logging.info('make a map: %s-%s' % (initialDescriptionType.get_name(), targetDescriptionType.get_name())) @@ -23,7 +24,7 @@ class ConceptMapping(object): if association == 100.0: return 100.0 depth = self.__conceptualDepth() / 100.0 - return association * ( 1 - depth * depth ) + return association * (1 - depth * depth) def __degreeOfAssociation(self): #assumes the 2 descriptors are connected in the slipnet by at most 1 link @@ -39,10 +40,10 @@ class ConceptMapping(object): if association == 100.0: return 100.0 depth = self.__conceptualDepth() / 100.0 - return association * ( 1 + depth * depth ) + return association * (1 + depth * depth) def __conceptualDepth(self): - return (self.initialDescriptor.conceptualDepth + self.targetDescriptor.conceptualDepth ) / 2.0 + return (self.initialDescriptor.conceptualDepth + self.targetDescriptor.conceptualDepth) / 2.0 def distinguishing(self): if self.initialDescriptor == slipnet.whole and self.targetDescriptor == slipnet.whole: diff --git a/copycat/copycat.py b/copycat/copycat.py index ff75ea4..3e92ea4 100644 --- a/copycat/copycat.py +++ b/copycat/copycat.py @@ -15,6 +15,7 @@ from temperature import temperature from coderack import coderack from coderackPressure import coderackPressures + def updateEverything(): workspace.updateEverything() coderack.updateCodelets() @@ -53,6 +54,7 @@ def runTrial(): for answer, count in answers.iteritems(): print '%s:%d' % (answer, count) + def run(initial, modified, target): workspace.setStrings(initial, modified, target) runTrial() diff --git a/copycat/correspondence.py b/copycat/correspondence.py index 3e7d0d7..931cda7 100644 --- a/copycat/correspondence.py +++ b/copycat/correspondence.py @@ -2,8 +2,9 @@ from workspace import workspace from workspaceStructure import WorkspaceStructure from formulas import getMappings + class Correspondence(WorkspaceStructure): - def __init__(self,objectFromInitial,objectFromTarget,conceptMappings,flipTargetObject): + def __init__(self, objectFromInitial, objectFromTarget, conceptMappings, flipTargetObject): WorkspaceStructure.__init__(self) self.objectFromInitial = objectFromInitial self.objectFromTarget = objectFromTarget @@ -15,13 +16,13 @@ class Correspondence(WorkspaceStructure): return '<%s>' % self.__str__() def __str__(self): - return 'Correspondence between %s and %s' % (self.objectFromInitial,self.objectFromTarget) + return 'Correspondence between %s and %s' % (self.objectFromInitial, self.objectFromTarget) def distinguishingConceptMappings(self): - return [ m for m in self.conceptMappings if m.distinguishing() ] + return [m for m in self.conceptMappings if m.distinguishing()] def relevantDistinguishingConceptMappings(self): - return [ m for m in self.conceptMappings if m.distinguishing() and m.relevant() ] + return [m for m in self.conceptMappings if m.distinguishing() and m.relevant()] def extract_target_bond(self): targetBond = False @@ -63,9 +64,9 @@ class Correspondence(WorkspaceStructure): return None def getIncompatibleCorrespondences(self): - return [ o.correspondence for o in workspace.initial.objects if o and self.incompatible(o.correspondence) ] + return [o.correspondence for o in workspace.initial.objects if o and self.incompatible(o.correspondence)] - def incompatible(self,other): + def incompatible(self, other): if not other: return False if self.objectFromInitial == other.objectFromInitial: @@ -78,7 +79,7 @@ class Correspondence(WorkspaceStructure): return True return False - def supporting(self,other): + def supporting(self, other): if self == other: return False if self.objectFromInitial == other.objectFromInitial: @@ -95,12 +96,12 @@ class Correspondence(WorkspaceStructure): def support(self): from letter import Letter - if isinstance(self.objectFromInitial,Letter) and self.objectFromInitial.spansString(): + if isinstance(self.objectFromInitial, Letter) and self.objectFromInitial.spansString(): return 100.0 - if isinstance(self.objectFromTarget,Letter) and self.objectFromTarget.spansString(): + if isinstance(self.objectFromTarget, Letter) and self.objectFromTarget.spansString(): return 100.0 - total = sum([ c.totalStrength for c in workspace.correspondences() if self.supporting(c) ]) - total = min(total,100.0) + total = sum([c.totalStrength for c in workspace.correspondences() if self.supporting(c)]) + total = min(total, 100.0) return total def updateInternalStrength(self): @@ -110,7 +111,7 @@ class Correspondence(WorkspaceStructure): if numberOfConceptMappings < 1: self.internalStrength = 0.0 return - totalStrength = sum([ m.strength() for m in relevantDistinguishingMappings ]) + totalStrength = sum([m.strength() for m in relevantDistinguishingMappings]) averageStrength = totalStrength / numberOfConceptMappings if numberOfConceptMappings == 1.0: numberOfConceptMappingsFactor = 0.8 @@ -123,7 +124,7 @@ class Correspondence(WorkspaceStructure): else: internalCoherenceFactor = 1.0 internalStrength = averageStrength * internalCoherenceFactor * numberOfConceptMappingsFactor - self.internalStrength = min(internalStrength,100.0) + self.internalStrength = min(internalStrength, 100.0) def updateExternalStrength(self): self.externalStrength = self.support() @@ -131,16 +132,16 @@ class Correspondence(WorkspaceStructure): def internallyCoherent(self): """Whether any pair of relevant distinguishing mappings support each other""" mappings = self.relevantDistinguishingConceptMappings() - for i in range(0,len(mappings)): - for j in range(0,len(mappings)): + for i in range(0, len(mappings)): + for j in range(0, len(mappings)): if i != j: if mappings[i].supports(mappings[j]): return True return False def slippages(self): - mappings = [ m for m in self.conceptMappings if m.slippage() ] - mappings += [ m for m in self.accessoryConceptMappings if m.slippage() ] + mappings = [m for m in self.conceptMappings if m.slippage()] + mappings += [m for m in self.accessoryConceptMappings if m.slippage()] return mappings def reflexive(self): @@ -151,7 +152,7 @@ class Correspondence(WorkspaceStructure): return False def buildCorrespondence(self): - workspace.structures += [ self ] + workspace.structures += [self] if self.objectFromInitial.correspondence: self.objectFromInitial.correspondence.breakCorrespondence() if self.objectFromTarget.correspondence: @@ -162,9 +163,9 @@ class Correspondence(WorkspaceStructure): relevantMappings = self.relevantDistinguishingConceptMappings() for mapping in relevantMappings: if mapping.slippage(): - self.accessoryConceptMappings += [ mapping.symmetricVersion() ] + self.accessoryConceptMappings += [mapping.symmetricVersion()] from group import Group - if isinstance(self.objectFromInitial,Group) and isinstance(self.objectFromTarget,Group): + if isinstance(self.objectFromInitial, Group) and isinstance(self.objectFromTarget, Group): bondMappings = getMappings( self.objectFromInitial, self.objectFromTarget, @@ -172,9 +173,9 @@ class Correspondence(WorkspaceStructure): self.objectFromTarget.bondDescriptions ) for mapping in bondMappings: - self.accessoryConceptMappings += [ mapping ] + self.accessoryConceptMappings += [mapping] if mapping.slippage(): - self.accessoryConceptMappings += [ mapping.symmetricVersion() ] + self.accessoryConceptMappings += [mapping.symmetricVersion()] for mapping in self.conceptMappings: if mapping.label: mapping.label.activation = 100.0 @@ -186,4 +187,3 @@ class Correspondence(WorkspaceStructure): workspace.structures.remove(self) self.objectFromInitial.correspondence = None self.objectFromTarget.correspondence = None - diff --git a/copycat/description.py b/copycat/description.py index 879d0c1..5d9ef40 100644 --- a/copycat/description.py +++ b/copycat/description.py @@ -1,8 +1,9 @@ import logging from workspaceStructure import WorkspaceStructure + class Description(WorkspaceStructure): - def __init__(self,workspaceObject,descriptionType,descriptor): + def __init__(self, workspaceObject, descriptionType, descriptor): WorkspaceStructure.__init__(self) self.object = workspaceObject self.string = workspaceObject.string @@ -13,7 +14,7 @@ class Description(WorkspaceStructure): return '' % self.__str__() def __str__(self): - s = 'description(%s) of %s' % (self.descriptor.get_name(),self.object) + s = 'description(%s) of %s' % (self.descriptor.get_name(), self.object) from workspace import workspace if self.object.string == workspace.initial: s += ' in initial string' @@ -29,13 +30,13 @@ class Description(WorkspaceStructure): def localSupport(self): from workspace import workspace - supporters = 0 # number of objects in the string with a descriptionType like self + supporters = 0 # number of objects in the string with a descriptionType like self for other in workspace.otherObjects(self.object): - if not ( self.object.isWithin(other) or other.isWithin(self.object) ): + if not (self.object.isWithin(other) or other.isWithin(self.object)): for description in other.descriptions: if description.descriptionType == self.descriptionType: supporters += 1 - results = { 0:0.0, 1:20.0, 2:60.0, 3:90.0 } + results = {0: 0.0, 1: 20.0, 2: 60.0, 3: 90.0} if supporters in results: return results[supporters] return 100.0 @@ -45,12 +46,10 @@ class Description(WorkspaceStructure): self.descriptor.buffer = 100.0 if not self.object.hasDescription(self.descriptor): logging.info('Add %s to descriptions' % self) - self.object.descriptions += [ self ] + self.object.descriptions += [self] def breakDescription(self): from workspace import workspace if self in workspace.structures: workspace.structures.remove(self) self.object.descriptions.remove(self) - - diff --git a/copycat/formulas.py b/copycat/formulas.py index 8fe4789..f05f382 100644 --- a/copycat/formulas.py +++ b/copycat/formulas.py @@ -1,4 +1,4 @@ -import math #, random +import math # , random import logging import utils @@ -7,6 +7,7 @@ from temperature import temperature actualTemperature = Temperature = 100.0 + def selectListPosition(probabilities): total = sum(probabilities) #logging.info('total: %s' % total) @@ -22,20 +23,23 @@ def selectListPosition(probabilities): index += 1 return 0 + def weightedAverage(values): total = 0.0 totalWeights = 0.0 - for value,weight in values: + for value, weight in values: total += value * weight totalWeights += weight if not totalWeights: return 0.0 return total / totalWeights + def temperatureAdjustedValue(value): #logging.info('Temperature: %s' % Temperature) #logging.info('actualTemperature: %s' % actualTemperature) - return value ** (((100.0-Temperature)/30.0)+0.5) + return value ** (((100.0 - Temperature) / 30.0) + 0.5) + def temperatureAdjustedProbability(value): if not value or value == 0.5 or not temperature.value: @@ -46,64 +50,73 @@ def temperatureAdjustedProbability(value): a = math.sqrt(coldness) b = 10.0 - a c = b / 100 - d = c * ( 1.0 - ( 1.0 - value ) ) # aka c * value, but we're following the java - e = ( 1.0 - value ) + d + d = c * (1.0 - (1.0 - value)) # aka c * value, but we're following the java + e = (1.0 - value) + d f = 1.0 - e - return max(f,0.5) + return max(f, 0.5) + def coinFlip(chance=0.5): return utils.random() < chance + def blur(value): root = math.sqrt(value) if coinFlip(): return value + root return value - root -def chooseObjectFromList(objects,attribute): + +def chooseObjectFromList(objects, attribute): if not objects: return None probabilities = [] for object in objects: - value = getattr(object,attribute) + value = getattr(object, attribute) probability = temperatureAdjustedValue(value) - logging.info('Object: %s, value: %d, probability: %d' % (object,value,probability)) - probabilities += [ probability ] + logging.info('Object: %s, value: %d, probability: %d' % (object, value, probability)) + probabilities += [probability] index = selectListPosition(probabilities) logging.info("Selected: %d" % index) return objects[index] + def chooseRelevantDescriptionByActivation(workspaceObject): descriptions = workspaceObject.relevantDescriptions() if not descriptions: return None - activations = [ description.descriptor.activation for description in descriptions ] + activations = [description.descriptor.activation for description in descriptions] index = selectListPosition(activations) - return descriptions[ index ] + return descriptions[index] + def similarPropertyLinks(slip_node): result = [] for slip_link in slip_node.propertyLinks: association = slip_link.degreeOfAssociation() / 100.0 - probability = temperatureAdjustedProbability( association ) + probability = temperatureAdjustedProbability(association) if coinFlip(probability): - result += [ slip_link ] + result += [slip_link] return result + def chooseSlipnodeByConceptualDepth(slip_nodes): if not slip_nodes: return None - depths = [ temperatureAdjustedValue(n.conceptualDepth) for n in slip_nodes ] + depths = [temperatureAdjustedValue(n.conceptualDepth) for n in slip_nodes] i = selectListPosition(depths) - return slip_nodes[ i ] + return slip_nodes[i] -def __relevantCategory(objekt,slipnode): + +def __relevantCategory(objekt, slipnode): return objekt.rightBond and objekt.rightBond.category == slipnode -def __relevantDirection(objekt,slipnode): + +def __relevantDirection(objekt, slipnode): return objekt.rightBond and objekt.rightBond.directionCategory == slipnode -def __localRelevance(string,slipnode,relevance): + +def __localRelevance(string, slipnode, relevance): numberOfObjectsNotSpanning = numberOfMatches = 0.0 #logging.info("find relevance for a string: %s" % string); for objekt in string.objects: @@ -111,22 +124,25 @@ def __localRelevance(string,slipnode,relevance): if not objekt.spansString(): #logging.info('non spanner: %s' % objekt) numberOfObjectsNotSpanning += 1.0 - if relevance(objekt,slipnode): + if relevance(objekt, slipnode): numberOfMatches += 1.0 #logging.info("matches: %d, not spanning: %d" % (numberOfMatches,numberOfObjectsNotSpanning)) if numberOfObjectsNotSpanning == 1: return 100.0 * numberOfMatches return 100.0 * numberOfMatches / (numberOfObjectsNotSpanning - 1.0) + def localBondCategoryRelevance(string, category): if len(string.objects) == 1: return 0.0 - return __localRelevance(string,category,__relevantCategory) + return __localRelevance(string, category, __relevantCategory) + def localDirectionCategoryRelevance(string, direction): - return __localRelevance(string,direction,__relevantDirection) + return __localRelevance(string, direction, __relevantDirection) -def getMappings(objectFromInitial,objectFromTarget, initialDescriptions, targetDescriptions): + +def getMappings(objectFromInitial, objectFromTarget, initialDescriptions, targetDescriptions): mappings = [] from conceptMapping import ConceptMapping for initialDescription in initialDescriptions: @@ -141,6 +157,5 @@ def getMappings(objectFromInitial,objectFromTarget, initialDescriptions, targetD objectFromInitial, objectFromTarget ) - mappings += [ mapping ] + mappings += [mapping] return mappings - diff --git a/copycat/group.py b/copycat/group.py index 98dc071..5d39997 100644 --- a/copycat/group.py +++ b/copycat/group.py @@ -1,13 +1,15 @@ -import utils, logging +import utils +import logging from workspace import workspace from workspaceObject import WorkspaceObject from slipnet import slipnet import formulas + class Group(WorkspaceObject): - def __init__(self,string,groupCategory,directionCategory,facet,objectList,bondList): - WorkspaceObject.__init__(self,string) + def __init__(self, string, groupCategory, directionCategory, facet, objectList, bondList): + WorkspaceObject.__init__(self, string) self.groupCategory = groupCategory self.directionCategory = directionCategory self.facet = facet @@ -36,7 +38,6 @@ class Group(WorkspaceObject): self.clampSalience = False self.name = '' - from description import Description if self.bondList and len(self.bondList): firstFacet = self.bondList[0].facet @@ -71,18 +72,18 @@ class Group(WorkspaceObject): s = self.string.__str__() l = self.leftStringPosition - 1 r = self.rightStringPosition - return 'group[%d:%d] == %s' % ( l, r - 1, s[l: r ]) + return 'group[%d:%d] == %s' % (l, r - 1, s[l:r]) def getIncompatibleGroups(self): result = [] for objekt in self.objectList: while objekt.group: - result += [ objekt.group ] + result += [objekt.group] objekt = objekt.group return result - def addBondDescription(self,description): - self.bondDescriptions += [ description ] + def addBondDescription(self, description): + self.bondDescriptions += [description] def singleLetterGroupProbability(self): numberOfSupporters = self.numberOfLocalSupportingGroups() @@ -100,15 +101,15 @@ class Group(WorkspaceObject): return formulas.temperatureAdjustedProbability(supportedActivation) def flippedVersion(self): - flippedBonds = [ b.flippedversion() for b in self.bondList ] + flippedBonds = [b.flippedversion() for b in self.bondList] flippedGroup = self.groupCategory.getRelatedNode(slipnet.flipped) flippedDirection = self.directionCategory.getRelatedNode(slipnet.flipped) return Group(self.string, flippedGroup, flippedDirection, self.facet, self.objectList, flippedBonds) def buildGroup(self): - workspace.objects += [ self ] - workspace.structures += [ self ] - self.string.objects += [ self ] + workspace.objects += [self] + workspace.structures += [self] + self.string.objects += [self] for objekt in self.objectList: objekt.group = self workspace.buildDescriptions(self) @@ -128,7 +129,7 @@ class Group(WorkspaceObject): probability = 0.5 ** fred value = formulas.temperatureAdjustedProbability(probability) if value < 0.06: - value = 0.0 # otherwise 1/20 chance always + value = 0.0 # otherwise 1/20 chance always return value def break_the_structure(self): @@ -168,7 +169,7 @@ class Group(WorkspaceObject): else: lengthFactor = 90.0 lengthWeight = 100.0 - bondWeight - weightList = ( (relatedBondAssociation, bondWeight), (lengthFactor, lengthWeight) ) + weightList = ((relatedBondAssociation, bondWeight), (lengthFactor, lengthWeight)) self.internalStrength = formulas.weightedAverage(weightList) def updateExternalStrength(self): @@ -181,14 +182,14 @@ class Group(WorkspaceObject): numberOfSupporters = self.numberOfLocalSupportingGroups() if numberOfSupporters == 0.0: return 0.0 - supportFactor = min(1.0,0.6 ** (1 / (numberOfSupporters ** 3 ))) + supportFactor = min(1.0, 0.6 ** (1 / (numberOfSupporters ** 3))) densityFactor = 100.0 * ((self.localDensity() / 100.0) ** 0.5) return densityFactor * supportFactor def numberOfLocalSupportingGroups(self): count = 0 for objekt in self.string.objects: - if isinstance(objekt,Group): + if isinstance(objekt, Group): if objekt.rightStringPosition < self.leftStringPosition or objekt.leftStringPosition > self.rightStringPosition: if objekt.groupCategory == self.groupCategory and objekt.directionCategory == self.directionCategory: count += 1 @@ -199,7 +200,7 @@ class Group(WorkspaceObject): halfLength = len(self.string) / 2.0 return 100.0 * numberOfSupporters / halfLength - def sameGroup(self,other): + def sameGroup(self, other): if self.leftStringPosition != other.leftStringPosition: return False if self.rightStringPosition != other.rightStringPosition: @@ -212,26 +213,24 @@ class Group(WorkspaceObject): return False return True - def morePossibleDescriptions(self,node): + def morePossibleDescriptions(self, node): result = [] i = 1 for number in slipnet.numbers: if node == number and len(self.objects) == i: - result += [ node ] + result += [node] i += 1 return result - def distinguishingDescriptor(self,descriptor): + def distinguishingDescriptor(self, descriptor): """Whether no other object of the same type (group) has the same descriptor""" - if not WorkspaceObject.distinguishingDescriptor(self,descriptor): + if not WorkspaceObject.distinguishingDescriptor(self, descriptor): return False for objekt in self.string.objects: # check to see if they are of the same type - if isinstance(objekt,Group) and objekt != self: + if isinstance(objekt, Group) and objekt != self: # check all descriptions for the descriptor for description in objekt.descriptions: if description.descriptor == descriptor: return False return True - - diff --git a/copycat/grouprun.py b/copycat/grouprun.py index df4e554..2b37fd1 100644 --- a/copycat/grouprun.py +++ b/copycat/grouprun.py @@ -1,5 +1,6 @@ from workspace import workspace + class GroupRun(object): def __init__(self): self.name = 'xxx' diff --git a/copycat/letter.py b/copycat/letter.py index 8dd91e4..a65c1da 100644 --- a/copycat/letter.py +++ b/copycat/letter.py @@ -1,26 +1,27 @@ from workspaceObject import WorkspaceObject from slipnet import slipnet + class Letter(WorkspaceObject): - def __init__(self,string,position,length): - WorkspaceObject.__init__(self,string) + def __init__(self, string, position, length): + WorkspaceObject.__init__(self, string) from workspace import workspace - workspace.objects += [ self ] - string.objects += [self ] + workspace.objects += [self] + string.objects += [self] self.leftStringPosition = position self.leftmost = self.leftStringPosition == 1 self.rightStringPosition = position self.rightmost = self.rightStringPosition == length - def describe(self,position,length): + def describe(self, position, length): if length == 1: - self.addDescription(slipnet.stringPositionCategory,slipnet.single) - if self.leftmost and length > 1: # ? why check length ? - self.addDescription(slipnet.stringPositionCategory,slipnet.leftmost) - if self.rightmost and length > 1: # ? why check length ? - self.addDescription(slipnet.stringPositionCategory,slipnet.rightmost) + self.addDescription(slipnet.stringPositionCategory, slipnet.single) + if self.leftmost and length > 1: # ? why check length ? + self.addDescription(slipnet.stringPositionCategory, slipnet.leftmost) + if self.rightmost and length > 1: # ? why check length ? + self.addDescription(slipnet.stringPositionCategory, slipnet.rightmost) if length > 2 and position * 2 == length + 1: - self.addDescription(slipnet.stringPositionCategory,slipnet.middle) + self.addDescription(slipnet.stringPositionCategory, slipnet.middle) def __repr__(self): return '' % self.__str__() @@ -30,19 +31,18 @@ class Letter(WorkspaceObject): return '' i = self.leftStringPosition - 1 if len(self.string) <= i: - raise ValueError, 'len(self.string) <= self.leftStringPosition :: %d <= %d' % (len(self.string),self.leftStringPosition) - return self.string[ i ] + raise ValueError('len(self.string) <= self.leftStringPosition :: %d <= %d' % (len(self.string), self.leftStringPosition)) + return self.string[i] - def distinguishingDescriptor(self,descriptor): + def distinguishingDescriptor(self, descriptor): """Whether no other object of the same type (letter) has the same descriptor""" - if not WorkspaceObject.distinguishingDescriptor(self,descriptor): + if not WorkspaceObject.distinguishingDescriptor(self, descriptor): return False for objekt in self.string.objects: # check to see if they are of the same type - if isinstance(objekt,Letter) and objekt != self: + if isinstance(objekt, Letter) and objekt != self: # check all descriptions for the descriptor for description in objekt.descriptions: if description.descriptor == descriptor: return False return True - diff --git a/copycat/replacement.py b/copycat/replacement.py index a06ca45..562cac8 100644 --- a/copycat/replacement.py +++ b/copycat/replacement.py @@ -1,9 +1,9 @@ from workspaceStructure import WorkspaceStructure + class Replacement(WorkspaceStructure): def __init__(self, objectFromInitial, objectFromModified, relation): WorkspaceStructure.__init__(self) self.objectFromInitial = objectFromInitial self.objectFromModified = objectFromModified self.relation = relation - diff --git a/copycat/rule.py b/copycat/rule.py index c9ea5c4..6bbbf64 100644 --- a/copycat/rule.py +++ b/copycat/rule.py @@ -3,8 +3,9 @@ from workspace import workspace from workspaceStructure import WorkspaceStructure from formulas import * + class Rule(WorkspaceStructure): - def __init__(self,facet,descriptor,category,relation): + def __init__(self, facet, descriptor, category, relation): WorkspaceStructure.__init__(self) self.facet = facet self.descriptor = descriptor @@ -20,15 +21,15 @@ class Rule(WorkspaceStructure): self.externalStrength = self.internalStrength def updateInternalStrength(self): - if not ( self.descriptor and self.relation ): + if not (self.descriptor and self.relation): self.internalStrength = 0.0 return - averageDepth = ( self.descriptor.conceptualDepth + self.relation.conceptualDepth ) / 2.0 + averageDepth = (self.descriptor.conceptualDepth + self.relation.conceptualDepth) / 2.0 averageDepth **= 1.1 # see if the object corresponds to an object # if so, see if the descriptor is present (modulo slippages) in the # corresponding object - changedObjects = [ o for o in workspace.initial.objects if o.changed ] + changedObjects = [o for o in workspace.initial.objects if o.changed] changed = changedObjects[0] sharedDescriptorTerm = 0.0 if changed and changed.correspondence: @@ -36,17 +37,17 @@ class Rule(WorkspaceStructure): slippages = workspace.slippages() slipnode = self.descriptor.applySlippages(slippages) if not targetObject.hasDescription(slipnode): - self.internalStrength = 0.0 + self.internalStrength = 0.0 return sharedDescriptorTerm = 100.0 sharedDescriptorWeight = ((100.0 - self.descriptor.conceptualDepth) / 10.0) ** 1.4 depthDifference = 100.0 - abs(self.descriptor.conceptualDepth - self.relation.conceptualDepth) - weights = ( (depthDifference,12), (averageDepth,18), (sharedDescriptorTerm,sharedDescriptorWeight) ) - self.internalStrength = weightedAverage( weights ) + weights = ((depthDifference, 12), (averageDepth, 18), (sharedDescriptorTerm, sharedDescriptorWeight)) + self.internalStrength = weightedAverage(weights) if self.internalStrength > 100.0: self.internalStrength = 100.0 - def ruleEqual(self,other): + def ruleEqual(self, other): if not other: return False if self.relation != other.relation: @@ -73,18 +74,18 @@ class Rule(WorkspaceStructure): if not correspondence: return False # find changed object - changeds = [ o for o in workspace.initial.objects if o.changed ] + changeds = [o for o in workspace.initial.objects if o.changed] if not changeds: return False changed = changeds[0] if correspondence.objectFromInitial != changed: return False # it is incompatible if the rule descriptor is not in the mapping list - if len([ m for m in correspondence.conceptMappings if m.initialDescriptor == self.descriptor ]): + if len([m for m in correspondence.conceptMappings if m.initialDescriptor == self.descriptor]): return False return True - def __changeString(self,string): + def __changeString(self, string): # applies the changes to self string ie. successor if self.facet == slipnet.length: if self.relation == slipnet.predecessor: @@ -96,11 +97,11 @@ class Rule(WorkspaceStructure): if self.relation == slipnet.predecessor: if 'a' in string: return None - return ''.join([ chr(ord(c) - 1) for c in string]) + return ''.join([chr(ord(c) - 1) for c in string]) elif self.relation == slipnet.successor: if 'z' in string: return None - return ''.join([ chr(ord(c) + 1) for c in string]) + return ''.join([chr(ord(c) + 1) for c in string]) else: return self.relation.name.lower() @@ -112,9 +113,9 @@ class Rule(WorkspaceStructure): self.relation = self.relation.applySlippages(slippages) # generate the final string self.finalAnswer = workspace.targetString - changeds = [ o for o in workspace.target.objects if + changeds = [o for o in workspace.target.objects if o.hasDescription(self.descriptor) and - o.hasDescription(self.category) ] + o.hasDescription(self.category)] changed = changeds and changeds[0] or None logging.debug('changed object = %s' % changed) if changed: @@ -131,4 +132,3 @@ class Rule(WorkspaceStructure): endString = self.finalAnswer[right:] self.finalAnswer = startString + middleString + endString return True - diff --git a/copycat/sliplink.py b/copycat/sliplink.py index fa08802..3814dd2 100644 --- a/copycat/sliplink.py +++ b/copycat/sliplink.py @@ -1,5 +1,6 @@ #from slipnode import Slipnode + class Sliplink(object): def __init__(self, source, destination, label=None, length=0.0): self.source = source @@ -25,4 +26,4 @@ class Sliplink(object): self.destination.buffer += self.intrinsicDegreeOfAssociation() def points_at(self, other): - return self.destination == other \ No newline at end of file + return self.destination == other diff --git a/copycat/slipnet.py b/copycat/slipnet.py index b8710fb..4de8f59 100644 --- a/copycat/slipnet.py +++ b/copycat/slipnet.py @@ -3,6 +3,7 @@ import logging from slipnode import Slipnode from sliplink import Sliplink + class SlipNet(object): def __init__(self): logging.debug("SlipNet.__init__()") @@ -242,7 +243,7 @@ class SlipNet(object): self.slipnodes += [slipnode] return slipnode - def __link_items_to_their_neighbours(self,items): + def __link_items_to_their_neighbours(self, items): previous = items[0] for item in items[1:]: self.__addNonSlipLink(previous, item, label=self.successor) diff --git a/copycat/slipnode.py b/copycat/slipnode.py index 38cf542..b3d200c 100644 --- a/copycat/slipnode.py +++ b/copycat/slipnode.py @@ -2,12 +2,15 @@ import math import utils import logging + def full_activation(): return 100 + def jump_threshold(): return 55.0 + class Slipnode(object): def __init__(self, name, depth, length=0.0): # logging.info('depth to %s for %s' % (depth,name)) @@ -57,7 +60,7 @@ class Slipnode(object): def fully_active(self): """Whether this node has full activation""" - return self.activation > full_activation() - 0.00001 # allow a little leeway for floats + return self.activation > full_activation() - 0.00001 # allow a little leeway for floats def activate_fully(self): """Make this node fully active""" @@ -79,7 +82,7 @@ class Slipnode(object): def update(self): act = self.activation self.oldActivation = act - self.buffer -= self.activation * ( 100.0 - self.conceptual_depth) / 100.0 + self.buffer -= self.activation * (100.0 - self.conceptual_depth) / 100.0 def linked(self, other): """Whether the other is among the outgoing links""" @@ -141,7 +144,7 @@ class Slipnode(object): def spread_activation(self): if self.fully_active(): - [ link.spread_activation() for link in self.outgoingLinks ] + [link.spread_activation() for link in self.outgoingLinks] def addBuffer(self): if not self.clamped: diff --git a/copycat/temperature.py b/copycat/temperature.py index 6e17b4b..b46c63d 100644 --- a/copycat/temperature.py +++ b/copycat/temperature.py @@ -1,5 +1,6 @@ import logging + class Temperature(object): def __init__(self): self.value = 100.0 diff --git a/copycat/utils.py b/copycat/utils.py index 1c3a946..a7e6439 100644 --- a/copycat/utils.py +++ b/copycat/utils.py @@ -1,4 +1,3 @@ - def any(things): """Return True if any of the things are True. @@ -57,6 +56,7 @@ def any(things): return True return False + def all(things): """Return True if all of the things are True. @@ -114,6 +114,8 @@ import logging seed = 999.0 count = 0 testably_random = True + + def random(): global testably_random if testably_random: @@ -130,6 +132,7 @@ def random(): # sys.exit(1) return seed / 2000.0 + def choice(aList): i = int(random() * len(aList)) return aList[i] @@ -137,4 +140,3 @@ def choice(aList): if __name__ == '__main__': import doctest doctest.testmod() - diff --git a/copycat/workspace.py b/copycat/workspace.py index e952e01..b17d9d7 100644 --- a/copycat/workspace.py +++ b/copycat/workspace.py @@ -4,6 +4,7 @@ from workspaceString import WorkspaceString unknownAnswer = '?' + class Workspace(object): def __init__(self): #logging.debug('workspace.__init__()') @@ -155,4 +156,3 @@ class Workspace(object): workspace = Workspace() - diff --git a/copycat/workspaceFormulas.py b/copycat/workspaceFormulas.py index cfd14a3..e38e590 100644 --- a/copycat/workspaceFormulas.py +++ b/copycat/workspaceFormulas.py @@ -5,6 +5,7 @@ from temperature import temperature from slipnet import slipnet import formulas + class WorkspaceFormulas(object): def __init__(self): self.clampTemperature = False @@ -16,7 +17,7 @@ class WorkspaceFormulas(object): if workspace.rule: workspace.rule.updateStrength() ruleWeakness = 100.0 - workspace.rule.totalStrength - values = ( (workspace.totalUnhappiness, 0.8), (ruleWeakness, 0.2), ) + values = ((workspace.totalUnhappiness, 0.8), (ruleWeakness, 0.2)) slightly_above_actual_temperature = formulas.actualTemperature + 0.001 logging.info('actualTemperature: %f' % slightly_above_actual_temperature) formulas.actualTemperature = formulas.weightedAverage(values) @@ -32,14 +33,17 @@ class WorkspaceFormulas(object): workspaceFormulas = WorkspaceFormulas() + def numberOfObjects(): return len(workspace.objects) -def chooseUnmodifiedObject(attribute,inObjects): - objects = [ o for o in inObjects if o.string != workspace.modified ] + +def chooseUnmodifiedObject(attribute, inObjects): + objects = [o for o in inObjects if o.string != workspace.modified] if not len(objects): print 'no objects available in initial or target strings' - return formulas.chooseObjectFromList(objects,attribute) + return formulas.chooseObjectFromList(objects, attribute) + def chooseNeighbour(source): objects = [] @@ -47,50 +51,56 @@ def chooseNeighbour(source): if objekt.string != source.string: continue if objekt.leftStringPosition == source.rightStringPosition + 1: - objects += [ objekt ] + objects += [objekt] elif source.leftStringPosition == objekt.rightStringPosition + 1: - objects += [ objekt ] - return formulas.chooseObjectFromList(objects,"intraStringSalience") + objects += [objekt] + return formulas.chooseObjectFromList(objects, "intraStringSalience") -def chooseDirectedNeighbor(source,direction): + +def chooseDirectedNeighbor(source, direction): if direction == slipnet.left: logging.info('Left') return __chooseLeftNeighbor(source) logging.info('Right') return __chooseRightNeighbor(source) + def __chooseLeftNeighbor(source): objects = [] for o in workspace.objects: - if o.string == source.string : + if o.string == source.string: if source.leftStringPosition == o.rightStringPosition + 1: - logging.info('%s is on left of %s' % (o,source)) - objects += [ o ] + logging.info('%s is on left of %s' % (o, source)) + objects += [o] else: - logging.info('%s is not on left of %s' % (o,source)) + logging.info('%s is not on left of %s' % (o, source)) logging.info('Number of left objects: %s' % len(objects)) - return formulas.chooseObjectFromList(objects,'intraStringSalience') + return formulas.chooseObjectFromList(objects, 'intraStringSalience') + def __chooseRightNeighbor(source): - objects = [ o for o in workspace.objects if + objects = [o for o in workspace.objects if o.string == source.string and o.leftStringPosition == source.rightStringPosition + 1 ] - return formulas.chooseObjectFromList(objects,'intraStringSalience') + return formulas.chooseObjectFromList(objects, 'intraStringSalience') + def chooseBondFacet(source, destination): - sourceFacets = [ d.descriptionType for d in source.descriptions if d.descriptionType in slipnet.bondFacets ] - bondFacets = [ d.descriptionType for d in destination.descriptions if d.descriptionType in sourceFacets ] + sourceFacets = [d.descriptionType for d in source.descriptions if d.descriptionType in slipnet.bondFacets] + bondFacets = [d.descriptionType for d in destination.descriptions if d.descriptionType in sourceFacets] if not bondFacets: return None - supports = [ __supportForDescriptionType(f,source.string) for f in bondFacets ] + supports = [__supportForDescriptionType(f, source.string) for f in bondFacets] i = formulas.selectListPosition(supports) - return bondFacets[ i ] + return bondFacets[i] -def __supportForDescriptionType(descriptionType,string): - return ( descriptionType.activation + __descriptionTypeSupport(descriptionType,string) ) / 2 -def __descriptionTypeSupport(descriptionType,string): +def __supportForDescriptionType(descriptionType, string): + return (descriptionType.activation + __descriptionTypeSupport(descriptionType, string)) / 2 + + +def __descriptionTypeSupport(descriptionType, string): """The proportion of objects in the string that have a description with this descriptionType""" numberOfObjects = totalNumberOfObjects = 0.0 for objekt in workspace.objects: @@ -101,11 +111,12 @@ def __descriptionTypeSupport(descriptionType,string): numberOfObjects += 1.0 return numberOfObjects / totalNumberOfObjects + def probabilityOfPosting(codeletName): if codeletName == 'breaker': return 1.0 if 'description' in codeletName: - result = ( formulas.Temperature / 100.0 ) ** 2 + result = (formulas.Temperature / 100.0) ** 2 else: result = workspace.intraStringUnhappiness / 100.0 if 'correspondence' in codeletName: @@ -126,6 +137,7 @@ def probabilityOfPosting(codeletName): return 1.0 return result + def howManyToPost(codeletName): if codeletName == 'breaker': return 1 @@ -156,5 +168,3 @@ def howManyToPost(codeletName): if number < formulas.blur(4.0): return 2 return 3 - - diff --git a/copycat/workspaceObject.py b/copycat/workspaceObject.py index 79d7360..fe3cec2 100644 --- a/copycat/workspaceObject.py +++ b/copycat/workspaceObject.py @@ -4,8 +4,9 @@ from description import Description from slipnet import slipnet from workspaceStructure import WorkspaceStructure + class WorkspaceObject(WorkspaceStructure): - def __init__(self,workspaceString): + def __init__(self, workspaceString): WorkspaceStructure.__init__(self) self.string = workspaceString #self.string.objects += [ self ] @@ -42,21 +43,21 @@ class WorkspaceObject(WorkspaceStructure): def spansString(self): return self.leftmost and self.rightmost - def addDescription(self,descriptionType,descriptor): - description = Description(self,descriptionType,descriptor) - logging.info("Adding description: %s to %s" % (description,self)) - self.descriptions += [ description ] + def addDescription(self, descriptionType, descriptor): + description = Description(self, descriptionType, descriptor) + logging.info("Adding description: %s to %s" % (description, self)) + self.descriptions += [description] - def addDescriptions(self,descriptions): + def addDescriptions(self, descriptions): #print 'addDescriptions 1' #print 'add %d to %d of %s' % (len(descriptions),len(self.descriptions), self.string.string) - copy = descriptions[:] # in case we add to our own descriptions, which turns the loop infinite + copy = descriptions[:] # in case we add to our own descriptions, which turns the loop infinite for description in copy: #print '%d addDescriptions 2 %s ' % (len(descriptions),description) logging.info('might add: %s' % description) if not self.containsDescription(description): #print '%d addDescriptions 3 %s ' % (len(descriptions),description) - self.addDescription(description.descriptionType,description.descriptor) + self.addDescription(description.descriptionType, description.descriptor) #print '%d addDescriptions 4 %s ' % (len(descriptions),description) else: logging.info("Won't add it") @@ -73,7 +74,7 @@ class WorkspaceObject(WorkspaceStructure): for bond in self.bonds: bondStrength += bond.totalStrength divisor = 6.0 - if self.spansString(): # XXX then we have already returned + if self.spansString(): # XXX then we have already returned divisor = 3.0 return bondStrength / divisor @@ -104,7 +105,7 @@ class WorkspaceObject(WorkspaceStructure): self.interStringUnhappiness = 100.0 - interStringHappiness #logging.info("Unhappy: %s"%self.interStringUnhappiness) - averageHappiness = ( intraStringHappiness + interStringHappiness ) / 2 + averageHappiness = (intraStringHappiness + interStringHappiness) / 2 self.totalUnhappiness = 100.0 - averageHappiness if self.clampSalience: @@ -112,45 +113,45 @@ class WorkspaceObject(WorkspaceStructure): self.interStringSalience = 100.0 else: from formulas import weightedAverage - self.intraStringSalience = weightedAverage( ((self.relativeImportance,0.2), (self.intraStringUnhappiness,0.8)) ) - self.interStringSalience = weightedAverage( ((self.relativeImportance,0.8), (self.interStringUnhappiness,0.2)) ) + self.intraStringSalience = weightedAverage(((self.relativeImportance, 0.2), (self.intraStringUnhappiness, 0.8))) + self.interStringSalience = weightedAverage(((self.relativeImportance, 0.8), (self.interStringUnhappiness, 0.2))) self.totalSalience = (self.intraStringSalience + self.interStringSalience) / 2.0 logging.info('Set salience of %s to %f = (%f + %f)/2' % ( - self.__str__(),self.totalSalience, self.intraStringSalience, self.interStringSalience)) + self.__str__(), self.totalSalience, self.intraStringSalience, self.interStringSalience)) - def isWithin(self,other): + def isWithin(self, other): return self.leftStringPosition >= other.leftStringPosition and self.rightStringPosition <= other.rightStringPosition def relevantDescriptions(self): - return [ d for d in self.descriptions if d.descriptionType.fully_active() ] + return [d for d in self.descriptions if d.descriptionType.fully_active()] - def morePossibleDescriptions(self,node): + def morePossibleDescriptions(self, node): return [] - def getPossibleDescriptions(self,descriptionType): + def getPossibleDescriptions(self, descriptionType): logging.info('getting possible descriptions for %s' % self) - descriptions = [ ] + descriptions = [] from group import Group for link in descriptionType.instanceLinks: node = link.destination if node == slipnet.first and self.hasDescription(slipnet.letters[0]): - descriptions += [ node ] + descriptions += [node] if node == slipnet.last and self.hasDescription(slipnet.letters[-1]): - descriptions += [ node ] + descriptions += [node] i = 1 for number in slipnet.numbers: - if node == number and isinstance(self,Group) and len(self.objectList) == i: - descriptions += [ node ] + if node == number and isinstance(self, Group) and len(self.objectList) == i: + descriptions += [node] i += 1 if node == slipnet.middle and self.middleObject(): - descriptions += [ node ] + descriptions += [node] s = '' for d in descriptions: - s = '%s, %s' % (s,d.get_name()) + s = '%s, %s' % (s, d.get_name()) logging.info(s) return descriptions - def containsDescription(self,sought): + def containsDescription(self, sought): soughtType = sought.descriptionType soughtDescriptor = sought.descriptor for d in self.descriptions: @@ -158,8 +159,8 @@ class WorkspaceObject(WorkspaceStructure): return True return False - def hasDescription(self,slipnode): - return [ d for d in self.descriptions if d.descriptor == slipnode ] and True or False + def hasDescription(self, slipnode): + return [d for d in self.descriptions if d.descriptor == slipnode] and True or False def middleObject(self): # XXX only works if string is 3 chars long @@ -172,7 +173,7 @@ class WorkspaceObject(WorkspaceStructure): objectOnMyRightIsRightmost = True return objectOnMyRightIsRightmost and objectOnMyLeftIsLeftmost - def distinguishingDescriptor(self,descriptor): + def distinguishingDescriptor(self, descriptor): """Whether no other object of the same type (ie. letter or group) has the same descriptor""" if descriptor == slipnet.letter: return False @@ -184,19 +185,19 @@ class WorkspaceObject(WorkspaceStructure): return True def relevantDistinguishingDescriptors(self): - return [ d.descriptor for d in self.relevantDescriptions() if self.distinguishingDescriptor(d.descriptor) ] + return [d.descriptor for d in self.relevantDescriptions() if self.distinguishingDescriptor(d.descriptor)] - def getDescriptor(self,descriptionType): + def getDescriptor(self, descriptionType): """The description attached to this object of the specified description type.""" descriptor = None - logging.info("\nIn %s, trying for type: %s" % (self,descriptionType.get_name())) + logging.info("\nIn %s, trying for type: %s" % (self, descriptionType.get_name())) for description in self.descriptions: logging.info("Trying description: %s" % description) if description.descriptionType == descriptionType: return description.descriptor return descriptor - def getDescriptionType(self,sought_description): + def getDescriptionType(self, sought_description): """The description_type attached to this object of the specified description""" for description in self.descriptions: if description.descriptor == sought_description: @@ -204,10 +205,10 @@ class WorkspaceObject(WorkspaceStructure): description = None return description - def getCommonGroups(self,other): - return [ o for o in self.string.objects if self.isWithin(o) and other.isWithin(o) ] + def getCommonGroups(self, other): + return [o for o in self.string.objects if self.isWithin(o) and other.isWithin(o)] - def letterDistance(self,other): + def letterDistance(self, other): if other.leftStringPosition > self.rightStringPosition: return other.leftStringPosition - self.rightStringPosition if self.leftStringPosition > other.rightStringPosition: @@ -217,10 +218,9 @@ class WorkspaceObject(WorkspaceStructure): def letterSpan(self): return self.rightStringPosition - self.leftStringPosition + 1 - def beside(self,other): + def beside(self, other): if self.string != other.string: return False if self.leftStringPosition == other.rightStringPosition + 1: return True return other.leftStringPosition == self.rightStringPosition + 1 - diff --git a/copycat/workspaceString.py b/copycat/workspaceString.py index ea68d01..3731a13 100644 --- a/copycat/workspaceString.py +++ b/copycat/workspaceString.py @@ -2,6 +2,7 @@ import logging from letter import Letter from slipnet import slipnet + class WorkspaceString(object): def __init__(self, s): self.string = s @@ -60,7 +61,7 @@ class WorkspaceString(object): else: for o in self.objects: logging.info('object: %s, relative: %d = raw: %d / total: %d' % ( - o, o.relativeImportance * 1000, o.rawImportance, total )) + o, o.relativeImportance * 1000, o.rawImportance, total)) o.relativeImportance = o.rawImportance / total def updateIntraStringUnhappiness(self): diff --git a/copycat/workspaceStructure.py b/copycat/workspaceStructure.py index 107e16b..7b2546c 100644 --- a/copycat/workspaceStructure.py +++ b/copycat/workspaceStructure.py @@ -1,5 +1,6 @@ import formulas + class WorkspaceStructure(object): def __init__(self): self.string = None @@ -14,7 +15,7 @@ class WorkspaceStructure(object): def updateTotalStrength(self): """Recalculate the total strength based on internal and external strengths""" - weights = ( (self.internalStrength, self.internalStrength), (self.externalStrength, 100 - self.internalStrength) ) + weights = ((self.internalStrength, self.internalStrength), (self.externalStrength, 100 - self.internalStrength)) strength = formulas.weightedAverage(weights) self.totalStrength = strength @@ -24,14 +25,14 @@ class WorkspaceStructure(object): def updateInternalStrength(self): """How internally cohesive the structure is""" - raise NotImplementedError, 'call of abstract method: WorkspaceStructure.updateInternalStrength()' + raise NotImplementedError('call of abstract method: WorkspaceStructure.updateInternalStrength()') def updateExternalStrength(self): - raise NotImplementedError, 'call of abstract method: WorkspaceStructure.updateExternalStrength()' + raise NotImplementedError('call of abstract method: WorkspaceStructure.updateExternalStrength()') def break_the_structure(self): """Break this workspace structure Exactly what is broken depends on sub-class """ - raise NotImplementedError, 'call of abstract method: WorkspaceStructure.break_the_structure()' + raise NotImplementedError('call of abstract method: WorkspaceStructure.break_the_structure()') From 2281870cf2864972b7acf2fa6157f961f8ec7a48 Mon Sep 17 00:00:00 2001 From: James Tauber Date: Sat, 1 Dec 2012 02:10:33 -0500 Subject: [PATCH 4/7] removed unnecessary utils --- copycat/codeletMethods.py | 24 +++---- copycat/coderack.py | 12 ++-- copycat/formulas.py | 9 ++- copycat/group.py | 3 +- copycat/slipnode.py | 3 +- copycat/utils.py | 142 -------------------------------------- 6 files changed, 24 insertions(+), 169 deletions(-) delete mode 100644 copycat/utils.py diff --git a/copycat/codeletMethods.py b/copycat/codeletMethods.py index f618add..0e210ac 100644 --- a/copycat/codeletMethods.py +++ b/copycat/codeletMethods.py @@ -1,4 +1,4 @@ -#import utils +import random from coderack import coderack from workspaceObject import WorkspaceObject @@ -31,7 +31,7 @@ def __getScoutSource(slipnode, relevanceMethod, typeName): logging.info('initial : relevance = %d, unhappiness=%d' % (initialRelevance, int(initialUnhappiness))) logging.info('target : relevance = %d, unhappiness=%d' % (targetRelevance, int(targetUnhappiness))) string = workspace.initial - if utils.random() * (initialRelevance + initialUnhappiness + targetRelevance + targetUnhappiness) > (initialRelevance + initialUnhappiness): + if random.random() * (initialRelevance + initialUnhappiness + targetRelevance + targetUnhappiness) > (initialRelevance + initialUnhappiness): string = workspace.target logging.info('target string selected: %s for %s' % (workspace.target, typeName)) else: @@ -62,7 +62,7 @@ def __structureVsStructure(structure1, weight1, structure2, weight2): structure2.updateStrength() weightedStrength1 = temperatureAdjustedValue(structure1.totalStrength * weight1) weightedStrength2 = temperatureAdjustedValue(structure2.totalStrength * weight2) - rhs = (weightedStrength1 + weightedStrength2) * utils.random() + rhs = (weightedStrength1 + weightedStrength2) * random.random() logging.info('%d > %d' % (weightedStrength1, rhs)) return weightedStrength1 > rhs @@ -108,7 +108,7 @@ def breaker(): isinstance(s, Bond) or isinstance(s, Correspondence)] assert len(structures) - structure = utils.choice(structures) + structure = random.choice(structures) __showWhichStringObjectIsFrom(structure) breakObjects = [structure] if isinstance(structure, Bond): @@ -251,14 +251,14 @@ def rule_strength_tester(codelet): rule = codelet.arguments[0] rule.updateStrength() probability = temperatureAdjustedProbability(rule.totalStrength / 100.0) - assert utils.random() <= probability + assert random.random() <= probability coderack.newCodelet('rule-builder', codelet, rule.totalStrength, rule) def replacement_finder(): # choose random letter in initial string letters = [o for o in workspace.initial.objects if isinstance(o, Letter)] - letterOfInitialString = utils.choice(letters) + letterOfInitialString = random.choice(letters) logging.info('selected letter in initial string = %s' % letterOfInitialString) if letterOfInitialString.replacement: logging.info("Replacement already found for %s, so fizzling" % letterOfInitialString) @@ -406,7 +406,7 @@ def top_down_group_scout__category(codelet): if category == slipnet.sameness and isinstance(source, Letter): group = Group(source.string, slipnet.samenessGroup, None, slipnet.letterCategory, [source], []) probability = group.singleLetterGroupProbability() - assert utils.random() >= probability + assert random.random() >= probability coderack.proposeSingleLetterGroup(source, codelet) return direction = firstBond.directionCategory @@ -528,7 +528,7 @@ def top_down_group_scout__direction(codelet): #noinspection PyStringFormat def group_scout__whole_string(codelet): string = workspace.initial - if utils.random() > 0.5: + if random.random() > 0.5: string = workspace.target logging.info('target string selected: %s' % workspace.target) else: @@ -553,7 +553,7 @@ def group_scout__whole_string(codelet): objects += [leftmost] assert leftmost.rightmost # choose a random bond from list - chosenBond = utils.choice(bonds) + chosenBond = random.choice(bonds) category = chosenBond.category directionCategory = chosenBond.directionCategory bondFacet = chosenBond.facet @@ -570,7 +570,7 @@ def group_strength_tester(codelet): group.updateStrength() strength = group.totalStrength probability = temperatureAdjustedProbability(strength / 100.0) - assert utils.random() <= probability + assert random.random() <= probability # it is strong enough - post builder & activate nodes group.groupCategory.getRelatedNode(slipnet.bondCategory).buffer = 100.0 if group.directionCategory: @@ -670,7 +670,7 @@ def __getCutOff(density): distribution = [1.0, 1.0, 2.0, 5.0, 150.0, 5.0, 2.0, 1.0, 1.0, 1.0] else: distribution = [1.0, 1.0, 1.0, 2.0, 5.0, 150.0, 5.0, 2.0, 1.0, 1.0] - stop = sum(distribution) * utils.random() + stop = sum(distribution) * random.random() total = 0.0 for i in range(0, len(distribution)): total += distribution[i] @@ -766,7 +766,7 @@ def correspondence_strength_tester(codelet): correspondence.updateStrength() strength = correspondence.totalStrength probability = temperatureAdjustedProbability(strength / 100.0) - assert utils.random() <= probability + assert random.random() <= probability # activate some concepts for mapping in correspondence.conceptMappings: mapping.initialDescriptionType.buffer = 100.0 diff --git a/copycat/coderack.py b/copycat/coderack.py index c0b7fcf..e25eef6 100644 --- a/copycat/coderack.py +++ b/copycat/coderack.py @@ -2,8 +2,8 @@ import re import inspect import math import logging +import random -import utils import formulas import workspaceFormulas from slipnet import slipnet @@ -70,7 +70,7 @@ class CodeRack(object): howMany = workspaceFormulas.howManyToPost(codeletName) #print '%s:%d' % (codeletName,howMany) for unused in range(0, howMany): - if utils.random() < probability: + if random.random() < probability: urgency = self.getUrgencyBin(node.activation * node.conceptualDepth / 100.0) codelet = Codelet(codeletName, urgency, self.codeletsRun) codelet.arguments += [node] @@ -105,7 +105,7 @@ class CodeRack(object): if formulas.Temperature < 25.0 and 'translator' in codeletName: urgency = 5 for unused in range(0, howMany): - if utils.random() < probability: + if random.random() < probability: codelet = Codelet(codeletName, urgency, self.codeletsRun) self.post(codelet) @@ -200,7 +200,7 @@ class CodeRack(object): for codelet in self.codelets: urgency = (coderack.codeletsRun - codelet.timeStamp) * (7.5 - codelet.urgency) urgencies += [urgency] - threshold = utils.random() * sum(urgencies) + threshold = random.random() * sum(urgencies) sumOfUrgencies = 0.0 for i in range(0, len(self.codelets)): sumOfUrgencies += urgencies[i] @@ -275,12 +275,12 @@ class CodeRack(object): return None temp = formulas.Temperature scale = (100.0 - temp + 10.0) / 15.0 - # threshold = sum( [ c.urgency ** scale for c in self.codelets ] ) * utils.random() + # threshold = sum( [ c.urgency ** scale for c in self.codelets ] ) * random.random() urgsum = 0.0 for codelet in self.codelets: urg = codelet.urgency ** scale urgsum += urg - r = utils.random() + r = random.random() threshold = r * urgsum chosen = None urgencySum = 0.0 diff --git a/copycat/formulas.py b/copycat/formulas.py index f05f382..b3fb011 100644 --- a/copycat/formulas.py +++ b/copycat/formulas.py @@ -1,7 +1,6 @@ -import math # , random +import math import logging - -import utils +import random from temperature import temperature @@ -11,7 +10,7 @@ actualTemperature = Temperature = 100.0 def selectListPosition(probabilities): total = sum(probabilities) #logging.info('total: %s' % total) - r = utils.random() + r = random.random() stopPosition = total * r #logging.info('stopPosition: %s' % stopPosition) total = 0 @@ -57,7 +56,7 @@ def temperatureAdjustedProbability(value): def coinFlip(chance=0.5): - return utils.random() < chance + return random.random() < chance def blur(value): diff --git a/copycat/group.py b/copycat/group.py index 5d39997..e4a2ba7 100644 --- a/copycat/group.py +++ b/copycat/group.py @@ -1,4 +1,3 @@ -import utils import logging from workspace import workspace @@ -63,7 +62,7 @@ class Group(WorkspaceObject): #check whether or not to add length description category probability = self.lengthDescriptionProbability() - if utils.random() < probability: + if random.random() < probability: length = len(self.objectList) if length < 6: self.addDescription(slipnet.length, slipnet.numbers[length - 1]) diff --git a/copycat/slipnode.py b/copycat/slipnode.py index b3d200c..9d69243 100644 --- a/copycat/slipnode.py +++ b/copycat/slipnode.py @@ -1,5 +1,4 @@ import math -import utils import logging @@ -155,7 +154,7 @@ class Slipnode(object): def jump(self): value = (self.activation / 100.0) ** 3 #logging.info('jumping for %s at activation %s' % (self.name,self.activation)) - if self.activation > jump_threshold() and utils.random() < value and not self.clamped: + if self.activation > jump_threshold() and random.random() < value and not self.clamped: self.activate_fully() def get_name(self): diff --git a/copycat/utils.py b/copycat/utils.py deleted file mode 100644 index a7e6439..0000000 --- a/copycat/utils.py +++ /dev/null @@ -1,142 +0,0 @@ -def any(things): - """Return True if any of the things are True. - - things should be iterable. - - If the things are empty, then we can't say any are True - >>> any([]) - False - - If all the things are False, then we can't say any are True - >>> any([False,False,False]) - False - - If all the things are equivalent to False, then we can't say any are True - >>> any([0,[],'']) - False - - The type of the true thing should not matter - >>> any([1,[],'']) - True - >>> any([0,(2,),'']) - True - >>> any([0,[],'foo']) - True - >>> any([0,[],True,'']) - True - - It should not matter where the True thing is - >>> any((True,False,False,False,False,)) - True - >>> any((False,False,True,False,False,)) - True - >>> any((False,False,False,False,True,)) - True - - The size of the sequence should not matter - >>> True == any((True,)) == any((True,True,)) == any((True,True,True,True,)) - True - - Any string is True - >>> any('foo') - True - - Except an empty string - >>> any('') - False - - The function cannot be applied to ints - >>> any(7) - Traceback (most recent call last): - ... - TypeError: iteration over non-sequence - """ - for thing in things: - if thing: - return True - return False - - -def all(things): - """Return True if all of the things are True. - - things should be iterable. - - If the things are empty, then we can't say all are True - >>> all([]) - False - - If all the things are False, then we can't say all are True - >>> all([False,False,False]) - False - - If all the things are equivalent to False, then we can't say all are True - >>> all([0,[],'']) - False - - The type of the false thing should not matter - >>> all([0,True,True,]) - False - >>> all([True,(),True,]) - False - >>> all([True,True,'',]) - False - - Position of the false thing should not matter - >>> all((False,True,True,)) - False - >>> all((True,False,True,)) - False - >>> all((True,True,False,)) - False - - any string is True - >>> all('foo') - True - - Except an empty string - >>> all('') - False - - The function cannot be applied to ints - >>> all(7) - Traceback (most recent call last): - ... - TypeError: iteration over non-sequence - """ - for thing in things: - if not thing: - return False - return len(things) > 0 - -import logging - -seed = 999.0 -count = 0 -testably_random = True - - -def random(): - global testably_random - if testably_random: - from random import random - return random() - global seed - global count - seed += 1.0 - count += 1 - if seed > 1999: - seed = 0.0 - logging.info("count: %d" % count) - #if seed == 998: - # sys.exit(1) - return seed / 2000.0 - - -def choice(aList): - i = int(random() * len(aList)) - return aList[i] - -if __name__ == '__main__': - import doctest - doctest.testmod() From b939f3ec3f80b59a1a1a42dba9578966b0dc3570 Mon Sep 17 00:00:00 2001 From: James Tauber Date: Sat, 1 Dec 2012 02:12:22 -0500 Subject: [PATCH 5/7] fixed conceptual_depth for conceptualDepth --- copycat/coderack.py | 2 +- copycat/slipnode.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/copycat/coderack.py b/copycat/coderack.py index e25eef6..f525aea 100644 --- a/copycat/coderack.py +++ b/copycat/coderack.py @@ -75,7 +75,7 @@ class CodeRack(object): codelet = Codelet(codeletName, urgency, self.codeletsRun) codelet.arguments += [node] logging.info('Post top down: %s, with urgency: %d' % (codelet.name, urgency)) - #logging.info("From slipnode %s, activation: %s, depth: %s" %(node.get_name(),node.activation,node.conceptual_depth) ) + #logging.info("From slipnode %s, activation: %s, depth: %s" %(node.get_name(),node.activation,node.conceptualDepth) ) self.post(codelet) def postBottomUpCodelets(self): diff --git a/copycat/slipnode.py b/copycat/slipnode.py index 9d69243..a56fb0a 100644 --- a/copycat/slipnode.py +++ b/copycat/slipnode.py @@ -13,7 +13,7 @@ def jump_threshold(): class Slipnode(object): def __init__(self, name, depth, length=0.0): # logging.info('depth to %s for %s' % (depth,name)) - self.conceptual_depth = depth + self.conceptualDepth = depth self.usualConceptualDepth = depth self.name = name self.intrinsicLinkLength = length @@ -49,7 +49,7 @@ class Slipnode(object): def setConceptualDepth(self, depth): logging.info('set depth to %s for %s' % (depth, self.name)) - self.conceptual_depth = depth + self.conceptualDepth = depth def category(self): if not len(self.categoryLinks): @@ -81,7 +81,7 @@ class Slipnode(object): def update(self): act = self.activation self.oldActivation = act - self.buffer -= self.activation * (100.0 - self.conceptual_depth) / 100.0 + self.buffer -= self.activation * (100.0 - self.conceptualDepth) / 100.0 def linked(self, other): """Whether the other is among the outgoing links""" From ab27b745bee82af2f21e3ebe5018db5bb7e2dc34 Mon Sep 17 00:00:00 2001 From: James Tauber Date: Sat, 1 Dec 2012 02:13:31 -0500 Subject: [PATCH 6/7] fixed missing random imports --- copycat/group.py | 1 + copycat/slipnode.py | 1 + 2 files changed, 2 insertions(+) diff --git a/copycat/group.py b/copycat/group.py index e4a2ba7..03ccb94 100644 --- a/copycat/group.py +++ b/copycat/group.py @@ -1,4 +1,5 @@ import logging +import random from workspace import workspace from workspaceObject import WorkspaceObject diff --git a/copycat/slipnode.py b/copycat/slipnode.py index a56fb0a..6c3db17 100644 --- a/copycat/slipnode.py +++ b/copycat/slipnode.py @@ -1,5 +1,6 @@ import math import logging +import random def full_activation(): From 8332b1387e5b1e3d521e456fdb076eda09c7b94f Mon Sep 17 00:00:00 2001 From: James Tauber Date: Sat, 1 Dec 2012 02:15:25 -0500 Subject: [PATCH 7/7] fixed indentation problem --- copycat/correspondence.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/copycat/correspondence.py b/copycat/correspondence.py index 931cda7..7eb3440 100644 --- a/copycat/correspondence.py +++ b/copycat/correspondence.py @@ -129,15 +129,15 @@ class Correspondence(WorkspaceStructure): def updateExternalStrength(self): self.externalStrength = self.support() - def internallyCoherent(self): - """Whether any pair of relevant distinguishing mappings support each other""" - mappings = self.relevantDistinguishingConceptMappings() - for i in range(0, len(mappings)): - for j in range(0, len(mappings)): - if i != j: - if mappings[i].supports(mappings[j]): - return True - return False + def internallyCoherent(self): + """Whether any pair of relevant distinguishing mappings support each other""" + mappings = self.relevantDistinguishingConceptMappings() + for i in range(0, len(mappings)): + for j in range(0, len(mappings)): + if i != j: + if mappings[i].supports(mappings[j]): + return True + return False def slippages(self): mappings = [m for m in self.conceptMappings if m.slippage()]