Files
copycat/copycat/correspondence.py
James Tauber cfaebd150f tabs to spaces
2012-11-30 02:12:44 -05:00

190 lines
7.6 KiB
Python

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