Merge pull request #3 from jtauber/master
improved PEP compliance and fixed errors preventing it from running
This commit is contained in:
@ -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.
|
||||||
|
|
||||||
|
|||||||
314
copycat/bond.py
314
copycat/bond.py
@ -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
|
||||||
|
|||||||
@ -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
@ -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()
|
||||||
|
|||||||
@ -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()
|
||||||
|
|||||||
@ -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
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -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()
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
413
copycat/group.py
413
copycat/group.py
@ -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
|
||||||
|
|||||||
@ -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()
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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:]))
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
240
copycat/rule.py
240
copycat/rule.py
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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()
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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()
|
||||||
|
|||||||
140
copycat/utils.py
140
copycat/utils.py
@ -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()
|
|
||||||
|
|
||||||
@ -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()
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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()')
|
||||||
|
|||||||
Reference in New Issue
Block a user