PEP 008, mostly lines too long

This commit is contained in:
J Alan Brogan
2014-12-22 16:38:10 +00:00
parent c0971ce029
commit 94a0ecae48
21 changed files with 633 additions and 415 deletions

View File

@ -4,7 +4,8 @@ from workspace import workspace
class Bond(WorkspaceStructure):
def __init__(self, source, destination, bondCategory, bondFacet, sourceDescriptor, destinationDescriptor):
def __init__(self, source, destination, bondCategory, bondFacet,
sourceDescriptor, destinationDescriptor):
WorkspaceStructure.__init__(self)
self.source = source
self.string = self.source.string
@ -12,7 +13,7 @@ class Bond(WorkspaceStructure):
self.leftObject = self.source
self.rightObject = self.destination
self.directionCategory = slipnet.right
if self.source.leftStringPosition > self.destination.rightStringPosition:
if self.source.leftIndex > self.destination.rightIndex:
self.leftObject = self.destination
self.rightObject = self.source
self.directionCategory = slipnet.left
@ -94,8 +95,8 @@ class Bond(WorkspaceStructure):
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
sourceGap = self.get_source().leftIndex != self.get_source().rightIndex
destinationGap = self.destination.leftIndex != self.destination.rightIndex
if sourceGap == destinationGap:
memberCompatibility = 1.0
else:

View File

