From cfaebd150ff47116efd074a622f65ffeee9578bd Mon Sep 17 00:00:00 2001 From: James Tauber Date: Fri, 30 Nov 2012 02:12:44 -0500 Subject: [PATCH] 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()'