From 25ba9bfe93b8cefb230c4602253b8fb8cc3f723e Mon Sep 17 00:00:00 2001 From: Arthur O'Dwyer Date: Mon, 17 Apr 2017 13:53:45 -0700 Subject: [PATCH] (Almost) contextualize all the things! NFC. The only top-level imports now are needed for inheritance relationships. The only function-level imports are HACKS that I need to FIXME; they all `from context import context as ctx` and then fetch whatever they actually need from the `ctx` just as if `ctx` had been passed in by the caller instead of fetched from this magical global storage. --- copycat/bond.py | 18 ++++- copycat/coderack.py | 131 ++++++++++++++++++----------------- copycat/conceptMapping.py | 5 +- copycat/context.py | 6 +- copycat/correspondence.py | 20 ++++-- copycat/description.py | 9 ++- copycat/formulas.py | 12 ++-- copycat/group.py | 29 +++++--- copycat/letter.py | 6 +- copycat/rule.py | 10 ++- copycat/temperature.py | 3 + copycat/workspaceFormulas.py | 16 ++++- copycat/workspaceObject.py | 16 +++-- copycat/workspaceString.py | 5 +- 14 files changed, 180 insertions(+), 106 deletions(-) diff --git a/copycat/bond.py b/copycat/bond.py index 35a850d..8ebe899 100644 --- a/copycat/bond.py +++ b/copycat/bond.py @@ -1,12 +1,12 @@ from workspaceStructure import WorkspaceStructure -from slipnet import slipnet -from workspace import workspace class Bond(WorkspaceStructure): # pylint: disable=too-many-arguments def __init__(self, source, destination, bondCategory, bondFacet, sourceDescriptor, destinationDescriptor): + from context import context as ctx + slipnet = ctx.slipnet WorkspaceStructure.__init__(self) self.source = source self.string = self.source.string @@ -30,6 +30,8 @@ class Bond(WorkspaceStructure): self.directionCategory = None def flippedVersion(self): + from context import context as ctx + slipnet = ctx.slipnet return Bond( self.destination, self.source, self.category.getRelatedNode(slipnet.opposite), @@ -43,6 +45,8 @@ class Bond(WorkspaceStructure): self.category.name, self.leftObject, self.rightObject) def buildBond(self): + from context import context as ctx + workspace = ctx.workspace workspace.structures += [self] self.string.bonds += [self] self.category.buffer = 100.0 @@ -57,6 +61,8 @@ class Bond(WorkspaceStructure): self.breakBond() def breakBond(self): + from context import context as ctx + workspace = ctx.workspace if self in workspace.structures: workspace.structures.remove(self) if self in self.string.bonds: @@ -71,6 +77,8 @@ class Bond(WorkspaceStructure): def getIncompatibleCorrespondences(self): # returns a list of correspondences that are incompatible with # self bond + from context import context as ctx + workspace = ctx.workspace incompatibles = [] if self.leftObject.leftmost and self.leftObject.correspondence: correspondence = self.leftObject.correspondence @@ -97,6 +105,8 @@ class Bond(WorkspaceStructure): return incompatibles def updateInternalStrength(self): + from context import context as ctx + slipnet = ctx.slipnet # bonds between objects of same type(ie. letter or group) are # stronger than bonds between different types sourceGap = self.source.leftIndex != self.source.rightIndex @@ -147,6 +157,8 @@ class Bond(WorkspaceStructure): # returns a rough measure of the density in the string # of the same bond-category and the direction-category of # the given bond + from context import context as ctx + workspace = ctx.workspace slotSum = 0.0 supportSum = 0.0 for object1 in workspace.objects: @@ -177,6 +189,8 @@ class Bond(WorkspaceStructure): def possibleGroupBonds(bondCategory, directionCategory, bondFacet, bonds): + from context import context as ctx + slipnet = ctx.slipnet result = [] for bond in bonds: if (bond.category == bondCategory and diff --git a/copycat/coderack.py b/copycat/coderack.py index 66915ef..63121c4 100644 --- a/copycat/coderack.py +++ b/copycat/coderack.py @@ -5,8 +5,6 @@ import random import codeletMethods import formulas from codelet import Codelet -from temperature import temperature -from workspace import workspace NUMBER_OF_BINS = 7 @@ -19,62 +17,9 @@ def getUrgencyBin(urgency): return i + 1 -def probabilityOfPosting(workspace, codeletName): - if codeletName == 'breaker': - return 1.0 - if 'description' in codeletName: - result = (temperature.value() / 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: - assert False - return result - - -def howManyToPost(workspace, codeletName): - if codeletName == 'breaker' or '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() - 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 - - class Coderack(object): def __init__(self, ctx): - assert ctx.slipnet is not None self.ctx = ctx - self.slipnet = ctx.slipnet self.reset() self.runCodelets = {} self.postings = {} @@ -115,13 +60,64 @@ class Coderack(object): def reset(self): self.codelets = [] self.codeletsRun = 0 - temperature.clamped = True def updateCodelets(self): if self.codeletsRun > 0: self.postTopDownCodelets() self.postBottomUpCodelets() + def probabilityOfPosting(self, codeletName): + temperature = self.ctx.temperature + workspace = self.ctx.workspace + if codeletName == 'breaker': + return 1.0 + if 'description' in codeletName: + result = (temperature.value() / 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: + assert False + return result + + def howManyToPost(self, codeletName): + workspace = self.ctx.workspace + if codeletName == 'breaker' or '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() + 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 + def post(self, codelet): self.postings[codelet.name] = self.postings.get(codelet.name, 0) + 1 self.codelets += [codelet] @@ -130,14 +126,15 @@ class Coderack(object): self.removeCodelet(oldCodelet) def postTopDownCodelets(self): - for node in self.slipnet.slipnodes: + slipnet = self.ctx.slipnet + for node in slipnet.slipnodes: #logging.info('Trying slipnode: %s' % node.get_name()) if node.activation != 100.0: continue #logging.info('using slipnode: %s' % node.get_name()) for codeletName in node.codelets: - probability = probabilityOfPosting(workspace, codeletName) - howMany = howManyToPost(workspace, codeletName) + probability = self.probabilityOfPosting(codeletName) + howMany = self.howManyToPost(codeletName) for _ in xrange(howMany): if not formulas.coinFlip(probability): continue @@ -162,8 +159,9 @@ class Coderack(object): self.__postBottomUpCodelets('breaker') def __postBottomUpCodelets(self, codeletName): - probability = probabilityOfPosting(workspace, codeletName) - howMany = howManyToPost(workspace, codeletName) + temperature = self.ctx.temperature + probability = self.probabilityOfPosting(codeletName) + howMany = self.howManyToPost(codeletName) urgency = 3 if codeletName == 'breaker': urgency = 1 @@ -238,14 +236,15 @@ class Coderack(object): oldCodelet, urgency, description) def proposeSingleLetterGroup(self, source, codelet): - self.proposeGroup([source], [], self.slipnet.samenessGroup, None, - self.slipnet.letterCategory, codelet) + slipnet = self.ctx.slipnet + self.proposeGroup([source], [], slipnet.samenessGroup, None, + slipnet.letterCategory, codelet) def proposeGroup(self, objects, bondList, groupCategory, directionCategory, bondFacet, oldCodelet): from group import Group - - bondCategory = groupCategory.getRelatedNode(self.slipnet.bondCategory) + slipnet = self.ctx.slipnet + bondCategory = groupCategory.getRelatedNode(slipnet.bondCategory) bondCategory.buffer = 100.0 if directionCategory: directionCategory.buffer = 100.0 @@ -285,6 +284,7 @@ class Coderack(object): return self.codelets[0] def postInitialCodelets(self): + workspace = self.ctx.workspace logging.info("posting initial codelets") codeletsToPost = [ 'bottom-up-bond-scout', @@ -304,6 +304,7 @@ class Coderack(object): self.run(codelet) def chooseCodeletToRun(self): + temperature = self.ctx.temperature assert self.codelets scale = (100.0 - temperature.value() + 10.0) / 15.0 urgsum = sum(codelet.urgency ** scale for codelet in self.codelets) diff --git a/copycat/conceptMapping.py b/copycat/conceptMapping.py index c089045..c4d19c1 100644 --- a/copycat/conceptMapping.py +++ b/copycat/conceptMapping.py @@ -1,5 +1,4 @@ import logging -from slipnet import slipnet class ConceptMapping(object): @@ -52,6 +51,8 @@ class ConceptMapping(object): self.targetDescriptor.conceptualDepth) / 2.0 def distinguishing(self): + from context import context as ctx + slipnet = ctx.slipnet if self.initialDescriptor == slipnet.whole: if self.targetDescriptor == slipnet.whole: return False @@ -140,6 +141,8 @@ class ConceptMapping(object): return False def slippage(self): + from context import context as ctx + slipnet = ctx.slipnet if self.label != slipnet.sameness: return self.label != slipnet.identity return False diff --git a/copycat/context.py b/copycat/context.py index 30f1055..6317af4 100644 --- a/copycat/context.py +++ b/copycat/context.py @@ -1,5 +1,6 @@ import logging + class Context(object): def __init__(self): self.temperature = None @@ -23,9 +24,10 @@ class Context(object): def runTrial(self, answers): """Run a trial of the copycat algorithm""" - self.slipnet.reset() - self.workspace.reset() self.coderack.reset() + self.slipnet.reset() + self.temperature.reset() + self.workspace.reset() lastUpdate = float('-inf') while not self.workspace.foundAnswer: lastUpdate = self.mainLoop(lastUpdate) diff --git a/copycat/correspondence.py b/copycat/correspondence.py index f8a1624..e4702b0 100644 --- a/copycat/correspondence.py +++ b/copycat/correspondence.py @@ -1,6 +1,7 @@ -from workspace import workspace +from conceptMapping import ConceptMapping +from letter import Letter from workspaceStructure import WorkspaceStructure -from formulas import getMappings +import formulas class Correspondence(WorkspaceStructure): @@ -44,14 +45,14 @@ class Correspondence(WorkspaceStructure): return initialBond def getIncompatibleBond(self): + from context import context as ctx + slipnet = ctx.slipnet 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, @@ -67,6 +68,8 @@ class Correspondence(WorkspaceStructure): return None def getIncompatibleCorrespondences(self): + from context import context as ctx + workspace = ctx.workspace return [o.correspondence for o in workspace.initial.objects if o and self.incompatible(o.correspondence)] @@ -99,7 +102,8 @@ class Correspondence(WorkspaceStructure): return False def support(self): - from letter import Letter + from context import context as ctx + workspace = ctx.workspace if isinstance(self.objectFromInitial, Letter): if self.objectFromInitial.spansString(): return 100.0 @@ -162,6 +166,8 @@ class Correspondence(WorkspaceStructure): return False def buildCorrespondence(self): + from context import context as ctx + workspace = ctx.workspace workspace.structures += [self] if self.objectFromInitial.correspondence: self.objectFromInitial.correspondence.breakCorrespondence() @@ -177,7 +183,7 @@ class Correspondence(WorkspaceStructure): from group import Group if isinstance(self.objectFromInitial, Group): if isinstance(self.objectFromTarget, Group): - bondMappings = getMappings( + bondMappings = formulas.getMappings( self.objectFromInitial, self.objectFromTarget, self.objectFromInitial.bondDescriptions, @@ -196,6 +202,8 @@ class Correspondence(WorkspaceStructure): self.breakCorrespondence() def breakCorrespondence(self): + from context import context as ctx + workspace = ctx.workspace workspace.structures.remove(self) self.objectFromInitial.correspondence = None self.objectFromTarget.correspondence = None diff --git a/copycat/description.py b/copycat/description.py index 4abb330..65a2d2a 100644 --- a/copycat/description.py +++ b/copycat/description.py @@ -15,7 +15,8 @@ class Description(WorkspaceStructure): def __str__(self): s = 'description(%s) of %s' % (self.descriptor.get_name(), self.object) - from workspace import workspace + from context import context as ctx + workspace = ctx.workspace if self.object.string == workspace.initial: s += ' in initial string' else: @@ -30,7 +31,8 @@ class Description(WorkspaceStructure): self.descriptionType.activation) / 2 def localSupport(self): - from workspace import workspace + from context import context as ctx + workspace = ctx.workspace described_like_self = 0 for other in workspace.objects: if self.object == other: @@ -53,7 +55,8 @@ class Description(WorkspaceStructure): self.object.descriptions += [self] def breakDescription(self): - from workspace import workspace + from context import context as ctx + workspace = ctx.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 7428b59..d23c0c7 100644 --- a/copycat/formulas.py +++ b/copycat/formulas.py @@ -2,7 +2,7 @@ import math import logging import random -from context import context +from conceptMapping import ConceptMapping def selectListPosition(probabilities): @@ -60,12 +60,13 @@ def blur(value): def chooseObjectFromList(objects, attribute): + from context import context as ctx if not objects: return None probabilities = [] for objekt in objects: value = getattr(objekt, attribute) - probability = temperatureAdjustedValue(context, value) + probability = temperatureAdjustedValue(ctx, value) logging.info('Object: %s, value: %d, probability: %d', objekt, value, probability) probabilities += [probability] @@ -85,19 +86,21 @@ def chooseRelevantDescriptionByActivation(workspaceObject): def similarPropertyLinks(slip_node): + from context import context as ctx result = [] for slip_link in slip_node.propertyLinks: association = slip_link.degreeOfAssociation() / 100.0 - probability = temperatureAdjustedProbability(context, association) + probability = temperatureAdjustedProbability(ctx, association) if coinFlip(probability): result += [slip_link] return result def chooseSlipnodeByConceptualDepth(slip_nodes): + from context import context as ctx if not slip_nodes: return None - depths = [temperatureAdjustedValue(context, n.conceptualDepth) for n in slip_nodes] + depths = [temperatureAdjustedValue(ctx, n.conceptualDepth) for n in slip_nodes] i = selectListPosition(depths) return slip_nodes[i] @@ -137,7 +140,6 @@ def localDirectionCategoryRelevance(string, direction): def getMappings(objectFromInitial, objectFromTarget, initialDescriptions, targetDescriptions): mappings = [] - from conceptMapping import ConceptMapping for initial in initialDescriptions: for target in targetDescriptions: if initial.descriptionType == target.descriptionType: diff --git a/copycat/group.py b/copycat/group.py index 8b6a537..96371d2 100644 --- a/copycat/group.py +++ b/copycat/group.py @@ -1,17 +1,16 @@ import logging import random -from workspace import workspace from workspaceObject import WorkspaceObject -from slipnet import slipnet import formulas -from context import context class Group(WorkspaceObject): # pylint: disable=too-many-instance-attributes def __init__(self, string, groupCategory, directionCategory, facet, objectList, bondList): + from context import context as ctx + slipnet = ctx.slipnet # pylint: disable=too-many-arguments WorkspaceObject.__init__(self, string) self.groupCategory = groupCategory @@ -75,6 +74,8 @@ class Group(WorkspaceObject): def add_length_description_category(self): #check whether or not to add length description category + from context import context as ctx + slipnet = ctx.slipnet probability = self.lengthDescriptionProbability() if random.random() < probability: length = len(self.objectList) @@ -100,6 +101,8 @@ class Group(WorkspaceObject): self.bondDescriptions += [description] def singleLetterGroupProbability(self): + from context import context as ctx + slipnet = ctx.slipnet numberOfSupporters = self.numberOfLocalSupportingGroups() if not numberOfSupporters: return 0.0 @@ -112,9 +115,11 @@ class Group(WorkspaceObject): support = self.localSupport() / 100.0 activation = slipnet.length.activation / 100.0 supportedActivation = (support * activation) ** exp - return formulas.temperatureAdjustedProbability(context, supportedActivation) + return formulas.temperatureAdjustedProbability(ctx, supportedActivation) def flippedVersion(self): + from context import context as ctx + slipnet = ctx.slipnet flippedBonds = [b.flippedversion() for b in self.bondList] flippedGroup = self.groupCategory.getRelatedNode(slipnet.flipped) flippedDirection = self.directionCategory.getRelatedNode( @@ -123,6 +128,8 @@ class Group(WorkspaceObject): self.facet, self.objectList, flippedBonds) def buildGroup(self): + from context import context as ctx + workspace = ctx.workspace workspace.objects += [self] workspace.structures += [self] self.string.objects += [self] @@ -137,13 +144,15 @@ class Group(WorkspaceObject): description.descriptor.buffer = 100.0 def lengthDescriptionProbability(self): + from context import context as ctx + slipnet = ctx.slipnet 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(context, probability) + value = formulas.temperatureAdjustedProbability(ctx, probability) if value < 0.06: value = 0.0 # otherwise 1/20 chance always return value @@ -152,6 +161,8 @@ class Group(WorkspaceObject): self.breakGroup() def breakGroup(self): + from context import context as ctx + workspace = ctx.workspace while len(self.descriptions): description = self.descriptions[-1] description.breakDescription() @@ -173,6 +184,8 @@ class Group(WorkspaceObject): self.rightBond.breakBond() def updateInternalStrength(self): + from context import context as ctx + slipnet = ctx.slipnet relatedBondAssociation = self.groupCategory.getRelatedNode( slipnet.bondCategory).degreeOfAssociation() bondWeight = relatedBondAssociation ** 0.98 @@ -234,12 +247,12 @@ class Group(WorkspaceObject): return True def morePossibleDescriptions(self, node): + from context import context as ctx + slipnet = ctx.slipnet result = [] - i = 1 - for number in slipnet.numbers: + for i, number in enumerate(slipnet.numbers, 1): if node == number and len(self.objects) == i: result += [node] - i += 1 return result def distinguishingDescriptor(self, descriptor): diff --git a/copycat/letter.py b/copycat/letter.py index 33156f5..7f4c2df 100644 --- a/copycat/letter.py +++ b/copycat/letter.py @@ -1,11 +1,11 @@ from workspaceObject import WorkspaceObject -from slipnet import slipnet class Letter(WorkspaceObject): def __init__(self, string, position, length): + from context import context as ctx + workspace = ctx.workspace WorkspaceObject.__init__(self, string) - from workspace import workspace workspace.objects += [self] string.objects += [self] self.leftIndex = position @@ -14,6 +14,8 @@ class Letter(WorkspaceObject): self.rightmost = self.rightIndex == length def describe(self, position, length): + from context import context as ctx + slipnet = ctx.slipnet if length == 1: self.addDescription(slipnet.stringPositionCategory, slipnet.single) diff --git a/copycat/rule.py b/copycat/rule.py index fdde058..4089039 100644 --- a/copycat/rule.py +++ b/copycat/rule.py @@ -1,8 +1,6 @@ import logging -from slipnet import slipnet -from workspace import workspace from workspaceStructure import WorkspaceStructure from formulas import weightedAverage @@ -26,6 +24,8 @@ class Rule(WorkspaceStructure): self.externalStrength = self.internalStrength def updateInternalStrength(self): + from context import context as ctx + workspace = ctx.workspace if not (self.descriptor and self.relation): self.internalStrength = 0.0 return @@ -81,6 +81,8 @@ class Rule(WorkspaceStructure): self.descriptor.buffer = 100.0 def incompatibleRuleCorrespondence(self, correspondence): + from context import context as ctx + workspace = ctx.workspace if not correspondence: return False # find changed object @@ -95,6 +97,8 @@ class Rule(WorkspaceStructure): for m in correspondence.conceptMappings) def __changeString(self, string): + from context import context as ctx + slipnet = ctx.slipnet # applies the changes to self string ie. successor if self.facet == slipnet.length: if self.relation == slipnet.predecessor: @@ -115,6 +119,8 @@ class Rule(WorkspaceStructure): return self.relation.name.lower() def buildTranslatedRule(self): + from context import context as ctx + workspace = ctx.workspace slippages = workspace.slippages() self.category = self.category.applySlippages(slippages) self.facet = self.facet.applySlippages(slippages) diff --git a/copycat/temperature.py b/copycat/temperature.py index 8c9d749..4ffed9d 100644 --- a/copycat/temperature.py +++ b/copycat/temperature.py @@ -1,6 +1,9 @@ class Temperature(object): def __init__(self): + self.reset() + + def reset(self): self.actual_value = 100.0 self.last_unclamped_value = 100.0 self.clamped = True diff --git a/copycat/workspaceFormulas.py b/copycat/workspaceFormulas.py index f40910d..27e8b9e 100644 --- a/copycat/workspaceFormulas.py +++ b/copycat/workspaceFormulas.py @@ -1,11 +1,11 @@ import logging -from workspace import workspace -from slipnet import slipnet import formulas def chooseUnmodifiedObject(attribute, inObjects): + from context import context as ctx + workspace = ctx.workspace objects = [o for o in inObjects if o.string != workspace.modified] if not len(objects): print 'no objects available in initial or target strings' @@ -13,6 +13,8 @@ def chooseUnmodifiedObject(attribute, inObjects): def chooseNeighbor(source): + from context import context as ctx + workspace = ctx.workspace objects = [] for objekt in workspace.objects: if objekt.string != source.string: @@ -25,6 +27,8 @@ def chooseNeighbor(source): def chooseDirectedNeighbor(source, direction): + from context import context as ctx + slipnet = ctx.slipnet if direction == slipnet.left: logging.info('Left') return __chooseLeftNeighbor(source) @@ -33,6 +37,8 @@ def chooseDirectedNeighbor(source, direction): def __chooseLeftNeighbor(source): + from context import context as ctx + workspace = ctx.workspace objects = [] for o in workspace.objects: if o.string == source.string: @@ -46,6 +52,8 @@ def __chooseLeftNeighbor(source): def __chooseRightNeighbor(source): + from context import context as ctx + workspace = ctx.workspace objects = [o for o in workspace.objects if o.string == source.string and o.leftIndex == source.rightIndex + 1] @@ -53,6 +61,8 @@ def __chooseRightNeighbor(source): def chooseBondFacet(source, destination): + from context import context as ctx + slipnet = ctx.slipnet sourceFacets = [d.descriptionType for d in source.descriptions if d.descriptionType in slipnet.bondFacets] bondFacets = [d.descriptionType for d in destination.descriptions @@ -72,6 +82,8 @@ def __supportForDescriptionType(descriptionType, string): def __descriptionTypeSupport(descriptionType, string): """The proportion of objects in the string with this descriptionType""" + from context import context as ctx + workspace = ctx.workspace described_count = total = 0 for objekt in workspace.objects: if objekt.string == string: diff --git a/copycat/workspaceObject.py b/copycat/workspaceObject.py index 7f0ad20..688a93e 100644 --- a/copycat/workspaceObject.py +++ b/copycat/workspaceObject.py @@ -2,7 +2,6 @@ import logging from description import Description from formulas import weightedAverage -from slipnet import slipnet from workspaceStructure import WorkspaceStructure @@ -50,6 +49,8 @@ class WorkspaceObject(WorkspaceStructure): self.descriptions += [description] def addDescriptions(self, descriptions): + from context import context as ctx + workspace = ctx.workspace copy = descriptions[:] # in case we add to our own descriptions for description in copy: logging.info('might add: %s', description) @@ -58,7 +59,6 @@ class WorkspaceObject(WorkspaceStructure): description.descriptor) else: logging.info("Won't add it") - from workspace import workspace workspace.buildDescriptions(self) def __calculateIntraStringHappiness(self): @@ -123,21 +123,21 @@ class WorkspaceObject(WorkspaceStructure): if d.descriptionType.fully_active()] def getPossibleDescriptions(self, descriptionType): + from group import Group # gross, TODO FIXME + from context import context as ctx + slipnet = ctx.slipnet 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.described(slipnet.letters[0]): descriptions += [node] if node == slipnet.last and self.described(slipnet.letters[-1]): descriptions += [node] - i = 1 - for number in slipnet.numbers: + for i, number in enumerate(slipnet.numbers, 1): 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] s = '' @@ -170,9 +170,13 @@ class WorkspaceObject(WorkspaceStructure): return objectOnMyRightIsRightmost and objectOnMyLeftIsLeftmost def distinguishingDescriptor(self, descriptor): + from context import context as ctx + slipnet = ctx.slipnet return slipnet.isDistinguishingDescriptor(descriptor) def relevantDistinguishingDescriptors(self): + from context import context as ctx + slipnet = ctx.slipnet return [d.descriptor for d in self.relevantDescriptions() if slipnet.isDistinguishingDescriptor(d.descriptor)] diff --git a/copycat/workspaceString.py b/copycat/workspaceString.py index cf450a9..765d787 100644 --- a/copycat/workspaceString.py +++ b/copycat/workspaceString.py @@ -1,10 +1,12 @@ import logging from letter import Letter -from slipnet import slipnet class WorkspaceString(object): def __init__(self, s): + from context import context as ctx + slipnet = ctx.slipnet + workspace = ctx.workspace self.string = s self.bonds = [] self.objects = [] @@ -14,7 +16,6 @@ class WorkspaceString(object): if not self.length: return position = 0 - from workspace import workspace for c in self.string.upper(): value = ord(c) - ord('A')