@ -28,14 +28,22 @@ def __getScoutSource(slipnode, relevanceMethod, typeName):
targetRelevance = relevanceMethod(workspace.target, slipnode)
initialUnhappiness = workspace.initial.intraStringUnhappiness
targetUnhappiness = workspace.target.intraStringUnhappiness
logging.info('initial : relevance = %d, unhappiness=%d' % (initialRelevance, int(initialUnhappiness)))
logging.info('target : relevance = %d, unhappiness=%d' % (targetRelevance, int(targetUnhappiness)))
logging.info('initial : relevance = %d, unhappiness=%d' % (
initialRelevance, int(initialUnhappiness)))
logging.info('target : relevance = %d, unhappiness=%d' % (
targetRelevance, int(targetUnhappiness)))
string = workspace.initial
if random.random() * (initialRelevance + initialUnhappiness + targetRelevance + targetUnhappiness) > (initialRelevance + initialUnhappiness):
relevances = initialRelevance + targetRelevance
unhappinesses = initialUnhappiness + targetUnhappiness
randomized = random.random() * (relevances + unhappinesses)
initials = initialRelevance + initialUnhappiness
if randomized > initials:
string = workspace.target
logging.info('target string selected: %s for %s' % (workspace.target, typeName))
logging.info('target string selected: %s for %s' % (
workspace.target, typeName))
else:
logging.info('initial string selected: %s for %s' % (workspace.initial, typeName))
logging.info('initial string selected: %s for %s' % (
workspace.initial, typeName))
source = chooseUnmodifiedObject('intraStringSalience', string.objects)
return source
@ -60,27 +68,32 @@ def __allOppositeMappings(mappings):
def __structureVsStructure(structure1, weight1, structure2, weight2):
structure1.updateStrength()
structure2.updateStrength()
weightedStrength1 = temperatureAdjustedValue(structure1.totalStrength * weight1)
weightedStrength2 = temperatureAdjustedValue(structure2.totalStrength * weight2)
weightedStrength1 = temperatureAdjustedValue(
structure1.totalStrength * weight1)
weightedStrength2 = temperatureAdjustedValue(
structure2.totalStrength * weight2)
rhs = (weightedStrength1 + weightedStrength2) * random.random()
logging.info('%d > %d' % (weightedStrength1, rhs))
return weightedStrength1 > rhs
def __fightItOut(structure, structureWeight, incompatibles, incompatibleWeight):
def __fight(structure, structureWeight, incompatibles, incompatibleWeight):
if not (incompatibles and len(incompatibles)):
return True
for incompatible in incompatibles:
if not __structureVsStructure(structure, structureWeight, incompatible, incompatibleWeight):
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):
def __fightIncompatibles(incompatibles, structure, name,
structureWeight, incompatibleWeight):
if len(incompatibles):
if __fightItOut(structure, structureWeight, incompatibles, incompatibleWeight):
if __fight(structure, structureWeight,
incompatibles, incompatibleWeight):
logging.info('broke the %s' % name)
return True
logging.info('failed to break %s: Fizzle' % name)
@ -104,19 +117,19 @@ def breaker():
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)]
isinstance(s, (Group, Bond, Correspondence))]
assert len(structures)
structure = random.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]
if structure.source.group:
if 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)
breakProbability = temperatureAdjustedProbability(
structure.totalStrength / 100.0)
if coinFlip(breakProbability):
return
for structure in breakObjects:
@ -131,11 +144,13 @@ def bottom_up_description_scout(codelet):
assert description
sliplinks = similarPropertyLinks(description.descriptor)
assert sliplinks and len(sliplinks)
values = [sliplink.degreeOfAssociation() * sliplink.destination.activation for sliplink in sliplinks]
values = [sliplink.degreeOfAssociation() * sliplink.destination.activation
for sliplink in sliplinks]
i = selectListPosition(values)
chosen = sliplinks[i]
chosenProperty = chosen.destination
coderack.proposeDescription(chosenObject, chosenProperty.category(), chosenProperty, codelet)
coderack.proposeDescription(chosenObject, chosenProperty.category(),
chosenProperty, codelet)
def top_down_description_scout(codelet):
@ -148,7 +163,8 @@ def top_down_description_scout(codelet):
values = [n.activation for n in descriptions]
i = selectListPosition(values)
chosenProperty = descriptions[i]
coderack.proposeDescription(chosenObject, chosenProperty.category(), chosenProperty, codelet)
coderack.proposeDescription(chosenObject, chosenProperty.category(),
chosenProperty, codelet)
def description_strength_tester(codelet):
@ -164,7 +180,7 @@ def description_strength_tester(codelet):
def description_builder(codelet):
description = codelet.arguments[0]
assert description.object in workspace.objects
if description.object.hasDescription(description.descriptor):
if description.object.described(description.descriptor):
description.descriptionType.buffer = 100.0
description.descriptor.buffer = 100.0
else:
@ -180,15 +196,18 @@ def bottom_up_bond_scout(codelet):
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())
bond_descriptors = __getDescriptors(bondFacet, source, destination)
sourceDescriptor, destinationDescriptor = bond_descriptors
logging.info("source descriptor: %s", sourceDescriptor.name.upper())
logging.info("destination descriptor: %s",
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)
coderack.proposeBond(source, destination, category, bondFacet,
sourceDescriptor, destinationDescriptor, codelet)
def rule_scout(codelet):
@ -201,15 +220,17 @@ def rule_scout(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
# ie. string-position (left-,right-most,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
otherObjectsOfSameLetter = [o for o in workspace.initial.objects
if not o != changed
and o.getDescriptionType(letter)]
if not len(otherObjectsOfSameLetter):
objectList += [letter]
# if this object corresponds to another object in the workspace
# objectList = the union of this and the distingushing descriptors
@ -219,9 +240,11 @@ def rule_scout(codelet):
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")
if targetObject.described(node):
if targetObject.distinguishingDescriptor(node):
newList += [node]
objectList = newList # XXX surely this should be +=
# "union of this and distinguishing descriptors"
assert objectList and len(objectList)
# use conceptual depth to choose a description
valueList = []
@ -231,11 +254,12 @@ def rule_scout(codelet):
valueList += [value]
i = selectListPosition(valueList)
descriptor = objectList[i]
# choose the relation (change the letmost object to..xxxx) i.e. "successor" or "d"
# choose the relation (change the letmost object to "successor" or "d"
objectList = []
if changed.replacement.relation:
objectList += [changed.replacement.relation]
objectList += [changed.replacement.objectFromModified.getDescriptor(slipnet.letterCategory)]
objectList += [changed.replacement.objectFromModified.getDescriptor(
slipnet.letterCategory)]
# use conceptual depth to choose a relation
valueList = []
for node in objectList:
@ -244,7 +268,8 @@ def rule_scout(codelet):
valueList += [value]
i = selectListPosition(valueList)
relation = objectList[i]
coderack.proposeRule(slipnet.letterCategory, descriptor, slipnet.letter, relation, codelet)
coderack.proposeRule(slipnet.letterCategory, descriptor,
slipnet.letter, relation, codelet)
def rule_strength_tester(codelet):
@ -259,12 +284,15 @@ def replacement_finder():
# choose random letter in initial string
letters = [o for o in workspace.initial.objects if isinstance(o, Letter)]
letterOfInitialString = random.choice(letters)
logging.info('selected letter in initial string = %s' % letterOfInitialString)
logging.info('selected letter in initial string = %s',
letterOfInitialString)
if letterOfInitialString.replacement:
logging.info("Replacement already found for %s, so fizzling" % letterOfInitialString)
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]
position = letterOfInitialString.leftIndex
moreLetters = [o for o in workspace.modified.objects
if isinstance(o, Letter) and o.leftIndex == position]
letterOfModifiedString = moreLetters and moreLetters[0] or None
assert letterOfModifiedString
position -= 1
@ -272,13 +300,17 @@ def replacement_finder():
modifiedAscii = ord(workspace.modifiedString[position])
diff = initialAscii - modifiedAscii
if abs(diff) < 2:
relations = {0: slipnet.sameness, -1: slipnet.successor, 1: slipnet.predecessor}
relations = {
0: slipnet.sameness,
-1: slipnet.successor,
1: slipnet.predecessor}
relation = relations[diff]
logging.info('Relation found: %s' % relation.name)
else:
relation = None
logging.info('no relation found')
letterOfInitialString.replacement = Replacement(letterOfInitialString, letterOfModifiedString, relation)
letterOfInitialString.replacement = Replacement(
letterOfInitialString, letterOfModifiedString, relation)
if relation != slipnet.sameness:
letterOfInitialString.changed = True
workspace.changedObject = letterOfInitialString
@ -293,7 +325,8 @@ def top_down_bond_scout__category(codelet):
logging.info('source: %s, destination: %s' % (source, destination))
assert destination
bondFacet = __getBondFacet(source, destination)
sourceDescriptor, destinationDescriptor = __getDescriptors(bondFacet, source, destination)
sourceDescriptor, destinationDescriptor = __getDescriptors(
bondFacet, source, destination)
forwardBond = sourceDescriptor.getBondCategory(destinationDescriptor)
if forwardBond == slipnet.identity:
forwardBond = slipnet.sameness
@ -302,24 +335,31 @@ def top_down_bond_scout__category(codelet):
backwardBond = destinationDescriptor.getBondCategory(sourceDescriptor)
assert category == forwardBond or category == backwardBond
if category == forwardBond:
coderack.proposeBond(source, destination, category, bondFacet, sourceDescriptor, destinationDescriptor, codelet)
coderack.proposeBond(source, destination, category,
bondFacet, sourceDescriptor,
destinationDescriptor, codelet)
else:
coderack.proposeBond(destination, source, category, bondFacet, destinationDescriptor, sourceDescriptor, codelet)
coderack.proposeBond(destination, source, category,
bondFacet, destinationDescriptor,
sourceDescriptor, codelet)
def top_down_bond_scout__direction(codelet):
direction = codelet.arguments[0]
source = __getScoutSource(direction, localDirectionCategoryRelevance, 'bond')
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)
sourceDescriptor, destinationDescriptor = __getDescriptors(
bondFacet, source, destination)
category = sourceDescriptor.getBondCategory(destinationDescriptor)
assert category
if category == slipnet.identity:
category = slipnet.sameness
coderack.proposeBond(source, destination, category, bondFacet, sourceDescriptor, destinationDescriptor, codelet)
coderack.proposeBond(source, destination, category, bondFacet,
sourceDescriptor, destinationDescriptor, codelet)
def bond_strength_tester(codelet):
@ -341,7 +381,8 @@ def bond_builder(codelet):
bond = codelet.arguments[0]
__showWhichStringObjectIsFrom(bond)
bond.updateStrength()
assert (bond.source in workspace.objects or bond.destination in workspace.objects)
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:
@ -363,8 +404,9 @@ def bond_builder(codelet):
incompatibleCorrespondences = bond.getIncompatibleCorrespondences()
if incompatibleCorrespondences:
logging.info("trying to break incompatible correspondences")
assert __fightItOut(bond, 2.0, incompatibleCorrespondences, 3.0)
#assert __fightIncompatibles(incompatibleCorrespondences,bond,'correspondences',2.0,3.0)
assert __fight(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:
@ -404,7 +446,8 @@ def top_down_group_scout__category(codelet):
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], [])
group = Group(source.string, slipnet.samenessGroup,
None, slipnet.letterCategory, [source], [])
probability = group.singleLetterGroupProbability()
assert random.random() >= probability
coderack.proposeSingleLetterGroup(source, codelet)
@ -415,27 +458,35 @@ def top_down_group_scout__category(codelet):
# 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
if not source.leftBond:
continue
if source.leftBond.category != category:
continue
if source.leftBond.directionCategory != direction:
if source.leftBond.directionCategory:
continue
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
if not destination.rightBond:
continue
if destination.rightBond.category != category:
continue
if destination.rightBond.directionCategory != direction:
if destination.rightBond.directionCategory:
continue
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 = []
@ -443,12 +494,14 @@ def top_down_group_scout__category(codelet):
bonds += [source.rightBond]
objects += [source.rightBond.rightObject]
source = source.rightBond.rightObject
coderack.proposeGroup(objects, bonds, groupCategory, direction, bondFacet, codelet)
coderack.proposeGroup(objects, bonds, groupCategory,
direction, bondFacet, codelet)
def top_down_group_scout__direction(codelet):
direction = codelet.arguments[0]
source = __getScoutSource(direction, localDirectionCategoryRelevance, 'direction')
source = __getScoutSource(direction, localDirectionCategoryRelevance,
'direction')
logging.info('source chosen = %s' % source)
assert not source.spansString()
if source.leftmost:
@ -494,26 +547,34 @@ def top_down_group_scout__direction(codelet):
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
if not source.leftBond:
continue
if source.leftBond.category != category:
continue
if source.leftBond.directionCategory != direction:
if source.leftBond.directionCategory:
continue
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
if not destination.rightBond:
continue
if destination.rightBond.category != category:
continue
if destination.rightBond.directionCategory != direction:
if destination.rightBond.directionCategory:
continue
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]
@ -522,7 +583,8 @@ def top_down_group_scout__direction(codelet):
bonds += [source.rightBond]
objects += [source.rightBond.rightObject]
source = source.rightBond.rightObject
coderack.proposeGroup(objects, bonds, groupCategory, direction, bondFacet, codelet)
coderack.proposeGroup(objects, bonds, groupCategory,
direction, bondFacet, codelet)
#noinspection PyStringFormat
@ -543,7 +605,9 @@ def group_scout__whole_string(codelet):
if leftmost.spansString():
# the object already spans the string - propose this object
group = leftmost
coderack.proposeGroup(group.objectList, group.bondList, group.groupCategory, group.directionCategory, group.facet, codelet)
coderack.proposeGroup(group.objectList, group.bondList,
group.groupCategory, group.directionCategory,
group.facet, codelet)
return
bonds = []
objects = [leftmost]
@ -560,7 +624,8 @@ def group_scout__whole_string(codelet):
bonds = possibleGroupBonds(category, directionCategory, bondFacet, bonds)
assert bonds
groupCategory = category.getRelatedNode(slipnet.groupCategory)
coderack.proposeGroup(objects, bonds, groupCategory, directionCategory, bondFacet, codelet)
coderack.proposeGroup(objects, bonds, groupCategory, directionCategory,
bondFacet, codelet)
def group_strength_tester(codelet):
@ -600,17 +665,21 @@ def group_builder(codelet):
#print 770
leftBond = objekt.leftBond
if leftBond:
lefty = leftBond.leftObject
if lefty != previous or leftBond.directionCategory != group.directionCategory:
incompatibleBonds += [leftBond]
if leftBond.leftObject == previous:
continue
if leftBond.directionCategory == group.directionCategory:
continue
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]
if rightBond.rightObject == next:
continue
if rightBond.directionCategory == group.directionCategory:
continue
incompatibleBonds += [rightBond]
next = objekt
# if incompatible bonds exist - fight
group.updateStrength()
@ -636,7 +705,9 @@ def group_builder(codelet):
destination = object1
category = group.groupCategory.getRelatedNode(slipnet.bondCategory)
facet = group.facet
newBond = Bond(source, destination, category, facet, source.getDescriptor(facet), destination.getDescriptor(facet))
newBond = Bond(source, destination, category, facet,
source.getDescriptor(facet),
destination.getDescriptor(facet))
newBond.buildBond()
group.bondList += [object1.rightBond]
for incompatible in incompatibleGroups:
@ -684,7 +755,8 @@ def rule_translator():
if len(workspace.initial) == 1 and len(workspace.target) == 1:
bondDensity = 1.0
else:
numberOfBonds = len(workspace.initial.bonds) + len(workspace.target.bonds)
numberOfBonds = (len(workspace.initial.bonds) +
len(workspace.target.bonds))
nearlyTotalLength = len(workspace.initial) + len(workspace.target) - 2
bondDensity = numberOfBonds / nearlyTotalLength
if bondDensity > 1.0:
@ -700,31 +772,43 @@ def rule_translator():
def bottom_up_correspondence_scout(codelet):
objectFromInitial = chooseUnmodifiedObject('interStringSalience', workspace.initial.objects)
objectFromTarget = chooseUnmodifiedObject('interStringSalience', workspace.target.objects)
objectFromInitial = chooseUnmodifiedObject('interStringSalience',
workspace.initial.objects)
objectFromTarget = chooseUnmodifiedObject('interStringSalience',
workspace.target.objects)
assert objectFromInitial.spansString() == objectFromTarget.spansString()
# get the posible concept mappings
conceptMappings = getMappings(objectFromInitial, objectFromTarget, objectFromInitial.relevantDescriptions(), objectFromTarget.relevantDescriptions())
conceptMappings = getMappings(objectFromInitial, objectFromTarget,
objectFromInitial.relevantDescriptions(),
objectFromTarget.relevantDescriptions())
assert conceptMappings and __slippability(conceptMappings)
#find out if any are distinguishing
distinguishingMappings = [m for m in conceptMappings if m.distinguishing()]
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]
opposites = [m for m in distinguishingMappings
if m.initialDescriptionType == slipnet.stringPositionCategory
and m.initialDescriptionType != slipnet.bondFacet]
initialDescriptionTypes = [m.initialDescriptionType for m in opposites]
flipTargetObject = False
if objectFromInitial.spansString() and objectFromTarget.spansString() and slipnet.directionCategory in initialDescriptionTypes and __allOppositeMappings(oppositeMappings) and slipnet.opposite.activation != 100.0:
if (objectFromInitial.spansString() and
objectFromTarget.spansString() and
slipnet.directionCategory in initialDescriptionTypes
and __allOppositeMappings(oppositeMappings)
and slipnet.opposite.activation != 100.0):
objectFromTarget = objectFromTarget.flippedVersion()
conceptMappings = getMappings(objectFromInitial, objectFromTarget, objectFromInitial.relevantDescriptions(), objectFromTarget.relevantDescriptions())
conceptMappings = getMappings(objectFromInitial, objectFromTarget,
objectFromInitial.relevantDescriptions(),
objectFromTarget.relevantDescriptions())
flipTargetObject = True
coderack.proposeCorrespondence(objectFromInitial, objectFromTarget, conceptMappings, flipTargetObject, codelet)
coderack.proposeCorrespondence(objectFromInitial, objectFromTarget,
conceptMappings, flipTargetObject, codelet)
def important_object_correspondence_scout(codelet):
objectFromInitial = chooseUnmodifiedObject('relativeImportance', workspace.initial.objects)
objectFromInitial = chooseUnmodifiedObject('relativeImportance',
workspace.initial.objects)
descriptors = objectFromInitial.relevantDistinguishingDescriptors()
slipnode = chooseSlipnodeByConceptualDepth(descriptors)
assert slipnode
@ -738,31 +822,47 @@ def important_object_correspondence_scout(codelet):
if description.descriptor == initialDescriptor:
targetCandidates += [objekt]
assert targetCandidates
objectFromTarget = chooseUnmodifiedObject('interStringSalience', targetCandidates)
objectFromTarget = chooseUnmodifiedObject('interStringSalience',
targetCandidates)
assert objectFromInitial.spansString() == objectFromTarget.spansString()
# get the posible concept mappings
conceptMappings = getMappings(objectFromInitial, objectFromTarget, objectFromInitial.relevantDescriptions(), objectFromTarget.relevantDescriptions())
conceptMappings = getMappings(objectFromInitial, objectFromTarget,
objectFromInitial.relevantDescriptions(),
objectFromTarget.relevantDescriptions())
assert conceptMappings and __slippability(conceptMappings)
#find out if any are distinguishing
distinguishingMappings = [m for m in conceptMappings if m.distinguishing()]
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]
opposites = [m for m in distinguishingMappings
if m.initialDescriptionType == slipnet.stringPositionCategory
and m.initialDescriptionType != slipnet.bondFacet]
initialDescriptionTypes = [m.initialDescriptionType for m in opposites]
flipTargetObject = False
if objectFromInitial.spansString() and objectFromTarget.spansString() and slipnet.directionCategory in initialDescriptionTypes and __allOppositeMappings(oppositeMappings) and slipnet.opposite.activation != 100.0:
if (objectFromInitial.spansString()
and objectFromTarget.spansString()
and slipnet.directionCategory in initialDescriptionTypes
and __allOppositeMappings(oppositeMappings)
and slipnet.opposite.activation != 100.0):
objectFromTarget = objectFromTarget.flippedVersion()
conceptMappings = getMappings(objectFromInitial, objectFromTarget, objectFromInitial.relevantDescriptions(), objectFromTarget.relevantDescriptions())
conceptMappings = getMappings(objectFromInitial, objectFromTarget,
objectFromInitial.relevantDescriptions(),
objectFromTarget.relevantDescriptions())
flipTargetObject = True
coderack.proposeCorrespondence(objectFromInitial, objectFromTarget, conceptMappings, flipTargetObject, codelet)
coderack.proposeCorrespondence(objectFromInitial, objectFromTarget,
conceptMappings, flipTargetObject, codelet)
def correspondence_strength_tester(codelet):
correspondence = codelet.arguments[0]
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()))
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)
@ -773,7 +873,8 @@ def correspondence_strength_tester(codelet):
mapping.initialDescriptor.buffer = 100.0
mapping.targetDescriptionType.buffer = 100.0
mapping.targetDescriptor.buffer = 100.0
coderack.newCodelet('correspondence-builder', codelet, strength, correspondence)
coderack.newCodelet('correspondence-builder', codelet,
strength, correspondence)
def correspondence_builder(codelet):
@ -788,7 +889,8 @@ def correspondence_builder(codelet):
targetNotFlipped = False
initialInObjects = objectFromInitial in workspace.objects
targetInObjects = objectFromTarget in workspace.objects
assert (initialInObjects or (not targetInObjects and (not (wantFlip and targetNotFlipped))))
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.
@ -799,32 +901,42 @@ def correspondence_builder(codelet):
if not mapping.isContainedBy(existing.conceptMappings):
existing.conceptMappings += [mapping]
return
incompatibleCorrespondences = correspondence.getIncompatibleCorrespondences()
incompatibles = 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)
if incompatibles:
correspondenceSpans = (correspondence.objectFromInitial.letterSpan() +
correspondence.objectFromTarget.letterSpan())
for incompatible in incompatibles:
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:
initial = correspondence.objectFromInitial
target = correspondence.objectFromTarget
if (initial.leftmost or initial.rightmost and
target.leftmost or target.rightmost):
# search for the incompatible bond
incompatibleBond = correspondence.getIncompatibleBond()
if incompatibleBond:
# bond found - fight against it
assert __structureVsStructure(correspondence, 3.0, incompatibleBond, 2.0)
assert __structureVsStructure(correspondence, 3.0,
incompatibleBond, 2.0)
# won against incompatible bond
incompatibleGroup = correspondence.objectFromTarget.group
incompatibleGroup = target.group
if incompatibleGroup:
assert __structureVsStructure(correspondence, 1.0, incompatibleGroup, 1.0)
assert __structureVsStructure(correspondence, 1.0,
incompatibleGroup, 1.0)
# if there is an incompatible rule, fight against it
incompatibleRule = None
if workspace.rule and workspace.rule.incompatibleRuleCorrespondence(correspondence):
incompatibleRule = workspace.rule
assert __structureVsStructure(correspondence, 1.0, incompatibleRule, 1.0)
for incompatible in incompatibleCorrespondences:
if workspace.rule:
if workspace.rule.incompatibleRuleCorrespondence(correspondence):
incompatibleRule = workspace.rule
assert __structureVsStructure(correspondence, 1.0,
incompatibleRule, 1.0)
for incompatible in incompatibles:
incompatible.break_the_structure()
# break incompatible group and bond if they exist
if incompatibleBond:

