Merge pull request #3 from jtauber/master

improved PEP compliance and fixed errors preventing it from running
This commit is contained in:
Alan
2012-12-10 07:59:00 -08:00
27 changed files with 3159 additions and 3223 deletions

View File

@ -1,7 +1,7 @@
co.py.cat co.py.cat
========= =========
An implementation of the [Douglas Hofstadter](http://prelectur.stanford.edu/lecturers/hofstadter/)'s [copycat](https://en.wikipedia.org/wiki/Copycat_%28software%29) [algorithm](http://www.al-got-rhythm.net) An implementation of [Douglas Hofstadter](http://prelectur.stanford.edu/lecturers/hofstadter/)'s [copycat](https://en.wikipedia.org/wiki/Copycat_%28software%29) [algorithm](http://www.al-got-rhythm.net)
This implementation is a copycat of Scott Boland's [Java implementation](http://itee.uq.edu.au/~scottb/_Copycat/), but re-written into Python. It's not a direct translation - but based on his code. I did not carry over the GUI, as this version can more usefully be run from command line, or imported for use by other Python scripts. This implementation is a copycat of Scott Boland's [Java implementation](http://itee.uq.edu.au/~scottb/_Copycat/), but re-written into Python. It's not a direct translation - but based on his code. I did not carry over the GUI, as this version can more usefully be run from command line, or imported for use by other Python scripts.

View File

@ -2,181 +2,183 @@ from workspaceStructure import WorkspaceStructure
from slipnet import slipnet from slipnet import slipnet
from workspace import workspace from workspace import workspace
class Bond(WorkspaceStructure): class Bond(WorkspaceStructure):
def __init__(self,source, destination, bondCategory, bondFacet, sourceDescriptor, destinationDescriptor): def __init__(self, source, destination, bondCategory, bondFacet, sourceDescriptor, destinationDescriptor):
WorkspaceStructure.__init__(self) WorkspaceStructure.__init__(self)
self.source = source self.source = source
self.string = self.source.string self.string = self.source.string
self.destination = destination self.destination = destination
self.leftObject = self.source self.leftObject = self.source
self.rightObject = self.destination self.rightObject = self.destination
self.directionCategory = slipnet.right self.directionCategory = slipnet.right
if self.source.leftStringPosition > self.destination.rightStringPosition: if self.source.leftStringPosition > self.destination.rightStringPosition:
self.leftObject = self.destination self.leftObject = self.destination
self.rightObject = self.source self.rightObject = self.source
self.directionCategory = slipnet.left self.directionCategory = slipnet.left
self.facet = bondFacet self.facet = bondFacet
self.sourceDescriptor = sourceDescriptor self.sourceDescriptor = sourceDescriptor
self.destinationDescriptor = destinationDescriptor self.destinationDescriptor = destinationDescriptor
self.category = bondCategory self.category = bondCategory
self.destinationIsOnRight = self.destination == self.rightObject self.destinationIsOnRight = self.destination == self.rightObject
self.bidirectional = self.sourceDescriptor == self.destinationDescriptor self.bidirectional = self.sourceDescriptor == self.destinationDescriptor
if self.bidirectional: if self.bidirectional:
self.directionCategory = None self.directionCategory = None
def flippedVersion(self): def flippedVersion(self):
""" """
""" """
return Bond( return Bond(
self.destination, self.get_source(), self.category.getRelatedNode(slipnet.opposite), self.destination, self.get_source(), self.category.getRelatedNode(slipnet.opposite),
self.facet, self.destinationDescriptor, self.sourceDescriptor self.facet, self.destinationDescriptor, self.sourceDescriptor
) )
def __repr__(self): def __repr__(self):
return '<Bond: %s>' % self.__str__() return '<Bond: %s>' % self.__str__()
def __str__(self): def __str__(self):
return '%s bond between %s and %s' % ( self.category.name, self.leftObject, self.rightObject) return '%s bond between %s and %s' % (self.category.name, self.leftObject, self.rightObject)
def buildBond(self): def buildBond(self):
workspace.structures += [ self ] workspace.structures += [self]
self.string.bonds += [ self ] self.string.bonds += [self]
self.category.buffer = 100.0 self.category.buffer = 100.0
if self.directionCategory: if self.directionCategory:
self.directionCategory.buffer = 100.0 self.directionCategory.buffer = 100.0
self.leftObject.rightBond = self self.leftObject.rightBond = self
self.rightObject.leftBond = self self.rightObject.leftBond = self
self.leftObject.bonds += [ self ] self.leftObject.bonds += [self]
self.rightObject.bonds += [ self ] self.rightObject.bonds += [self]
def break_the_structure(self): def break_the_structure(self):
self.breakBond() self.breakBond()
def breakBond(self): def breakBond(self):
if self in workspace.structures: if self in workspace.structures:
workspace.structures.remove(self) workspace.structures.remove(self)
if self in self.string.bonds: if self in self.string.bonds:
self.string.bonds.remove(self) self.string.bonds.remove(self)
self.leftObject.rightBond = None self.leftObject.rightBond = None
self.rightObject.leftBond = None self.rightObject.leftBond = None
if self in self.leftObject.bonds: if self in self.leftObject.bonds:
self.leftObject.bonds.remove(self) self.leftObject.bonds.remove(self)
if self in self.rightObject.bonds: if self in self.rightObject.bonds:
self.rightObject.bonds.remove(self) self.rightObject.bonds.remove(self)
def getIncompatibleCorrespondences(self): def getIncompatibleCorrespondences(self):
# returns a list of correspondences that are incompatible with # returns a list of correspondences that are incompatible with
# self bond # self bond
incompatibles = [] incompatibles = []
if self.leftObject.leftmost and self.leftObject.correspondence: if self.leftObject.leftmost and self.leftObject.correspondence:
correspondence = self.leftObject.correspondence correspondence = self.leftObject.correspondence
if self.string == workspace.initial: if self.string == workspace.initial:
objekt = self.leftObject.correspondence.objectFromTarget objekt = self.leftObject.correspondence.objectFromTarget
else: else:
objekt = self.leftObject.correspondence.objectFromInitial objekt = self.leftObject.correspondence.objectFromInitial
if objekt.leftmost and objekt.rightBond: if objekt.leftmost and objekt.rightBond:
if objekt.rightBond.directionCategory and objekt.rightBond.directionCategory != self.directionCategory: if objekt.rightBond.directionCategory and objekt.rightBond.directionCategory != self.directionCategory:
incompatibles += [ correspondence ] incompatibles += [correspondence]
if self.rightObject.rightmost and self.rightObject.correspondence: if self.rightObject.rightmost and self.rightObject.correspondence:
correspondence = self.rightObject.correspondence correspondence = self.rightObject.correspondence
if self.string == workspace.initial: if self.string == workspace.initial:
objekt = self.rightObject.correspondence.objectFromTarget objekt = self.rightObject.correspondence.objectFromTarget
else: else:
objekt = self.rightObject.correspondence.objectFromInitial objekt = self.rightObject.correspondence.objectFromInitial
if objekt.rightmost and objekt.leftBond: if objekt.rightmost and objekt.leftBond:
if objekt.leftBond.directionCategory and objekt.leftBond.directionCategory != self.directionCategory: if objekt.leftBond.directionCategory and objekt.leftBond.directionCategory != self.directionCategory:
incompatibles += [ correspondence ] incompatibles += [correspondence]
return incompatibles return incompatibles
def updateInternalStrength(self): def updateInternalStrength(self):
# bonds between objects of same type(ie. letter or group) are # bonds between objects of same type(ie. letter or group) are
# stronger than bonds between different types # stronger than bonds between different types
sourceGap = self.get_source().leftStringPosition != self.get_source().rightStringPosition sourceGap = self.get_source().leftStringPosition != self.get_source().rightStringPosition
destinationGap = self.destination.leftStringPosition != self.destination.rightStringPosition destinationGap = self.destination.leftStringPosition != self.destination.rightStringPosition
if sourceGap == destinationGap: if sourceGap == destinationGap:
memberCompatibility = 1.0 memberCompatibility = 1.0
else: else:
memberCompatibility = 0.7 memberCompatibility = 0.7
# letter category bonds are stronger # letter category bonds are stronger
if self.facet == slipnet.letterCategory: if self.facet == slipnet.letterCategory:
facetFactor = 1.0 facetFactor = 1.0
else: else:
facetFactor = 0.7 facetFactor = 0.7
strength = min(100.0,memberCompatibility * facetFactor * self.category.bondDegreeOfAssociation()) strength = min(100.0, memberCompatibility * facetFactor * self.category.bondDegreeOfAssociation())
self.internalStrength = strength self.internalStrength = strength
def updateExternalStrength(self): def updateExternalStrength(self):
self.externalStrength = 0.0 self.externalStrength = 0.0
supporters = self.numberOfLocalSupportingBonds() supporters = self.numberOfLocalSupportingBonds()
if supporters > 0.0: if supporters > 0.0:
density = self.localDensity() / 100.0 density = self.localDensity() / 100.0
density = density ** 0.5 * 100.0 density = density ** 0.5 * 100.0
supportFactor = 0.6 ** (1.0 / supporters ** 3) supportFactor = 0.6 ** (1.0 / supporters ** 3)
supportFactor = max(1.0,supportFactor) supportFactor = max(1.0, supportFactor)
strength = supportFactor * density strength = supportFactor * density
self.externalStrength = strength self.externalStrength = strength
def numberOfLocalSupportingBonds(self): def numberOfLocalSupportingBonds(self):
return len([ b for b in self.string.bonds if b.string == self.get_source().string and return len([b for b in self.string.bonds if b.string == self.get_source().string and
self.leftObject.letterDistance(b.leftObject) != 0 and self.leftObject.letterDistance(b.leftObject) != 0 and
self.rightObject.letterDistance(b.rightObject) != 0 and self.rightObject.letterDistance(b.rightObject) != 0 and
self.category == b.category and self.category == b.category and
self.directionCategory == b.directionCategory ]) self.directionCategory == b.directionCategory])
def sameCategories(self,other): def sameCategories(self, other):
return self.category == other.category and self.directionCategory == other.directionCategory return self.category == other.category and self.directionCategory == other.directionCategory
def myEnds(self,object1,object2): def myEnds(self, object1, object2):
if self.get_source() == object1 and self.destination == object2: if self.get_source() == object1 and self.destination == object2:
return True return True
return self.get_source() == object2 and self.destination == object1 return self.get_source() == object2 and self.destination == object1
def localDensity(self): def localDensity(self):
# returns a rough measure of the density in the string # returns a rough measure of the density in the string
# of the same bond-category and the direction-category of # of the same bond-category and the direction-category of
# the given bond # the given bond
slotSum = supportSum = 0.0 slotSum = supportSum = 0.0
for object1 in workspace.objects: for object1 in workspace.objects:
if object1.string == self.string: if object1.string == self.string:
for object2 in workspace.objects: for object2 in workspace.objects:
if object1.beside(object2): if object1.beside(object2):
slotSum += 1.0 slotSum += 1.0
for bond in self.string.bonds: for bond in self.string.bonds:
if bond != self and self.sameCategories(bond) and self.myEnds(object1,object2): if bond != self and self.sameCategories(bond) and self.myEnds(object1, object2):
supportSum += 1.0 supportSum += 1.0
if slotSum == 0.0: if slotSum == 0.0:
return 0.0 return 0.0
return 100.0 * supportSum / slotSum return 100.0 * supportSum / slotSum
def sameNeighbours(self,other): def sameNeighbours(self, other):
if self.leftObject == other.leftObject: if self.leftObject == other.leftObject:
return True return True
return self.rightObject == other.rightObject return self.rightObject == other.rightObject
def getIncompatibleBonds(self): def getIncompatibleBonds(self):
return [ b for b in self.string.bonds if self.sameNeighbours(b) ] return [b for b in self.string.bonds if self.sameNeighbours(b)]
def get_source(self): def get_source(self):
return self.source return self.source
def set_source(self, value):
self.source = value
def set_source(self, value):
self.source = value
def possibleGroupBonds(bondCategory, directionCategory, bondFacet, bonds): def possibleGroupBonds(bondCategory, directionCategory, bondFacet, bonds):
result = [] result = []
for bond in bonds: for bond in bonds:
if bond.category == bondCategory and bond.directionCategory == directionCategory: if bond.category == bondCategory and bond.directionCategory == directionCategory:
result += [ bond ] result += [bond]
else: else:
# a modified bond might be made # a modified bond might be made
if bondCategory == slipnet.sameness: if bondCategory == slipnet.sameness:
return None # a different bond cannot be made here return None # a different bond cannot be made here
if bond.category == bondCategory or bond.directionCategory == directionCategory: if bond.category == bondCategory or bond.directionCategory == directionCategory:
return None # a different bond cannot be made here return None # a different bond cannot be made here
if bond.category == slipnet.sameness: if bond.category == slipnet.sameness:
return None return None
bond = Bond(bond.destination, bond.get_source(), bondCategory, bondFacet, bond.destinationDescriptor, bond.sourceDescriptor) bond = Bond(bond.destination, bond.get_source(), bondCategory, bondFacet, bond.destinationDescriptor, bond.sourceDescriptor)
result += [ bond ] result += [bond]
return result return result

View File

@ -1,10 +1,10 @@
class Codelet(object): class Codelet(object):
def __init__(self, name, urgency, timestamp): def __init__(self, name, urgency, timestamp):
self.name = name self.name = name
self.urgency = urgency self.urgency = urgency
self.arguments = [] self.arguments = []
self.pressure = None self.pressure = None
self.timeStamp = timestamp self.timeStamp = timestamp
def __repr__(self): def __repr__(self):
return '<Codelet: %s>' % self.name return '<Codelet: %s>' % self.name

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,9 @@
import re, inspect, math, logging import re
import inspect
import math
import logging
import random
import utils
import formulas import formulas
import workspaceFormulas import workspaceFormulas
from slipnet import slipnet from slipnet import slipnet
@ -12,327 +15,328 @@ MAX_NUMBER_OF_CODELETS = 100
codeletsUsed = {} codeletsUsed = {}
class CodeRack(object): class CodeRack(object):
def __init__(self): def __init__(self):
#logging.debug('coderack.__init__()') #logging.debug('coderack.__init__()')
self.speedUpBonds = False self.speedUpBonds = False
self.removeBreakerCodelets = False self.removeBreakerCodelets = False
self.removeTerracedScan = False self.removeTerracedScan = False
self.pressures = CoderackPressures() self.pressures = CoderackPressures()
self.pressures.initialisePressures() self.pressures.initialisePressures()
self.reset() 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.codeletMethodsDir = None
self.runCodelets = {} self.runCodelets = {}
self.postings = {} self.postings = {}
def reset(self): def reset(self):
#logging.debug('coderack.reset()') #logging.debug('coderack.reset()')
from temperature import temperature from temperature import temperature
self.codelets = [] self.codelets = []
self.codeletsRun = 0 self.codeletsRun = 0
temperature.clamped = True temperature.clamped = True
self.pressures.reset() self.pressures.reset()
def updateCodelets(self): def updateCodelets(self):
if self.codeletsRun > 0: if self.codeletsRun > 0:
self.postTopDownCodelets() self.postTopDownCodelets()
self.postBottomUpCodelets() self.postBottomUpCodelets()
def getUrgencyBin(self, urgency): def getUrgencyBin(self, urgency):
bin = int(urgency) * NUMBER_OF_BINS bin = int(urgency) * NUMBER_OF_BINS
bin /= 100 bin /= 100
if bin >= NUMBER_OF_BINS: if bin >= NUMBER_OF_BINS:
bin = NUMBER_OF_BINS - 1 bin = NUMBER_OF_BINS - 1
return bin + 1 return bin + 1
def post(self, codelet): def post(self, codelet):
#logging.info('Posting codelet called: %s, with urgency %f' % (codelet.name,codelet.urgency)) #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.postings[codelet.name] = self.postings.get(codelet.name, 0) + 1
self.pressures.addCodelet(codelet) self.pressures.addCodelet(codelet)
self.codelets += [codelet] self.codelets += [codelet]
if len(self.codelets) > 100: if len(self.codelets) > 100:
oldCodelet = self.chooseOldCodelet() oldCodelet = self.chooseOldCodelet()
self.removeCodelet(oldCodelet) self.removeCodelet(oldCodelet)
def postTopDownCodelets(self): def postTopDownCodelets(self):
for node in slipnet.slipnodes: for node in slipnet.slipnodes:
#logging.info('Trying slipnode: %s' % node.get_name()) #logging.info('Trying slipnode: %s' % node.get_name())
if node.activation == 100.0: if node.activation == 100.0:
#logging.info('using slipnode: %s' % node.get_name()) #logging.info('using slipnode: %s' % node.get_name())
for codeletName in node.codelets: for codeletName in node.codelets:
probability = workspaceFormulas.probabilityOfPosting(codeletName) probability = workspaceFormulas.probabilityOfPosting(codeletName)
howMany = workspaceFormulas.howManyToPost(codeletName) howMany = workspaceFormulas.howManyToPost(codeletName)
#print '%s:%d' % (codeletName,howMany) #print '%s:%d' % (codeletName,howMany)
for unused in range(0, howMany): for unused in range(0, howMany):
if utils.random() < probability: if random.random() < probability:
urgency = self.getUrgencyBin(node.activation * node.conceptualDepth / 100.0) urgency = self.getUrgencyBin(node.activation * node.conceptualDepth / 100.0)
codelet = Codelet(codeletName, urgency, self.codeletsRun) codelet = Codelet(codeletName, urgency, self.codeletsRun)
codelet.arguments += [node] codelet.arguments += [node]
logging.info('Post top down: %s, with urgency: %d' % (codelet.name, urgency)) logging.info('Post top down: %s, with urgency: %d' % (codelet.name, urgency))
#logging.info("From slipnode %s, activation: %s, depth: %s" %(node.get_name(),node.activation,node.conceptual_depth) ) #logging.info("From slipnode %s, activation: %s, depth: %s" %(node.get_name(),node.activation,node.conceptualDepth) )
self.post(codelet) self.post(codelet)
def postBottomUpCodelets(self): def postBottomUpCodelets(self):
logging.info("posting bottom up codelets") logging.info("posting bottom up codelets")
self.__postBottomUpCodelets('bottom-up-description-scout') self.__postBottomUpCodelets('bottom-up-description-scout')
self.__postBottomUpCodelets('bottom-up-bond-scout') self.__postBottomUpCodelets('bottom-up-bond-scout')
self.__postBottomUpCodelets('group-scout--whole-string') self.__postBottomUpCodelets('group-scout--whole-string')
self.__postBottomUpCodelets('bottom-up-correspondence-scout') self.__postBottomUpCodelets('bottom-up-correspondence-scout')
self.__postBottomUpCodelets('important-object-correspondence-scout') self.__postBottomUpCodelets('important-object-correspondence-scout')
self.__postBottomUpCodelets('replacement-finder') self.__postBottomUpCodelets('replacement-finder')
self.__postBottomUpCodelets('rule-scout') self.__postBottomUpCodelets('rule-scout')
self.__postBottomUpCodelets('rule-translator') self.__postBottomUpCodelets('rule-translator')
if not self.removeBreakerCodelets: if not self.removeBreakerCodelets:
self.__postBottomUpCodelets('breaker') self.__postBottomUpCodelets('breaker')
def __postBottomUpCodelets(self, codeletName): def __postBottomUpCodelets(self, codeletName):
probability = workspaceFormulas.probabilityOfPosting(codeletName) probability = workspaceFormulas.probabilityOfPosting(codeletName)
howMany = workspaceFormulas.howManyToPost(codeletName) howMany = workspaceFormulas.howManyToPost(codeletName)
#if codeletName == 'bottom-up-bond-scout': #if codeletName == 'bottom-up-bond-scout':
# print 'post --> %f:%d' % (probability,howMany) # print 'post --> %f:%d' % (probability,howMany)
if self.speedUpBonds: if self.speedUpBonds:
if 'bond' in codeletName or 'group' in codeletName: if 'bond' in codeletName or 'group' in codeletName:
howMany *= 3 howMany *= 3
urgency = 3 urgency = 3
if codeletName == 'breaker': if codeletName == 'breaker':
urgency = 1 urgency = 1
if formulas.Temperature < 25.0 and 'translator' in codeletName: if formulas.Temperature < 25.0 and 'translator' in codeletName:
urgency = 5 urgency = 5
for unused in range(0, howMany): for unused in range(0, howMany):
if utils.random() < probability: if random.random() < probability:
codelet = Codelet(codeletName, urgency, self.codeletsRun) codelet = Codelet(codeletName, urgency, self.codeletsRun)
self.post(codelet) self.post(codelet)
def removeCodelet(self, codelet): def removeCodelet(self, codelet):
self.codelets.remove(codelet) self.codelets.remove(codelet)
self.pressures.removeCodelet(codelet) self.pressures.removeCodelet(codelet)
def newCodelet(self, name, oldCodelet, strength, arguments=None): def newCodelet(self, name, oldCodelet, strength, arguments=None):
#logging.debug('Posting new codelet called %s' % name) #logging.debug('Posting new codelet called %s' % name)
urgency = self.getUrgencyBin(strength) urgency = self.getUrgencyBin(strength)
newCodelet = Codelet(name, urgency, self.codeletsRun) newCodelet = Codelet(name, urgency, self.codeletsRun)
if arguments: if arguments:
newCodelet.arguments = [arguments] newCodelet.arguments = [arguments]
else: else:
newCodelet.arguments = oldCodelet.arguments newCodelet.arguments = oldCodelet.arguments
newCodelet.pressure = oldCodelet.pressure newCodelet.pressure = oldCodelet.pressure
self.tryRun(newCodelet) self.tryRun(newCodelet)
def proposeRule(self, facet, description, category, relation, oldCodelet): def proposeRule(self, facet, description, category, relation, oldCodelet):
"""Creates a proposed rule, and posts a rule-strength-tester codelet. """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 from rule import Rule
rule = Rule(facet, description, category, relation) rule = Rule(facet, description, category, relation)
rule.updateStrength() rule.updateStrength()
if description and relation: if description and relation:
depths = description.conceptualDepth + relation.conceptualDepth depths = description.conceptualDepth + relation.conceptualDepth
depths /= 200.0 depths /= 200.0
urgency = math.sqrt(depths) * 100.0 urgency = math.sqrt(depths) * 100.0
else: else:
urgency = 0 urgency = 0
self.newCodelet('rule-strength-tester', oldCodelet, urgency, rule) 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 from correspondence import Correspondence
correspondence = Correspondence(initialObject, targetObject, conceptMappings, flipTargetObject) correspondence = Correspondence(initialObject, targetObject, conceptMappings, flipTargetObject)
for mapping in conceptMappings: for mapping in conceptMappings:
mapping.initialDescriptionType.buffer = 100.0 mapping.initialDescriptionType.buffer = 100.0
mapping.initialDescriptor.buffer = 100.0 mapping.initialDescriptor.buffer = 100.0
mapping.targetDescriptionType.buffer = 100.0 mapping.targetDescriptionType.buffer = 100.0
mapping.targetDescriptor.buffer = 100.0 mapping.targetDescriptor.buffer = 100.0
mappings = correspondence.distinguishingConceptMappings() mappings = correspondence.distinguishingConceptMappings()
urgency = sum([mapping.strength() for mapping in mappings]) urgency = sum([mapping.strength() for mapping in mappings])
numberOfMappings = len(mappings) numberOfMappings = len(mappings)
if urgency: if urgency:
urgency /= numberOfMappings urgency /= numberOfMappings
bin = self.getUrgencyBin(urgency) bin = self.getUrgencyBin(urgency)
logging.info('urgency: %s, number: %d, bin: %d' % (urgency, numberOfMappings, bin)) logging.info('urgency: %s, number: %d, bin: %d' % (urgency, numberOfMappings, bin))
self.newCodelet('correspondence-strength-tester', oldCodelet, urgency, correspondence) self.newCodelet('correspondence-strength-tester', oldCodelet, urgency, correspondence)
def proposeDescription(self, objekt, descriptionType, descriptor, oldCodelet): def proposeDescription(self, objekt, descriptionType, descriptor, oldCodelet):
from description import Description from description import Description
description = Description(objekt, descriptionType, descriptor) description = Description(objekt, descriptionType, descriptor)
descriptor.buffer = 100.0 descriptor.buffer = 100.0
urgency = descriptionType.activation urgency = descriptionType.activation
self.newCodelet('description-strength-tester', oldCodelet, urgency, description) self.newCodelet('description-strength-tester', oldCodelet, urgency, description)
def proposeSingleLetterGroup(self, source, codelet): 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 from group import Group
bondCategory = groupCategory.getRelatedNode(slipnet.bondCategory) bondCategory = groupCategory.getRelatedNode(slipnet.bondCategory)
bondCategory.buffer = 100.0 bondCategory.buffer = 100.0
if directionCategory: if directionCategory:
directionCategory.buffer = 100.0 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() urgency = bondCategory.bondDegreeOfAssociation()
self.newCodelet('group-strength-tester', oldCodelet, urgency, group) 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 from bond import Bond
bondFacet.buffer = 100.0 bondFacet.buffer = 100.0
sourceDescriptor.buffer = 100.0 sourceDescriptor.buffer = 100.0
destinationDescriptor.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() urgency = bondCategory.bondDegreeOfAssociation()
self.newCodelet('bond-strength-tester', oldCodelet, urgency, bond) self.newCodelet('bond-strength-tester', oldCodelet, urgency, bond)
def chooseOldCodelet(self): def chooseOldCodelet(self):
# selects an old codelet to remove from the coderack # selects an old codelet to remove from the coderack
# more likely to select lower urgency codelets # more likely to select lower urgency codelets
if not len(self.codelets): if not len(self.codelets):
return None return None
urgencies = [] urgencies = []
for codelet in self.codelets: 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] urgencies += [urgency]
threshold = utils.random() * sum(urgencies) threshold = random.random() * sum(urgencies)
sumOfUrgencies = 0.0 sumOfUrgencies = 0.0
for i in range(0, len(self.codelets)): for i in range(0, len(self.codelets)):
sumOfUrgencies += urgencies[i] sumOfUrgencies += urgencies[i]
if sumOfUrgencies > threshold: if sumOfUrgencies > threshold:
return self.codelets[i] return self.codelets[i]
return self.codelets[0] return self.codelets[0]
def postInitialCodelets(self): def postInitialCodelets(self):
#logging.debug('Posting initial codelets') #logging.debug('Posting initial codelets')
#logging.debug('Number of inital codelets: %d' % len(self.initialCodeletNames)) #logging.debug('Number of inital codelets: %d' % len(self.initialCodeletNames))
#logging.debug('Number of workspaceObjects: %d' % workspace.numberOfObjects()) #logging.debug('Number of workspaceObjects: %d' % workspace.numberOfObjects())
for name in self.initialCodeletNames: for name in self.initialCodeletNames:
for unused in range(0, workspaceFormulas.numberOfObjects()): for unused in range(0, workspaceFormulas.numberOfObjects()):
codelet = Codelet(name, 1, self.codeletsRun) codelet = Codelet(name, 1, self.codeletsRun)
self.post(codelet) self.post(codelet)
codelet2 = Codelet(name, 1, self.codeletsRun) codelet2 = Codelet(name, 1, self.codeletsRun)
self.post(codelet2) self.post(codelet2)
def tryRun(self, newCodelet): def tryRun(self, newCodelet):
if self.removeTerracedScan: if self.removeTerracedScan:
self.run(newCodelet) self.run(newCodelet)
else: else:
self.post(newCodelet) self.post(newCodelet)
def getCodeletmethods(self): def getCodeletmethods(self):
import codeletMethods import codeletMethods
self.codeletMethodsDir = dir(codeletMethods) self.codeletMethodsDir = dir(codeletMethods)
knownCodeletNames = ( knownCodeletNames = (
'breaker', 'breaker',
'bottom-up-description-scout', 'bottom-up-description-scout',
'top-down-description-scout', 'top-down-description-scout',
'description-strength-tester', 'description-strength-tester',
'description-builder', 'description-builder',
'bottom-up-bond-scout', 'bottom-up-bond-scout',
'top-down-bond-scout--category', 'top-down-bond-scout--category',
'top-down-bond-scout--direction', 'top-down-bond-scout--direction',
'bond-strength-tester', 'bond-strength-tester',
'bond-builder', 'bond-builder',
'top-down-group-scout--category', 'top-down-group-scout--category',
'top-down-group-scout--direction', 'top-down-group-scout--direction',
'group-scout--whole-string', 'group-scout--whole-string',
'group-strength-tester', 'group-strength-tester',
'group-builder', 'group-builder',
'replacement-finder', 'replacement-finder',
'rule-scout', 'rule-scout',
'rule-strength-tester', 'rule-strength-tester',
'rule-builder', 'rule-builder',
'rule-translator', 'rule-translator',
'bottom-up-correspondence-scout', 'bottom-up-correspondence-scout',
'important-object-correspondence-scout', 'important-object-correspondence-scout',
'correspondence-strength-tester', 'correspondence-strength-tester',
'correspondence-builder', 'correspondence-builder',
) )
self.methods = {} self.methods = {}
for codeletName in knownCodeletNames: for codeletName in knownCodeletNames:
methodName = re.sub('[ -]', '_', codeletName) methodName = re.sub('[ -]', '_', codeletName)
if methodName not in self.codeletMethodsDir: 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) method = getattr(codeletMethods, methodName)
self.methods[methodName] = method self.methods[methodName] = method
def chooseAndRunCodelet(self): def chooseAndRunCodelet(self):
if not len(coderack.codelets): if not len(coderack.codelets):
coderack.postInitialCodelets() coderack.postInitialCodelets()
codelet = self.chooseCodeletToRun() codelet = self.chooseCodeletToRun()
if codelet: if codelet:
self.run(codelet) self.run(codelet)
def chooseCodeletToRun(self): def chooseCodeletToRun(self):
if not self.codelets: if not self.codelets:
return None return None
temp = formulas.Temperature temp = formulas.Temperature
scale = ( 100.0 - temp + 10.0 ) / 15.0 scale = (100.0 - temp + 10.0) / 15.0
# threshold = sum( [ c.urgency ** scale for c in self.codelets ] ) * utils.random() # threshold = sum( [ c.urgency ** scale for c in self.codelets ] ) * random.random()
urgsum = 0.0 urgsum = 0.0
for codelet in self.codelets: for codelet in self.codelets:
urg = codelet.urgency ** scale urg = codelet.urgency ** scale
urgsum += urg urgsum += urg
r = utils.random() r = random.random()
threshold = r * urgsum threshold = r * urgsum
chosen = None chosen = None
urgencySum = 0.0 urgencySum = 0.0
logging.info('temperature: %f' % formulas.Temperature) logging.info('temperature: %f' % formulas.Temperature)
logging.info('actualTemperature: %f' % formulas.actualTemperature) logging.info('actualTemperature: %f' % formulas.actualTemperature)
logging.info('Slipnet:') logging.info('Slipnet:')
for node in slipnet.slipnodes: 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:') logging.info('Coderack:')
for codelet in self.codelets: for codelet in self.codelets:
logging.info('\t%s, %d' % (codelet.name, codelet.urgency)) logging.info('\t%s, %d' % (codelet.name, codelet.urgency))
from workspace import workspace from workspace import workspace
workspace.initial.log("Initial: ") workspace.initial.log("Initial: ")
workspace.target.log("Target: ") workspace.target.log("Target: ")
for codelet in self.codelets: for codelet in self.codelets:
urgencySum += codelet.urgency ** scale urgencySum += codelet.urgency ** scale
if not chosen and urgencySum > threshold: if not chosen and urgencySum > threshold:
chosen = codelet chosen = codelet
break break
if not chosen: if not chosen:
chosen = self.codelets[0] chosen = self.codelets[0]
self.removeCodelet(chosen) 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 return chosen
def run(self, codelet): def run(self, codelet):
methodName = re.sub('[ -]', '_', codelet.name) methodName = re.sub('[ -]', '_', codelet.name)
self.codeletsRun += 1 self.codeletsRun += 1
self.runCodelets[methodName] = self.runCodelets.get(methodName, 0) + 1 self.runCodelets[methodName] = self.runCodelets.get(methodName, 0) + 1
#if self.codeletsRun > 2000: #if self.codeletsRun > 2000:
#import sys #import sys
#print "running too many codelets" #print "running too many codelets"
#for name,count in self.postings.iteritems(): #for name,count in self.postings.iteritems():
#print '%d:%s' % (count,name) #print '%d:%s' % (count,name)
#raise ValueError #raise ValueError
#else: #else:
# print 'running %d' % self.codeletsRun # print 'running %d' % self.codeletsRun
if not self.codeletMethodsDir: if not self.codeletMethodsDir:
self.getCodeletmethods() self.getCodeletmethods()
#if not self.codeletMethodsDir: #if not self.codeletMethodsDir:
method = self.methods[methodName] method = self.methods[methodName]
if not method: 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): if not callable(method):
raise RuntimeError, 'Cannot call %s()' % methodName raise RuntimeError('Cannot call %s()' % methodName)
args, varargs, varkw, defaults = inspect.getargspec(method) args, varargs, varkw, defaults = inspect.getargspec(method)
#global codeletsUsed #global codeletsUsed
#codeletsUsed[methodName] = codeletsUsed.get(methodName,0) + 1 #codeletsUsed[methodName] = codeletsUsed.get(methodName,0) + 1
try: try:
if 'codelet' in args: if 'codelet' in args:
method(codelet) method(codelet)
else: else:
method() method()
except AssertionError: except AssertionError:
pass pass
coderack = CodeRack() coderack = CodeRack()

View File

@ -2,132 +2,134 @@ import logging
from formulas import Temperature from formulas import Temperature
from slipnet import slipnet from slipnet import slipnet
class CoderackPressure(object):
def __init__(self, name):
self.name = name
def reset(self): class CoderackPressure(object):
self.unmodifedValues = [] def __init__(self, name):
self.values = [] self.name = name
self.codelets = []
def reset(self):
self.unmodifedValues = []
self.values = []
self.codelets = []
class CoderackPressures(object): class CoderackPressures(object):
def __init__(self): def __init__(self):
#logging.debug('coderackPressures.__init__()') #logging.debug('coderackPressures.__init__()')
self.initialisePressures() self.initialisePressures()
self.reset() self.reset()
def initialisePressures(self): def initialisePressures(self):
#logging.debug('coderackPressures.initialisePressures()') #logging.debug('coderackPressures.initialisePressures()')
self.pressures = [] self.pressures = []
self.pressures += [CoderackPressure('Bottom Up Bonds')] self.pressures += [CoderackPressure('Bottom Up Bonds')]
self.pressures += [CoderackPressure('Top Down Successor Bonds')] self.pressures += [CoderackPressure('Top Down Successor Bonds')]
self.pressures += [CoderackPressure('Top Down Predecessor Bonds')] self.pressures += [CoderackPressure('Top Down Predecessor Bonds')]
self.pressures += [CoderackPressure('Top Down Sameness Bonds')] self.pressures += [CoderackPressure('Top Down Sameness Bonds')]
self.pressures += [CoderackPressure('Top Down Left Bonds')] self.pressures += [CoderackPressure('Top Down Left Bonds')]
self.pressures += [CoderackPressure('Top Down Right Bonds')] self.pressures += [CoderackPressure('Top Down Right Bonds')]
self.pressures += [CoderackPressure('Top Down Successor Group')] self.pressures += [CoderackPressure('Top Down Successor Group')]
self.pressures += [CoderackPressure('Top Down Predecessor Group')] self.pressures += [CoderackPressure('Top Down Predecessor Group')]
self.pressures += [CoderackPressure('Top Down Sameness Group')] self.pressures += [CoderackPressure('Top Down Sameness Group')]
self.pressures += [CoderackPressure('Top Down Left Group')] self.pressures += [CoderackPressure('Top Down Left Group')]
self.pressures += [CoderackPressure('Top Down Right Group')] self.pressures += [CoderackPressure('Top Down Right Group')]
self.pressures += [CoderackPressure('Bottom Up Whole Group')] self.pressures += [CoderackPressure('Bottom Up Whole Group')]
self.pressures += [CoderackPressure('Replacement Finder')] self.pressures += [CoderackPressure('Replacement Finder')]
self.pressures += [CoderackPressure('Rule Codelets')] self.pressures += [CoderackPressure('Rule Codelets')]
self.pressures += [CoderackPressure('Rule Translator')] self.pressures += [CoderackPressure('Rule Translator')]
self.pressures += [CoderackPressure('Bottom Up Correspondences')] self.pressures += [CoderackPressure('Bottom Up Correspondences')]
self.pressures += [CoderackPressure('Important Object Correspondences')] self.pressures += [CoderackPressure('Important Object Correspondences')]
self.pressures += [CoderackPressure('Breakers')] self.pressures += [CoderackPressure('Breakers')]
def calculatePressures(self): def calculatePressures(self):
#logging.debug('coderackPressures.calculatePressures()') #logging.debug('coderackPressures.calculatePressures()')
scale = ( 100.0 - Temperature + 10.0 ) / 15.0 scale = (100.0 - Temperature + 10.0) / 15.0
values = [] values = []
for pressure in self.pressures: for pressure in self.pressures:
value = sum([c.urgency ** scale for c in pressure.codelets]) value = sum([c.urgency ** scale for c in pressure.codelets])
values += [value] values += [value]
totalValue = sum(values) totalValue = sum(values)
if not totalValue: if not totalValue:
totalValue = 1.0 totalValue = 1.0
values = [value / totalValue for value in values] values = [value / totalValue for value in values]
self.maxValue = max(values) self.maxValue = max(values)
for pressure, value in zip(self.pressures, values): for pressure, value in zip(self.pressures, values):
pressure.values += [value * 100.0] pressure.values += [value * 100.0]
for codelet in self.removedCodelets: for codelet in self.removedCodelets:
if codelet.pressure: if codelet.pressure:
codelet.pressure.codelets.removeElement(codelet) codelet.pressure.codelets.removeElement(codelet)
self.removedCodelets = [] self.removedCodelets = []
def reset(self): def reset(self):
#logging.debug('coderackPressures.reset()') #logging.debug('coderackPressures.reset()')
self.maxValue = 0.001 self.maxValue = 0.001
for pressure in self.pressures: for pressure in self.pressures:
pressure.reset() pressure.reset()
self.removedCodelets = [] self.removedCodelets = []
def addCodelet(self, codelet): def addCodelet(self, codelet):
node = None node = None
i = -1 i = -1
if codelet.name == 'bottom-up-bond-scout': if codelet.name == 'bottom-up-bond-scout':
i = 0 i = 0
if codelet.name == 'top-down-bond-scout--category': if codelet.name == 'top-down-bond-scout--category':
node = codelet.arguments[0] node = codelet.arguments[0]
if node == slipnet.successor: if node == slipnet.successor:
i = 1 i = 1
elif node == slipnet.predecessor: elif node == slipnet.predecessor:
i = 2 i = 2
else: else:
i = 3 i = 3
if codelet.name == 'top-down-bond-scout--direction': if codelet.name == 'top-down-bond-scout--direction':
node = codelet.arguments[0] node = codelet.arguments[0]
if node == slipnet.left: if node == slipnet.left:
i = 4 i = 4
elif node == slipnet.right: elif node == slipnet.right:
i = 5 i = 5
else: else:
i = 3 i = 3
if codelet.name == 'top-down-group-scout--category': if codelet.name == 'top-down-group-scout--category':
node = codelet.arguments[0] node = codelet.arguments[0]
if node == slipnet.successorGroup: if node == slipnet.successorGroup:
i = 6 i = 6
elif node == slipnet.predecessorGroup: elif node == slipnet.predecessorGroup:
i = 7 i = 7
else: else:
i = 8 i = 8
if codelet.name == 'top-down-group-scout--direction': if codelet.name == 'top-down-group-scout--direction':
node = codelet.arguments[0] node = codelet.arguments[0]
if node == slipnet.left: if node == slipnet.left:
i = 9 i = 9
elif node == slipnet.right: elif node == slipnet.right:
i = 10 i = 10
if codelet.name == 'group-scout--whole-string': if codelet.name == 'group-scout--whole-string':
i = 11 i = 11
if codelet.name == 'replacement-finder': if codelet.name == 'replacement-finder':
i = 12 i = 12
if codelet.name == 'rule-scout': if codelet.name == 'rule-scout':
i = 13 i = 13
if codelet.name == 'rule-translator': if codelet.name == 'rule-translator':
i = 14 i = 14
if codelet.name == 'bottom-up-correspondence-scout': if codelet.name == 'bottom-up-correspondence-scout':
i = 15 i = 15
if codelet.name == 'important-object-correspondence-scout': if codelet.name == 'important-object-correspondence-scout':
i = 16 i = 16
if codelet.name == 'breaker': if codelet.name == 'breaker':
i = 17 i = 17
if i >= 0: if i >= 0:
self.pressures[i].codelets += [codelet] self.pressures[i].codelets += [codelet]
if codelet.pressure: if codelet.pressure:
codelet.pressure.codelets += [codelet] # XXX why do this codelet.pressure.codelets += [codelet] # XXX why do this
if i >= 0: if i >= 0:
codelet.pressure = self.pressures[i] # when following with this ? codelet.pressure = self.pressures[i] # when following with this ?
logging.info('Add %s: %d' % (codelet.name, i)) logging.info('Add %s: %d' % (codelet.name, i))
if node: if node:
logging.info('Node: %s' % node.name) logging.info('Node: %s' % node.name)
def removeCodelet(self, codelet): def removeCodelet(self, codelet):
self.removedCodelets += [codelet] self.removedCodelets += [codelet]
def numberOfPressures(self): def numberOfPressures(self):
return len(self.pressures) return len(self.pressures)
coderackPressures = CoderackPressures() coderackPressures = CoderackPressures()

View File