View File

@ -25,7 +25,9 @@ class CodeRack(object):
self.pressures = CoderackPressures()
self.pressures.initialisePressures()
self.reset()
self.initialCodeletNames = ('bottom-up-bond-scout', 'replacement-finder', 'bottom-up-correspondence-scout')
self.initialCodeletNames = ('bottom-up-bond-scout',
'replacement-finder',
'bottom-up-correspondence-scout')
self.codeletMethodsDir = None
self.runCodelets = {}
self.postings = {}
@ -52,7 +54,6 @@ class CodeRack(object):
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]
@ -63,20 +64,23 @@ class CodeRack(object):
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 random.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.conceptualDepth) )
self.post(codelet)
if node.activation != 100.0:
continue
#logging.info('using slipnode: %s' % node.get_name())
for codeletName in node.codelets:
probability = workspaceFormulas.probabilityOfPosting(
codeletName)
howMany = workspaceFormulas.howManyToPost(codeletName)
for unused in range(0, howMany):
if random.random() >= probability:
continue
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)
self.post(codelet)
def postBottomUpCodelets(self):
logging.info("posting bottom up codelets")
@ -127,7 +131,8 @@ class CodeRack(object):
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
The new codelet has urgency a function of
the degree of conceptual-depth of the descriptions in the rule
"""
from rule import Rule
@ -141,10 +146,12 @@ class CodeRack(object):
urgency = 0
self.newCodelet('rule-strength-tester', oldCodelet, urgency, rule)
def proposeCorrespondence(self, initialObject, targetObject, conceptMappings, flipTargetObject, oldCodelet):
def proposeCorrespondence(self, initialObject, targetObject,
conceptMappings, flipTargetObject, oldCodelet):
from correspondence import Correspondence
correspondence = Correspondence(initialObject, targetObject, conceptMappings, flipTargetObject)
correspondence = Correspondence(initialObject, targetObject,
conceptMappings, flipTargetObject)
for mapping in conceptMappings:
mapping.initialDescriptionType.buffer = 100.0
mapping.initialDescriptor.buffer = 100.0
@ -156,38 +163,46 @@ class CodeRack(object):
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)
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):
def proposeDescription(self, objekt, type_, descriptor, oldCodelet):
from description import Description
description = Description(objekt, descriptionType, descriptor)
description = Description(objekt, type_, descriptor)
descriptor.buffer = 100.0
urgency = descriptionType.activation
self.newCodelet('description-strength-tester', oldCodelet, urgency, description)
urgency = type_.activation
self.newCodelet('description-strength-tester',
oldCodelet, urgency, description)
def proposeSingleLetterGroup(self, source, codelet):
self.proposeGroup([source], [], slipnet.samenessGroup, None, slipnet.letterCategory, codelet)
self.proposeGroup([source], [], slipnet.samenessGroup, None,
slipnet.letterCategory, codelet)
def proposeGroup(self, objects, bondList, groupCategory, directionCategory, bondFacet, oldCodelet):
def proposeGroup(self, objects, bondList, groupCategory, directionCategory,
bondFacet, oldCodelet):
from group import Group
bondCategory = groupCategory.getRelatedNode(slipnet.bondCategory)
bondCategory.buffer = 100.0
if directionCategory:
directionCategory.buffer = 100.0
group = Group(objects[0].string, groupCategory, directionCategory, bondFacet, objects, bondList)
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):
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)
bond = Bond(source, destination, bondCategory, bondFacet,
sourceDescriptor, destinationDescriptor)
urgency = bondCategory.bondDegreeOfAssociation()
self.newCodelet('bond-strength-tester', oldCodelet, urgency, bond)
@ -198,7 +213,8 @@ class CodeRack(object):
return None
urgencies = []
for codelet in self.codelets:
urgency = (coderack.codeletsRun - codelet.timeStamp) * (7.5 - codelet.urgency)
urgency = ((coderack.codeletsRun - codelet.timeStamp) *
(7.5 - codelet.urgency))
urgencies += [urgency]
threshold = random.random() * sum(urgencies)
sumOfUrgencies = 0.0
@ -209,9 +225,6 @@ class CodeRack(object):
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)
@ -230,36 +243,36 @@ class CodeRack(object):
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',
)
'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)
raise NotImplementedError(
'Cannot find %s in codeletMethods' % methodName)
method = getattr(codeletMethods, methodName)
self.methods[methodName] = method
@ -275,7 +288,6 @@ class CodeRack(object):
return None
temp = formulas.Temperature
scale = (100.0 - temp + 10.0) / 15.0
# threshold = sum( [ c.urgency ** scale for c in self.codelets ] ) * random.random()
urgsum = 0.0
for codelet in self.codelets:
urg = codelet.urgency ** scale
@ -288,7 +300,9 @@ class CodeRack(object):
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("\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))
@ -304,7 +318,8 @@ class CodeRack(object):
if not chosen:
chosen = self.codelets[0]
self.removeCodelet(chosen)
logging.info('chosen codelet\n\t%s, urgency = %s' % (chosen.name, chosen.urgency))
logging.info('chosen codelet\n\t%s, urgency = %s',
chosen.name, chosen.urgency)
return chosen
def run(self, codelet):
@ -325,7 +340,8 @@ class CodeRack(object):
#if not self.codeletMethodsDir:
method = self.methods[methodName]
if not method:
raise ValueError('Found %s in codeletMethods, but cannot get it' % methodName)
raise ValueError('Found %s in codeletMethods, but cannot get it',
methodName)
if not callable(method):
raise RuntimeError('Cannot call %s()' % methodName)
args, varargs, varkw, defaults = inspect.getargspec(method)

View File

@ -38,7 +38,8 @@ class CoderackPressures(object):
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(
'Important Object Correspondences')]
self.pressures += [CoderackPressure('Breakers')]
def calculatePressures(self):
@ -121,7 +122,7 @@ class CoderackPressures(object):
if codelet.pressure:
codelet.pressure.codelets += [codelet] # XXX why do this
if i >= 0:
codelet.pressure = self.pressures[i] # when following with this ?
codelet.pressure = self.pressures[i] # when this is next?
logging.info('Add %s: %d' % (codelet.name, i))
if node:
logging.info('Node: %s' % node.name)

View File

@ -3,8 +3,11 @@ 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()))
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
@ -14,7 +17,8 @@ class ConceptMapping(object):
self.label = initialDescriptor.getBondCategory(targetDescriptor)
def __repr__(self):
return '<ConceptMapping: %s from %s to %s>' % (self.__str__(), self.initialDescriptor, self.targetDescriptor)
return '<ConceptMapping: %s from %s to %s>' % (
self.__str__(), self.initialDescriptor, self.targetDescriptor)
def __str__(self):
return self.label and self.label.name or 'anonymous'
@ -27,7 +31,7 @@ class ConceptMapping(object):
return association * (1 - depth * depth)
def __degreeOfAssociation(self):
#assumes the 2 descriptors are connected in the slipnet by at most 1 link
# Assumes the 2 descriptors are connected in the slipnet by <= 1 link
if self.initialDescriptor == self.targetDescriptor:
return 100.0
for link in self.initialDescriptor.lateralSlipLinks:
@ -43,14 +47,18 @@ class ConceptMapping(object):
return association * (1 + depth * depth)
def __conceptualDepth(self):
return (self.initialDescriptor.conceptualDepth + self.targetDescriptor.conceptualDepth) / 2.0
return (self.initialDescriptor.conceptualDepth +
self.targetDescriptor.conceptualDepth) / 2.0
def distinguishing(self):
if self.initialDescriptor == slipnet.whole and self.targetDescriptor == slipnet.whole:
if self.initialDescriptor == slipnet.whole:
if self.targetDescriptor == slipnet.whole:
return False
if not self.initialObject.distinguishingDescriptor(
self.initialDescriptor):
return False
if not self.initialObject.distinguishingDescriptor(self.initialDescriptor):
return False
return self.targetObject.distinguishingDescriptor(self.targetDescriptor)
return self.targetObject.distinguishingDescriptor(
self.targetDescriptor)
def sameInitialType(self, other):
return self.initialDescriptionType == other.initialDescriptionType
@ -68,7 +76,8 @@ class ConceptMapping(object):
return self.targetDescriptor == other.targetDescriptor
def sameDescriptors(self, other):
return self.sameInitialDescriptor(other) and self.sameTargetDescriptor(other)
if self.sameInitialDescriptor(other):
return self.sameTargetDescriptor(other)
def sameKind(self, other):
return self.sameTypes(other) and self.sameDescriptors(other)
@ -92,9 +101,9 @@ class ConceptMapping(object):
# 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.
# 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:
@ -102,18 +111,20 @@ class ConceptMapping(object):
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.
# 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 self.initialDescriptor == other.initialDescriptor and self.targetDescriptor == other.targetDescriptor:
return True
if self.initialDescriptor == other.initialDescriptor:
if self.targetDescriptor == other.targetDescriptor:
return True
# if the descriptors are not related return false
if not self.related(other):
return False
@ -122,15 +133,18 @@ class ConceptMapping(object):
return self.label == other.label
def relevant(self):
return self.initialDescriptionType.fully_active() and self.targetDescriptionType.fully_active()
if self.initialDescriptionType.fully_active():
return self.targetDescriptionType.fully_active()
def slippage(self):
return self.label != slipnet.sameness and self.label != slipnet.identity
if self.label != slipnet.sameness:
return self.label != slipnet.identity
def symmetricVersion(self):
if not self.slippage():
return self
if self.targetDescriptor.getBondCategory(self.initialDescriptor) == self.label:
bond = self.targetDescriptor.getBondCategory(self.initialDescriptor)
if bond == self.label:
return self
return ConceptMapping(
self.targetDescriptionType,
@ -140,4 +154,3 @@ class ConceptMapping(object):
self.initialObject,
self.targetObject
)

View File

@ -1,11 +1,6 @@
import logging
logging.basicConfig(
level=logging.INFO,
#format='%(asctime)s %(filename)s:%(lineno)d %(message)s',
format='%(message)s',
filename='./copycat.log',
filemode='w'
)
logging.basicConfig(level=logging.INFO, format='%(message)s',
filename='./copycat.log', filemode='w')
from workspace import workspace
@ -27,10 +22,13 @@ def updateEverything():
def mainLoop(lastUpdate):
temperature.tryUnclamp()
result = lastUpdate
if coderack.codeletsRun - lastUpdate >= slipnet.timeStepLength or not coderack.codeletsRun:
if not coderack.codeletsRun:
updateEverything()
result = coderack.codeletsRun
logging.debug('Number of codelets: %d' % len(coderack.codelets))
elif coderack.codeletsRun - lastUpdate >= slipnet.timeStepLength:
updateEverything()
result = coderack.codeletsRun
logging.debug('Number of codelets: %d', len(coderack.codelets))
coderack.chooseAndRunCodelet()
return result

View File

@ -4,7 +4,8 @@ from formulas import getMappings
class Correspondence(WorkspaceStructure):
def __init__(self, objectFromInitial, objectFromTarget, conceptMappings, flipTargetObject):
def __init__(self, objectFromInitial, objectFromTarget,
conceptMappings, flipTargetObject):
WorkspaceStructure.__init__(self)
self.objectFromInitial = objectFromInitial
self.objectFromTarget = objectFromTarget
@ -16,13 +17,15 @@ class Correspondence(WorkspaceStructure):
return '<%s>' % self.__str__()
def __str__(self):
return 'Correspondence between %s and %s' % (self.objectFromInitial, self.objectFromTarget)
return 'Correspondence between %s and %s' % (
self.objectFromInitial, self.objectFromTarget)
def distinguishingConceptMappings(self):
return [m for m in self.conceptMappings if m.distinguishing()]
def relevantDistinguishingConceptMappings(self):
return [m for m in self.conceptMappings if m.distinguishing() and m.relevant()]
return [m for m in self.conceptMappings
if m.distinguishing() and m.relevant()]
def extract_target_bond(self):
targetBond = False
@ -64,7 +67,8 @@ class Correspondence(WorkspaceStructure):
return None
def getIncompatibleCorrespondences(self):
return [o.correspondence for o in workspace.initial.objects if o and self.incompatible(o.correspondence)]
return [o.correspondence for o in workspace.initial.objects
if o and self.incompatible(o.correspondence)]
def incompatible(self, other):
if not other:
@ -96,22 +100,27 @@ class Correspondence(WorkspaceStructure):
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)])
if isinstance(self.objectFromInitial, Letter):
if self.objectFromInitial.spansString():
return 100.0
if isinstance(self.objectFromTarget, Letter):
if 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)
"""A function of how many concept mappings there are
Also considered: their strength and how well they cohere"""
distinguishingMappings = self.relevantDistinguishingConceptMappings()
numberOfConceptMappings = len(distinguishingMappings)
if numberOfConceptMappings < 1:
self.internalStrength = 0.0
return
totalStrength = sum([m.strength() for m in relevantDistinguishingMappings])
totalStrength = sum([m.strength() for m in distinguishingMappings])
averageStrength = totalStrength / numberOfConceptMappings
if numberOfConceptMappings == 1.0:
numberOfConceptMappingsFactor = 0.8
@ -123,14 +132,15 @@ class Correspondence(WorkspaceStructure):
internalCoherenceFactor = 2.5
else:
internalCoherenceFactor = 1.0
internalStrength = averageStrength * internalCoherenceFactor * numberOfConceptMappingsFactor
internalStrength = (averageStrength * internalCoherenceFactor *
numberOfConceptMappingsFactor)
self.internalStrength = min(internalStrength, 100.0)
def updateExternalStrength(self):
self.externalStrength = self.support()
def internallyCoherent(self):
"""Whether any pair of relevant distinguishing mappings support each other"""
"""Whether any pair of distinguishing mappings support each other"""
mappings = self.relevantDistinguishingConceptMappings()
for i in range(0, len(mappings)):
for j in range(0, len(mappings)):
@ -145,9 +155,10 @@ class Correspondence(WorkspaceStructure):
return mappings
def reflexive(self):
if not self.objectFromInitial.correspondence:
initial = self.objectFromInitial
if not initial.correspondence:
return False
if self.objectFromInitial.correspondence.objectFromTarget == self.objectFromTarget:
if initial.correspondence.objectFromTarget == self.objectFromTarget:
return True
return False
@ -165,17 +176,19 @@ class Correspondence(WorkspaceStructure):
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()]
if isinstance(self.objectFromInitial, Group):
if 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

View File

@ -26,25 +26,27 @@ class Description(WorkspaceStructure):
self.internalStrength = self.descriptor.conceptualDepth
def updateExternalStrength(self):
self.externalStrength = (self.localSupport() + self.descriptionType.activation) / 2
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
described_like_self = 0
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
if self.object.isWithin(other) or other.isWithin(self.object):
continue
for description in other.descriptions:
if description.descriptionType == self.descriptionType:
described_like_self += 1
results = {0: 0.0, 1: 20.0, 2: 60.0, 3: 90.0}
if supporters in results:
return results[supporters]
if described_like_self in results:
return results[described_like_self]
return 100.0
def build(self):
self.descriptionType.buffer = 100.0
self.descriptor.buffer = 100.0
if not self.object.hasDescription(self.descriptor):
if not self.object.described(self.descriptor):
logging.info('Add %s to descriptions' % self)
self.object.descriptions += [self]

View File

@ -14,12 +14,12 @@ def selectListPosition(probabilities):
stopPosition = total * r
#logging.info('stopPosition: %s' % stopPosition)
total = 0
index = 0
i = 0
for probability in probabilities:
total += probability
if total > stopPosition:
return index
index += 1
return i
i += 1
return 0
@ -75,9 +75,9 @@ def chooseObjectFromList(objects, 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]
i = selectListPosition(probabilities)
logging.info("Selected: %d" % i)
return objects[i]
def chooseRelevantDescriptionByActivation(workspaceObject):
@ -85,8 +85,8 @@ def chooseRelevantDescriptionByActivation(workspaceObject):
if not descriptions:
return None
activations = [description.descriptor.activation for description in descriptions]
index = selectListPosition(activations)
return descriptions[index]
i = selectListPosition(activations)
return descriptions[i]
def similarPropertyLinks(slip_node):

View File

@ -19,10 +19,10 @@ class Group(WorkspaceObject):
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.leftIndex = leftObject.leftIndex
self.leftmost = self.leftIndex == 1
self.rightIndex = rightObject.rightIndex
self.rightmost = self.rightIndex == len(self.string)
self.descriptions = []
self.bondDescriptions = []
@ -54,9 +54,9 @@ class Group(WorkspaceObject):
self.addDescription(slipnet.directionCategory, self.directionCategory)
if self.spansString():
self.addDescription(slipnet.stringPositionCategory, slipnet.whole)
elif self.leftStringPosition == 1:
elif self.leftIndex == 1:
self.addDescription(slipnet.stringPositionCategory, slipnet.leftmost)
elif self.rightStringPosition == self.string.length:
elif self.rightIndex == self.string.length:
self.addDescription(slipnet.stringPositionCategory, slipnet.rightmost)
elif self.middleObject():
self.addDescription(slipnet.stringPositionCategory, slipnet.middle)
@ -70,8 +70,8 @@ class Group(WorkspaceObject):
def __str__(self):
s = self.string.__str__()
l = self.leftStringPosition - 1
r = self.rightStringPosition
l = self.leftIndex - 1
r = self.rightIndex
return 'group[%d:%d] == %s' % (l, r - 1, s[l:r])
def getIncompatibleGroups(self):
@ -190,7 +190,7 @@ class Group(WorkspaceObject):
count = 0
for objekt in self.string.objects:
if isinstance(objekt, Group):
if objekt.rightStringPosition < self.leftStringPosition or objekt.leftStringPosition > self.rightStringPosition:
if objekt.rightIndex < self.leftIndex or objekt.leftIndex > self.rightIndex:
if objekt.groupCategory == self.groupCategory and objekt.directionCategory == self.directionCategory:
count += 1
return count
@ -201,9 +201,9 @@ class Group(WorkspaceObject):
return 100.0 * numberOfSupporters / halfLength
def sameGroup(self, other):
if self.leftStringPosition != other.leftStringPosition:
if self.leftIndex != other.leftIndex:
return False
if self.rightStringPosition != other.rightStringPosition:
if self.rightIndex != other.rightIndex:
return False
if self.groupCategory != other.groupCategory:
return False

View File

@ -8,10 +8,10 @@ class Letter(WorkspaceObject):
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
self.leftIndex = position
self.leftmost = self.leftIndex == 1
self.rightIndex = position
self.rightmost = self.rightIndex == length
def describe(self, position, length):
if length == 1:
@ -29,9 +29,9 @@ class Letter(WorkspaceObject):
def __str__(self):
if not self.string:
return ''
i = self.leftStringPosition - 1
i = self.leftIndex - 1
if len(self.string) <= i:
raise ValueError('len(self.string) <= self.leftStringPosition :: %d <= %d' % (len(self.string), self.leftStringPosition))
raise ValueError('len(self.string) <= self.leftIndex :: %d <= %d' % (len(self.string), self.leftIndex))
return self.string[i]
def distinguishingDescriptor(self, descriptor):

View File

@ -15,7 +15,9 @@ class Rule(WorkspaceStructure):
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)
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
@ -24,7 +26,8 @@ class Rule(WorkspaceStructure):
if not (self.descriptor and self.relation):
self.internalStrength = 0.0
return
averageDepth = (self.descriptor.conceptualDepth + self.relation.conceptualDepth) / 2.0
averageDepth = (self.descriptor.conceptualDepth +
self.relation.conceptualDepth) / 2.0
averageDepth **= 1.1
# see if the object corresponds to an object
# if so, see if the descriptor is present (modulo slippages) in the
@ -36,13 +39,17 @@ class Rule(WorkspaceStructure):
targetObject = changed.correspondence.objectFromTarget
slippages = workspace.slippages()
slipnode = self.descriptor.applySlippages(slippages)
if not targetObject.hasDescription(slipnode):
if not targetObject.described(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))
conceptual_height = (100.0 - self.descriptor.conceptualDepth) / 10.0
sharedDescriptorWeight = conceptual_height ** 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
@ -81,9 +88,8 @@ class Rule(WorkspaceStructure):
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
return bool([m for m in correspondence.conceptMappings
if m.initialDescriptor == self.descriptor])
def __changeString(self, string):
# applies the changes to self string ie. successor
@ -114,17 +120,18 @@ class Rule(WorkspaceStructure):
# 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)]
o.described(self.descriptor) and
o.described(self.category)]
changed = changeds and changeds[0] or None
logging.debug('changed object = %s' % changed)
if changed:
left = changed.leftStringPosition
left = changed.leftIndex
startString = ''
if left > 1:
startString = self.finalAnswer[0: left - 1]
right = changed.rightStringPosition
middleString = self.__changeString(self.finalAnswer[left - 1: right])
right = changed.rightIndex
middleString = self.__changeString(
self.finalAnswer[left - 1: right])
if not middleString:
return False
endString = ''

View File

@ -38,8 +38,6 @@ class SlipNet(object):
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:
@ -103,10 +101,13 @@ class SlipNet(object):
# categories
self.letterCategory = self.__addNode('letterCategory', 30.0)
self.stringPositionCategory = self.__addNode('stringPositionCategory', 70.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.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)
@ -151,14 +152,18 @@ class SlipNet(object):
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.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)
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)
@ -167,17 +172,25 @@ class SlipNet(object):
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.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)
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)
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)

View File

@ -1,6 +1,6 @@
import math
import logging
import random
from random import random
def full_activation():
@ -48,6 +48,9 @@ class Slipnode(object):
def unclamp(self):
self.clamped = False
def unclamped(self):
return not self.clamped
def setConceptualDepth(self, depth):
logging.info('set depth to %s for %s' % (depth, self.name))
self.conceptualDepth = depth
@ -60,7 +63,8 @@ class Slipnode(object):
def fully_active(self):
"""Whether this node has full activation"""
return self.activation > full_activation() - 0.00001 # allow a little leeway for floats
float_margin = 0.00001
return self.activation > full_activation() - float_margin
def activate_fully(self):
"""Make this node fully active"""
@ -115,7 +119,8 @@ class Slipnode(object):
if relation == slipnet.identity:
return self
destinations = [l.destination for l in self.outgoingLinks if l.label == relation]
destinations = [l.destination
for l in self.outgoingLinks if l.label == relation]
if destinations:
return destinations[0]
node = None
@ -147,15 +152,21 @@ class Slipnode(object):
[link.spread_activation() for link in self.outgoingLinks]
def addBuffer(self):
if not self.clamped:
if self.unclamped():
self.activation += self.buffer
self.activation = min(self.activation, 100)
self.activation = max(self.activation, 0)
def jump(self):
def can_jump():
if self.activation <= jump_threshold():
return False
if self.clamped:
return False
value = (self.activation / 100.0) ** 3
#logging.info('jumping for %s at activation %s' % (self.name,self.activation))
if self.activation > jump_threshold() and random.random() < value and not self.clamped:
return random() < value
def jump(self):
if self.can_jump():
self.activate_fully()
def get_name(self):

View File

@ -8,17 +8,17 @@ class Temperature(object):
self.clampTime = 30
def update(self, value):
logging.debug('update to %s' % value)
logging.debug('update to %s', value)
self.value = value
def tryUnclamp(self):
from coderack import coderack
if self.clamped and coderack.codeletsRun >= self.clampTime:
logging.info('unclamp temperature at %d' % coderack.codeletsRun)
logging.info('unclamp temperature at %d', coderack.codeletsRun)
self.clamped = False
def log(self):
logging.debug('temperature.value: %f' % self.value)
logging.debug('temperature.value: %f', self.value)
temperature = Temperature()

View File

@ -1,2 +0,0 @@
from exceptions import NotImplementedError
raise NotImplementedError

View File

@ -5,6 +5,13 @@ from workspaceString import WorkspaceString
unknownAnswer = '?'
def __adjustUnhappiness(values):
result = sum(values) / 2
if result > 100.0:
result = 100.0
return result
class Workspace(object):
def __init__(self):
#logging.debug('workspace.__init__()')
@ -15,7 +22,8 @@ class Workspace(object):
self.interStringUnhappiness = 0.0
def __repr__(self):
return '<Workspace trying %s:%s::%s:?>' % (self.initialString, self.modifiedString, self.targetString)
return '<Workspace trying %s:%s::%s:?>' % (
self.initialString, self.modifiedString, self.targetString)
def setStrings(self, initial, modified, target):
self.targetString = target
@ -33,16 +41,15 @@ class Workspace(object):
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 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])
self.intraStringUnhappiness = __adjustUnhappiness([
o.relativeImportance * o.intraStringUnhappiness
for o in self.objects])
self.interStringUnhappiness = __adjustUnhappiness([
o.relativeImportance * o.interStringUnhappiness
for o in self.objects])
self.totalUnhappiness = __adjustUnhappiness([
o.relativeImportance * o.totalUnhappiness for o in self.objects])
def assessTemperature(self):
self.calculateIntraStringUnhappiness()
@ -50,20 +57,23 @@ class Workspace(object):
self.calculateTotalUnhappiness()
def calculateIntraStringUnhappiness(self):
values = [o.relativeImportance * o.intraStringUnhappiness for o in self.objects]
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]
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]
logging.info("%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)
@ -81,12 +91,15 @@ class Workspace(object):
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]
"""A list of all objects in the workspace with >= 1 open bond slots"""
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)]
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)
@ -94,22 +107,25 @@ class Workspace(object):
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 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."""
"""A list of all unreplaced objects in the inital string"""
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 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]
"""A list of all uncorresponded objects in the inital string"""
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)
@ -127,7 +143,8 @@ class Workspace(object):
def slippages(self):
result = []
if self.changedObject and self.changedObject.correspondence:
result = [m for m in self.changedObject.correspondence.conceptMappings]
result = [m for m in
self.changedObject.correspondence.conceptMappings]
for objekt in workspace.initial.objects:
if objekt.correspondence:
for mapping in objekt.correspondence.slippages():
@ -148,9 +165,7 @@ class Workspace(object):
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]