@ -1,142 +1,143 @@
import logging import logging
from slipnet import slipnet from slipnet import slipnet
class ConceptMapping(object): class ConceptMapping(object):
def __init__(self, initialDescriptionType, targetDescriptionType, initialDescriptor, targetDescriptor, initialObject, targetObject): def __init__(self, initialDescriptionType, targetDescriptionType, initialDescriptor, targetDescriptor, initialObject, targetObject):
logging.info('make a map: %s-%s' % (initialDescriptionType.get_name(), targetDescriptionType.get_name())) logging.info('make a map: %s-%s' % (initialDescriptionType.get_name(), targetDescriptionType.get_name()))
self.initialDescriptionType = initialDescriptionType self.initialDescriptionType = initialDescriptionType
self.targetDescriptionType = targetDescriptionType self.targetDescriptionType = targetDescriptionType
self.initialDescriptor = initialDescriptor self.initialDescriptor = initialDescriptor
self.targetDescriptor = targetDescriptor self.targetDescriptor = targetDescriptor
self.initialObject = initialObject self.initialObject = initialObject
self.targetObject = targetObject self.targetObject = targetObject
self.label = initialDescriptor.getBondCategory(targetDescriptor) self.label = initialDescriptor.getBondCategory(targetDescriptor)
def __repr__(self): 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): def __str__(self):
return self.label and self.label.name or 'anonymous' return self.label and self.label.name or 'anonymous'
def slipability(self): def slipability(self):
association = self.__degreeOfAssociation() association = self.__degreeOfAssociation()
if association == 100.0: if association == 100.0:
return 100.0 return 100.0
depth = self.__conceptualDepth() / 100.0 depth = self.__conceptualDepth() / 100.0
return association * ( 1 - depth * depth ) return association * (1 - depth * depth)
def __degreeOfAssociation(self): 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 at most 1 link
if self.initialDescriptor == self.targetDescriptor: if self.initialDescriptor == self.targetDescriptor:
return 100.0 return 100.0
for link in self.initialDescriptor.lateralSlipLinks: for link in self.initialDescriptor.lateralSlipLinks:
if link.destination == self.targetDescriptor: if link.destination == self.targetDescriptor:
return link.degreeOfAssociation() return link.degreeOfAssociation()
return 0.0 return 0.0
def strength(self): def strength(self):
association = self.__degreeOfAssociation() association = self.__degreeOfAssociation()
if association == 100.0: if association == 100.0:
return 100.0 return 100.0
depth = self.__conceptualDepth() / 100.0 depth = self.__conceptualDepth() / 100.0
return association * ( 1 + depth * depth ) return association * (1 + depth * depth)
def __conceptualDepth(self): def __conceptualDepth(self):
return (self.initialDescriptor.conceptualDepth + self.targetDescriptor.conceptualDepth ) / 2.0 return (self.initialDescriptor.conceptualDepth + self.targetDescriptor.conceptualDepth) / 2.0
def distinguishing(self): def distinguishing(self):
if self.initialDescriptor == slipnet.whole and self.targetDescriptor == slipnet.whole: if self.initialDescriptor == slipnet.whole and self.targetDescriptor == slipnet.whole:
return False return False
if not self.initialObject.distinguishingDescriptor(self.initialDescriptor): if not self.initialObject.distinguishingDescriptor(self.initialDescriptor):
return False return False
return self.targetObject.distinguishingDescriptor(self.targetDescriptor) return self.targetObject.distinguishingDescriptor(self.targetDescriptor)
def sameInitialType(self, other): def sameInitialType(self, other):
return self.initialDescriptionType == other.initialDescriptionType return self.initialDescriptionType == other.initialDescriptionType
def sameTargetType(self, other): def sameTargetType(self, other):
return self.targetDescriptionType == other.targetDescriptionType return self.targetDescriptionType == other.targetDescriptionType
def sameTypes(self, other): def sameTypes(self, other):
return self.sameInitialType(other) and self.sameTargetType(other) return self.sameInitialType(other) and self.sameTargetType(other)
def sameInitialDescriptor(self, other): def sameInitialDescriptor(self, other):
return self.initialDescriptor == other.initialDescriptor return self.initialDescriptor == other.initialDescriptor
def sameTargetDescriptor(self, other): def sameTargetDescriptor(self, other):
return self.targetDescriptor == other.targetDescriptor return self.targetDescriptor == other.targetDescriptor
def sameDescriptors(self, other): def sameDescriptors(self, other):
return self.sameInitialDescriptor(other) and self.sameTargetDescriptor(other) return self.sameInitialDescriptor(other) and self.sameTargetDescriptor(other)
def sameKind(self, other): def sameKind(self, other):
return self.sameTypes(other) and self.sameDescriptors(other) return self.sameTypes(other) and self.sameDescriptors(other)
def nearlySameKind(self, other): def nearlySameKind(self, other):
return self.sameTypes(other) and self.sameInitialDescriptor(other) return self.sameTypes(other) and self.sameInitialDescriptor(other)
def isContainedBy(self, mappings): def isContainedBy(self, mappings):
return any([self.sameKind(mapping) for mapping in mappings]) return any([self.sameKind(mapping) for mapping in mappings])
def isNearlyContainedBy(self, mappings): def isNearlyContainedBy(self, mappings):
return any([self.nearlySameKind(mapping) for mapping in mappings]) return any([self.nearlySameKind(mapping) for mapping in mappings])
def related(self, other): def related(self, other):
if self.initialDescriptor.related(other.initialDescriptor): if self.initialDescriptor.related(other.initialDescriptor):
return True return True
return self.targetDescriptor.related(other.targetDescriptor) return self.targetDescriptor.related(other.targetDescriptor)
def incompatible(self, other): def incompatible(self, other):
# Concept-mappings (a -> b) and (c -> d) are incompatible if a is # Concept-mappings (a -> b) and (c -> d) are incompatible if a is
# related to c or if b is related to d, and the a -> b relationship is # 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 # different from the c -> d relationship. E.g., rightmost -> leftmost
# is incompatible with right -> right, since rightmost is linked # is incompatible with right -> right, since rightmost is linked
# to right, but the relationships (opposite and identity) are different. # to right, but the relationships (opposite and identity) are different.
# Notice that slipnet distances are not looked at, only slipnet links. This # Notice that slipnet distances are not looked at, only slipnet links. This
# should be changed eventually. # should be changed eventually.
if not self.related(other): if not self.related(other):
return False return False
if not self.label or not other.label: if not self.label or not other.label:
return False return False
return self.label != other.label return self.label != other.label
def supports(self, other): def supports(self, other):
# Concept-mappings (a -> b) and (c -> d) support each other if a is related # 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 # 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 # c -> d relationship. E.g., rightmost -> rightmost supports right -> right
# and leftmost -> leftmost. Notice that slipnet distances are not looked # and leftmost -> leftmost. Notice that slipnet distances are not looked
# at, only slipnet links. This should be changed eventually. # at, only slipnet links. This should be changed eventually.
# If the two concept-mappings are the same, then return t. This # If the two concept-mappings are the same, then return t. This
# means that letter->group supports letter->group, even though these # means that letter->group supports letter->group, even though these
# concept-mappings have no label. # concept-mappings have no label.
if self.initialDescriptor == other.initialDescriptor and self.targetDescriptor == other.targetDescriptor: if self.initialDescriptor == other.initialDescriptor and self.targetDescriptor == other.targetDescriptor:
return True return True
# if the descriptors are not related return false # if the descriptors are not related return false
if not self.related(other): if not self.related(other):
return False return False
if not self.label or not other.label: if not self.label or not other.label:
return False return False
return self.label == other.label return self.label == other.label
def relevant(self): def relevant(self):
return self.initialDescriptionType.fully_active() and self.targetDescriptionType.fully_active() return self.initialDescriptionType.fully_active() and self.targetDescriptionType.fully_active()
def slippage(self): def slippage(self):
return self.label != slipnet.sameness and self.label != slipnet.identity return self.label != slipnet.sameness and self.label != slipnet.identity
def symmetricVersion(self): def symmetricVersion(self):
if not self.slippage(): if not self.slippage():
return self return self
if self.targetDescriptor.getBondCategory(self.initialDescriptor) == self.label: if self.targetDescriptor.getBondCategory(self.initialDescriptor) == self.label:
return self return self
return ConceptMapping( return ConceptMapping(
self.targetDescriptionType, self.targetDescriptionType,
self.initialDescriptionType, self.initialDescriptionType,
self.targetDescriptor, self.targetDescriptor,
self.initialDescriptor1, self.initialDescriptor1,
self.initialObject, self.initialObject,
self.targetObject self.targetObject
) )

View File

@ -1,10 +1,10 @@
import logging import logging
logging.basicConfig( logging.basicConfig(
level=logging.INFO, level=logging.INFO,
#format='%(asctime)s %(filename)s:%(lineno)d %(message)s', #format='%(asctime)s %(filename)s:%(lineno)d %(message)s',
format='%(message)s', format='%(message)s',
filename='./copycat.log', filename='./copycat.log',
filemode='w' filemode='w'
) )
@ -15,44 +15,46 @@ from temperature import temperature
from coderack import coderack from coderack import coderack
from coderackPressure import coderackPressures from coderackPressure import coderackPressures
def updateEverything(): def updateEverything():
workspace.updateEverything() workspace.updateEverything()
coderack.updateCodelets() coderack.updateCodelets()
slipnet.update() slipnet.update()
workspaceFormulas.updateTemperature() workspaceFormulas.updateTemperature()
coderackPressures.calculatePressures() coderackPressures.calculatePressures()
def mainLoop(lastUpdate): def mainLoop(lastUpdate):
temperature.tryUnclamp() temperature.tryUnclamp()
result = lastUpdate result = lastUpdate
if coderack.codeletsRun - lastUpdate >= slipnet.timeStepLength or not coderack.codeletsRun: if coderack.codeletsRun - lastUpdate >= slipnet.timeStepLength or not coderack.codeletsRun:
updateEverything() updateEverything()
result = coderack.codeletsRun result = coderack.codeletsRun
logging.debug('Number of codelets: %d' % len(coderack.codelets)) logging.debug('Number of codelets: %d' % len(coderack.codelets))
coderack.chooseAndRunCodelet() coderack.chooseAndRunCodelet()
return result return result
def runTrial(): def runTrial():
"""Run a trial of the copycat algorithm""" """Run a trial of the copycat algorithm"""
answers = {} answers = {}
slipnet.reset() slipnet.reset()
workspace.reset() workspace.reset()
coderack.reset() coderack.reset()
lastUpdate = 0 lastUpdate = 0
while not workspace.foundAnswer: while not workspace.foundAnswer:
lastUpdate = mainLoop(lastUpdate) lastUpdate = mainLoop(lastUpdate)
if workspace.rule: if workspace.rule:
answer = workspace.rule.finalAnswer answer = workspace.rule.finalAnswer
else: else:
answer = None answer = None
print '%d: %s' % (coderack.codeletsRun, answer) print '%d: %s' % (coderack.codeletsRun, answer)
answers[answer] = answers.get(answer, 0) + 1 answers[answer] = answers.get(answer, 0) + 1
logging.debug('codelets used:') logging.debug('codelets used:')
for answer, count in answers.iteritems(): for answer, count in answers.iteritems():
print '%s:%d' % (answer, count) print '%s:%d' % (answer, count)
def run(initial, modified, target): def run(initial, modified, target):
workspace.setStrings(initial, modified, target) workspace.setStrings(initial, modified, target)
runTrial() runTrial()

View File

@ -2,188 +2,188 @@ from workspace import workspace
from workspaceStructure import WorkspaceStructure from workspaceStructure import WorkspaceStructure
from formulas import getMappings from formulas import getMappings
class Correspondence(WorkspaceStructure): class Correspondence(WorkspaceStructure):
def __init__(self,objectFromInitial,objectFromTarget,conceptMappings,flipTargetObject): def __init__(self, objectFromInitial, objectFromTarget, conceptMappings, flipTargetObject):
WorkspaceStructure.__init__(self) WorkspaceStructure.__init__(self)
self.objectFromInitial = objectFromInitial self.objectFromInitial = objectFromInitial
self.objectFromTarget = objectFromTarget self.objectFromTarget = objectFromTarget
self.conceptMappings = conceptMappings self.conceptMappings = conceptMappings
self.flipTargetObject = flipTargetObject self.flipTargetObject = flipTargetObject
self.accessoryConceptMappings = [] self.accessoryConceptMappings = []
def __repr__(self): def __repr__(self):
return '<%s>' % self.__str__() return '<%s>' % self.__str__()
def __str__(self): 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): def distinguishingConceptMappings(self):
return [ m for m in self.conceptMappings if m.distinguishing() ] return [m for m in self.conceptMappings if m.distinguishing()]
def relevantDistinguishingConceptMappings(self): 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): def extract_target_bond(self):
targetBond = False targetBond = False
if self.objectFromTarget.leftmost: if self.objectFromTarget.leftmost:
targetBond = self.objectFromTarget.rightBond targetBond = self.objectFromTarget.rightBond
elif self.objectFromTarget.rightmost: elif self.objectFromTarget.rightmost:
targetBond = self.objectFromTarget.leftBond targetBond = self.objectFromTarget.leftBond
return targetBond return targetBond
def extract_initial_bond(self): def extract_initial_bond(self):
initialBond = False initialBond = False
if self.objectFromInitial.leftmost: if self.objectFromInitial.leftmost:
initialBond = self.objectFromInitial.rightBond initialBond = self.objectFromInitial.rightBond
elif self.objectFromInitial.rightmost: elif self.objectFromInitial.rightmost:
initialBond = self.objectFromInitial.leftBond initialBond = self.objectFromInitial.leftBond
return initialBond return initialBond
def getIncompatibleBond(self): def getIncompatibleBond(self):
initialBond = self.extract_initial_bond() initialBond = self.extract_initial_bond()
if not initialBond: if not initialBond:
return None return None
targetBond = self.extract_target_bond() targetBond = self.extract_target_bond()
if not targetBond: if not targetBond:
return None return None
from conceptMapping import ConceptMapping from conceptMapping import ConceptMapping
from slipnet import slipnet from slipnet import slipnet
if initialBond.directionCategory and targetBond.directionCategory: if initialBond.directionCategory and targetBond.directionCategory:
mapping = ConceptMapping( mapping = ConceptMapping(
slipnet.directionCategory, slipnet.directionCategory,
slipnet.directionCategory, slipnet.directionCategory,
initialBond.directionCategory, initialBond.directionCategory,
targetBond.directionCategory, targetBond.directionCategory,
None, None,
None None
) )
for m in self.conceptMappings: for m in self.conceptMappings:
if m.incompatible(mapping): if m.incompatible(mapping):
return targetBond return targetBond
return None return None
def getIncompatibleCorrespondences(self): def getIncompatibleCorrespondences(self):
return [ o.correspondence for o in workspace.initial.objects if o and self.incompatible(o.correspondence) ] return [o.correspondence for o in workspace.initial.objects if o and self.incompatible(o.correspondence)]
def incompatible(self,other): def incompatible(self, other):
if not other: if not other:
return False return False
if self.objectFromInitial == other.objectFromInitial: if self.objectFromInitial == other.objectFromInitial:
return True return True
if self.objectFromTarget == other.objectFromTarget: if self.objectFromTarget == other.objectFromTarget:
return True return True
for mapping in self.conceptMappings: for mapping in self.conceptMappings:
for otherMapping in other.conceptMappings: for otherMapping in other.conceptMappings:
if mapping.incompatible(otherMapping): if mapping.incompatible(otherMapping):
return True return True
return False return False
def supporting(self,other): def supporting(self, other):
if self == other: if self == other:
return False return False
if self.objectFromInitial == other.objectFromInitial: if self.objectFromInitial == other.objectFromInitial:
return False return False
if self.objectFromTarget == other.objectFromTarget: if self.objectFromTarget == other.objectFromTarget:
return False return False
if self.incompatible(other): if self.incompatible(other):
return False return False
for mapping in self.distinguishingConceptMappings(): for mapping in self.distinguishingConceptMappings():
for otherMapping in other.distinguishingConceptMappings(): for otherMapping in other.distinguishingConceptMappings():
if mapping.supports(otherMapping): if mapping.supports(otherMapping):
return True return True
return False return False
def support(self): def support(self):
from letter import Letter from letter import Letter
if isinstance(self.objectFromInitial,Letter) and self.objectFromInitial.spansString(): if isinstance(self.objectFromInitial, Letter) and self.objectFromInitial.spansString():
return 100.0 return 100.0
if isinstance(self.objectFromTarget,Letter) and self.objectFromTarget.spansString(): if isinstance(self.objectFromTarget, Letter) and self.objectFromTarget.spansString():
return 100.0 return 100.0
total = sum([ c.totalStrength for c in workspace.correspondences() if self.supporting(c) ]) total = sum([c.totalStrength for c in workspace.correspondences() if self.supporting(c)])
total = min(total,100.0) total = min(total, 100.0)
return total return total
def updateInternalStrength(self): def updateInternalStrength(self):
"""A function of how many conceptMappings there are, their strength and how well they cohere""" """A function of how many conceptMappings there are, their strength and how well they cohere"""
relevantDistinguishingMappings = self.relevantDistinguishingConceptMappings() relevantDistinguishingMappings = self.relevantDistinguishingConceptMappings()
numberOfConceptMappings = len(relevantDistinguishingMappings) numberOfConceptMappings = len(relevantDistinguishingMappings)
if numberOfConceptMappings < 1: if numberOfConceptMappings < 1:
self.internalStrength = 0.0 self.internalStrength = 0.0
return return
totalStrength = sum([ m.strength() for m in relevantDistinguishingMappings ]) totalStrength = sum([m.strength() for m in relevantDistinguishingMappings])
averageStrength = totalStrength / numberOfConceptMappings averageStrength = totalStrength / numberOfConceptMappings
if numberOfConceptMappings == 1.0: if numberOfConceptMappings == 1.0:
numberOfConceptMappingsFactor = 0.8 numberOfConceptMappingsFactor = 0.8
elif numberOfConceptMappings == 2.0: elif numberOfConceptMappings == 2.0:
numberOfConceptMappingsFactor = 1.2 numberOfConceptMappingsFactor = 1.2
else: else:
numberOfConceptMappingsFactor = 1.6 numberOfConceptMappingsFactor = 1.6
if self.internallyCoherent(): if self.internallyCoherent():
internalCoherenceFactor = 2.5 internalCoherenceFactor = 2.5
else: else:
internalCoherenceFactor = 1.0 internalCoherenceFactor = 1.0
internalStrength = averageStrength * internalCoherenceFactor * numberOfConceptMappingsFactor internalStrength = averageStrength * internalCoherenceFactor * numberOfConceptMappingsFactor
self.internalStrength = min(internalStrength,100.0) self.internalStrength = min(internalStrength, 100.0)
def updateExternalStrength(self): def updateExternalStrength(self):
self.externalStrength = self.support() self.externalStrength = self.support()
def internallyCoherent(self): def internallyCoherent(self):
"""Whether any pair of relevant distinguishing mappings support each other""" """Whether any pair of relevant distinguishing mappings support each other"""
mappings = self.relevantDistinguishingConceptMappings() mappings = self.relevantDistinguishingConceptMappings()
for i in range(0,len(mappings)): for i in range(0, len(mappings)):
for j in range(0,len(mappings)): for j in range(0, len(mappings)):
if i != j: if i != j:
if mappings[i].supports(mappings[j]): if mappings[i].supports(mappings[j]):
return True return True
return False return False
def slippages(self): def slippages(self):
mappings = [ m for m in self.conceptMappings if m.slippage() ] mappings = [m for m in self.conceptMappings if m.slippage()]
mappings += [ m for m in self.accessoryConceptMappings if m.slippage() ] mappings += [m for m in self.accessoryConceptMappings if m.slippage()]
return mappings return mappings
def reflexive(self): def reflexive(self):
if not self.objectFromInitial.correspondence: if not self.objectFromInitial.correspondence:
return False return False
if self.objectFromInitial.correspondence.objectFromTarget == self.objectFromTarget: if self.objectFromInitial.correspondence.objectFromTarget == self.objectFromTarget:
return True return True
return False return False
def buildCorrespondence(self): def buildCorrespondence(self):
workspace.structures += [ self ] workspace.structures += [self]
if self.objectFromInitial.correspondence: if self.objectFromInitial.correspondence:
self.objectFromInitial.correspondence.breakCorrespondence() self.objectFromInitial.correspondence.breakCorrespondence()
if self.objectFromTarget.correspondence: if self.objectFromTarget.correspondence:
self.objectFromTarget.correspondence.breakCorrespondence() self.objectFromTarget.correspondence.breakCorrespondence()
self.objectFromInitial.correspondence = self self.objectFromInitial.correspondence = self
self.objectFromTarget.correspondence = self self.objectFromTarget.correspondence = self
# add mappings to accessory-concept-mapping-list # add mappings to accessory-concept-mapping-list
relevantMappings = self.relevantDistinguishingConceptMappings() relevantMappings = self.relevantDistinguishingConceptMappings()
for mapping in relevantMappings: for mapping in relevantMappings:
if mapping.slippage(): if mapping.slippage():
self.accessoryConceptMappings += [ mapping.symmetricVersion() ] self.accessoryConceptMappings += [mapping.symmetricVersion()]
from group import Group from group import Group
if isinstance(self.objectFromInitial,Group) and isinstance(self.objectFromTarget,Group): if isinstance(self.objectFromInitial, Group) and isinstance(self.objectFromTarget, Group):
bondMappings = getMappings( bondMappings = getMappings(
self.objectFromInitial, self.objectFromInitial,
self.objectFromTarget, self.objectFromTarget,
self.objectFromInitial.bondDescriptions, self.objectFromInitial.bondDescriptions,
self.objectFromTarget.bondDescriptions self.objectFromTarget.bondDescriptions
) )
for mapping in bondMappings: for mapping in bondMappings:
self.accessoryConceptMappings += [ mapping ] self.accessoryConceptMappings += [mapping]
if mapping.slippage(): if mapping.slippage():
self.accessoryConceptMappings += [ mapping.symmetricVersion() ] self.accessoryConceptMappings += [mapping.symmetricVersion()]
for mapping in self.conceptMappings: for mapping in self.conceptMappings:
if mapping.label: if mapping.label:
mapping.label.activation = 100.0 mapping.label.activation = 100.0
def break_the_structure(self): def break_the_structure(self):
self.breakCorrespondence() self.breakCorrespondence()
def breakCorrespondence(self):
workspace.structures.remove(self)
self.objectFromInitial.correspondence = None
self.objectFromTarget.correspondence = None
def breakCorrespondence(self):
workspace.structures.remove(self)
self.objectFromInitial.correspondence = None
self.objectFromTarget.correspondence = None

View File

@ -1,56 +1,55 @@
import logging import logging
from workspaceStructure import WorkspaceStructure from workspaceStructure import WorkspaceStructure
class Description(WorkspaceStructure): class Description(WorkspaceStructure):
def __init__(self,workspaceObject,descriptionType,descriptor): def __init__(self, workspaceObject, descriptionType, descriptor):
WorkspaceStructure.__init__(self) WorkspaceStructure.__init__(self)
self.object = workspaceObject self.object = workspaceObject
self.string = workspaceObject.string self.string = workspaceObject.string
self.descriptionType = descriptionType self.descriptionType = descriptionType
self.descriptor = descriptor self.descriptor = descriptor
def __repr__(self): def __repr__(self):
return '<Description: %s>' % self.__str__() return '<Description: %s>' % self.__str__()
def __str__(self): def __str__(self):
s = 'description(%s) of %s' % (self.descriptor.get_name(),self.object) s = 'description(%s) of %s' % (self.descriptor.get_name(), self.object)
from workspace import workspace from workspace import workspace
if self.object.string == workspace.initial: if self.object.string == workspace.initial:
s += ' in initial string' s += ' in initial string'
else: else:
s += ' in target string' s += ' in target string'
return s return s
def updateInternalStrength(self): def updateInternalStrength(self):
self.internalStrength = self.descriptor.conceptualDepth self.internalStrength = self.descriptor.conceptualDepth
def updateExternalStrength(self): def updateExternalStrength(self):
self.externalStrength = (self.localSupport() + self.descriptionType.activation) / 2 self.externalStrength = (self.localSupport() + self.descriptionType.activation) / 2
def localSupport(self): def localSupport(self):
from workspace import workspace from workspace import workspace
supporters = 0 # number of objects in the string with a descriptionType like self supporters = 0 # number of objects in the string with a descriptionType like self
for other in workspace.otherObjects(self.object): for other in workspace.otherObjects(self.object):
if not ( self.object.isWithin(other) or other.isWithin(self.object) ): if not (self.object.isWithin(other) or other.isWithin(self.object)):
for description in other.descriptions: for description in other.descriptions:
if description.descriptionType == self.descriptionType: if description.descriptionType == self.descriptionType:
supporters += 1 supporters += 1
results = { 0:0.0, 1:20.0, 2:60.0, 3:90.0 } results = {0: 0.0, 1: 20.0, 2: 60.0, 3: 90.0}
if supporters in results: if supporters in results:
return results[supporters] return results[supporters]
return 100.0 return 100.0
def build(self):
self.descriptionType.buffer = 100.0
self.descriptor.buffer = 100.0
if not self.object.hasDescription(self.descriptor):
logging.info('Add %s to descriptions' % self)
self.object.descriptions += [ self ]
def breakDescription(self):
from workspace import workspace
if self in workspace.structures:
workspace.structures.remove(self)
self.object.descriptions.remove(self)
def build(self):
self.descriptionType.buffer = 100.0
self.descriptor.buffer = 100.0
if not self.object.hasDescription(self.descriptor):
logging.info('Add %s to descriptions' % self)
self.object.descriptions += [self]
def breakDescription(self):
from workspace import workspace
if self in workspace.structures:
workspace.structures.remove(self)
self.object.descriptions.remove(self)

View File

@ -1,146 +1,160 @@
import math #, random import math
import logging import logging
import random
import utils
from temperature import temperature from temperature import temperature
actualTemperature = Temperature = 100.0 actualTemperature = Temperature = 100.0
def selectListPosition(probabilities): def selectListPosition(probabilities):
total = sum(probabilities) total = sum(probabilities)
#logging.info('total: %s' % total) #logging.info('total: %s' % total)
r = utils.random() r = random.random()
stopPosition = total * r stopPosition = total * r
#logging.info('stopPosition: %s' % stopPosition) #logging.info('stopPosition: %s' % stopPosition)
total = 0 total = 0
index = 0 index = 0
for probability in probabilities: for probability in probabilities:
total += probability total += probability
if total > stopPosition: if total > stopPosition:
return index return index
index += 1 index += 1
return 0 return 0
def weightedAverage(values): def weightedAverage(values):
total = 0.0 total = 0.0
totalWeights = 0.0 totalWeights = 0.0
for value,weight in values: for value, weight in values:
total += value * weight total += value * weight
totalWeights += weight totalWeights += weight
if not totalWeights: if not totalWeights:
return 0.0 return 0.0
return total / totalWeights return total / totalWeights
def temperatureAdjustedValue(value): def temperatureAdjustedValue(value):
#logging.info('Temperature: %s' % Temperature) #logging.info('Temperature: %s' % Temperature)
#logging.info('actualTemperature: %s' % actualTemperature) #logging.info('actualTemperature: %s' % actualTemperature)
return value ** (((100.0-Temperature)/30.0)+0.5) return value ** (((100.0 - Temperature) / 30.0) + 0.5)
def temperatureAdjustedProbability(value): def temperatureAdjustedProbability(value):
if not value or value == 0.5 or not temperature.value: if not value or value == 0.5 or not temperature.value:
return value return value
if value < 0.5: if value < 0.5:
return 1.0 - temperatureAdjustedProbability(1.0 - value) return 1.0 - temperatureAdjustedProbability(1.0 - value)
coldness = 100.0 - temperature.value coldness = 100.0 - temperature.value
a = math.sqrt(coldness) a = math.sqrt(coldness)
b = 10.0 - a b = 10.0 - a
c = b / 100 c = b / 100
d = c * ( 1.0 - ( 1.0 - value ) ) # aka c * value, but we're following the java d = c * (1.0 - (1.0 - value)) # aka c * value, but we're following the java
e = ( 1.0 - value ) + d e = (1.0 - value) + d
f = 1.0 - e f = 1.0 - e
return max(f,0.5) return max(f, 0.5)
def coinFlip(chance=0.5): def coinFlip(chance=0.5):
return utils.random() < chance return random.random() < chance
def blur(value): def blur(value):
root = math.sqrt(value) root = math.sqrt(value)
if coinFlip(): if coinFlip():
return value + root return value + root
return value - root return value - root
def chooseObjectFromList(objects, attribute):
if not objects:
return None
probabilities = []
for object in objects:
value = getattr(object, attribute)
probability = temperatureAdjustedValue(value)
logging.info('Object: %s, value: %d, probability: %d' % (object, value, probability))
probabilities += [probability]
index = selectListPosition(probabilities)
logging.info("Selected: %d" % index)
return objects[index]
def chooseObjectFromList(objects,attribute):
if not objects:
return None
probabilities = []
for object in objects:
value = getattr(object,attribute)
probability = temperatureAdjustedValue(value)
logging.info('Object: %s, value: %d, probability: %d' % (object,value,probability))
probabilities += [ probability ]
index = selectListPosition(probabilities)
logging.info("Selected: %d" % index)
return objects[index]
def chooseRelevantDescriptionByActivation(workspaceObject): def chooseRelevantDescriptionByActivation(workspaceObject):
descriptions = workspaceObject.relevantDescriptions() descriptions = workspaceObject.relevantDescriptions()
if not descriptions: if not descriptions:
return None return None
activations = [ description.descriptor.activation for description in descriptions ] activations = [description.descriptor.activation for description in descriptions]
index = selectListPosition(activations) index = selectListPosition(activations)
return descriptions[ index ] return descriptions[index]
def similarPropertyLinks(slip_node): def similarPropertyLinks(slip_node):
result = [] result = []
for slip_link in slip_node.propertyLinks: for slip_link in slip_node.propertyLinks:
association = slip_link.degreeOfAssociation() / 100.0 association = slip_link.degreeOfAssociation() / 100.0
probability = temperatureAdjustedProbability( association ) probability = temperatureAdjustedProbability(association)
if coinFlip(probability): if coinFlip(probability):
result += [ slip_link ] result += [slip_link]
return result return result
def chooseSlipnodeByConceptualDepth(slip_nodes): def chooseSlipnodeByConceptualDepth(slip_nodes):
if not slip_nodes: if not slip_nodes:
return None return None
depths = [ temperatureAdjustedValue(n.conceptualDepth) for n in slip_nodes ] depths = [temperatureAdjustedValue(n.conceptualDepth) for n in slip_nodes]
i = selectListPosition(depths) i = selectListPosition(depths)
return slip_nodes[ i ] return slip_nodes[i]
def __relevantCategory(objekt,slipnode):
return objekt.rightBond and objekt.rightBond.category == slipnode
def __relevantDirection(objekt,slipnode): def __relevantCategory(objekt, slipnode):
return objekt.rightBond and objekt.rightBond.directionCategory == slipnode return objekt.rightBond and objekt.rightBond.category == slipnode
def __relevantDirection(objekt, slipnode):
return objekt.rightBond and objekt.rightBond.directionCategory == slipnode
def __localRelevance(string, slipnode, relevance):
numberOfObjectsNotSpanning = numberOfMatches = 0.0
#logging.info("find relevance for a string: %s" % string);
for objekt in string.objects:
#logging.info('object: %s' % objekt)
if not objekt.spansString():
#logging.info('non spanner: %s' % objekt)
numberOfObjectsNotSpanning += 1.0
if relevance(objekt, slipnode):
numberOfMatches += 1.0
#logging.info("matches: %d, not spanning: %d" % (numberOfMatches,numberOfObjectsNotSpanning))
if numberOfObjectsNotSpanning == 1:
return 100.0 * numberOfMatches
return 100.0 * numberOfMatches / (numberOfObjectsNotSpanning - 1.0)
def __localRelevance(string,slipnode,relevance):
numberOfObjectsNotSpanning = numberOfMatches = 0.0
#logging.info("find relevance for a string: %s" % string);
for objekt in string.objects:
#logging.info('object: %s' % objekt)
if not objekt.spansString():
#logging.info('non spanner: %s' % objekt)
numberOfObjectsNotSpanning += 1.0
if relevance(objekt,slipnode):
numberOfMatches += 1.0
#logging.info("matches: %d, not spanning: %d" % (numberOfMatches,numberOfObjectsNotSpanning))
if numberOfObjectsNotSpanning == 1:
return 100.0 * numberOfMatches
return 100.0 * numberOfMatches / (numberOfObjectsNotSpanning - 1.0)
def localBondCategoryRelevance(string, category): def localBondCategoryRelevance(string, category):
if len(string.objects) == 1: if len(string.objects) == 1:
return 0.0 return 0.0
return __localRelevance(string,category,__relevantCategory) return __localRelevance(string, category, __relevantCategory)
def localDirectionCategoryRelevance(string, direction): def localDirectionCategoryRelevance(string, direction):
return __localRelevance(string,direction,__relevantDirection) return __localRelevance(string, direction, __relevantDirection)
def getMappings(objectFromInitial,objectFromTarget, initialDescriptions, targetDescriptions):
mappings = []
from conceptMapping import ConceptMapping
for initialDescription in initialDescriptions:
for targetDescription in targetDescriptions:
if initialDescription.descriptionType == targetDescription.descriptionType:
if initialDescription.descriptor == targetDescription.descriptor or initialDescription.descriptor.slipLinked(targetDescription.descriptor):
mapping = ConceptMapping(
initialDescription.descriptionType,
targetDescription.descriptionType,
initialDescription.descriptor,
targetDescription.descriptor,
objectFromInitial,
objectFromTarget
)
mappings += [ mapping ]
return mappings
def getMappings(objectFromInitial, objectFromTarget, initialDescriptions, targetDescriptions):
mappings = []
from conceptMapping import ConceptMapping
for initialDescription in initialDescriptions:
for targetDescription in targetDescriptions:
if initialDescription.descriptionType == targetDescription.descriptionType:
if initialDescription.descriptor == targetDescription.descriptor or initialDescription.descriptor.slipLinked(targetDescription.descriptor):
mapping = ConceptMapping(
initialDescription.descriptionType,
targetDescription.descriptionType,
initialDescription.descriptor,
targetDescription.descriptor,
objectFromInitial,
objectFromTarget
)
mappings += [mapping]
return mappings

View File

@ -1,237 +1,236 @@
import utils, logging import logging
import random
from workspace import workspace from workspace import workspace
from workspaceObject import WorkspaceObject from workspaceObject import WorkspaceObject
from slipnet import slipnet from slipnet import slipnet
import formulas import formulas
class Group(WorkspaceObject): class Group(WorkspaceObject):
def __init__(self,string,groupCategory,directionCategory,facet,objectList,bondList): def __init__(self, string, groupCategory, directionCategory, facet, objectList, bondList):
WorkspaceObject.__init__(self,string) WorkspaceObject.__init__(self, string)
self.groupCategory = groupCategory self.groupCategory = groupCategory
self.directionCategory = directionCategory self.directionCategory = directionCategory
self.facet = facet self.facet = facet
self.objectList = objectList self.objectList = objectList
self.bondList = bondList self.bondList = bondList
self.bondCategory = self.groupCategory.getRelatedNode(slipnet.bondCategory) self.bondCategory = self.groupCategory.getRelatedNode(slipnet.bondCategory)
leftObject = objectList[0] leftObject = objectList[0]
rightObject = objectList[-1] rightObject = objectList[-1]
self.leftStringPosition = leftObject.leftStringPosition self.leftStringPosition = leftObject.leftStringPosition
self.leftmost = self.leftStringPosition == 1 self.leftmost = self.leftStringPosition == 1
self.rightStringPosition = rightObject.rightStringPosition self.rightStringPosition = rightObject.rightStringPosition
self.rightmost = self.rightStringPosition == len(self.string) self.rightmost = self.rightStringPosition == len(self.string)
self.descriptions = [] self.descriptions = []
self.bondDescriptions = [] self.bondDescriptions = []
self.extrinsicDescriptions = [] self.extrinsicDescriptions = []
self.outgoingBonds = [] self.outgoingBonds = []
self.incomingBonds = [] self.incomingBonds = []
self.bonds = [] self.bonds = []
self.leftBond = None self.leftBond = None
self.rightBond = None self.rightBond = None
self.correspondence = None self.correspondence = None
self.changed = False self.changed = False
self.newAnswerLetter = False self.newAnswerLetter = False
self.clampSalience = False self.clampSalience = False
self.name = '' self.name = ''
from description import Description
if self.bondList and len(self.bondList):
firstFacet = self.bondList[0].facet
self.addBondDescription(Description(self, slipnet.bondFacet, firstFacet))
self.addBondDescription(Description(self, slipnet.bondCategory, self.bondCategory))
from description import Description self.addDescription(slipnet.objectCategory, slipnet.group)
if self.bondList and len(self.bondList): self.addDescription(slipnet.groupCategory, self.groupCategory)
firstFacet = self.bondList[0].facet if not self.directionCategory:
self.addBondDescription(Description(self, slipnet.bondFacet, firstFacet)) # sameness group - find letterCategory
self.addBondDescription(Description(self, slipnet.bondCategory, self.bondCategory)) letter = self.objectList[0].getDescriptor(self.facet)
self.addDescription(self.facet, letter)
if self.directionCategory:
self.addDescription(slipnet.directionCategory, self.directionCategory)
if self.spansString():
self.addDescription(slipnet.stringPositionCategory, slipnet.whole)
elif self.leftStringPosition == 1:
self.addDescription(slipnet.stringPositionCategory, slipnet.leftmost)
elif self.rightStringPosition == self.string.length:
self.addDescription(slipnet.stringPositionCategory, slipnet.rightmost)
elif self.middleObject():
self.addDescription(slipnet.stringPositionCategory, slipnet.middle)
self.addDescription(slipnet.objectCategory, slipnet.group) #check whether or not to add length description category
self.addDescription(slipnet.groupCategory, self.groupCategory) probability = self.lengthDescriptionProbability()
if not self.directionCategory: if random.random() < probability:
# sameness group - find letterCategory length = len(self.objectList)
letter = self.objectList[0].getDescriptor(self.facet) if length < 6:
self.addDescription(self.facet, letter) self.addDescription(slipnet.length, slipnet.numbers[length - 1])
if self.directionCategory:
self.addDescription(slipnet.directionCategory, self.directionCategory)
if self.spansString():
self.addDescription(slipnet.stringPositionCategory, slipnet.whole)
elif self.leftStringPosition == 1:
self.addDescription(slipnet.stringPositionCategory, slipnet.leftmost)
elif self.rightStringPosition == self.string.length:
self.addDescription(slipnet.stringPositionCategory, slipnet.rightmost)
elif self.middleObject():
self.addDescription(slipnet.stringPositionCategory, slipnet.middle)
#check whether or not to add length description category def __str__(self):
probability = self.lengthDescriptionProbability() s = self.string.__str__()
if utils.random() < probability: l = self.leftStringPosition - 1
length = len(self.objectList) r = self.rightStringPosition
if length < 6: return 'group[%d:%d] == %s' % (l, r - 1, s[l:r])
self.addDescription(slipnet.length, slipnet.numbers[length - 1])
def __str__(self): def getIncompatibleGroups(self):
s = self.string.__str__() result = []
l = self.leftStringPosition - 1 for objekt in self.objectList:
r = self.rightStringPosition while objekt.group:
return 'group[%d:%d] == %s' % ( l, r - 1, s[l: r ]) result += [objekt.group]
objekt = objekt.group
return result
def getIncompatibleGroups(self): def addBondDescription(self, description):
result = [] self.bondDescriptions += [description]
for objekt in self.objectList:
while objekt.group:
result += [ objekt.group ]
objekt = objekt.group
return result
def addBondDescription(self,description): def singleLetterGroupProbability(self):
self.bondDescriptions += [ description ] numberOfSupporters = self.numberOfLocalSupportingGroups()
if not numberOfSupporters:
return 0.0
if numberOfSupporters == 1:
exp = 4.0
elif numberOfSupporters == 2:
exp = 2.0
else:
exp = 1.0
support = self.localSupport() / 100.0
activation = slipnet.length.activation / 100.0
supportedActivation = (support * activation) ** exp
return formulas.temperatureAdjustedProbability(supportedActivation)
def singleLetterGroupProbability(self): def flippedVersion(self):
numberOfSupporters = self.numberOfLocalSupportingGroups() flippedBonds = [b.flippedversion() for b in self.bondList]
if not numberOfSupporters: flippedGroup = self.groupCategory.getRelatedNode(slipnet.flipped)
return 0.0 flippedDirection = self.directionCategory.getRelatedNode(slipnet.flipped)
if numberOfSupporters == 1: return Group(self.string, flippedGroup, flippedDirection, self.facet, self.objectList, flippedBonds)
exp = 4.0
elif numberOfSupporters == 2:
exp = 2.0
else:
exp = 1.0
support = self.localSupport() / 100.0
activation = slipnet.length.activation / 100.0
supportedActivation = (support * activation) ** exp
return formulas.temperatureAdjustedProbability(supportedActivation)
def flippedVersion(self): def buildGroup(self):
flippedBonds = [ b.flippedversion() for b in self.bondList ] workspace.objects += [self]
flippedGroup = self.groupCategory.getRelatedNode(slipnet.flipped) workspace.structures += [self]
flippedDirection = self.directionCategory.getRelatedNode(slipnet.flipped) self.string.objects += [self]
return Group(self.string, flippedGroup, flippedDirection, self.facet, self.objectList, flippedBonds) for objekt in self.objectList:
objekt.group = self
workspace.buildDescriptions(self)
self.activateDescriptions()
def buildGroup(self): def activateDescriptions(self):
workspace.objects += [ self ] for description in self.descriptions:
workspace.structures += [ self ] logging.info('Activate: %s' % description)
self.string.objects += [ self ] description.descriptor.buffer = 100.0
for objekt in self.objectList:
objekt.group = self
workspace.buildDescriptions(self)
self.activateDescriptions()
def activateDescriptions(self): def lengthDescriptionProbability(self):
for description in self.descriptions: length = len(self.objectList)
logging.info('Activate: %s' % description) if length > 5:
description.descriptor.buffer = 100.0 return 0.0
cubedlength = length ** 3
fred = cubedlength * (100.0 - slipnet.length.activation) / 100.0
probability = 0.5 ** fred
value = formulas.temperatureAdjustedProbability(probability)
if value < 0.06:
value = 0.0 # otherwise 1/20 chance always
return value
def lengthDescriptionProbability(self): def break_the_structure(self):
length = len(self.objectList) self.breakGroup()
if length > 5:
return 0.0
cubedlength = length ** 3
fred = cubedlength * (100.0 - slipnet.length.activation) / 100.0
probability = 0.5 ** fred
value = formulas.temperatureAdjustedProbability(probability)
if value < 0.06:
value = 0.0 # otherwise 1/20 chance always
return value
def break_the_structure(self): def breakGroup(self):
self.breakGroup() while len(self.descriptions):
description = self.descriptions[-1]
description.breakDescription()
for objekt in self.objectList:
objekt.group = None
if self.group:
self.group.breakGroup()
if self in workspace.structures:
workspace.structures.remove(self)
if self in workspace.objects:
workspace.objects.remove(self)
if self in self.string.objects:
self.string.objects.remove(self)
if self.correspondence:
self.correspondence.breakCorrespondence()
if self.leftBond:
self.leftBond.breakBond()
if self.rightBond:
self.rightBond.breakBond()
def breakGroup(self): def updateInternalStrength(self):
while len(self.descriptions): relatedBondAssociation = self.groupCategory.getRelatedNode(slipnet.bondCategory).degreeOfAssociation()
description = self.descriptions[-1] bondWeight = relatedBondAssociation ** 0.98
description.breakDescription() length = len(self.objectList)
for objekt in self.objectList: if length == 1:
objekt.group = None lengthFactor = 5.0
if self.group: elif length == 2:
self.group.breakGroup() lengthFactor = 20.0
if self in workspace.structures: elif length == 3:
workspace.structures.remove(self) lengthFactor = 60.0
if self in workspace.objects: else:
workspace.objects.remove(self) lengthFactor = 90.0
if self in self.string.objects: lengthWeight = 100.0 - bondWeight
self.string.objects.remove(self) weightList = ((relatedBondAssociation, bondWeight), (lengthFactor, lengthWeight))
if self.correspondence: self.internalStrength = formulas.weightedAverage(weightList)
self.correspondence.breakCorrespondence()
if self.leftBond:
self.leftBond.breakBond()
if self.rightBond:
self.rightBond.breakBond()
def updateInternalStrength(self): def updateExternalStrength(self):
relatedBondAssociation = self.groupCategory.getRelatedNode(slipnet.bondCategory).degreeOfAssociation() if self.spansString():
bondWeight = relatedBondAssociation ** 0.98 self.externalStrength = 100.0
length = len(self.objectList) else:
if length == 1: self.externalStrength = self.localSupport()
lengthFactor = 5.0
elif length == 2:
lengthFactor = 20.0
elif length == 3:
lengthFactor = 60.0
else:
lengthFactor = 90.0
lengthWeight = 100.0 - bondWeight
weightList = ( (relatedBondAssociation, bondWeight), (lengthFactor, lengthWeight) )
self.internalStrength = formulas.weightedAverage(weightList)
def updateExternalStrength(self): def localSupport(self):
if self.spansString(): numberOfSupporters = self.numberOfLocalSupportingGroups()
self.externalStrength = 100.0 if numberOfSupporters == 0.0:
else: return 0.0
self.externalStrength = self.localSupport() supportFactor = min(1.0, 0.6 ** (1 / (numberOfSupporters ** 3)))
densityFactor = 100.0 * ((self.localDensity() / 100.0) ** 0.5)
return densityFactor * supportFactor
def localSupport(self): def numberOfLocalSupportingGroups(self):
numberOfSupporters = self.numberOfLocalSupportingGroups() count = 0
if numberOfSupporters == 0.0: for objekt in self.string.objects:
return 0.0 if isinstance(objekt, Group):
supportFactor = min(1.0,0.6 ** (1 / (numberOfSupporters ** 3 ))) if objekt.rightStringPosition < self.leftStringPosition or objekt.leftStringPosition > self.rightStringPosition:
densityFactor = 100.0 * ((self.localDensity() / 100.0) ** 0.5) if objekt.groupCategory == self.groupCategory and objekt.directionCategory == self.directionCategory:
return densityFactor * supportFactor count += 1
return count
def numberOfLocalSupportingGroups(self): def localDensity(self):
count = 0 numberOfSupporters = self.numberOfLocalSupportingGroups()
for objekt in self.string.objects: halfLength = len(self.string) / 2.0
if isinstance(objekt,Group): return 100.0 * numberOfSupporters / halfLength
if objekt.rightStringPosition < self.leftStringPosition or objekt.leftStringPosition > self.rightStringPosition:
if objekt.groupCategory == self.groupCategory and objekt.directionCategory == self.directionCategory:
count += 1
return count
def localDensity(self): def sameGroup(self, other):
numberOfSupporters = self.numberOfLocalSupportingGroups() if self.leftStringPosition != other.leftStringPosition:
halfLength = len(self.string) / 2.0 return False
return 100.0 * numberOfSupporters / halfLength if self.rightStringPosition != other.rightStringPosition:
return False
def sameGroup(self,other): if self.groupCategory != other.groupCategory:
if self.leftStringPosition != other.leftStringPosition: return False
return False if self.directionCategory != other.directionCategory:
if self.rightStringPosition != other.rightStringPosition: return False
return False if self.facet != other.facet:
if self.groupCategory != other.groupCategory: return False
return False return True
if self.directionCategory != other.directionCategory:
return False
if self.facet != other.facet:
return False
return True
def morePossibleDescriptions(self,node):
result = []
i = 1
for number in slipnet.numbers:
if node == number and len(self.objects) == i:
result += [ node ]
i += 1
return result
def distinguishingDescriptor(self,descriptor):
"""Whether no other object of the same type (group) has the same descriptor"""
if not WorkspaceObject.distinguishingDescriptor(self,descriptor):
return False
for objekt in self.string.objects:
# check to see if they are of the same type
if isinstance(objekt,Group) and objekt != self:
# check all descriptions for the descriptor
for description in objekt.descriptions:
if description.descriptor == descriptor:
return False
return True
def morePossibleDescriptions(self, node):
result = []
i = 1
for number in slipnet.numbers:
if node == number and len(self.objects) == i:
result += [node]
i += 1
return result
def distinguishingDescriptor(self, descriptor):
"""Whether no other object of the same type (group) has the same descriptor"""
if not WorkspaceObject.distinguishingDescriptor(self, descriptor):
return False
for objekt in self.string.objects:
# check to see if they are of the same type
if isinstance(objekt, Group) and objekt != self:
# check all descriptions for the descriptor
for description in objekt.descriptions:
if description.descriptor == descriptor:
return False
return True