View File

@ -50,9 +50,9 @@ def chooseNeighbour(source):
for objekt in workspace.objects:
if objekt.string != source.string:
continue
if objekt.leftStringPosition == source.rightStringPosition + 1:
if objekt.leftIndex == source.rightIndex + 1:
objects += [objekt]
elif source.leftStringPosition == objekt.rightStringPosition + 1:
elif source.leftIndex == objekt.rightIndex + 1:
objects += [objekt]
return formulas.chooseObjectFromList(objects, "intraStringSalience")
@ -69,7 +69,7 @@ def __chooseLeftNeighbor(source):
objects = []
for o in workspace.objects:
if o.string == source.string:
if source.leftStringPosition == o.rightStringPosition + 1:
if source.leftIndex == o.rightIndex + 1:
logging.info('%s is on left of %s' % (o, source))
objects += [o]
else:
@ -81,7 +81,7 @@ def __chooseLeftNeighbor(source):
def __chooseRightNeighbor(source):
objects = [o for o in workspace.objects if
o.string == source.string and
o.leftStringPosition == source.rightStringPosition + 1
o.leftIndex == source.rightIndex + 1
]
return formulas.chooseObjectFromList(objects, 'intraStringSalience')

View File

@ -26,8 +26,8 @@ class WorkspaceObject(WorkspaceStructure):
self.newAnswerLetter = False
self.name = ''
self.replacement = None
self.rightStringPosition = 0
self.leftStringPosition = 0
self.rightIndex = 0
self.leftIndex = 0
self.leftmost = False
self.rightmost = False
self.intraStringSalience = 0.0
@ -49,19 +49,14 @@ class WorkspaceObject(WorkspaceStructure):
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
copy = descriptions[:] # in case we add to our own descriptions
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)
self.addDescription(description.descriptionType,
description.descriptor)
else:
logging.info("Won't add it")
#print '%d added, have %d ' % (len(descriptions),len(self.descriptions))
from workspace import workspace
workspace.buildDescriptions(self)
@ -113,17 +108,25 @@ class WorkspaceObject(WorkspaceStructure):
self.interStringSalience = 100.0
else:
from formulas import weightedAverage
self.intraStringSalience = weightedAverage(((self.relativeImportance, 0.2), (self.intraStringUnhappiness, 0.8)))
self.interStringSalience = weightedAverage(((self.relativeImportance, 0.8), (self.interStringUnhappiness, 0.2)))
self.totalSalience = (self.intraStringSalience + self.interStringSalience) / 2.0
self.intraStringSalience = weightedAverage((
(self.relativeImportance, 0.2),
(self.intraStringUnhappiness, 0.8)))
self.interStringSalience = weightedAverage((
(self.relativeImportance, 0.8),
(self.interStringUnhappiness, 0.2)))
self.totalSalience = (self.intraStringSalience +
self.interStringSalience) / 2.0
logging.info('Set salience of %s to %f = (%f + %f)/2' % (
self.__str__(), self.totalSalience, self.intraStringSalience, self.interStringSalience))
self.__str__(), self.totalSalience,
self.intraStringSalience, self.interStringSalience))
def isWithin(self, other):
return self.leftStringPosition >= other.leftStringPosition and self.rightStringPosition <= other.rightStringPosition
return (self.leftIndex >= other.leftIndex and
self.rightIndex <= other.rightIndex)
def relevantDescriptions(self):
return [d for d in self.descriptions if d.descriptionType.fully_active()]
return [d for d in self.descriptions
if d.descriptionType.fully_active()]
def morePossibleDescriptions(self, node):
return []
@ -134,14 +137,15 @@ class WorkspaceObject(WorkspaceStructure):
from group import Group
for link in descriptionType.instanceLinks:
node = link.destination
if node == slipnet.first and self.hasDescription(slipnet.letters[0]):
if node == slipnet.first and self.described(slipnet.letters[0]):
descriptions += [node]
if node == slipnet.last and self.hasDescription(slipnet.letters[-1]):
if node == slipnet.last and self.described(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]
if node == number and isinstance(self, Group):
if len(self.objectList) == i:
descriptions += [node]
i += 1
if node == slipnet.middle and self.middleObject():
descriptions += [node]
@ -155,26 +159,27 @@ class WorkspaceObject(WorkspaceStructure):
soughtType = sought.descriptionType
soughtDescriptor = sought.descriptor
for d in self.descriptions:
if soughtType == d.descriptionType and soughtDescriptor == d.descriptor:
return True
if soughtType == d.descriptionType:
if 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 described(self, slipnode):
return bool([d for d in self.descriptions if d.descriptor == slipnode])
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:
if objekt.leftmost and objekt.rightIndex == self.leftIndex - 1:
objectOnMyLeftIsLeftmost = True
if objekt.rightmost and objekt.leftStringPosition == self.rightStringPosition + 1:
if objekt.rightmost and objekt.leftIndex == self.rightIndex + 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"""
"""Whether no other object of the same type has the same descriptor"""
if descriptor == slipnet.letter:
return False
if descriptor == slipnet.group:
@ -185,12 +190,15 @@ class WorkspaceObject(WorkspaceStructure):
return True
def relevantDistinguishingDescriptors(self):
return [d.descriptor for d in self.relevantDescriptions() if self.distinguishingDescriptor(d.descriptor)]
return [d.descriptor
for d in self.relevantDescriptions()
if self.distinguishingDescriptor(d.descriptor)]
def getDescriptor(self, descriptionType):
"""The description attached to this object of the specified description type."""
"""The description attached to this object of the description type."""
descriptor = None
logging.info("\nIn %s, trying for type: %s" % (self, descriptionType.get_name()))
logging.info("\nIn %s, trying for type: %s" % (
self, descriptionType.get_name()))
for description in self.descriptions:
logging.info("Trying description: %s" % description)
if description.descriptionType == descriptionType:
@ -198,7 +206,7 @@ class WorkspaceObject(WorkspaceStructure):
return descriptor
def getDescriptionType(self, sought_description):
"""The description_type attached to this object of the specified description"""
"""The description_type attached to this object of that description"""
for description in self.descriptions:
if description.descriptor == sought_description:
return description.descriptionType
@ -206,21 +214,22 @@ class WorkspaceObject(WorkspaceStructure):
return description
def getCommonGroups(self, other):
return [o for o in self.string.objects if self.isWithin(o) and other.isWithin(o)]
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
if other.leftIndex > self.rightIndex:
return other.leftIndex - self.rightIndex
if self.leftIndex > other.rightIndex:
return self.leftIndex - other.rightIndex
return 0
def letterSpan(self):
return self.rightStringPosition - self.leftStringPosition + 1
return self.rightIndex - self.leftIndex + 1
def beside(self, other):
if self.string != other.string:
return False
if self.leftStringPosition == other.rightStringPosition + 1:
if self.leftIndex == other.rightIndex + 1:
return True
return other.leftStringPosition == self.rightStringPosition + 1
return other.leftIndex == self.rightIndex + 1

View File

@ -21,7 +21,8 @@ class WorkspaceString(object):
letter = Letter(self, position + 1, self.length)
letter.workspaceString = self
letter.addDescription(slipnet.objectCategory, slipnet.letter)
letter.addDescription(slipnet.letterCategory, slipnet.letters[value])
letter.addDescription(slipnet.letterCategory,
slipnet.letters[value])
letter.describe(position + 1, self.length)
workspace.buildDescriptions(letter)
self.letters += [letter]
@ -31,7 +32,8 @@ class WorkspaceString(object):
return '<WorkspaceString: %s>' % 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))
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)
@ -60,8 +62,9 @@ class WorkspaceString(object):
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))
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):

View File

@ -1,6 +1,11 @@
import formulas
def abstract_call(objekt, name):
raise NotImplementedError('call of abstract method: %s.%s()' %
(objekt.__class__.__name__, name))
class WorkspaceStructure(object):
def __init__(self):
self.string = None
@ -14,8 +19,9 @@ class WorkspaceStructure(object):
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))
"""Recalculate the strength from internal and external strengths"""
weights = ((self.internalStrength, self.internalStrength),
(self.externalStrength, 100 - self.internalStrength))
strength = formulas.weightedAverage(weights)
self.totalStrength = strength
@ -25,14 +31,14 @@ class WorkspaceStructure(object):
def updateInternalStrength(self):
"""How internally cohesive the structure is"""
raise NotImplementedError('call of abstract method: WorkspaceStructure.updateInternalStrength()')
abstract_call(self, 'updateInternalStrength')
def updateExternalStrength(self):
raise NotImplementedError('call of abstract method: WorkspaceStructure.updateExternalStrength()')
abstract_call(self, 'updateExternalStrength')
def break_the_structure(self):
"""Break this workspace structure
Exactly what is broken depends on sub-class
"""
raise NotImplementedError('call of abstract method: WorkspaceStructure.break_the_structure()')
abstract_call(self, 'break_the_structure')