View File

@ -1,14 +1,15 @@
from workspace import workspace from workspace import workspace
class GroupRun(object): class GroupRun(object):
def __init__(self): def __init__(self):
self.name = 'xxx' self.name = 'xxx'
self.maximumNumberOfRuns = 1000 self.maximumNumberOfRuns = 1000
self.runStrings = [] self.runStrings = []
self.answers = [] self.answers = []
self.scores = [0] * 100 self.scores = [0] * 100
self.initial = workspace.initial self.initial = workspace.initial
self.modified = workspace.modified self.modified = workspace.modified
self.target = workspace.target self.target = workspace.target
groupRun = GroupRun() groupRun = GroupRun()

View File

@ -1,48 +1,48 @@
from workspaceObject import WorkspaceObject from workspaceObject import WorkspaceObject
from slipnet import slipnet from slipnet import slipnet
class Letter(WorkspaceObject): class Letter(WorkspaceObject):
def __init__(self,string,position,length): def __init__(self, string, position, length):
WorkspaceObject.__init__(self,string) WorkspaceObject.__init__(self, string)
from workspace import workspace from workspace import workspace
workspace.objects += [ self ] workspace.objects += [self]
string.objects += [self ] string.objects += [self]
self.leftStringPosition = position self.leftStringPosition = position
self.leftmost = self.leftStringPosition == 1 self.leftmost = self.leftStringPosition == 1
self.rightStringPosition = position self.rightStringPosition = position
self.rightmost = self.rightStringPosition == length self.rightmost = self.rightStringPosition == length
def describe(self,position,length): def describe(self, position, length):
if length == 1: if length == 1:
self.addDescription(slipnet.stringPositionCategory,slipnet.single) self.addDescription(slipnet.stringPositionCategory, slipnet.single)
if self.leftmost and length > 1: # ? why check length ? if self.leftmost and length > 1: # ? why check length ?
self.addDescription(slipnet.stringPositionCategory,slipnet.leftmost) self.addDescription(slipnet.stringPositionCategory, slipnet.leftmost)
if self.rightmost and length > 1: # ? why check length ? if self.rightmost and length > 1: # ? why check length ?
self.addDescription(slipnet.stringPositionCategory,slipnet.rightmost) self.addDescription(slipnet.stringPositionCategory, slipnet.rightmost)
if length > 2 and position * 2 == length + 1: if length > 2 and position * 2 == length + 1:
self.addDescription(slipnet.stringPositionCategory,slipnet.middle) self.addDescription(slipnet.stringPositionCategory, slipnet.middle)
def __repr__(self): def __repr__(self):
return '<Letter: %s>' % self.__str__() return '<Letter: %s>' % self.__str__()
def __str__(self): def __str__(self):
if not self.string: if not self.string:
return '' return ''
i = self.leftStringPosition - 1 i = self.leftStringPosition - 1
if len(self.string) <= i: 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.leftStringPosition :: %d <= %d' % (len(self.string), self.leftStringPosition))
return self.string[ i ] return self.string[i]
def distinguishingDescriptor(self,descriptor):
"""Whether no other object of the same type (letter) has the same descriptor"""
if not WorkspaceObject.distinguishingDescriptor(self,descriptor):
return False
for objekt in self.string.objects:
# check to see if they are of the same type
if isinstance(objekt,Letter) and objekt != self:
# check all descriptions for the descriptor
for description in objekt.descriptions:
if description.descriptor == descriptor:
return False
return True
def distinguishingDescriptor(self, descriptor):
"""Whether no other object of the same type (letter) has the same descriptor"""
if not WorkspaceObject.distinguishingDescriptor(self, descriptor):
return False
for objekt in self.string.objects:
# check to see if they are of the same type
if isinstance(objekt, Letter) and objekt != self:
# check all descriptions for the descriptor
for description in objekt.descriptions:
if description.descriptor == descriptor:
return False
return True

View File

@ -7,15 +7,15 @@ import copycat
def main(program, args): def main(program, args):
"""Run the program""" """Run the program"""
try: try:
initial, modified, target = args initial, modified, target = args
copycat.run(initial, modified, target) copycat.run(initial, modified, target)
return 0 return 0
except ValueError: except ValueError:
print >> sys.stderr, 'Usage: %s initial modified target' % program print >> sys.stderr, 'Usage: %s initial modified target' % program
return 1 return 1
if __name__ == '__main__': if __name__ == '__main__':
sys.exit(main(sys.argv[0], sys.argv[1:])) sys.exit(main(sys.argv[0], sys.argv[1:]))

View File

@ -1,9 +1,9 @@
from workspaceStructure import WorkspaceStructure from workspaceStructure import WorkspaceStructure
class Replacement(WorkspaceStructure):
def __init__(self, objectFromInitial, objectFromModified, relation):
WorkspaceStructure.__init__(self)
self.objectFromInitial = objectFromInitial
self.objectFromModified = objectFromModified
self.relation = relation
class Replacement(WorkspaceStructure):
def __init__(self, objectFromInitial, objectFromModified, relation):
WorkspaceStructure.__init__(self)
self.objectFromInitial = objectFromInitial
self.objectFromModified = objectFromModified
self.relation = relation

View File

@ -3,132 +3,132 @@ from workspace import workspace
from workspaceStructure import WorkspaceStructure from workspaceStructure import WorkspaceStructure
from formulas import * from formulas import *
class Rule(WorkspaceStructure): class Rule(WorkspaceStructure):
def __init__(self,facet,descriptor,category,relation): def __init__(self, facet, descriptor, category, relation):
WorkspaceStructure.__init__(self) WorkspaceStructure.__init__(self)
self.facet = facet self.facet = facet
self.descriptor = descriptor self.descriptor = descriptor
self.category = category self.category = category
self.relation = relation self.relation = relation
def __str__(self): def __str__(self):
if not self.facet: if not self.facet:
return 'Empty rule' 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): def updateExternalStrength(self):
self.externalStrength = self.internalStrength self.externalStrength = self.internalStrength
def updateInternalStrength(self): def updateInternalStrength(self):
if not ( self.descriptor and self.relation ): if not (self.descriptor and self.relation):
self.internalStrength = 0.0 self.internalStrength = 0.0
return return
averageDepth = ( self.descriptor.conceptualDepth + self.relation.conceptualDepth ) / 2.0 averageDepth = (self.descriptor.conceptualDepth + self.relation.conceptualDepth) / 2.0
averageDepth **= 1.1 averageDepth **= 1.1
# see if the object corresponds to an object # see if the object corresponds to an object
# if so, see if the descriptor is present (modulo slippages) in the # if so, see if the descriptor is present (modulo slippages) in the
# corresponding object # corresponding object
changedObjects = [ o for o in workspace.initial.objects if o.changed ] changedObjects = [o for o in workspace.initial.objects if o.changed]
changed = changedObjects[0] changed = changedObjects[0]
sharedDescriptorTerm = 0.0 sharedDescriptorTerm = 0.0
if changed and changed.correspondence: if changed and changed.correspondence:
targetObject = changed.correspondence.objectFromTarget targetObject = changed.correspondence.objectFromTarget
slippages = workspace.slippages() slippages = workspace.slippages()
slipnode = self.descriptor.applySlippages(slippages) slipnode = self.descriptor.applySlippages(slippages)
if not targetObject.hasDescription(slipnode): if not targetObject.hasDescription(slipnode):
self.internalStrength = 0.0 self.internalStrength = 0.0
return return
sharedDescriptorTerm = 100.0 sharedDescriptorTerm = 100.0
sharedDescriptorWeight = ((100.0 - self.descriptor.conceptualDepth) / 10.0) ** 1.4 sharedDescriptorWeight = ((100.0 - self.descriptor.conceptualDepth) / 10.0) ** 1.4
depthDifference = 100.0 - abs(self.descriptor.conceptualDepth - self.relation.conceptualDepth) depthDifference = 100.0 - abs(self.descriptor.conceptualDepth - self.relation.conceptualDepth)
weights = ( (depthDifference,12), (averageDepth,18), (sharedDescriptorTerm,sharedDescriptorWeight) ) weights = ((depthDifference, 12), (averageDepth, 18), (sharedDescriptorTerm, sharedDescriptorWeight))
self.internalStrength = weightedAverage( weights ) self.internalStrength = weightedAverage(weights)
if self.internalStrength > 100.0: if self.internalStrength > 100.0:
self.internalStrength = 100.0 self.internalStrength = 100.0
def ruleEqual(self,other): def ruleEqual(self, other):
if not other: if not other:
return False return False
if self.relation != other.relation: if self.relation != other.relation:
return False return False
if self.facet != other.facet: if self.facet != other.facet:
return False return False
if self.category != other.category: if self.category != other.category:
return False return False
if self.descriptor != other.descriptor: if self.descriptor != other.descriptor:
return False return False
return True return True
def activateRuleDescriptions(self): def activateRuleDescriptions(self):
if self.relation: if self.relation:
self.relation.buffer = 100.0 self.relation.buffer = 100.0
if self.facet: if self.facet:
self.facet.buffer = 100.0 self.facet.buffer = 100.0
if self.category: if self.category:
self.category.buffer = 100.0 self.category.buffer = 100.0
if self.descriptor: if self.descriptor:
self.descriptor.buffer = 100.0 self.descriptor.buffer = 100.0
def incompatibleRuleCorrespondence(self, correspondence): def incompatibleRuleCorrespondence(self, correspondence):
if not correspondence: if not correspondence:
return False return False
# find changed object # find changed object
changeds = [ o for o in workspace.initial.objects if o.changed ] changeds = [o for o in workspace.initial.objects if o.changed]
if not changeds: if not changeds:
return False return False
changed = changeds[0] changed = changeds[0]
if correspondence.objectFromInitial != changed: if correspondence.objectFromInitial != changed:
return False return False
# it is incompatible if the rule descriptor is not in the mapping list # it is incompatible if the rule descriptor is not in the mapping list
if len([ m for m in correspondence.conceptMappings if m.initialDescriptor == self.descriptor ]): if len([m for m in correspondence.conceptMappings if m.initialDescriptor == self.descriptor]):
return False return False
return True return True
def __changeString(self,string): def __changeString(self, string):
# applies the changes to self string ie. successor # applies the changes to self string ie. successor
if self.facet == slipnet.length: if self.facet == slipnet.length:
if self.relation == slipnet.predecessor: if self.relation == slipnet.predecessor:
return string[0:-1] return string[0:-1]
if self.relation == slipnet.successor: if self.relation == slipnet.successor:
return string + string[0:1] return string + string[0:1]
return string return string
# apply character changes # apply character changes
if self.relation == slipnet.predecessor: if self.relation == slipnet.predecessor:
if 'a' in string: if 'a' in string:
return None return None
return ''.join([ chr(ord(c) - 1) for c in string]) return ''.join([chr(ord(c) - 1) for c in string])
elif self.relation == slipnet.successor: elif self.relation == slipnet.successor:
if 'z' in string: if 'z' in string:
return None return None
return ''.join([ chr(ord(c) + 1) for c in string]) return ''.join([chr(ord(c) + 1) for c in string])
else: else:
return self.relation.name.lower() return self.relation.name.lower()
def buildTranslatedRule(self):
slippages = workspace.slippages()
self.category = self.category.applySlippages(slippages)
self.facet = self.facet.applySlippages(slippages)
self.descriptor = self.descriptor.applySlippages(slippages)
self.relation = self.relation.applySlippages(slippages)
# generate the final string
self.finalAnswer = workspace.targetString
changeds = [ o for o in workspace.target.objects if
o.hasDescription(self.descriptor) and
o.hasDescription(self.category) ]
changed = changeds and changeds[0] or None
logging.debug('changed object = %s' % changed)
if changed:
left = changed.leftStringPosition
startString = ''
if left > 1:
startString = self.finalAnswer[0: left - 1]
right = changed.rightStringPosition
middleString = self.__changeString(self.finalAnswer[left - 1: right])
if not middleString:
return False
endString = ''
if right < len(self.finalAnswer):
endString = self.finalAnswer[right:]
self.finalAnswer = startString + middleString + endString
return True
def buildTranslatedRule(self):
slippages = workspace.slippages()
self.category = self.category.applySlippages(slippages)
self.facet = self.facet.applySlippages(slippages)
self.descriptor = self.descriptor.applySlippages(slippages)
self.relation = self.relation.applySlippages(slippages)
# generate the final string
self.finalAnswer = workspace.targetString
changeds = [o for o in workspace.target.objects if
o.hasDescription(self.descriptor) and
o.hasDescription(self.category)]
changed = changeds and changeds[0] or None
logging.debug('changed object = %s' % changed)
if changed:
left = changed.leftStringPosition
startString = ''
if left > 1:
startString = self.finalAnswer[0: left - 1]
right = changed.rightStringPosition
middleString = self.__changeString(self.finalAnswer[left - 1: right])
if not middleString:
return False
endString = ''
if right < len(self.finalAnswer):
endString = self.finalAnswer[right:]
self.finalAnswer = startString + middleString + endString
return True

View File

@ -1,28 +1,29 @@
#from slipnode import Slipnode #from slipnode import Slipnode
class Sliplink(object): class Sliplink(object):
def __init__(self, source, destination, label=None, length=0.0): def __init__(self, source, destination, label=None, length=0.0):
self.source = source self.source = source
self.destination = destination self.destination = destination
self.label = label self.label = label
self.fixedLength = length self.fixedLength = length
source.outgoingLinks += [self] source.outgoingLinks += [self]
destination.incomingLinks += [self] destination.incomingLinks += [self]
def degreeOfAssociation(self): def degreeOfAssociation(self):
if self.fixedLength > 0 or not self.label: if self.fixedLength > 0 or not self.label:
return 100.0 - self.fixedLength return 100.0 - self.fixedLength
return self.label.degreeOfAssociation() return self.label.degreeOfAssociation()
def intrinsicDegreeOfAssociation(self): def intrinsicDegreeOfAssociation(self):
if self.fixedLength > 1: if self.fixedLength > 1:
return 100.0 - self.fixedLength return 100.0 - self.fixedLength
if self.label: if self.label:
return 100.0 - self.label.intrinsicLinkLength return 100.0 - self.label.intrinsicLinkLength
return 0.0 return 0.0
def spread_activation(self): def spread_activation(self):
self.destination.buffer += self.intrinsicDegreeOfAssociation() self.destination.buffer += self.intrinsicDegreeOfAssociation()
def points_at(self, other): def points_at(self, other):
return self.destination == other return self.destination == other

View File

@ -3,250 +3,251 @@ import logging
from slipnode import Slipnode from slipnode import Slipnode
from sliplink import Sliplink from sliplink import Sliplink
class SlipNet(object): class SlipNet(object):
def __init__(self): def __init__(self):
logging.debug("SlipNet.__init__()") logging.debug("SlipNet.__init__()")
self.initiallyClampedSlipnodes = [] self.initiallyClampedSlipnodes = []
self.slipnodes = [] self.slipnodes = []
self.sliplinks = [] self.sliplinks = []
self.bondFacets = [] self.bondFacets = []
self.timeStepLength = 15 self.timeStepLength = 15
self.numberOfUpdates = 0 self.numberOfUpdates = 0
self.__addInitialNodes() self.__addInitialNodes()
self.__addInitialLinks() self.__addInitialLinks()
self.predecessor = None self.predecessor = None
def __repr__(self): def __repr__(self):
return '<slipnet>' return '<slipnet>'
def setConceptualDepths(self, depth): def setConceptualDepths(self, depth):
logging.debug('slipnet set all depths to %f' % depth) logging.debug('slipnet set all depths to %f' % depth)
[node.setConceptualDepth(depth) for node in self.slipnodes] [node.setConceptualDepth(depth) for node in self.slipnodes]
def reset(self): def reset(self):
logging.debug('slipnet.reset()') logging.debug('slipnet.reset()')
self.numberOfUpdates = 0 self.numberOfUpdates = 0
for node in self.slipnodes: for node in self.slipnodes:
node.reset() node.reset()
if node in self.initiallyClampedSlipnodes: if node in self.initiallyClampedSlipnodes:
node.clampHigh() node.clampHigh()
def update(self): def update(self):
logging.debug('slipnet.update()') logging.debug('slipnet.update()')
self.numberOfUpdates += 1 self.numberOfUpdates += 1
if self.numberOfUpdates == 50: if self.numberOfUpdates == 50:
[node.unclamp() for node in self.initiallyClampedSlipnodes] [node.unclamp() for node in self.initiallyClampedSlipnodes]
[node.update() for node in self.slipnodes] [node.update() for node in self.slipnodes]
# Note - spreadActivation() affects more than one node, so the following # Note - spreadActivation() affects more than one node, so the following
# cannot go in a general "for node" loop with the other node actions # cannot go in a general "for node" loop with the other node actions
for node in self.slipnodes: for node in self.slipnodes:
node.spread_activation() node.spread_activation()
for node in self.slipnodes: for node in self.slipnodes:
node.addBuffer() node.addBuffer()
node.jump() node.jump()
node.buffer = 0.0 node.buffer = 0.0
def __addInitialNodes(self): def __addInitialNodes(self):
self.slipnodes = [] self.slipnodes = []
self.letters = [] self.letters = []
for c in 'abcdefghijklmnopqrstuvwxyz': for c in 'abcdefghijklmnopqrstuvwxyz':
slipnode = self.__addNode(c, 10.0) slipnode = self.__addNode(c, 10.0)
self.letters += [slipnode] self.letters += [slipnode]
self.numbers = [] self.numbers = []
for c in '12345': for c in '12345':
slipnode = self.__addNode(c, 30.0) slipnode = self.__addNode(c, 30.0)
self.numbers += [slipnode] self.numbers += [slipnode]
# string positions # string positions
self.leftmost = self.__addNode('leftmost', 40.0) self.leftmost = self.__addNode('leftmost', 40.0)
self.rightmost = self.__addNode('rightmost', 40.0) self.rightmost = self.__addNode('rightmost', 40.0)
self.middle = self.__addNode('middle', 40.0) self.middle = self.__addNode('middle', 40.0)
self.single = self.__addNode('single', 40.0) self.single = self.__addNode('single', 40.0)
self.whole = self.__addNode('whole', 40.0) self.whole = self.__addNode('whole', 40.0)
# alphabetic positions # alphabetic positions
self.first = self.__addNode('first', 60.0) self.first = self.__addNode('first', 60.0)
self.last = self.__addNode('last', 60.0) self.last = self.__addNode('last', 60.0)
# directions # directions
self.left = self.__addNode('left', 40.0) self.left = self.__addNode('left', 40.0)
self.left.codelets += ['top-down-bond-scout--direction'] self.left.codelets += ['top-down-bond-scout--direction']
self.left.codelets += ['top-down-group-scout--direction'] self.left.codelets += ['top-down-group-scout--direction']
self.right = self.__addNode('right', 40.0) self.right = self.__addNode('right', 40.0)
self.right.codelets += ['top-down-bond-scout--direction'] self.right.codelets += ['top-down-bond-scout--direction']
self.right.codelets += ['top-down-group-scout--direction'] self.right.codelets += ['top-down-group-scout--direction']
# bond types # bond types
self.predecessor = self.__addNode('predecessor', 50.0, 60.0) self.predecessor = self.__addNode('predecessor', 50.0, 60.0)
self.predecessor.codelets += ['top-down-bond-scout--category'] self.predecessor.codelets += ['top-down-bond-scout--category']
self.successor = self.__addNode('successor', 50.0, 60.0) self.successor = self.__addNode('successor', 50.0, 60.0)
self.successor.codelets += ['top-down-bond-scout--category'] self.successor.codelets += ['top-down-bond-scout--category']
self.sameness = self.__addNode('sameness', 80.0) self.sameness = self.__addNode('sameness', 80.0)
self.sameness.codelets += ['top-down-bond-scout--category'] self.sameness.codelets += ['top-down-bond-scout--category']
# group types # group types
self.predecessorGroup = self.__addNode('predecessorGroup', 50.0) self.predecessorGroup = self.__addNode('predecessorGroup', 50.0)
self.predecessorGroup.codelets += ['top-down-group-scout--category'] self.predecessorGroup.codelets += ['top-down-group-scout--category']
self.successorGroup = self.__addNode('successorGroup', 50.0) self.successorGroup = self.__addNode('successorGroup', 50.0)
self.successorGroup.codelets += ['top-down-group-scout--category'] self.successorGroup.codelets += ['top-down-group-scout--category']
self.samenessGroup = self.__addNode('samenessGroup', 80.0) self.samenessGroup = self.__addNode('samenessGroup', 80.0)
self.samenessGroup.codelets += ['top-down-group-scout--category'] self.samenessGroup.codelets += ['top-down-group-scout--category']
# other relations # other relations
self.identity = self.__addNode('identity', 90.0) self.identity = self.__addNode('identity', 90.0)
self.opposite = self.__addNode('opposite', 90.0, 80.0) self.opposite = self.__addNode('opposite', 90.0, 80.0)
# objects # objects
self.letter = self.__addNode('letter', 20.0) self.letter = self.__addNode('letter', 20.0)
self.group = self.__addNode('group', 80.0) self.group = self.__addNode('group', 80.0)
# categories # categories
self.letterCategory = self.__addNode('letterCategory', 30.0) 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.stringPositionCategory.codelets += ['top-down-description-scout']
self.alphabeticPositionCategory = self.__addNode('alphabeticPositionCategory', 80.0) self.alphabeticPositionCategory = self.__addNode('alphabeticPositionCategory', 80.0)
self.alphabeticPositionCategory.codelets += ['top-down-description-scout'] self.alphabeticPositionCategory.codelets += ['top-down-description-scout']
self.directionCategory = self.__addNode('directionCategory', 70.0) self.directionCategory = self.__addNode('directionCategory', 70.0)
self.bondCategory = self.__addNode('bondCategory', 80.0) self.bondCategory = self.__addNode('bondCategory', 80.0)
self.groupCategory = self.__addNode('groupCategory', 80.0) self.groupCategory = self.__addNode('groupCategory', 80.0)
self.length = self.__addNode('length', 60.0) self.length = self.__addNode('length', 60.0)
self.objectCategory = self.__addNode('objectCategory', 90.0) self.objectCategory = self.__addNode('objectCategory', 90.0)
self.bondFacet = self.__addNode('bondFacet', 90.0) self.bondFacet = self.__addNode('bondFacet', 90.0)
# specify the descriptor types that bonds can form between # specify the descriptor types that bonds can form between
self.bondFacets += [self.letterCategory] self.bondFacets += [self.letterCategory]
self.bondFacets += [self.length] self.bondFacets += [self.length]
# #
self.initiallyClampedSlipnodes += [self.letterCategory] self.initiallyClampedSlipnodes += [self.letterCategory]
self.letterCategory.clamped = True self.letterCategory.clamped = True
self.initiallyClampedSlipnodes += [self.stringPositionCategory] self.initiallyClampedSlipnodes += [self.stringPositionCategory]
self.stringPositionCategory.clamped = True self.stringPositionCategory.clamped = True
def __addInitialLinks(self): def __addInitialLinks(self):
self.sliplinks = [] self.sliplinks = []
self.__link_items_to_their_neighbours(self.letters) self.__link_items_to_their_neighbours(self.letters)
self.__link_items_to_their_neighbours(self.numbers) self.__link_items_to_their_neighbours(self.numbers)
# letter categories # letter categories
for letter in self.letters: for letter in self.letters:
self.__addInstanceLink(self.letterCategory, letter, 97.0) self.__addInstanceLink(self.letterCategory, letter, 97.0)
self.__addCategoryLink(self.samenessGroup, self.letterCategory, 50.0) self.__addCategoryLink(self.samenessGroup, self.letterCategory, 50.0)
# lengths # lengths
for number in self.numbers: for number in self.numbers:
self.__addInstanceLink(self.length, number, 100.0) self.__addInstanceLink(self.length, number, 100.0)
self.__addNonSlipLink(self.predecessorGroup, self.length, length=95.0) self.__addNonSlipLink(self.predecessorGroup, self.length, length=95.0)
self.__addNonSlipLink(self.successorGroup, self.length, length=95.0) self.__addNonSlipLink(self.successorGroup, self.length, length=95.0)
self.__addNonSlipLink(self.samenessGroup, self.length, length=95.0) self.__addNonSlipLink(self.samenessGroup, self.length, length=95.0)
# opposites # opposites
self.__addOppositeLink(self.first, self.last) self.__addOppositeLink(self.first, self.last)
self.__addOppositeLink(self.leftmost, self.rightmost) self.__addOppositeLink(self.leftmost, self.rightmost)
self.__addOppositeLink(self.left, self.right) self.__addOppositeLink(self.left, self.right)
self.__addOppositeLink(self.successor, self.predecessor) self.__addOppositeLink(self.successor, self.predecessor)
self.__addOppositeLink(self.successorGroup, self.predecessorGroup) self.__addOppositeLink(self.successorGroup, self.predecessorGroup)
# properties # properties
self.__addPropertyLink(self.letters[0], self.first, 75.0) self.__addPropertyLink(self.letters[0], self.first, 75.0)
self.__addPropertyLink(self.letters[-1], self.last, 75.0) self.__addPropertyLink(self.letters[-1], self.last, 75.0)
# object categories # object categories
self.__addInstanceLink(self.objectCategory, self.letter, 100.0) self.__addInstanceLink(self.objectCategory, self.letter, 100.0)
self.__addInstanceLink(self.objectCategory, self.group, 100.0) self.__addInstanceLink(self.objectCategory, self.group, 100.0)
# string positions # string positions
self.__addInstanceLink(self.stringPositionCategory, self.leftmost, 100.0) self.__addInstanceLink(self.stringPositionCategory, self.leftmost, 100.0)
self.__addInstanceLink(self.stringPositionCategory, self.rightmost, 100.0) self.__addInstanceLink(self.stringPositionCategory, self.rightmost, 100.0)
self.__addInstanceLink(self.stringPositionCategory, self.middle, 100.0) self.__addInstanceLink(self.stringPositionCategory, self.middle, 100.0)
self.__addInstanceLink(self.stringPositionCategory, self.single, 100.0) self.__addInstanceLink(self.stringPositionCategory, self.single, 100.0)
self.__addInstanceLink(self.stringPositionCategory, self.whole, 100.0) self.__addInstanceLink(self.stringPositionCategory, self.whole, 100.0)
# alphabetic positions # alphabetic positions
self.__addInstanceLink(self.alphabeticPositionCategory, self.first, 100.0) self.__addInstanceLink(self.alphabeticPositionCategory, self.first, 100.0)
self.__addInstanceLink(self.alphabeticPositionCategory, self.last, 100.0) self.__addInstanceLink(self.alphabeticPositionCategory, self.last, 100.0)
# direction categories # direction categories
self.__addInstanceLink(self.directionCategory, self.left, 100.0) self.__addInstanceLink(self.directionCategory, self.left, 100.0)
self.__addInstanceLink(self.directionCategory, self.right, 100.0) self.__addInstanceLink(self.directionCategory, self.right, 100.0)
# bond categories # bond categories
self.__addInstanceLink(self.bondCategory, self.predecessor, 100.0) self.__addInstanceLink(self.bondCategory, self.predecessor, 100.0)
self.__addInstanceLink(self.bondCategory, self.successor, 100.0) self.__addInstanceLink(self.bondCategory, self.successor, 100.0)
self.__addInstanceLink(self.bondCategory, self.sameness, 100.0) self.__addInstanceLink(self.bondCategory, self.sameness, 100.0)
# group categories # 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.successorGroup, 100.0)
self.__addInstanceLink(self.groupCategory, self.samenessGroup, 100.0) self.__addInstanceLink(self.groupCategory, self.samenessGroup, 100.0)
# link bonds to their groups # link bonds to their groups
self.__addNonSlipLink(self.sameness, self.samenessGroup, label=self.groupCategory, length=30.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.successor, self.successorGroup, label=self.groupCategory, length=60.0)
self.__addNonSlipLink(self.predecessor, self.predecessorGroup, label=self.groupCategory, length=60.0) self.__addNonSlipLink(self.predecessor, self.predecessorGroup, label=self.groupCategory, length=60.0)
# link bond groups to their bonds # link bond groups to their bonds
self.__addNonSlipLink(self.samenessGroup, self.sameness, 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.successorGroup, self.successor, label=self.bondCategory, length=90.0)
self.__addNonSlipLink(self.predecessorGroup, self.predecessor, label=self.bondCategory, length=90.0) self.__addNonSlipLink(self.predecessorGroup, self.predecessor, label=self.bondCategory, length=90.0)
# bond facets # bond facets
self.__addInstanceLink(self.bondFacet, self.letterCategory, 100.0) self.__addInstanceLink(self.bondFacet, self.letterCategory, 100.0)
self.__addInstanceLink(self.bondFacet, self.length, 100.0) self.__addInstanceLink(self.bondFacet, self.length, 100.0)
# letter category to length # letter category to length
self.__addSlipLink(self.letterCategory, self.length, length=95.0) self.__addSlipLink(self.letterCategory, self.length, length=95.0)
self.__addSlipLink(self.length, self.letterCategory, length=95.0) self.__addSlipLink(self.length, self.letterCategory, length=95.0)
# letter to group # letter to group
self.__addSlipLink(self.letter, self.group, length=90.0) self.__addSlipLink(self.letter, self.group, length=90.0)
self.__addSlipLink(self.group, self.letter, length=90.0) self.__addSlipLink(self.group, self.letter, length=90.0)
# direction-position, direction-neighbour, position-neighbour # direction-position, direction-neighbour, position-neighbour
self.__addBidirectionalLink(self.left, self.leftmost, 90.0) self.__addBidirectionalLink(self.left, self.leftmost, 90.0)
self.__addBidirectionalLink(self.right, self.rightmost, 90.0) self.__addBidirectionalLink(self.right, self.rightmost, 90.0)
self.__addBidirectionalLink(self.right, self.leftmost, 100.0) self.__addBidirectionalLink(self.right, self.leftmost, 100.0)
self.__addBidirectionalLink(self.left, self.rightmost, 100.0) self.__addBidirectionalLink(self.left, self.rightmost, 100.0)
self.__addBidirectionalLink(self.leftmost, self.first, 100.0) self.__addBidirectionalLink(self.leftmost, self.first, 100.0)
self.__addBidirectionalLink(self.rightmost, self.first, 100.0) self.__addBidirectionalLink(self.rightmost, self.first, 100.0)
self.__addBidirectionalLink(self.leftmost, self.last, 100.0) self.__addBidirectionalLink(self.leftmost, self.last, 100.0)
self.__addBidirectionalLink(self.rightmost, self.last, 100.0) self.__addBidirectionalLink(self.rightmost, self.last, 100.0)
# other # other
self.__addSlipLink(self.single, self.whole, length=90.0) self.__addSlipLink(self.single, self.whole, length=90.0)
self.__addSlipLink(self.whole, self.single, length=90.0) self.__addSlipLink(self.whole, self.single, length=90.0)
def __addLink(self, source, destination, label=None, length=0.0): def __addLink(self, source, destination, label=None, length=0.0):
link = Sliplink(source, destination, label=label, length=length) link = Sliplink(source, destination, label=label, length=length)
self.sliplinks += [link] self.sliplinks += [link]
return link return link
def __addSlipLink(self, source, destination, label=None, length=0.0): def __addSlipLink(self, source, destination, label=None, length=0.0):
link = self.__addLink(source, destination, label, length) link = self.__addLink(source, destination, label, length)
source.lateralSlipLinks += [link] source.lateralSlipLinks += [link]
def __addNonSlipLink(self, source, destination, label=None, length=0.0): def __addNonSlipLink(self, source, destination, label=None, length=0.0):
link = self.__addLink(source, destination, label, length) link = self.__addLink(source, destination, label, length)
source.lateralNonSlipLinks += [link] source.lateralNonSlipLinks += [link]
def __addBidirectionalLink(self, source, destination, length): def __addBidirectionalLink(self, source, destination, length):
self.__addNonSlipLink(source, destination, length=length) self.__addNonSlipLink(source, destination, length=length)
self.__addNonSlipLink(destination, source, length=length) self.__addNonSlipLink(destination, source, length=length)
def __addCategoryLink(self, source, destination, length): def __addCategoryLink(self, source, destination, length):
#noinspection PyArgumentEqualDefault #noinspection PyArgumentEqualDefault
link = self.__addLink(source, destination, None, length) link = self.__addLink(source, destination, None, length)
source.categoryLinks += [link] source.categoryLinks += [link]
def __addInstanceLink(self, source, destination, length): def __addInstanceLink(self, source, destination, length):
categoryLength = source.conceptualDepth - destination.conceptualDepth categoryLength = source.conceptualDepth - destination.conceptualDepth
self.__addCategoryLink(destination, source, categoryLength) self.__addCategoryLink(destination, source, categoryLength)
#noinspection PyArgumentEqualDefault #noinspection PyArgumentEqualDefault
link = self.__addLink(source, destination, None, length) link = self.__addLink(source, destination, None, length)
source.instanceLinks += [link] source.instanceLinks += [link]
def __addPropertyLink(self, source, destination, length): def __addPropertyLink(self, source, destination, length):
#noinspection PyArgumentEqualDefault #noinspection PyArgumentEqualDefault
link = self.__addLink(source, destination, None, length) link = self.__addLink(source, destination, None, length)
source.propertyLinks += [link] source.propertyLinks += [link]
def __addOppositeLink(self, source, destination): def __addOppositeLink(self, source, destination):
self.__addSlipLink(source, destination, label=self.opposite) self.__addSlipLink(source, destination, label=self.opposite)
self.__addSlipLink(destination, source, label=self.opposite) self.__addSlipLink(destination, source, label=self.opposite)
def __addNode(self, name, depth, length=0): def __addNode(self, name, depth, length=0):
slipnode = Slipnode(name, depth, length) slipnode = Slipnode(name, depth, length)
self.slipnodes += [slipnode] self.slipnodes += [slipnode]
return slipnode return slipnode
def __link_items_to_their_neighbours(self,items): def __link_items_to_their_neighbours(self, items):
previous = items[0] previous = items[0]
for item in items[1:]: for item in items[1:]:
self.__addNonSlipLink(previous, item, label=self.successor) self.__addNonSlipLink(previous, item, label=self.successor)
self.__addNonSlipLink(item, previous, label=self.predecessor) self.__addNonSlipLink(item, previous, label=self.predecessor)
previous = item previous = item
slipnet = SlipNet() slipnet = SlipNet()

View File

@ -1,161 +1,164 @@
import math import math
import utils
import logging import logging
import random
def full_activation(): def full_activation():
return 100 return 100
def jump_threshold(): def jump_threshold():
return 55.0 return 55.0
class Slipnode(object): class Slipnode(object):
def __init__(self, name, depth, length=0.0): def __init__(self, name, depth, length=0.0):
# logging.info('depth to %s for %s' % (depth,name)) # logging.info('depth to %s for %s' % (depth,name))
self.conceptual_depth = depth self.conceptualDepth = depth
self.usualConceptualDepth = depth self.usualConceptualDepth = depth
self.name = name self.name = name
self.intrinsicLinkLength = length self.intrinsicLinkLength = length
self.shrunkLinkLength = length * 0.4 self.shrunkLinkLength = length * 0.4
self.activation = 0.0 self.activation = 0.0
self.buffer = 0.0 self.buffer = 0.0
self.clamped = False self.clamped = False
self.bondFacetFactor = 0.0 self.bondFacetFactor = 0.0
self.categoryLinks = [] self.categoryLinks = []
self.instanceLinks = [] self.instanceLinks = []
self.propertyLinks = [] self.propertyLinks = []
self.lateralSlipLinks = [] self.lateralSlipLinks = []
self.lateralNonSlipLinks = [] self.lateralNonSlipLinks = []
self.incomingLinks = [] self.incomingLinks = []
self.outgoingLinks = [] self.outgoingLinks = []
self.codelets = [] self.codelets = []
self.clampBondDegreeOfAssociation = False self.clampBondDegreeOfAssociation = False
def __repr__(self): def __repr__(self):
return '<Slipnode: %s>' % self.name return '<Slipnode: %s>' % self.name
def reset(self): def reset(self):
self.buffer = 0.0 self.buffer = 0.0
self.activation = 0.0 self.activation = 0.0
def clampHigh(self): def clampHigh(self):
self.clamped = True self.clamped = True
self.activation = 100.0 self.activation = 100.0
def unclamp(self): def unclamp(self):
self.clamped = False self.clamped = False
def setConceptualDepth(self, depth): def setConceptualDepth(self, depth):
logging.info('set depth to %s for %s' % (depth, self.name)) logging.info('set depth to %s for %s' % (depth, self.name))
self.conceptual_depth = depth self.conceptualDepth = depth
def category(self): def category(self):
if not len(self.categoryLinks): if not len(self.categoryLinks):
return None return None
link = self.categoryLinks[0] link = self.categoryLinks[0]
return link.destination return link.destination
def fully_active(self): def fully_active(self):
"""Whether this node has full activation""" """Whether this node has full activation"""
return self.activation > full_activation() - 0.00001 # allow a little leeway for floats return self.activation > full_activation() - 0.00001 # allow a little leeway for floats
def activate_fully(self): def activate_fully(self):
"""Make this node fully active""" """Make this node fully active"""
self.activation = full_activation() self.activation = full_activation()
def bondDegreeOfAssociation(self): def bondDegreeOfAssociation(self):
linkLength = self.intrinsicLinkLength linkLength = self.intrinsicLinkLength
if (not self.clampBondDegreeOfAssociation) and self.fully_active(): if (not self.clampBondDegreeOfAssociation) and self.fully_active():
linkLength = self.shrunkLinkLength linkLength = self.shrunkLinkLength
result = math.sqrt(100 - linkLength) * 11.0 result = math.sqrt(100 - linkLength) * 11.0
return min(100.0, result) return min(100.0, result)
def degreeOfAssociation(self): def degreeOfAssociation(self):
linkLength = self.intrinsicLinkLength linkLength = self.intrinsicLinkLength
if self.fully_active(): if self.fully_active():
linkLength = self.shrunkLinkLength linkLength = self.shrunkLinkLength
return 100.0 - linkLength return 100.0 - linkLength
def update(self): def update(self):
act = self.activation act = self.activation
self.oldActivation = act self.oldActivation = act
self.buffer -= self.activation * ( 100.0 - self.conceptual_depth) / 100.0 self.buffer -= self.activation * (100.0 - self.conceptualDepth) / 100.0
def linked(self, other): def linked(self, other):
"""Whether the other is among the outgoing links""" """Whether the other is among the outgoing links"""
return self.points_at(self.outgoingLinks, other) return self.points_at(self.outgoingLinks, other)
def slipLinked(self, other): def slipLinked(self, other):
"""Whether the other is among the lateral links""" """Whether the other is among the lateral links"""
return self.points_at(self.lateralSlipLinks, other) return self.points_at(self.lateralSlipLinks, other)
def points_at(self, links, other): def points_at(self, links, other):
"""Whether any of the links points at the other""" """Whether any of the links points at the other"""
return any([l.points_at(other) for l in links]) return any([l.points_at(other) for l in links])
def related(self, other): def related(self, other):
"""Same or linked""" """Same or linked"""
return self == other or self.linked(other) return self == other or self.linked(other)
def applySlippages(self, slippages): def applySlippages(self, slippages):
for slippage in slippages: for slippage in slippages:
if self == slippage.initialDescriptor: if self == slippage.initialDescriptor:
return slippage.targetDescriptor return slippage.targetDescriptor
return self return self
def getRelatedNode(self, relation): def getRelatedNode(self, relation):
"""Return the node that is linked to this node via this relation. """Return the node that is linked to this node via this relation.
If no linked node is found, return None If no linked node is found, return None
""" """
from slipnet import slipnet from slipnet import slipnet
if relation == slipnet.identity: if relation == slipnet.identity:
return self 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: if destinations:
return destinations[0] return destinations[0]
node = None node = None
return node return node
def getBondCategory(self, destination): def getBondCategory(self, destination):
"""Return the label of the link between these nodes if it exists. """Return the label of the link between these nodes if it exists.
If it does not exist return None If it does not exist return None
""" """
from slipnet import slipnet from slipnet import slipnet
result = None result = None
if self == destination: if self == destination:
result = slipnet.identity result = slipnet.identity
else: else:
for link in self.outgoingLinks: for link in self.outgoingLinks:
if link.destination == destination: if link.destination == destination:
result = link.label result = link.label
break break
if result: if result:
logging.info('Got bond: %s' % result.name) logging.info('Got bond: %s' % result.name)
else: else:
logging.info('Got no bond') logging.info('Got no bond')
return result return result
def spread_activation(self): def spread_activation(self):
if self.fully_active(): if self.fully_active():
[ link.spread_activation() for link in self.outgoingLinks ] [link.spread_activation() for link in self.outgoingLinks]
def addBuffer(self): def addBuffer(self):
if not self.clamped: if not self.clamped:
self.activation += self.buffer self.activation += self.buffer
self.activation = min(self.activation, 100) self.activation = min(self.activation, 100)
self.activation = max(self.activation, 0) self.activation = max(self.activation, 0)
def jump(self): def jump(self):
value = (self.activation / 100.0) ** 3 value = (self.activation / 100.0) ** 3
#logging.info('jumping for %s at activation %s' % (self.name,self.activation)) #logging.info('jumping for %s at activation %s' % (self.name,self.activation))
if self.activation > jump_threshold() and utils.random() < value and not self.clamped: if self.activation > jump_threshold() and random.random() < value and not self.clamped:
self.activate_fully() self.activate_fully()
def get_name(self): def get_name(self):
if len(self.name) == 1: if len(self.name) == 1:
return self.name.upper() return self.name.upper()
return self.name return self.name

View File

@ -1,23 +1,24 @@
import logging import logging
class Temperature(object): class Temperature(object):
def __init__(self): def __init__(self):
self.value = 100.0 self.value = 100.0
self.clamped = True self.clamped = True
self.clampTime = 30 self.clampTime = 30
def update(self, value): def update(self, value):
logging.debug('update to %s' % value) logging.debug('update to %s' % value)
self.value = value self.value = value
def tryUnclamp(self): def tryUnclamp(self):
from coderack import coderack from coderack import coderack
if self.clamped and coderack.codeletsRun >= self.clampTime: 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 self.clamped = False
def log(self): def log(self):
logging.debug('temperature.value: %f' % self.value) logging.debug('temperature.value: %f' % self.value)
temperature = Temperature() temperature = Temperature()

View File

@ -1,140 +0,0 @@
def any(things):
"""Return True if any of the things are True.
things should be iterable.
If the things are empty, then we can't say any are True
>>> any([])
False
If all the things are False, then we can't say any are True
>>> any([False,False,False])
False
If all the things are equivalent to False, then we can't say any are True
>>> any([0,[],''])
False
The type of the true thing should not matter
>>> any([1,[],''])
True
>>> any([0,(2,),''])
True
>>> any([0,[],'foo'])
True
>>> any([0,[],True,''])
True
It should not matter where the True thing is
>>> any((True,False,False,False,False,))
True
>>> any((False,False,True,False,False,))
True
>>> any((False,False,False,False,True,))
True
The size of the sequence should not matter
>>> True == any((True,)) == any((True,True,)) == any((True,True,True,True,))
True
Any string is True
>>> any('foo')
True
Except an empty string
>>> any('')
False
The function cannot be applied to ints
>>> any(7)
Traceback (most recent call last):
...
TypeError: iteration over non-sequence
"""
for thing in things:
if thing:
return True
return False
def all(things):
"""Return True if all of the things are True.
things should be iterable.
If the things are empty, then we can't say all are True
>>> all([])
False
If all the things are False, then we can't say all are True
>>> all([False,False,False])
False
If all the things are equivalent to False, then we can't say all are True
>>> all([0,[],''])
False
The type of the false thing should not matter
>>> all([0,True,True,])
False
>>> all([True,(),True,])
False
>>> all([True,True,'',])
False
Position of the false thing should not matter
>>> all((False,True,True,))
False
>>> all((True,False,True,))
False
>>> all((True,True,False,))
False
any string is True
>>> all('foo')
True
Except an empty string
>>> all('')
False
The function cannot be applied to ints
>>> all(7)
Traceback (most recent call last):
...
TypeError: iteration over non-sequence
"""
for thing in things:
if not thing:
return False
return len(things) > 0
import logging
seed = 999.0
count = 0
testably_random = True
def random():
global testably_random
if testably_random:
from random import random
return random()
global seed
global count
seed += 1.0
count += 1
if seed > 1999:
seed = 0.0
logging.info("count: %d" % count)
#if seed == 998:
# sys.exit(1)
return seed / 2000.0
def choice(aList):
i = int(random() * len(aList))
return aList[i]
if __name__ == '__main__':
import doctest
doctest.testmod()

View File

@ -4,155 +4,155 @@ from workspaceString import WorkspaceString
unknownAnswer = '?' unknownAnswer = '?'
class Workspace(object): class Workspace(object):
def __init__(self): def __init__(self):
#logging.debug('workspace.__init__()') #logging.debug('workspace.__init__()')
self.setStrings('', '', '') self.setStrings('', '', '')
self.reset() self.reset()
self.totalUnhappiness = 0.0 self.totalUnhappiness = 0.0
self.intraStringUnhappiness = 0.0 self.intraStringUnhappiness = 0.0
self.interStringUnhappiness = 0.0 self.interStringUnhappiness = 0.0
def __repr__(self): 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): def setStrings(self, initial, modified, target):
self.targetString = target self.targetString = target
self.initialString = initial self.initialString = initial
self.modifiedString = modified self.modifiedString = modified
def reset(self): def reset(self):
#logging.debug('workspace.reset()') #logging.debug('workspace.reset()')
self.foundAnswer = False self.foundAnswer = False
self.changedObject = None self.changedObject = None
self.objects = [] self.objects = []
self.structures = [] self.structures = []
self.rule = None self.rule = None
self.initial = WorkspaceString(self.initialString) self.initial = WorkspaceString(self.initialString)
self.modified = WorkspaceString(self.modifiedString) self.modified = WorkspaceString(self.modifiedString)
self.target = WorkspaceString(self.targetString) self.target = WorkspaceString(self.targetString)
def __adjustUnhappiness(self, values): def __adjustUnhappiness(self, values):
result = sum(values) / 2 result = sum(values) / 2
if result > 100.0: if result > 100.0:
result = 100.0 result = 100.0
return result return result
def assessUnhappiness(self): def assessUnhappiness(self):
self.intraStringUnhappiness = self.__adjustUnhappiness([o.relativeImportance * o.intraStringUnhappiness for o in self.objects]) 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.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.totalUnhappiness = self.__adjustUnhappiness([o.relativeImportance * o.totalUnhappiness for o in self.objects])
def assessTemperature(self): def assessTemperature(self):
self.calculateIntraStringUnhappiness() self.calculateIntraStringUnhappiness()
self.calculateInterStringUnhappiness() self.calculateInterStringUnhappiness()
self.calculateTotalUnhappiness() self.calculateTotalUnhappiness()
def calculateIntraStringUnhappiness(self): 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 value = sum(values) / 2.0
self.intraStringUnhappiness = min(value, 100.0) self.intraStringUnhappiness = min(value, 100.0)
def calculateInterStringUnhappiness(self): 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 value = sum(values) / 2.0
self.interStringUnhappiness = min(value, 100.0) self.interStringUnhappiness = min(value, 100.0)
def calculateTotalUnhappiness(self): def calculateTotalUnhappiness(self):
for o in self.objects: for o in self.objects:
logging.info("object: %s, totalUnhappiness: %d, relativeImportance: %d" % ( logging.info("object: %s, totalUnhappiness: %d, relativeImportance: %d" % (
o, o.totalUnhappiness, o.relativeImportance * 1000)) o, o.totalUnhappiness, o.relativeImportance * 1000))
values = [o.relativeImportance * o.totalUnhappiness for o in self.objects] values = [o.relativeImportance * o.totalUnhappiness for o in self.objects]
value = sum(values) / 2.0 value = sum(values) / 2.0
self.totalUnhappiness = min(value, 100.0) self.totalUnhappiness = min(value, 100.0)
def updateEverything(self): def updateEverything(self):
for structure in self.structures: for structure in self.structures:
structure.updateStrength() structure.updateStrength()
for obj in self.objects: for obj in self.objects:
obj.updateValue() obj.updateValue()
self.initial.updateRelativeImportance() self.initial.updateRelativeImportance()
self.target.updateRelativeImportance() self.target.updateRelativeImportance()
self.initial.updateIntraStringUnhappiness() self.initial.updateIntraStringUnhappiness()
self.target.updateIntraStringUnhappiness() self.target.updateIntraStringUnhappiness()
def otherObjects(self, anObject): def otherObjects(self, anObject):
return [o for o in self.objects if o != anObject] return [o for o in self.objects if o != anObject]
def numberOfUnrelatedObjects(self): def numberOfUnrelatedObjects(self):
"""A list of all objects in the workspace that have at least one bond slot open.""" """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] objects = [o for o in self.objects if o.string == self.initial or o.string == self.target]
#print 'A: %d' % len(objects) #print 'A: %d' % len(objects)
objects = [o for o in objects if not o.spansString()] objects = [o for o in objects if not o.spansString()]
#print 'B: %d' % len(objects) #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) #print 'C: %d' % len(objects)
#objects = [ o for o in objects if ] #objects = [ o for o in objects if ]
#print 'D: %d' % len(objects) #print 'D: %d' % len(objects)
return len(objects) return len(objects)
def numberOfUngroupedObjects(self): def numberOfUngroupedObjects(self):
"""A list of all objects in the workspace that have no group.""" """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.spansString()]
objects = [o for o in objects if not o.group] objects = [o for o in objects if not o.group]
return len(objects) return len(objects)
def numberOfUnreplacedObjects(self): def numberOfUnreplacedObjects(self):
"""A list of all objects in the inital string that have not been replaced.""" """A list of all objects in the inital string that have not been replaced."""
from letter import Letter 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] objects = [o for o in objects if not o.replacement]
return len(objects) return len(objects)
def numberOfUncorrespondingObjects(self): def numberOfUncorrespondingObjects(self):
"""A list of all objects in the inital string that have not been replaced.""" """A list of all objects in the inital string that have not been replaced."""
objects = [o for o in self.objects if o.string == self.initial or o.string == self.target] objects = [o for o in self.objects if o.string == self.initial or o.string == self.target]
objects = [o for o in objects if not o.correspondence] objects = [o for o in objects if not o.correspondence]
return len(objects) return len(objects)
def numberOfBonds(self): def numberOfBonds(self):
"""The number of bonds in the workspace""" """The number of bonds in the workspace"""
from bond import Bond from bond import Bond
return len([o for o in self.structures if isinstance(o, Bond)]) return len([o for o in self.structures if isinstance(o, Bond)])
def correspondences(self): def correspondences(self):
from correspondence import Correspondence from correspondence import Correspondence
return [s for s in self.structures if isinstance(s, Correspondence)] return [s for s in self.structures if isinstance(s, Correspondence)]
def slippages(self): def slippages(self):
result = [] result = []
if self.changedObject and self.changedObject.correspondence: 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: for objekt in workspace.initial.objects:
if objekt.correspondence: if objekt.correspondence:
for mapping in objekt.correspondence.slippages(): for mapping in objekt.correspondence.slippages():
if not mapping.isNearlyContainedBy(result): if not mapping.isNearlyContainedBy(result):
result += [mapping] result += [mapping]
return result return result
def buildRule(self, rule): def buildRule(self, rule):
if self.rule: if self.rule:
self.structures.remove(self.rule) self.structures.remove(self.rule)
self.rule = rule self.rule = rule
self.structures += [rule] self.structures += [rule]
rule.activateRuleDescriptions() rule.activateRuleDescriptions()
def breakRule(self): def breakRule(self):
self.rule = None self.rule = None
def buildDescriptions(self, objekt): def buildDescriptions(self, objekt):
for description in objekt.descriptions: for description in objekt.descriptions:
description.descriptionType.buffer = 100.0 description.descriptionType.buffer = 100.0
#logging.info("Set buffer to 100 for " + description.descriptionType.get_name()); #logging.info("Set buffer to 100 for " + description.descriptionType.get_name());
description.descriptor.buffer = 100.0 description.descriptor.buffer = 100.0
#logging.info("Set buffer to 100 for " + description.descriptor.get_name()); #logging.info("Set buffer to 100 for " + description.descriptor.get_name());
if description not in self.structures: if description not in self.structures:
self.structures += [description] self.structures += [description]
workspace = Workspace() workspace = Workspace()

View File

@ -5,156 +5,166 @@ from temperature import temperature
from slipnet import slipnet from slipnet import slipnet
import formulas import formulas
class WorkspaceFormulas(object):
def __init__(self):
self.clampTemperature = False
def updateTemperature(self): class WorkspaceFormulas(object):
logging.debug('updateTemperature') def __init__(self):
workspace.assessTemperature() self.clampTemperature = False
ruleWeakness = 100.0
if workspace.rule: def updateTemperature(self):
workspace.rule.updateStrength() logging.debug('updateTemperature')
ruleWeakness = 100.0 - workspace.rule.totalStrength workspace.assessTemperature()
values = ( (workspace.totalUnhappiness, 0.8), (ruleWeakness, 0.2), ) ruleWeakness = 100.0
slightly_above_actual_temperature = formulas.actualTemperature + 0.001 if workspace.rule:
logging.info('actualTemperature: %f' % slightly_above_actual_temperature) workspace.rule.updateStrength()
formulas.actualTemperature = formulas.weightedAverage(values) ruleWeakness = 100.0 - workspace.rule.totalStrength
logging.info('unhappiness: %f, weakness: %f, actualTemperature: %f' % ( values = ((workspace.totalUnhappiness, 0.8), (ruleWeakness, 0.2))
workspace.totalUnhappiness + 0.001, ruleWeakness + 0.001, formulas.actualTemperature + 0.001)) slightly_above_actual_temperature = formulas.actualTemperature + 0.001
if temperature.clamped: logging.info('actualTemperature: %f' % slightly_above_actual_temperature)
formulas.actualTemperature = 100.0 formulas.actualTemperature = formulas.weightedAverage(values)
logging.info('actualTemperature: %f' % (formulas.actualTemperature + 0.001)) logging.info('unhappiness: %f, weakness: %f, actualTemperature: %f' % (
temperature.update(formulas.actualTemperature) workspace.totalUnhappiness + 0.001, ruleWeakness + 0.001, formulas.actualTemperature + 0.001))
if not self.clampTemperature: if temperature.clamped:
formulas.Temperature = formulas.actualTemperature formulas.actualTemperature = 100.0
temperature.update(formulas.Temperature) logging.info('actualTemperature: %f' % (formulas.actualTemperature + 0.001))
temperature.update(formulas.actualTemperature)
if not self.clampTemperature:
formulas.Temperature = formulas.actualTemperature
temperature.update(formulas.Temperature)
workspaceFormulas = WorkspaceFormulas() workspaceFormulas = WorkspaceFormulas()
def numberOfObjects():
return len(workspace.objects)
def chooseUnmodifiedObject(attribute,inObjects): def numberOfObjects():
objects = [ o for o in inObjects if o.string != workspace.modified ] return len(workspace.objects)
if not len(objects):
print 'no objects available in initial or target strings'
return formulas.chooseObjectFromList(objects,attribute) def chooseUnmodifiedObject(attribute, inObjects):
objects = [o for o in inObjects if o.string != workspace.modified]
if not len(objects):
print 'no objects available in initial or target strings'
return formulas.chooseObjectFromList(objects, attribute)
def chooseNeighbour(source): def chooseNeighbour(source):
objects = [] objects = []
for objekt in workspace.objects: for objekt in workspace.objects:
if objekt.string != source.string: if objekt.string != source.string:
continue continue
if objekt.leftStringPosition == source.rightStringPosition + 1: if objekt.leftStringPosition == source.rightStringPosition + 1:
objects += [ objekt ] objects += [objekt]
elif source.leftStringPosition == objekt.rightStringPosition + 1: elif source.leftStringPosition == objekt.rightStringPosition + 1:
objects += [ objekt ] objects += [objekt]
return formulas.chooseObjectFromList(objects,"intraStringSalience") return formulas.chooseObjectFromList(objects, "intraStringSalience")
def chooseDirectedNeighbor(source, direction):
if direction == slipnet.left:
logging.info('Left')
return __chooseLeftNeighbor(source)
logging.info('Right')
return __chooseRightNeighbor(source)
def chooseDirectedNeighbor(source,direction):
if direction == slipnet.left:
logging.info('Left')
return __chooseLeftNeighbor(source)
logging.info('Right')
return __chooseRightNeighbor(source)
def __chooseLeftNeighbor(source): def __chooseLeftNeighbor(source):
objects = [] objects = []
for o in workspace.objects: for o in workspace.objects:
if o.string == source.string : if o.string == source.string:
if source.leftStringPosition == o.rightStringPosition + 1: if source.leftStringPosition == o.rightStringPosition + 1:
logging.info('%s is on left of %s' % (o,source)) logging.info('%s is on left of %s' % (o, source))
objects += [ o ] objects += [o]
else: else:
logging.info('%s is not on left of %s' % (o,source)) logging.info('%s is not on left of %s' % (o, source))
logging.info('Number of left objects: %s' % len(objects)) logging.info('Number of left objects: %s' % len(objects))
return formulas.chooseObjectFromList(objects,'intraStringSalience') return formulas.chooseObjectFromList(objects, 'intraStringSalience')
def __chooseRightNeighbor(source): def __chooseRightNeighbor(source):
objects = [ o for o in workspace.objects if objects = [o for o in workspace.objects if
o.string == source.string and o.string == source.string and
o.leftStringPosition == source.rightStringPosition + 1 o.leftStringPosition == source.rightStringPosition + 1
] ]
return formulas.chooseObjectFromList(objects,'intraStringSalience') return formulas.chooseObjectFromList(objects, 'intraStringSalience')
def chooseBondFacet(source, destination): def chooseBondFacet(source, destination):
sourceFacets = [ d.descriptionType for d in source.descriptions if d.descriptionType in slipnet.bondFacets ] sourceFacets = [d.descriptionType for d in source.descriptions if d.descriptionType in slipnet.bondFacets]
bondFacets = [ d.descriptionType for d in destination.descriptions if d.descriptionType in sourceFacets ] bondFacets = [d.descriptionType for d in destination.descriptions if d.descriptionType in sourceFacets]
if not bondFacets: if not bondFacets:
return None return None
supports = [ __supportForDescriptionType(f,source.string) for f in bondFacets ] supports = [__supportForDescriptionType(f, source.string) for f in bondFacets]
i = formulas.selectListPosition(supports) i = formulas.selectListPosition(supports)
return bondFacets[ i ] return bondFacets[i]
def __supportForDescriptionType(descriptionType,string):
return ( descriptionType.activation + __descriptionTypeSupport(descriptionType,string) ) / 2
def __descriptionTypeSupport(descriptionType,string): def __supportForDescriptionType(descriptionType, string):
"""The proportion of objects in the string that have a description with this descriptionType""" return (descriptionType.activation + __descriptionTypeSupport(descriptionType, string)) / 2
numberOfObjects = totalNumberOfObjects = 0.0
for objekt in workspace.objects:
if objekt.string == string: def __descriptionTypeSupport(descriptionType, string):
totalNumberOfObjects += 1.0 """The proportion of objects in the string that have a description with this descriptionType"""
for description in objekt.descriptions: numberOfObjects = totalNumberOfObjects = 0.0
if description.descriptionType == descriptionType: for objekt in workspace.objects:
numberOfObjects += 1.0 if objekt.string == string:
return numberOfObjects / totalNumberOfObjects totalNumberOfObjects += 1.0
for description in objekt.descriptions:
if description.descriptionType == descriptionType:
numberOfObjects += 1.0
return numberOfObjects / totalNumberOfObjects
def probabilityOfPosting(codeletName): def probabilityOfPosting(codeletName):
if codeletName == 'breaker': if codeletName == 'breaker':
return 1.0 return 1.0
if 'description' in codeletName: if 'description' in codeletName:
result = ( formulas.Temperature / 100.0 ) ** 2 result = (formulas.Temperature / 100.0) ** 2
else: else:
result = workspace.intraStringUnhappiness / 100.0 result = workspace.intraStringUnhappiness / 100.0
if 'correspondence' in codeletName: if 'correspondence' in codeletName:
result = workspace.interStringUnhappiness / 100.0 result = workspace.interStringUnhappiness / 100.0
if 'replacement' in codeletName: if 'replacement' in codeletName:
if workspace.numberOfUnreplacedObjects() > 0: if workspace.numberOfUnreplacedObjects() > 0:
return 1.0 return 1.0
return 0.0 return 0.0
if 'rule' in codeletName: if 'rule' in codeletName:
if not workspace.rule: if not workspace.rule:
return 1.0 return 1.0
return workspace.rule.totalWeakness() / 100.0 return workspace.rule.totalWeakness() / 100.0
if 'translator' in codeletName: if 'translator' in codeletName:
if not workspace.rule: if not workspace.rule:
assert 0 assert 0
return 0.0 return 0.0
assert 0 assert 0
return 1.0 return 1.0
return result return result
def howManyToPost(codeletName): def howManyToPost(codeletName):
if codeletName == 'breaker': if codeletName == 'breaker':
return 1 return 1
if 'description' in codeletName: if 'description' in codeletName:
return 1 return 1
if 'translator' in codeletName: if 'translator' in codeletName:
if not workspace.rule: if not workspace.rule:
return 0 return 0
return 1 return 1
if 'rule' in codeletName: if 'rule' in codeletName:
return 2 return 2
if 'group' in codeletName and not workspace.numberOfBonds(): if 'group' in codeletName and not workspace.numberOfBonds():
return 0 return 0
if 'replacement' in codeletName and workspace.rule: if 'replacement' in codeletName and workspace.rule:
return 0 return 0
number = 0 number = 0
if 'bond' in codeletName: if 'bond' in codeletName:
number = workspace.numberOfUnrelatedObjects() number = workspace.numberOfUnrelatedObjects()
# print 'post number of unrelated: %d, objects: %d' % (number,len(workspace.objects)) # print 'post number of unrelated: %d, objects: %d' % (number,len(workspace.objects))
if 'group' in codeletName: if 'group' in codeletName:
number = workspace.numberOfUngroupedObjects() number = workspace.numberOfUngroupedObjects()
if 'replacement' in codeletName: if 'replacement' in codeletName:
number = workspace.numberOfUnreplacedObjects() number = workspace.numberOfUnreplacedObjects()
if 'correspondence' in codeletName: if 'correspondence' in codeletName:
number = workspace.numberOfUncorrespondingObjects() number = workspace.numberOfUncorrespondingObjects()
if number < formulas.blur(2.0): if number < formulas.blur(2.0):
return 1 return 1
if number < formulas.blur(4.0): if number < formulas.blur(4.0):
return 2 return 2
return 3 return 3

View File

@ -4,223 +4,223 @@ from description import Description
from slipnet import slipnet from slipnet import slipnet
from workspaceStructure import WorkspaceStructure from workspaceStructure import WorkspaceStructure
class WorkspaceObject(WorkspaceStructure): class WorkspaceObject(WorkspaceStructure):
def __init__(self,workspaceString): def __init__(self, workspaceString):
WorkspaceStructure.__init__(self) WorkspaceStructure.__init__(self)
self.string = workspaceString self.string = workspaceString
#self.string.objects += [ self ] #self.string.objects += [ self ]
self.descriptions = [] self.descriptions = []
self.extrinsicDescriptions = [] self.extrinsicDescriptions = []
self.incomingBonds = [] self.incomingBonds = []
self.outgoingBonds = [] self.outgoingBonds = []
self.bonds = [] self.bonds = []
self.group = None self.group = None
self.changed = None self.changed = None
self.correspondence = None self.correspondence = None
self.clampSalience = False self.clampSalience = False
self.rawImportance = 0.0 self.rawImportance = 0.0
self.relativeImportance = 0.0 self.relativeImportance = 0.0
self.leftBond = None self.leftBond = None
self.rightBond = None self.rightBond = None
self.newAnswerLetter = False self.newAnswerLetter = False
self.name = '' self.name = ''
self.replacement = None self.replacement = None
self.rightStringPosition = 0 self.rightStringPosition = 0
self.leftStringPosition = 0 self.leftStringPosition = 0
self.leftmost = False self.leftmost = False
self.rightmost = False self.rightmost = False
self.intraStringSalience = 0.0 self.intraStringSalience = 0.0
self.interStringSalience = 0.0 self.interStringSalience = 0.0
self.totalSalience = 0.0 self.totalSalience = 0.0
self.intraStringUnhappiness = 0.0 self.intraStringUnhappiness = 0.0
self.interStringUnhappiness = 0.0 self.interStringUnhappiness = 0.0
self.totalUnhappiness = 0.0 self.totalUnhappiness = 0.0
def __str__(self): def __str__(self):
return 'object' return 'object'
def spansString(self): def spansString(self):
return self.leftmost and self.rightmost return self.leftmost and self.rightmost
def addDescription(self,descriptionType,descriptor): def addDescription(self, descriptionType, descriptor):
description = Description(self,descriptionType,descriptor) description = Description(self, descriptionType, descriptor)
logging.info("Adding description: %s to %s" % (description,self)) logging.info("Adding description: %s to %s" % (description, self))
self.descriptions += [ description ] self.descriptions += [description]
def addDescriptions(self,descriptions): def addDescriptions(self, descriptions):
#print 'addDescriptions 1' #print 'addDescriptions 1'
#print 'add %d to %d of %s' % (len(descriptions),len(self.descriptions), self.string.string) #print 'add %d to %d of %s' % (len(descriptions),len(self.descriptions), self.string.string)
copy = descriptions[:] # in case we add to our own descriptions, which turns the loop infinite copy = descriptions[:] # in case we add to our own descriptions, which turns the loop infinite
for description in copy: for description in copy:
#print '%d addDescriptions 2 %s ' % (len(descriptions),description) #print '%d addDescriptions 2 %s ' % (len(descriptions),description)
logging.info('might add: %s' % description) logging.info('might add: %s' % description)
if not self.containsDescription(description): if not self.containsDescription(description):
#print '%d addDescriptions 3 %s ' % (len(descriptions),description) #print '%d addDescriptions 3 %s ' % (len(descriptions),description)
self.addDescription(description.descriptionType,description.descriptor) self.addDescription(description.descriptionType, description.descriptor)
#print '%d addDescriptions 4 %s ' % (len(descriptions),description) #print '%d addDescriptions 4 %s ' % (len(descriptions),description)
else: else:
logging.info("Won't add it") logging.info("Won't add it")
#print '%d added, have %d ' % (len(descriptions),len(self.descriptions)) #print '%d added, have %d ' % (len(descriptions),len(self.descriptions))
from workspace import workspace from workspace import workspace
workspace.buildDescriptions(self) workspace.buildDescriptions(self)
def __calculateIntraStringHappiness(self): def __calculateIntraStringHappiness(self):
if self.spansString(): if self.spansString():
return 100.0 return 100.0
if self.group: if self.group:
return self.group.totalStrength return self.group.totalStrength
bondStrength = 0.0 bondStrength = 0.0
for bond in self.bonds: for bond in self.bonds:
bondStrength += bond.totalStrength bondStrength += bond.totalStrength
divisor = 6.0 divisor = 6.0
if self.spansString(): # XXX then we have already returned if self.spansString(): # XXX then we have already returned
divisor = 3.0 divisor = 3.0
return bondStrength / divisor return bondStrength / divisor
def __calculateRawImportance(self): def __calculateRawImportance(self):
"""Calculate the raw importance of this object. """Calculate the raw importance of this object.
Which is the sum of all relevant descriptions""" Which is the sum of all relevant descriptions"""
result = 0.0 result = 0.0
for description in self.descriptions: for description in self.descriptions:
if description.descriptionType.fully_active(): if description.descriptionType.fully_active():
result += description.descriptor.activation result += description.descriptor.activation
else: else:
result += description.descriptor.activation / 20.0 result += description.descriptor.activation / 20.0
if self.group: if self.group:
result *= 2.0 / 3.0 result *= 2.0 / 3.0
if self.changed: if self.changed:
result *= 2.0 result *= 2.0
return result return result
def updateValue(self): def updateValue(self):
self.rawImportance = self.__calculateRawImportance() self.rawImportance = self.__calculateRawImportance()
intraStringHappiness = self.__calculateIntraStringHappiness() intraStringHappiness = self.__calculateIntraStringHappiness()
self.intraStringUnhappiness = 100.0 - intraStringHappiness self.intraStringUnhappiness = 100.0 - intraStringHappiness
interStringHappiness = 0.0 interStringHappiness = 0.0
if self.correspondence: if self.correspondence:
interStringHappiness = self.correspondence.totalStrength interStringHappiness = self.correspondence.totalStrength
self.interStringUnhappiness = 100.0 - interStringHappiness self.interStringUnhappiness = 100.0 - interStringHappiness
#logging.info("Unhappy: %s"%self.interStringUnhappiness) #logging.info("Unhappy: %s"%self.interStringUnhappiness)
averageHappiness = ( intraStringHappiness + interStringHappiness ) / 2 averageHappiness = (intraStringHappiness + interStringHappiness) / 2
self.totalUnhappiness = 100.0 - averageHappiness self.totalUnhappiness = 100.0 - averageHappiness
if self.clampSalience: if self.clampSalience:
self.intraStringSalience = 100.0 self.intraStringSalience = 100.0
self.interStringSalience = 100.0 self.interStringSalience = 100.0
else: else:
from formulas import weightedAverage from formulas import weightedAverage
self.intraStringSalience = weightedAverage( ((self.relativeImportance,0.2), (self.intraStringUnhappiness,0.8)) ) self.intraStringSalience = weightedAverage(((self.relativeImportance, 0.2), (self.intraStringUnhappiness, 0.8)))
self.interStringSalience = weightedAverage( ((self.relativeImportance,0.8), (self.interStringUnhappiness,0.2)) ) self.interStringSalience = weightedAverage(((self.relativeImportance, 0.8), (self.interStringUnhappiness, 0.2)))
self.totalSalience = (self.intraStringSalience + self.interStringSalience) / 2.0 self.totalSalience = (self.intraStringSalience + self.interStringSalience) / 2.0
logging.info('Set salience of %s to %f = (%f + %f)/2' % ( logging.info('Set salience of %s to %f = (%f + %f)/2' % (
self.__str__(),self.totalSalience, self.intraStringSalience, self.interStringSalience)) self.__str__(), self.totalSalience, self.intraStringSalience, self.interStringSalience))
def isWithin(self,other): def isWithin(self, other):
return self.leftStringPosition >= other.leftStringPosition and self.rightStringPosition <= other.rightStringPosition return self.leftStringPosition >= other.leftStringPosition and self.rightStringPosition <= other.rightStringPosition
def relevantDescriptions(self): def relevantDescriptions(self):
return [ d for d in self.descriptions if d.descriptionType.fully_active() ] return [d for d in self.descriptions if d.descriptionType.fully_active()]
def morePossibleDescriptions(self,node): def morePossibleDescriptions(self, node):
return [] return []
def getPossibleDescriptions(self,descriptionType): def getPossibleDescriptions(self, descriptionType):
logging.info('getting possible descriptions for %s' % self) logging.info('getting possible descriptions for %s' % self)
descriptions = [ ] descriptions = []
from group import Group from group import Group
for link in descriptionType.instanceLinks: for link in descriptionType.instanceLinks:
node = link.destination node = link.destination
if node == slipnet.first and self.hasDescription(slipnet.letters[0]): if node == slipnet.first and self.hasDescription(slipnet.letters[0]):
descriptions += [ node ] descriptions += [node]
if node == slipnet.last and self.hasDescription(slipnet.letters[-1]): if node == slipnet.last and self.hasDescription(slipnet.letters[-1]):
descriptions += [ node ] descriptions += [node]
i = 1 i = 1
for number in slipnet.numbers: for number in slipnet.numbers:
if node == number and isinstance(self,Group) and len(self.objectList) == i: if node == number and isinstance(self, Group) and len(self.objectList) == i:
descriptions += [ node ] descriptions += [node]
i += 1 i += 1
if node == slipnet.middle and self.middleObject(): if node == slipnet.middle and self.middleObject():
descriptions += [ node ] descriptions += [node]
s = '' s = ''
for d in descriptions: for d in descriptions:
s = '%s, %s' % (s,d.get_name()) s = '%s, %s' % (s, d.get_name())
logging.info(s) logging.info(s)
return descriptions return descriptions
def containsDescription(self,sought): def containsDescription(self, sought):
soughtType = sought.descriptionType soughtType = sought.descriptionType
soughtDescriptor = sought.descriptor soughtDescriptor = sought.descriptor
for d in self.descriptions: for d in self.descriptions:
if soughtType == d.descriptionType and soughtDescriptor == d.descriptor: if soughtType == d.descriptionType and soughtDescriptor == d.descriptor:
return True return True
return False return False
def hasDescription(self,slipnode): def hasDescription(self, slipnode):
return [ d for d in self.descriptions if d.descriptor == slipnode ] and True or False return [d for d in self.descriptions if d.descriptor == slipnode] and True or False
def middleObject(self): def middleObject(self):
# XXX only works if string is 3 chars long # XXX only works if string is 3 chars long
# as we have access to the string, why not just " == len / 2" ? # as we have access to the string, why not just " == len / 2" ?
objectOnMyRightIsRightmost = objectOnMyLeftIsLeftmost = False objectOnMyRightIsRightmost = objectOnMyLeftIsLeftmost = False
for objekt in self.string.objects: for objekt in self.string.objects:
if objekt.leftmost and objekt.rightStringPosition == self.leftStringPosition - 1: if objekt.leftmost and objekt.rightStringPosition == self.leftStringPosition - 1:
objectOnMyLeftIsLeftmost = True objectOnMyLeftIsLeftmost = True
if objekt.rightmost and objekt.leftStringPosition == self.rightStringPosition + 1: if objekt.rightmost and objekt.leftStringPosition == self.rightStringPosition + 1:
objectOnMyRightIsRightmost = True objectOnMyRightIsRightmost = True
return objectOnMyRightIsRightmost and objectOnMyLeftIsLeftmost return objectOnMyRightIsRightmost and objectOnMyLeftIsLeftmost
def distinguishingDescriptor(self,descriptor): def distinguishingDescriptor(self, descriptor):
"""Whether no other object of the same type (ie. letter or group) has the same descriptor""" """Whether no other object of the same type (ie. letter or group) has the same descriptor"""
if descriptor == slipnet.letter: if descriptor == slipnet.letter:
return False return False
if descriptor == slipnet.group: if descriptor == slipnet.group:
return False return False
for number in slipnet.numbers: for number in slipnet.numbers:
if number == descriptor: if number == descriptor:
return False return False
return True return True
def relevantDistinguishingDescriptors(self): def relevantDistinguishingDescriptors(self):
return [ d.descriptor for d in self.relevantDescriptions() if self.distinguishingDescriptor(d.descriptor) ] return [d.descriptor for d in self.relevantDescriptions() if self.distinguishingDescriptor(d.descriptor)]
def getDescriptor(self,descriptionType): def getDescriptor(self, descriptionType):
"""The description attached to this object of the specified description type.""" """The description attached to this object of the specified description type."""
descriptor = None 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: for description in self.descriptions:
logging.info("Trying description: %s" % description) logging.info("Trying description: %s" % description)
if description.descriptionType == descriptionType: if description.descriptionType == descriptionType:
return description.descriptor return description.descriptor
return descriptor return descriptor
def getDescriptionType(self,sought_description): def getDescriptionType(self, sought_description):
"""The description_type attached to this object of the specified description""" """The description_type attached to this object of the specified description"""
for description in self.descriptions: for description in self.descriptions:
if description.descriptor == sought_description: if description.descriptor == sought_description:
return description.descriptionType return description.descriptionType
description = None description = None
return description return description
def getCommonGroups(self,other): 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): def letterDistance(self, other):
if other.leftStringPosition > self.rightStringPosition: if other.leftStringPosition > self.rightStringPosition:
return other.leftStringPosition - self.rightStringPosition return other.leftStringPosition - self.rightStringPosition
if self.leftStringPosition > other.rightStringPosition: if self.leftStringPosition > other.rightStringPosition:
return self.leftStringPosition - other.rightStringPosition return self.leftStringPosition - other.rightStringPosition
return 0 return 0
def letterSpan(self): def letterSpan(self):
return self.rightStringPosition - self.leftStringPosition + 1 return self.rightStringPosition - self.leftStringPosition + 1
def beside(self,other):
if self.string != other.string:
return False
if self.leftStringPosition == other.rightStringPosition + 1:
return True
return other.leftStringPosition == self.rightStringPosition + 1
def beside(self, other):
if self.string != other.string:
return False
if self.leftStringPosition == other.rightStringPosition + 1:
return True
return other.leftStringPosition == self.rightStringPosition + 1

View File

@ -2,79 +2,80 @@ import logging
from letter import Letter from letter import Letter
from slipnet import slipnet from slipnet import slipnet
class WorkspaceString(object): class WorkspaceString(object):
def __init__(self, s): def __init__(self, s):
self.string = s self.string = s
self.bonds = [] self.bonds = []
self.objects = [] self.objects = []
self.letters = [] self.letters = []
self.length = len(s) self.length = len(s)
self.intraStringUnhappiness = 0.0 self.intraStringUnhappiness = 0.0
if not self.length: if not self.length:
return return
position = 0 position = 0
from workspace import workspace from workspace import workspace
for c in self.string.upper(): for c in self.string.upper():
value = ord(c) - ord('A') value = ord(c) - ord('A')
letter = Letter(self, position + 1, self.length) letter = Letter(self, position + 1, self.length)
letter.workspaceString = self letter.workspaceString = self
letter.addDescription(slipnet.objectCategory, slipnet.letter) 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) letter.describe(position + 1, self.length)
workspace.buildDescriptions(letter) workspace.buildDescriptions(letter)
self.letters += [letter] self.letters += [letter]
position += 1 position += 1
def __repr__(self): def __repr__(self):
return '<WorkspaceString: %s>' % self.string return '<WorkspaceString: %s>' % self.string
def __str__(self): 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): def log(self, heading):
s = '%s: %s - ' % (heading, self) s = '%s: %s - ' % (heading, self)
for l in self.letters: for l in self.letters:
s += ' %s' % l s += ' %s' % l
s += '; ' s += '; '
for o in self.objects: for o in self.objects:
s += ' %s' % o s += ' %s' % o
s += '; ' s += '; '
for b in self.bonds: for b in self.bonds:
s += ' %s' % b s += ' %s' % b
s += '.' s += '.'
logging.info(s) logging.info(s)
def __len__(self): def __len__(self):
return len(self.string) return len(self.string)
def __getitem__(self, i): def __getitem__(self, i):
return self.string[i] return self.string[i]
def updateRelativeImportance(self): def updateRelativeImportance(self):
"""Update the normalised importance of all objects in the string""" """Update the normalised importance of all objects in the string"""
total = sum([o.rawImportance for o in self.objects]) total = sum([o.rawImportance for o in self.objects])
if not total: if not total:
for o in self.objects: for o in self.objects:
o.relativeImportance = 0.0 o.relativeImportance = 0.0
else: else:
for o in self.objects: for o in self.objects:
logging.info('object: %s, relative: %d = raw: %d / total: %d' % ( logging.info('object: %s, relative: %d = raw: %d / total: %d' % (
o, o.relativeImportance * 1000, o.rawImportance, total )) o, o.relativeImportance * 1000, o.rawImportance, total))
o.relativeImportance = o.rawImportance / total o.relativeImportance = o.rawImportance / total
def updateIntraStringUnhappiness(self): def updateIntraStringUnhappiness(self):
if not len(self.objects): if not len(self.objects):
self.intraStringUnhappiness = 0.0 self.intraStringUnhappiness = 0.0
return return
total = sum([o.intraStringUnhappiness for o in self.objects]) total = sum([o.intraStringUnhappiness for o in self.objects])
self.intraStringUnhappiness = total / len(self.objects) self.intraStringUnhappiness = total / len(self.objects)
def equivalentGroup(self, sought): def equivalentGroup(self, sought):
from group import Group from group import Group
for objekt in self.objects: for objekt in self.objects:
if isinstance(objekt, Group): if isinstance(objekt, Group):
if objekt.sameGroup(sought): if objekt.sameGroup(sought):
return objekt return objekt
return None return None

View File

@ -1,37 +1,38 @@
import formulas import formulas
class WorkspaceStructure(object): class WorkspaceStructure(object):
def __init__(self): def __init__(self):
self.string = None self.string = None
self.internalStrength = 0.0 self.internalStrength = 0.0
self.externalStrength = 0.0 self.externalStrength = 0.0
self.totalStrength = 0.0 self.totalStrength = 0.0
def updateStrength(self): def updateStrength(self):
self.updateInternalStrength() self.updateInternalStrength()
self.updateExternalStrength() self.updateExternalStrength()
self.updateTotalStrength() self.updateTotalStrength()
def updateTotalStrength(self): def updateTotalStrength(self):
"""Recalculate the total strength based on internal and external strengths""" """Recalculate the total strength based on internal and external strengths"""
weights = ( (self.internalStrength, self.internalStrength), (self.externalStrength, 100 - self.internalStrength) ) weights = ((self.internalStrength, self.internalStrength), (self.externalStrength, 100 - self.internalStrength))
strength = formulas.weightedAverage(weights) strength = formulas.weightedAverage(weights)
self.totalStrength = strength self.totalStrength = strength
def totalWeakness(self): def totalWeakness(self):
"""The total weakness is derived from total strength""" """The total weakness is derived from total strength"""
return 100 - self.totalStrength ** 0.95 return 100 - self.totalStrength ** 0.95
def updateInternalStrength(self): def updateInternalStrength(self):
"""How internally cohesive the structure is""" """How internally cohesive the structure is"""
raise NotImplementedError, 'call of abstract method: WorkspaceStructure.updateInternalStrength()' raise NotImplementedError('call of abstract method: WorkspaceStructure.updateInternalStrength()')
def updateExternalStrength(self): def updateExternalStrength(self):
raise NotImplementedError, 'call of abstract method: WorkspaceStructure.updateExternalStrength()' raise NotImplementedError('call of abstract method: WorkspaceStructure.updateExternalStrength()')
def break_the_structure(self): def break_the_structure(self):
"""Break this workspace structure """Break this workspace structure
Exactly what is broken depends on sub-class Exactly what is broken depends on sub-class
""" """
raise NotImplementedError, 'call of abstract method: WorkspaceStructure.break_the_structure()' raise NotImplementedError('call of abstract method: WorkspaceStructure.break_the_structure()')