Major overhaul of "randomness" throughout.
- Nobody does `import random` anymore. - Random numbers are gotten from `ctx.random`, which is an object of type `Randomness` with all the convenience methods that used to be obnoxious functions in the `formulas` module. - Every place that was using `random.random()` to implement the equivalent of Python3 `random.choices(seq, weights)` has been updated to use `ctx.random.weighted_choice(seq, weights)`. This has a functional effect, since the details of random number generation have changed. The *statistical* effect should be small. I do observe that Copycat is having trouble inventing the "mrrjjjj" solution right now (even in 1000 test runs), so maybe something is slightly broken.
This commit is contained in:
@ -1,6 +1,5 @@
|
|||||||
import inspect
|
import inspect
|
||||||
import logging
|
import logging
|
||||||
import random
|
|
||||||
|
|
||||||
import formulas
|
import formulas
|
||||||
from workspaceFormulas import chooseDirectedNeighbor
|
from workspaceFormulas import chooseDirectedNeighbor
|
||||||
@ -37,7 +36,9 @@ def __showWhichStringObjectIsFrom(structure):
|
|||||||
#print 'object chosen = %s from %s string' % (structure, whence)
|
#print 'object chosen = %s from %s string' % (structure, whence)
|
||||||
|
|
||||||
|
|
||||||
def __getScoutSource(workspace, slipnode, relevanceMethod, typeName):
|
def __getScoutSource(ctx, slipnode, relevanceMethod, typeName):
|
||||||
|
random = ctx.random
|
||||||
|
workspace = ctx.workspace
|
||||||
initialRelevance = relevanceMethod(workspace.initial, slipnode)
|
initialRelevance = relevanceMethod(workspace.initial, slipnode)
|
||||||
targetRelevance = relevanceMethod(workspace.target, slipnode)
|
targetRelevance = relevanceMethod(workspace.target, slipnode)
|
||||||
initialUnhappiness = workspace.initial.intraStringUnhappiness
|
initialUnhappiness = workspace.initial.intraStringUnhappiness
|
||||||
@ -47,11 +48,9 @@ def __getScoutSource(workspace, slipnode, relevanceMethod, typeName):
|
|||||||
logging.info('target : relevance = %d, unhappiness=%d',
|
logging.info('target : relevance = %d, unhappiness=%d',
|
||||||
targetRelevance, int(targetUnhappiness))
|
targetRelevance, int(targetUnhappiness))
|
||||||
string = workspace.initial
|
string = workspace.initial
|
||||||
relevances = initialRelevance + targetRelevance
|
|
||||||
unhappinesses = initialUnhappiness + targetUnhappiness
|
|
||||||
randomized = random.random() * (relevances + unhappinesses)
|
|
||||||
initials = initialRelevance + initialUnhappiness
|
initials = initialRelevance + initialUnhappiness
|
||||||
if randomized > initials:
|
targets = targetRelevance + targetUnhappiness
|
||||||
|
if random.weighted_greater_than(targets, initials):
|
||||||
string = workspace.target
|
string = workspace.target
|
||||||
logging.info('target string selected: %s for %s',
|
logging.info('target string selected: %s for %s',
|
||||||
workspace.target, typeName)
|
workspace.target, typeName)
|
||||||
@ -76,7 +75,9 @@ def __getDescriptors(bondFacet, source, destination):
|
|||||||
|
|
||||||
|
|
||||||
def __structureVsStructure(structure1, weight1, structure2, weight2):
|
def __structureVsStructure(structure1, weight1, structure2, weight2):
|
||||||
|
"""Return true if the first structure comes out stronger than the second."""
|
||||||
ctx = structure1.ctx
|
ctx = structure1.ctx
|
||||||
|
random = ctx.random
|
||||||
temperature = ctx.temperature
|
temperature = ctx.temperature
|
||||||
structure1.updateStrength()
|
structure1.updateStrength()
|
||||||
structure2.updateStrength()
|
structure2.updateStrength()
|
||||||
@ -84,9 +85,7 @@ def __structureVsStructure(structure1, weight1, structure2, weight2):
|
|||||||
structure1.totalStrength * weight1)
|
structure1.totalStrength * weight1)
|
||||||
weightedStrength2 = temperature.getAdjustedValue(
|
weightedStrength2 = temperature.getAdjustedValue(
|
||||||
structure2.totalStrength * weight2)
|
structure2.totalStrength * weight2)
|
||||||
rhs = (weightedStrength1 + weightedStrength2) * random.random()
|
return random.weighted_greater_than(weightedStrength1, weightedStrength2)
|
||||||
logging.info('%d > %d', weightedStrength1, rhs)
|
|
||||||
return weightedStrength1 > rhs
|
|
||||||
|
|
||||||
|
|
||||||
def __fight(structure, structureWeight, incompatibles, incompatibleWeight):
|
def __fight(structure, structureWeight, incompatibles, incompatibleWeight):
|
||||||
@ -115,21 +114,23 @@ def __fightIncompatibles(incompatibles, structure, name,
|
|||||||
|
|
||||||
|
|
||||||
def __slippability(ctx, conceptMappings):
|
def __slippability(ctx, conceptMappings):
|
||||||
|
random = ctx.random
|
||||||
temperature = ctx.temperature
|
temperature = ctx.temperature
|
||||||
for mapping in conceptMappings:
|
for mapping in conceptMappings:
|
||||||
slippiness = mapping.slippability() / 100.0
|
slippiness = mapping.slippability() / 100.0
|
||||||
probabilityOfSlippage = temperature.getAdjustedProbability(slippiness)
|
probabilityOfSlippage = temperature.getAdjustedProbability(slippiness)
|
||||||
if formulas.coinFlip(probabilityOfSlippage):
|
if random.coinFlip(probabilityOfSlippage):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
@codelet('breaker')
|
@codelet('breaker')
|
||||||
def breaker(ctx, codelet):
|
def breaker(ctx, codelet):
|
||||||
|
random = ctx.random
|
||||||
temperature = ctx.temperature
|
temperature = ctx.temperature
|
||||||
workspace = ctx.workspace
|
workspace = ctx.workspace
|
||||||
probabilityOfFizzle = (100.0 - temperature.value()) / 100.0
|
probabilityOfFizzle = (100.0 - temperature.value()) / 100.0
|
||||||
if formulas.coinFlip(probabilityOfFizzle):
|
if random.coinFlip(probabilityOfFizzle):
|
||||||
return
|
return
|
||||||
# choose a structure at random
|
# choose a structure at random
|
||||||
structures = [s for s in workspace.structures if
|
structures = [s for s in workspace.structures if
|
||||||
@ -146,18 +147,28 @@ def breaker(ctx, codelet):
|
|||||||
for structure in breakObjects:
|
for structure in breakObjects:
|
||||||
breakProbability = temperature.getAdjustedProbability(
|
breakProbability = temperature.getAdjustedProbability(
|
||||||
structure.totalStrength / 100.0)
|
structure.totalStrength / 100.0)
|
||||||
if formulas.coinFlip(breakProbability):
|
if random.coinFlip(breakProbability):
|
||||||
return
|
return
|
||||||
for structure in breakObjects:
|
for structure in breakObjects:
|
||||||
structure.break_the_structure()
|
structure.break_the_structure()
|
||||||
|
|
||||||
|
|
||||||
def similarPropertyLinks(slip_node, temperature):
|
def chooseRelevantDescriptionByActivation(ctx, workspaceObject):
|
||||||
|
random = ctx.random
|
||||||
|
descriptions = workspaceObject.relevantDescriptions()
|
||||||
|
weights = [description.descriptor.activation
|
||||||
|
for description in descriptions]
|
||||||
|
return random.weighted_choice(descriptions, weights)
|
||||||
|
|
||||||
|
|
||||||
|
def similarPropertyLinks(ctx, slip_node):
|
||||||
|
random = ctx.random
|
||||||
|
temperature = ctx.temperature
|
||||||
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 = temperature.getAdjustedProbability(association)
|
probability = temperature.getAdjustedProbability(association)
|
||||||
if formulas.coinFlip(probability):
|
if random.coinFlip(probability):
|
||||||
result += [slip_link]
|
result += [slip_link]
|
||||||
return result
|
return result
|
||||||
|
|
||||||
@ -165,19 +176,21 @@ def similarPropertyLinks(slip_node, temperature):
|
|||||||
@codelet('bottom-up-description-scout')
|
@codelet('bottom-up-description-scout')
|
||||||
def bottom_up_description_scout(ctx, codelet):
|
def bottom_up_description_scout(ctx, codelet):
|
||||||
coderack = ctx.coderack
|
coderack = ctx.coderack
|
||||||
temperature = ctx.temperature
|
random = ctx.random
|
||||||
workspace = ctx.workspace
|
workspace = ctx.workspace
|
||||||
chosenObject = chooseUnmodifiedObject('totalSalience', workspace.objects)
|
chosenObject = chooseUnmodifiedObject('totalSalience', workspace.objects)
|
||||||
assert chosenObject
|
assert chosenObject
|
||||||
__showWhichStringObjectIsFrom(chosenObject)
|
__showWhichStringObjectIsFrom(chosenObject)
|
||||||
description = formulas.chooseRelevantDescriptionByActivation(chosenObject)
|
# choose relevant description by activation
|
||||||
|
descriptions = chosenObject.relevantDescriptions()
|
||||||
|
weights = [d.descriptor.activation for d in descriptions]
|
||||||
|
description = random.weighted_choice(descriptions, weights)
|
||||||
assert description
|
assert description
|
||||||
sliplinks = similarPropertyLinks(description.descriptor, temperature)
|
sliplinks = similarPropertyLinks(ctx, description.descriptor)
|
||||||
assert sliplinks
|
assert sliplinks
|
||||||
values = [sliplink.degreeOfAssociation() * sliplink.destination.activation
|
weights = [sliplink.degreeOfAssociation() * sliplink.destination.activation
|
||||||
for sliplink in sliplinks]
|
for sliplink in sliplinks]
|
||||||
i = formulas.selectListPosition(values)
|
chosen = random.weighted_choice(sliplinks, weights)
|
||||||
chosen = sliplinks[i]
|
|
||||||
chosenProperty = chosen.destination
|
chosenProperty = chosen.destination
|
||||||
coderack.proposeDescription(chosenObject, chosenProperty.category(),
|
coderack.proposeDescription(chosenObject, chosenProperty.category(),
|
||||||
chosenProperty, codelet)
|
chosenProperty, codelet)
|
||||||
@ -186,6 +199,7 @@ def bottom_up_description_scout(ctx, codelet):
|
|||||||
@codelet('top-down-description-scout')
|
@codelet('top-down-description-scout')
|
||||||
def top_down_description_scout(ctx, codelet):
|
def top_down_description_scout(ctx, codelet):
|
||||||
coderack = ctx.coderack
|
coderack = ctx.coderack
|
||||||
|
random = ctx.random
|
||||||
workspace = ctx.workspace
|
workspace = ctx.workspace
|
||||||
descriptionType = codelet.arguments[0]
|
descriptionType = codelet.arguments[0]
|
||||||
chosenObject = chooseUnmodifiedObject('totalSalience', workspace.objects)
|
chosenObject = chooseUnmodifiedObject('totalSalience', workspace.objects)
|
||||||
@ -193,9 +207,8 @@ def top_down_description_scout(ctx, codelet):
|
|||||||
__showWhichStringObjectIsFrom(chosenObject)
|
__showWhichStringObjectIsFrom(chosenObject)
|
||||||
descriptions = chosenObject.getPossibleDescriptions(descriptionType)
|
descriptions = chosenObject.getPossibleDescriptions(descriptionType)
|
||||||
assert descriptions and len(descriptions)
|
assert descriptions and len(descriptions)
|
||||||
values = [n.activation for n in descriptions]
|
weights = [n.activation for n in descriptions]
|
||||||
i = formulas.selectListPosition(values)
|
chosenProperty = random.weighted_choice(descriptions, weights)
|
||||||
chosenProperty = descriptions[i]
|
|
||||||
coderack.proposeDescription(chosenObject, chosenProperty.category(),
|
coderack.proposeDescription(chosenObject, chosenProperty.category(),
|
||||||
chosenProperty, codelet)
|
chosenProperty, codelet)
|
||||||
|
|
||||||
@ -203,13 +216,14 @@ def top_down_description_scout(ctx, codelet):
|
|||||||
@codelet('description-strength-tester')
|
@codelet('description-strength-tester')
|
||||||
def description_strength_tester(ctx, codelet):
|
def description_strength_tester(ctx, codelet):
|
||||||
coderack = ctx.coderack
|
coderack = ctx.coderack
|
||||||
|
random = ctx.random
|
||||||
temperature = ctx.temperature
|
temperature = ctx.temperature
|
||||||
description = codelet.arguments[0]
|
description = codelet.arguments[0]
|
||||||
description.descriptor.buffer = 100.0
|
description.descriptor.buffer = 100.0
|
||||||
description.updateStrength()
|
description.updateStrength()
|
||||||
strength = description.totalStrength
|
strength = description.totalStrength
|
||||||
probability = temperature.getAdjustedProbability(strength / 100.0)
|
probability = temperature.getAdjustedProbability(strength / 100.0)
|
||||||
assert formulas.coinFlip(probability)
|
assert random.coinFlip(probability)
|
||||||
coderack.newCodelet('description-builder', codelet, strength)
|
coderack.newCodelet('description-builder', codelet, strength)
|
||||||
|
|
||||||
|
|
||||||
@ -255,6 +269,7 @@ def bottom_up_bond_scout(ctx, codelet):
|
|||||||
@codelet('rule-scout')
|
@codelet('rule-scout')
|
||||||
def rule_scout(ctx, codelet):
|
def rule_scout(ctx, codelet):
|
||||||
coderack = ctx.coderack
|
coderack = ctx.coderack
|
||||||
|
random = ctx.random
|
||||||
slipnet = ctx.slipnet
|
slipnet = ctx.slipnet
|
||||||
temperature = ctx.temperature
|
temperature = ctx.temperature
|
||||||
workspace = ctx.workspace
|
workspace = ctx.workspace
|
||||||
@ -292,15 +307,13 @@ def rule_scout(ctx, codelet):
|
|||||||
newList += [node]
|
newList += [node]
|
||||||
objectList = newList # surely this should be +=
|
objectList = newList # surely this should be +=
|
||||||
# "union of this and distinguishing descriptors"
|
# "union of this and distinguishing descriptors"
|
||||||
assert objectList and len(objectList)
|
assert objectList
|
||||||
# use conceptual depth to choose a description
|
# use conceptual depth to choose a description
|
||||||
valueList = []
|
weights = [
|
||||||
for node in objectList:
|
temperature.getAdjustedValue(node.conceptualDepth)
|
||||||
depth = node.conceptualDepth
|
for node in objectList
|
||||||
value = temperature.getAdjustedValue(depth)
|
]
|
||||||
valueList += [value]
|
descriptor = random.weighted_choice(objectList, weights)
|
||||||
i = formulas.selectListPosition(valueList)
|
|
||||||
descriptor = objectList[i]
|
|
||||||
# choose the relation (change the letmost object to "successor" or "d"
|
# choose the relation (change the letmost object to "successor" or "d"
|
||||||
objectList = []
|
objectList = []
|
||||||
if changed.replacement.relation:
|
if changed.replacement.relation:
|
||||||
@ -308,13 +321,11 @@ def rule_scout(ctx, codelet):
|
|||||||
objectList += [changed.replacement.objectFromModified.getDescriptor(
|
objectList += [changed.replacement.objectFromModified.getDescriptor(
|
||||||
slipnet.letterCategory)]
|
slipnet.letterCategory)]
|
||||||
# use conceptual depth to choose a relation
|
# use conceptual depth to choose a relation
|
||||||
valueList = []
|
weights = [
|
||||||
for node in objectList:
|
temperature.getAdjustedValue(node.conceptualDepth)
|
||||||
depth = node.conceptualDepth
|
for node in objectList
|
||||||
value = temperature.getAdjustedValue(depth)
|
]
|
||||||
valueList += [value]
|
relation = random.weighted_choice(objectList, weights)
|
||||||
i = formulas.selectListPosition(valueList)
|
|
||||||
relation = objectList[i]
|
|
||||||
coderack.proposeRule(slipnet.letterCategory, descriptor,
|
coderack.proposeRule(slipnet.letterCategory, descriptor,
|
||||||
slipnet.letter, relation, codelet)
|
slipnet.letter, relation, codelet)
|
||||||
|
|
||||||
@ -322,16 +333,18 @@ def rule_scout(ctx, codelet):
|
|||||||
@codelet('rule-strength-tester')
|
@codelet('rule-strength-tester')
|
||||||
def rule_strength_tester(ctx, codelet):
|
def rule_strength_tester(ctx, codelet):
|
||||||
coderack = ctx.coderack
|
coderack = ctx.coderack
|
||||||
|
random = ctx.random
|
||||||
temperature = ctx.temperature
|
temperature = ctx.temperature
|
||||||
rule = codelet.arguments[0]
|
rule = codelet.arguments[0]
|
||||||
rule.updateStrength()
|
rule.updateStrength()
|
||||||
probability = temperature.getAdjustedProbability(rule.totalStrength / 100.0)
|
probability = temperature.getAdjustedProbability(rule.totalStrength / 100.0)
|
||||||
if formulas.coinFlip(probability):
|
if random.coinFlip(probability):
|
||||||
coderack.newCodelet('rule-builder', codelet, rule.totalStrength, rule)
|
coderack.newCodelet('rule-builder', codelet, rule.totalStrength, rule)
|
||||||
|
|
||||||
|
|
||||||
@codelet('replacement-finder')
|
@codelet('replacement-finder')
|
||||||
def replacement_finder(ctx, codelet):
|
def replacement_finder(ctx, codelet):
|
||||||
|
random = ctx.random
|
||||||
slipnet = ctx.slipnet
|
slipnet = ctx.slipnet
|
||||||
workspace = ctx.workspace
|
workspace = ctx.workspace
|
||||||
# choose random letter in initial string
|
# choose random letter in initial string
|
||||||
@ -374,10 +387,9 @@ def replacement_finder(ctx, codelet):
|
|||||||
def top_down_bond_scout__category(ctx, codelet):
|
def top_down_bond_scout__category(ctx, codelet):
|
||||||
coderack = ctx.coderack
|
coderack = ctx.coderack
|
||||||
slipnet = ctx.slipnet
|
slipnet = ctx.slipnet
|
||||||
workspace = ctx.workspace
|
|
||||||
logging.info('top_down_bond_scout__category')
|
logging.info('top_down_bond_scout__category')
|
||||||
category = codelet.arguments[0]
|
category = codelet.arguments[0]
|
||||||
source = __getScoutSource(workspace, category, formulas.localBondCategoryRelevance,
|
source = __getScoutSource(ctx, category, formulas.localBondCategoryRelevance,
|
||||||
'bond')
|
'bond')
|
||||||
destination = chooseNeighbor(source)
|
destination = chooseNeighbor(source)
|
||||||
logging.info('source: %s, destination: %s', source, destination)
|
logging.info('source: %s, destination: %s', source, destination)
|
||||||
@ -406,9 +418,8 @@ def top_down_bond_scout__category(ctx, codelet):
|
|||||||
def top_down_bond_scout__direction(ctx, codelet):
|
def top_down_bond_scout__direction(ctx, codelet):
|
||||||
coderack = ctx.coderack
|
coderack = ctx.coderack
|
||||||
slipnet = ctx.slipnet
|
slipnet = ctx.slipnet
|
||||||
workspace = ctx.workspace
|
|
||||||
direction = codelet.arguments[0]
|
direction = codelet.arguments[0]
|
||||||
source = __getScoutSource(workspace,
|
source = __getScoutSource(ctx,
|
||||||
direction, formulas.localDirectionCategoryRelevance, 'bond')
|
direction, formulas.localDirectionCategoryRelevance, 'bond')
|
||||||
destination = chooseDirectedNeighbor(source, direction)
|
destination = chooseDirectedNeighbor(source, direction)
|
||||||
assert destination
|
assert destination
|
||||||
@ -427,6 +438,7 @@ def top_down_bond_scout__direction(ctx, codelet):
|
|||||||
@codelet('bond-strength-tester')
|
@codelet('bond-strength-tester')
|
||||||
def bond_strength_tester(ctx, codelet):
|
def bond_strength_tester(ctx, codelet):
|
||||||
coderack = ctx.coderack
|
coderack = ctx.coderack
|
||||||
|
random = ctx.random
|
||||||
temperature = ctx.temperature
|
temperature = ctx.temperature
|
||||||
bond = codelet.arguments[0]
|
bond = codelet.arguments[0]
|
||||||
__showWhichStringObjectIsFrom(bond)
|
__showWhichStringObjectIsFrom(bond)
|
||||||
@ -434,7 +446,7 @@ def bond_strength_tester(ctx, codelet):
|
|||||||
strength = bond.totalStrength
|
strength = bond.totalStrength
|
||||||
probability = temperature.getAdjustedProbability(strength / 100.0)
|
probability = temperature.getAdjustedProbability(strength / 100.0)
|
||||||
logging.info('bond strength = %d for %s', strength, bond)
|
logging.info('bond strength = %d for %s', strength, bond)
|
||||||
assert formulas.coinFlip(probability)
|
assert random.coinFlip(probability)
|
||||||
bond.facet.buffer = 100.0
|
bond.facet.buffer = 100.0
|
||||||
bond.sourceDescriptor.buffer = 100.0
|
bond.sourceDescriptor.buffer = 100.0
|
||||||
bond.destinationDescriptor.buffer = 100.0
|
bond.destinationDescriptor.buffer = 100.0
|
||||||
@ -489,12 +501,12 @@ def bond_builder(ctx, codelet):
|
|||||||
@codelet('top-down-group-scout--category')
|
@codelet('top-down-group-scout--category')
|
||||||
def top_down_group_scout__category(ctx, codelet):
|
def top_down_group_scout__category(ctx, codelet):
|
||||||
coderack = ctx.coderack
|
coderack = ctx.coderack
|
||||||
|
random = ctx.random
|
||||||
slipnet = ctx.slipnet
|
slipnet = ctx.slipnet
|
||||||
workspace = ctx.workspace
|
|
||||||
groupCategory = codelet.arguments[0]
|
groupCategory = codelet.arguments[0]
|
||||||
category = groupCategory.getRelatedNode(slipnet.bondCategory)
|
category = groupCategory.getRelatedNode(slipnet.bondCategory)
|
||||||
assert category
|
assert category
|
||||||
source = __getScoutSource(workspace, category, formulas.localBondCategoryRelevance,
|
source = __getScoutSource(ctx, category, formulas.localBondCategoryRelevance,
|
||||||
'group')
|
'group')
|
||||||
assert source and not source.spansString()
|
assert source and not source.spansString()
|
||||||
if source.leftmost:
|
if source.leftmost:
|
||||||
@ -502,11 +514,10 @@ def top_down_group_scout__category(ctx, codelet):
|
|||||||
elif source.rightmost:
|
elif source.rightmost:
|
||||||
direction = slipnet.left
|
direction = slipnet.left
|
||||||
else:
|
else:
|
||||||
activations = [slipnet.left.activation, slipnet.right.activation]
|
direction = random.weighted_choice(
|
||||||
if not formulas.selectListPosition(activations):
|
[slipnet.left, slipnet.right],
|
||||||
direction = slipnet.left
|
[slipnet.left.activation, slipnet.right.activation]
|
||||||
else:
|
)
|
||||||
direction = slipnet.right
|
|
||||||
if direction == slipnet.left:
|
if direction == slipnet.left:
|
||||||
firstBond = source.leftBond
|
firstBond = source.leftBond
|
||||||
else:
|
else:
|
||||||
@ -522,7 +533,7 @@ def top_down_group_scout__category(ctx, codelet):
|
|||||||
group = Group(source.string, slipnet.samenessGroup,
|
group = Group(source.string, slipnet.samenessGroup,
|
||||||
None, slipnet.letterCategory, [source], [])
|
None, slipnet.letterCategory, [source], [])
|
||||||
probability = group.singleLetterGroupProbability()
|
probability = group.singleLetterGroupProbability()
|
||||||
if formulas.coinFlip(probability):
|
if random.coinFlip(probability):
|
||||||
coderack.proposeSingleLetterGroup(source, codelet)
|
coderack.proposeSingleLetterGroup(source, codelet)
|
||||||
return
|
return
|
||||||
direction = firstBond.directionCategory
|
direction = firstBond.directionCategory
|
||||||
@ -574,10 +585,10 @@ def top_down_group_scout__category(ctx, codelet):
|
|||||||
@codelet('top-down-group-scout--direction')
|
@codelet('top-down-group-scout--direction')
|
||||||
def top_down_group_scout__direction(ctx, codelet):
|
def top_down_group_scout__direction(ctx, codelet):
|
||||||
coderack = ctx.coderack
|
coderack = ctx.coderack
|
||||||
|
random = ctx.random
|
||||||
slipnet = ctx.slipnet
|
slipnet = ctx.slipnet
|
||||||
workspace = ctx.workspace
|
|
||||||
direction = codelet.arguments[0]
|
direction = codelet.arguments[0]
|
||||||
source = __getScoutSource(workspace, direction,
|
source = __getScoutSource(ctx, direction,
|
||||||
formulas.localDirectionCategoryRelevance,
|
formulas.localDirectionCategoryRelevance,
|
||||||
'direction')
|
'direction')
|
||||||
logging.info('source chosen = %s', source)
|
logging.info('source chosen = %s', source)
|
||||||
@ -587,12 +598,10 @@ def top_down_group_scout__direction(ctx, codelet):
|
|||||||
elif source.rightmost:
|
elif source.rightmost:
|
||||||
mydirection = slipnet.left
|
mydirection = slipnet.left
|
||||||
else:
|
else:
|
||||||
activations = [slipnet.left.activation]
|
mydirection = random.weighted_choice(
|
||||||
activations += [slipnet.right.activation]
|
[slipnet.left, slipnet.right],
|
||||||
if not formulas.selectListPosition(activations):
|
[slipnet.left.activation, slipnet.right.activation]
|
||||||
mydirection = slipnet.left
|
)
|
||||||
else:
|
|
||||||
mydirection = slipnet.right
|
|
||||||
if mydirection == slipnet.left:
|
if mydirection == slipnet.left:
|
||||||
firstBond = source.leftBond
|
firstBond = source.leftBond
|
||||||
else:
|
else:
|
||||||
@ -669,9 +678,10 @@ def top_down_group_scout__direction(ctx, codelet):
|
|||||||
@codelet('group-scout--whole-string')
|
@codelet('group-scout--whole-string')
|
||||||
def group_scout__whole_string(ctx, codelet):
|
def group_scout__whole_string(ctx, codelet):
|
||||||
coderack = ctx.coderack
|
coderack = ctx.coderack
|
||||||
|
random = ctx.random
|
||||||
slipnet = ctx.slipnet
|
slipnet = ctx.slipnet
|
||||||
workspace = ctx.workspace
|
workspace = ctx.workspace
|
||||||
if formulas.coinFlip():
|
if random.coinFlip():
|
||||||
string = workspace.target
|
string = workspace.target
|
||||||
logging.info('target string selected: %s', workspace.target)
|
logging.info('target string selected: %s', workspace.target)
|
||||||
else:
|
else:
|
||||||
@ -713,6 +723,7 @@ def group_scout__whole_string(ctx, codelet):
|
|||||||
@codelet('group-strength-tester')
|
@codelet('group-strength-tester')
|
||||||
def group_strength_tester(ctx, codelet):
|
def group_strength_tester(ctx, codelet):
|
||||||
coderack = ctx.coderack
|
coderack = ctx.coderack
|
||||||
|
random = ctx.random
|
||||||
slipnet = ctx.slipnet
|
slipnet = ctx.slipnet
|
||||||
temperature = ctx.temperature
|
temperature = ctx.temperature
|
||||||
# update strength value of the group
|
# update strength value of the group
|
||||||
@ -721,7 +732,7 @@ def group_strength_tester(ctx, codelet):
|
|||||||
group.updateStrength()
|
group.updateStrength()
|
||||||
strength = group.totalStrength
|
strength = group.totalStrength
|
||||||
probability = temperature.getAdjustedProbability(strength / 100.0)
|
probability = temperature.getAdjustedProbability(strength / 100.0)
|
||||||
if formulas.coinFlip(probability):
|
if random.coinFlip(probability):
|
||||||
# it is strong enough - post builder & activate nodes
|
# it is strong enough - post builder & activate nodes
|
||||||
group.groupCategory.getRelatedNode(slipnet.bondCategory).buffer = 100.0
|
group.groupCategory.getRelatedNode(slipnet.bondCategory).buffer = 100.0
|
||||||
if group.directionCategory:
|
if group.directionCategory:
|
||||||
@ -821,29 +832,23 @@ def rule_builder(ctx, codelet):
|
|||||||
workspace.buildRule(rule)
|
workspace.buildRule(rule)
|
||||||
|
|
||||||
|
|
||||||
def __getCutOff(density):
|
def __getCutoffWeights(bondDensity):
|
||||||
if density > 0.8:
|
if bondDensity > 0.8:
|
||||||
distribution = [5.0, 150.0, 5.0, 2.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]
|
return [5.0, 150.0, 5.0, 2.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]
|
||||||
elif density > 0.6:
|
elif bondDensity > 0.6:
|
||||||
distribution = [2.0, 5.0, 150.0, 5.0, 2.0, 1.0, 1.0, 1.0, 1.0, 1.0]
|
return [2.0, 5.0, 150.0, 5.0, 2.0, 1.0, 1.0, 1.0, 1.0, 1.0]
|
||||||
elif density > 0.4:
|
elif bondDensity > 0.4:
|
||||||
distribution = [1.0, 2.0, 5.0, 150.0, 5.0, 2.0, 1.0, 1.0, 1.0, 1.0]
|
return [1.0, 2.0, 5.0, 150.0, 5.0, 2.0, 1.0, 1.0, 1.0, 1.0]
|
||||||
elif density > 0.2:
|
elif bondDensity > 0.2:
|
||||||
distribution = [1.0, 1.0, 2.0, 5.0, 150.0, 5.0, 2.0, 1.0, 1.0, 1.0]
|
return [1.0, 1.0, 2.0, 5.0, 150.0, 5.0, 2.0, 1.0, 1.0, 1.0]
|
||||||
else:
|
else:
|
||||||
distribution = [1.0, 1.0, 1.0, 2.0, 5.0, 150.0, 5.0, 2.0, 1.0, 1.0]
|
return [1.0, 1.0, 1.0, 2.0, 5.0, 150.0, 5.0, 2.0, 1.0, 1.0]
|
||||||
stop = sum(distribution) * random.random()
|
|
||||||
total = 0.0
|
|
||||||
for i in xrange(len(distribution)):
|
|
||||||
total += distribution[i]
|
|
||||||
if total >= stop:
|
|
||||||
return i + 1
|
|
||||||
return len(distribution)
|
|
||||||
|
|
||||||
|
|
||||||
@codelet('rule-translator')
|
@codelet('rule-translator')
|
||||||
def rule_translator(ctx, codelet):
|
def rule_translator(ctx, codelet):
|
||||||
coderack = ctx.coderack
|
coderack = ctx.coderack
|
||||||
|
random = ctx.random
|
||||||
temperature = ctx.temperature
|
temperature = ctx.temperature
|
||||||
workspace = ctx.workspace
|
workspace = ctx.workspace
|
||||||
assert workspace.rule
|
assert workspace.rule
|
||||||
@ -854,9 +859,9 @@ def rule_translator(ctx, codelet):
|
|||||||
len(workspace.target.bonds))
|
len(workspace.target.bonds))
|
||||||
nearlyTotalLength = len(workspace.initial) + len(workspace.target) - 2
|
nearlyTotalLength = len(workspace.initial) + len(workspace.target) - 2
|
||||||
bondDensity = numberOfBonds / nearlyTotalLength
|
bondDensity = numberOfBonds / nearlyTotalLength
|
||||||
if bondDensity > 1.0:
|
bondDensity = min(bondDensity, 1.0)
|
||||||
bondDensity = 1.0
|
weights = __getCutoffWeights(bondDensity)
|
||||||
cutoff = __getCutOff(bondDensity) * 10.0
|
cutoff = 10.0 * random.weighted_choice(range(1, 11), weights)
|
||||||
if cutoff >= temperature.actual_value:
|
if cutoff >= temperature.actual_value:
|
||||||
if workspace.rule.buildTranslatedRule():
|
if workspace.rule.buildTranslatedRule():
|
||||||
workspace.foundAnswer = True
|
workspace.foundAnswer = True
|
||||||
@ -905,24 +910,19 @@ def bottom_up_correspondence_scout(ctx, codelet):
|
|||||||
conceptMappings, flipTargetObject, codelet)
|
conceptMappings, flipTargetObject, codelet)
|
||||||
|
|
||||||
|
|
||||||
def chooseSlipnodeByConceptualDepth(slip_nodes, temperature):
|
|
||||||
if not slip_nodes:
|
|
||||||
return None
|
|
||||||
depths = [temperature.getAdjustedValue(n.conceptualDepth) for n in slip_nodes]
|
|
||||||
i = formulas.selectListPosition(depths)
|
|
||||||
return slip_nodes[i]
|
|
||||||
|
|
||||||
|
|
||||||
@codelet('important-object-correspondence-scout')
|
@codelet('important-object-correspondence-scout')
|
||||||
def important_object_correspondence_scout(ctx, codelet):
|
def important_object_correspondence_scout(ctx, codelet):
|
||||||
coderack = ctx.coderack
|
coderack = ctx.coderack
|
||||||
|
random = ctx.random
|
||||||
slipnet = ctx.slipnet
|
slipnet = ctx.slipnet
|
||||||
temperature = ctx.temperature
|
temperature = ctx.temperature
|
||||||
workspace = ctx.workspace
|
workspace = ctx.workspace
|
||||||
objectFromInitial = chooseUnmodifiedObject('relativeImportance',
|
objectFromInitial = chooseUnmodifiedObject('relativeImportance',
|
||||||
workspace.initial.objects)
|
workspace.initial.objects)
|
||||||
descriptors = objectFromInitial.relevantDistinguishingDescriptors()
|
descriptors = objectFromInitial.relevantDistinguishingDescriptors()
|
||||||
slipnode = chooseSlipnodeByConceptualDepth(descriptors, temperature)
|
# choose descriptor by conceptual depth
|
||||||
|
weights = [temperature.getAdjustedValue(n.conceptualDepth) for n in descriptors]
|
||||||
|
slipnode = random.weighted_choice(descriptors, weights)
|
||||||
assert slipnode
|
assert slipnode
|
||||||
initialDescriptor = slipnode
|
initialDescriptor = slipnode
|
||||||
for mapping in workspace.slippages():
|
for mapping in workspace.slippages():
|
||||||
@ -971,6 +971,7 @@ def important_object_correspondence_scout(ctx, codelet):
|
|||||||
@codelet('correspondence-strength-tester')
|
@codelet('correspondence-strength-tester')
|
||||||
def correspondence_strength_tester(ctx, codelet):
|
def correspondence_strength_tester(ctx, codelet):
|
||||||
coderack = ctx.coderack
|
coderack = ctx.coderack
|
||||||
|
random = ctx.random
|
||||||
temperature = ctx.temperature
|
temperature = ctx.temperature
|
||||||
workspace = ctx.workspace
|
workspace = ctx.workspace
|
||||||
correspondence = codelet.arguments[0]
|
correspondence = codelet.arguments[0]
|
||||||
@ -984,7 +985,7 @@ def correspondence_strength_tester(ctx, codelet):
|
|||||||
correspondence.updateStrength()
|
correspondence.updateStrength()
|
||||||
strength = correspondence.totalStrength
|
strength = correspondence.totalStrength
|
||||||
probability = temperature.getAdjustedProbability(strength / 100.0)
|
probability = temperature.getAdjustedProbability(strength / 100.0)
|
||||||
if formulas.coinFlip(probability):
|
if random.coinFlip(probability):
|
||||||
# activate some concepts
|
# activate some concepts
|
||||||
for mapping in correspondence.conceptMappings:
|
for mapping in correspondence.conceptMappings:
|
||||||
mapping.initialDescriptionType.buffer = 100.0
|
mapping.initialDescriptionType.buffer = 100.0
|
||||||
|
|||||||
@ -1,9 +1,7 @@
|
|||||||
import math
|
import math
|
||||||
import logging
|
import logging
|
||||||
import random
|
|
||||||
|
|
||||||
import codeletMethods
|
import codeletMethods
|
||||||
import formulas
|
|
||||||
from bond import Bond
|
from bond import Bond
|
||||||
from codelet import Codelet
|
from codelet import Codelet
|
||||||
from correspondence import Correspondence
|
from correspondence import Correspondence
|
||||||
@ -95,6 +93,7 @@ class Coderack(object):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
def howManyToPost(self, codeletName):
|
def howManyToPost(self, codeletName):
|
||||||
|
random = self.ctx.random
|
||||||
workspace = self.ctx.workspace
|
workspace = self.ctx.workspace
|
||||||
if codeletName == 'breaker' or 'description' in codeletName:
|
if codeletName == 'breaker' or 'description' in codeletName:
|
||||||
return 1
|
return 1
|
||||||
@ -117,9 +116,9 @@ class Coderack(object):
|
|||||||
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 < random.sqrtBlur(2.0):
|
||||||
return 1
|
return 1
|
||||||
if number < formulas.blur(4.0):
|
if number < random.sqrtBlur(4.0):
|
||||||
return 2
|
return 2
|
||||||
return 3
|
return 3
|
||||||
|
|
||||||
@ -131,6 +130,7 @@ class Coderack(object):
|
|||||||
self.removeCodelet(oldCodelet)
|
self.removeCodelet(oldCodelet)
|
||||||
|
|
||||||
def postTopDownCodelets(self):
|
def postTopDownCodelets(self):
|
||||||
|
random = self.ctx.random
|
||||||
slipnet = self.ctx.slipnet
|
slipnet = self.ctx.slipnet
|
||||||
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())
|
||||||
@ -141,7 +141,7 @@ class Coderack(object):
|
|||||||
probability = self.probabilityOfPosting(codeletName)
|
probability = self.probabilityOfPosting(codeletName)
|
||||||
howMany = self.howManyToPost(codeletName)
|
howMany = self.howManyToPost(codeletName)
|
||||||
for _ in xrange(howMany):
|
for _ in xrange(howMany):
|
||||||
if not formulas.coinFlip(probability):
|
if not random.coinFlip(probability):
|
||||||
continue
|
continue
|
||||||
urgency = getUrgencyBin(
|
urgency = getUrgencyBin(
|
||||||
node.activation * node.conceptualDepth / 100.0)
|
node.activation * node.conceptualDepth / 100.0)
|
||||||
@ -164,6 +164,7 @@ class Coderack(object):
|
|||||||
self.__postBottomUpCodelets('breaker')
|
self.__postBottomUpCodelets('breaker')
|
||||||
|
|
||||||
def __postBottomUpCodelets(self, codeletName):
|
def __postBottomUpCodelets(self, codeletName):
|
||||||
|
random = self.ctx.random
|
||||||
temperature = self.ctx.temperature
|
temperature = self.ctx.temperature
|
||||||
probability = self.probabilityOfPosting(codeletName)
|
probability = self.probabilityOfPosting(codeletName)
|
||||||
howMany = self.howManyToPost(codeletName)
|
howMany = self.howManyToPost(codeletName)
|
||||||
@ -173,7 +174,7 @@ class Coderack(object):
|
|||||||
if temperature.value() < 25.0 and 'translator' in codeletName:
|
if temperature.value() < 25.0 and 'translator' in codeletName:
|
||||||
urgency = 5
|
urgency = 5
|
||||||
for _ in xrange(howMany):
|
for _ in xrange(howMany):
|
||||||
if formulas.coinFlip(probability):
|
if random.coinFlip(probability):
|
||||||
codelet = Codelet(codeletName, urgency, self.codeletsRun)
|
codelet = Codelet(codeletName, urgency, self.codeletsRun)
|
||||||
self.post(codelet)
|
self.post(codelet)
|
||||||
|
|
||||||
@ -264,20 +265,13 @@ class Coderack(object):
|
|||||||
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):
|
|
||||||
return None
|
|
||||||
urgencies = []
|
urgencies = []
|
||||||
for codelet in self.codelets:
|
for codelet in self.codelets:
|
||||||
urgency = ((self.codeletsRun - codelet.birthdate) *
|
urgency = ((self.codeletsRun - codelet.birthdate) *
|
||||||
(7.5 - codelet.urgency))
|
(7.5 - codelet.urgency))
|
||||||
urgencies += [urgency]
|
urgencies += [urgency]
|
||||||
threshold = random.random() * sum(urgencies)
|
random = self.ctx.random
|
||||||
sumOfUrgencies = 0.0
|
return random.weighted_choice(self.codelets, urgencies)
|
||||||
for i in xrange(len(self.codelets)):
|
|
||||||
sumOfUrgencies += urgencies[i]
|
|
||||||
if sumOfUrgencies > threshold:
|
|
||||||
return self.codelets[i]
|
|
||||||
return self.codelets[0]
|
|
||||||
|
|
||||||
def postInitialCodelets(self):
|
def postInitialCodelets(self):
|
||||||
workspace = self.ctx.workspace
|
workspace = self.ctx.workspace
|
||||||
@ -300,22 +294,12 @@ class Coderack(object):
|
|||||||
self.run(codelet)
|
self.run(codelet)
|
||||||
|
|
||||||
def chooseCodeletToRun(self):
|
def chooseCodeletToRun(self):
|
||||||
|
random = self.ctx.random
|
||||||
temperature = self.ctx.temperature
|
temperature = self.ctx.temperature
|
||||||
assert self.codelets
|
assert self.codelets
|
||||||
scale = (100.0 - temperature.value() + 10.0) / 15.0
|
scale = (100.0 - temperature.value() + 10.0) / 15.0
|
||||||
urgsum = sum(codelet.urgency ** scale for codelet in self.codelets)
|
chosen = random.weighted_choice(self.codelets, [codelet.urgency ** scale for codelet in self.codelets])
|
||||||
threshold = random.random() * urgsum
|
|
||||||
chosen = self.codelets[0]
|
|
||||||
urgencySum = 0.0
|
|
||||||
|
|
||||||
for codelet in self.codelets:
|
|
||||||
urgencySum += codelet.urgency ** scale
|
|
||||||
if urgencySum > threshold:
|
|
||||||
chosen = codelet
|
|
||||||
break
|
|
||||||
self.removeCodelet(chosen)
|
self.removeCodelet(chosen)
|
||||||
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):
|
||||||
|
|||||||
@ -3,10 +3,11 @@ import logging
|
|||||||
|
|
||||||
class Context(object):
|
class Context(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.temperature = None
|
|
||||||
self.coderack = None
|
self.coderack = None
|
||||||
self.workspace = None
|
self.random = None
|
||||||
self.slipnet = None
|
self.slipnet = None
|
||||||
|
self.temperature = None
|
||||||
|
self.workspace = None
|
||||||
|
|
||||||
def mainLoop(self, lastUpdate):
|
def mainLoop(self, lastUpdate):
|
||||||
currentTime = self.coderack.codeletsRun
|
currentTime = self.coderack.codeletsRun
|
||||||
@ -15,7 +16,7 @@ class Context(object):
|
|||||||
if currentTime >= lastUpdate + 15:
|
if currentTime >= lastUpdate + 15:
|
||||||
self.workspace.updateEverything()
|
self.workspace.updateEverything()
|
||||||
self.coderack.updateCodelets()
|
self.coderack.updateCodelets()
|
||||||
self.slipnet.update()
|
self.slipnet.update(self.random)
|
||||||
self.temperature.update(self.workspace.getUpdatedTemperature())
|
self.temperature.update(self.workspace.getUpdatedTemperature())
|
||||||
lastUpdate = currentTime
|
lastUpdate = currentTime
|
||||||
logging.debug('Number of codelets: %d', len(self.coderack.codelets))
|
logging.debug('Number of codelets: %d', len(self.coderack.codelets))
|
||||||
|
|||||||
@ -1,16 +1,16 @@
|
|||||||
import logging
|
from coderack import Coderack
|
||||||
|
from randomness import Randomness
|
||||||
from workspace import Workspace
|
|
||||||
from slipnet import Slipnet
|
from slipnet import Slipnet
|
||||||
from temperature import Temperature
|
from temperature import Temperature
|
||||||
from coderack import Coderack
|
from workspace import Workspace
|
||||||
|
|
||||||
from context import context
|
from context import context
|
||||||
|
|
||||||
|
|
||||||
|
context.coderack = Coderack(context)
|
||||||
|
context.random = Randomness(42)
|
||||||
context.slipnet = Slipnet()
|
context.slipnet = Slipnet()
|
||||||
context.temperature = Temperature()
|
context.temperature = Temperature()
|
||||||
context.coderack = Coderack(context)
|
|
||||||
context.workspace = Workspace(context)
|
context.workspace = Workspace(context)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,25 +1,6 @@
|
|||||||
import math
|
|
||||||
import random
|
|
||||||
|
|
||||||
from conceptMapping import ConceptMapping
|
from conceptMapping import ConceptMapping
|
||||||
|
|
||||||
|
|
||||||
def selectListPosition(probabilities):
|
|
||||||
total = sum(probabilities)
|
|
||||||
#logging.info('total: %s' % total)
|
|
||||||
r = random.random()
|
|
||||||
stopPosition = total * r
|
|
||||||
#logging.info('stopPosition: %s' % stopPosition)
|
|
||||||
total = 0
|
|
||||||
i = 0
|
|
||||||
for probability in probabilities:
|
|
||||||
total += probability
|
|
||||||
if total > stopPosition:
|
|
||||||
return i
|
|
||||||
i += 1
|
|
||||||
return 0
|
|
||||||
|
|
||||||
|
|
||||||
def weightedAverage(values):
|
def weightedAverage(values):
|
||||||
total = 0.0
|
total = 0.0
|
||||||
totalWeights = 0.0
|
totalWeights = 0.0
|
||||||
@ -31,27 +12,6 @@ def weightedAverage(values):
|
|||||||
return total / totalWeights
|
return total / totalWeights
|
||||||
|
|
||||||
|
|
||||||
def coinFlip(chance=0.5):
|
|
||||||
return random.random() < chance
|
|
||||||
|
|
||||||
|
|
||||||
def blur(value):
|
|
||||||
root = math.sqrt(value)
|
|
||||||
if coinFlip():
|
|
||||||
return value + root
|
|
||||||
return value - root
|
|
||||||
|
|
||||||
|
|
||||||
def chooseRelevantDescriptionByActivation(workspaceObject):
|
|
||||||
descriptions = workspaceObject.relevantDescriptions()
|
|
||||||
if not descriptions:
|
|
||||||
return None
|
|
||||||
activations = [description.descriptor.activation
|
|
||||||
for description in descriptions]
|
|
||||||
i = selectListPosition(activations)
|
|
||||||
return descriptions[i]
|
|
||||||
|
|
||||||
|
|
||||||
def __relevantCategory(objekt, slipnode):
|
def __relevantCategory(objekt, slipnode):
|
||||||
return objekt.rightBond and objekt.rightBond.category == slipnode
|
return objekt.rightBond and objekt.rightBond.category == slipnode
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import logging
|
import logging
|
||||||
import random
|
|
||||||
|
|
||||||
from workspaceObject import WorkspaceObject
|
from workspaceObject import WorkspaceObject
|
||||||
import formulas
|
import formulas
|
||||||
@ -73,9 +72,10 @@ class Group(WorkspaceObject):
|
|||||||
|
|
||||||
def add_length_description_category(self):
|
def add_length_description_category(self):
|
||||||
#check whether or not to add length description category
|
#check whether or not to add length description category
|
||||||
|
random = self.ctx.random
|
||||||
slipnet = self.ctx.slipnet
|
slipnet = self.ctx.slipnet
|
||||||
probability = self.lengthDescriptionProbability()
|
probability = self.lengthDescriptionProbability()
|
||||||
if random.random() < probability:
|
if random.coinFlip(probability):
|
||||||
length = len(self.objectList)
|
length = len(self.objectList)
|
||||||
if length < 6:
|
if length < 6:
|
||||||
self.addDescription(slipnet.length,
|
self.addDescription(slipnet.length,
|
||||||
|
|||||||
@ -1,11 +1,8 @@
|
|||||||
"""Run the copycat program"""
|
"""Run the copycat program"""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import random
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
random.seed(42)
|
|
||||||
|
|
||||||
import copycat
|
import copycat
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
41
copycat/randomness.py
Normal file
41
copycat/randomness.py
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import bisect
|
||||||
|
import math
|
||||||
|
import random
|
||||||
|
|
||||||
|
def accumulate(iterable):
|
||||||
|
total = 0
|
||||||
|
for v in iterable:
|
||||||
|
total += v
|
||||||
|
yield total
|
||||||
|
|
||||||
|
class Randomness(object):
|
||||||
|
def __init__(self, seed=None):
|
||||||
|
self.rng = random.Random(seed)
|
||||||
|
|
||||||
|
def coinFlip(self, p=0.5):
|
||||||
|
return self.rng.random() < p
|
||||||
|
|
||||||
|
def choice(self, seq):
|
||||||
|
return self.rng.choice(seq)
|
||||||
|
|
||||||
|
def weighted_choice(self, seq, weights):
|
||||||
|
if not seq:
|
||||||
|
# Many callers rely on this behavior.
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
cum_weights = list(accumulate(weights))
|
||||||
|
total = cum_weights[-1]
|
||||||
|
return seq[bisect.bisect_left(cum_weights, self.rng.random() * total)]
|
||||||
|
|
||||||
|
def weighted_greater_than(self, first, second):
|
||||||
|
total = first + second
|
||||||
|
if total == 0:
|
||||||
|
return False
|
||||||
|
return self.coinFlip(float(first) / total)
|
||||||
|
|
||||||
|
def sqrtBlur(self, value):
|
||||||
|
# This is exceedingly dumb, but it matches the Java code.
|
||||||
|
root = math.sqrt(value)
|
||||||
|
if self.coinFlip():
|
||||||
|
return value + root
|
||||||
|
return value - root
|
||||||
@ -32,7 +32,7 @@ class Slipnet(object):
|
|||||||
for node in self.initiallyClampedSlipnodes:
|
for node in self.initiallyClampedSlipnodes:
|
||||||
node.clampHigh()
|
node.clampHigh()
|
||||||
|
|
||||||
def update(self):
|
def update(self, random):
|
||||||
logging.debug('slipnet.update()')
|
logging.debug('slipnet.update()')
|
||||||
self.numberOfUpdates += 1
|
self.numberOfUpdates += 1
|
||||||
if self.numberOfUpdates == 50:
|
if self.numberOfUpdates == 50:
|
||||||
@ -44,7 +44,7 @@ class Slipnet(object):
|
|||||||
node.spread_activation()
|
node.spread_activation()
|
||||||
for node in self.slipnodes:
|
for node in self.slipnodes:
|
||||||
node.addBuffer()
|
node.addBuffer()
|
||||||
node.jump()
|
node.jump(random)
|
||||||
node.buffer = 0.0
|
node.buffer = 0.0
|
||||||
|
|
||||||
def isDistinguishingDescriptor(self, descriptor):
|
def isDistinguishingDescriptor(self, descriptor):
|
||||||
|
|||||||
@ -1,10 +1,5 @@
|
|||||||
import math
|
import math
|
||||||
import logging
|
import logging
|
||||||
import random
|
|
||||||
|
|
||||||
|
|
||||||
def full_activation():
|
|
||||||
return 100
|
|
||||||
|
|
||||||
|
|
||||||
def jump_threshold():
|
def jump_threshold():
|
||||||
@ -65,11 +60,7 @@ class Slipnode(object):
|
|||||||
def fully_active(self):
|
def fully_active(self):
|
||||||
"""Whether this node has full activation"""
|
"""Whether this node has full activation"""
|
||||||
float_margin = 0.00001
|
float_margin = 0.00001
|
||||||
return self.activation > full_activation() - float_margin
|
return self.activation > 100.0 - float_margin
|
||||||
|
|
||||||
def activate_fully(self):
|
|
||||||
"""Make this node fully active"""
|
|
||||||
self.activation = full_activation()
|
|
||||||
|
|
||||||
def bondDegreeOfAssociation(self):
|
def bondDegreeOfAssociation(self):
|
||||||
linkLength = self.intrinsicLinkLength
|
linkLength = self.intrinsicLinkLength
|
||||||
@ -112,7 +103,8 @@ class Slipnode(object):
|
|||||||
|
|
||||||
If no linked node is found, return None
|
If no linked node is found, return None
|
||||||
"""
|
"""
|
||||||
if relation == self.slipnet.identity:
|
slipnet = self.slipnet
|
||||||
|
if relation == slipnet.identity:
|
||||||
return self
|
return self
|
||||||
destinations = [l.destination
|
destinations = [l.destination
|
||||||
for l in self.outgoingLinks if l.label == relation]
|
for l in self.outgoingLinks if l.label == relation]
|
||||||
@ -125,9 +117,10 @@ class Slipnode(object):
|
|||||||
|
|
||||||
If it does not exist return None
|
If it does not exist return None
|
||||||
"""
|
"""
|
||||||
|
slipnet = self.slipnet
|
||||||
result = None
|
result = None
|
||||||
if self == destination:
|
if self == destination:
|
||||||
result = self.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:
|
||||||
@ -149,17 +142,14 @@ class Slipnode(object):
|
|||||||
self.activation += self.buffer
|
self.activation += self.buffer
|
||||||
self.activation = min(max(0, self.activation), 100)
|
self.activation = min(max(0, self.activation), 100)
|
||||||
|
|
||||||
def can_jump(self):
|
def jump(self, random):
|
||||||
if self.activation <= jump_threshold():
|
if self.activation <= jump_threshold():
|
||||||
return False
|
return
|
||||||
if self.clamped:
|
if self.clamped:
|
||||||
return False
|
return
|
||||||
value = (self.activation / 100.0) ** 3
|
value = (self.activation / 100.0) ** 3
|
||||||
return random.random() < value
|
if random.coinFlip(value):
|
||||||
|
self.activation = 100.0
|
||||||
def jump(self):
|
|
||||||
if self.can_jump():
|
|
||||||
self.activate_fully()
|
|
||||||
|
|
||||||
def get_name(self):
|
def get_name(self):
|
||||||
if len(self.name) == 1:
|
if len(self.name) == 1:
|
||||||
|
|||||||
@ -1,34 +1,29 @@
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
import formulas
|
|
||||||
|
|
||||||
|
def __chooseObjectFromList(ctx, objects, attribute):
|
||||||
def __chooseObjectFromList(temperature, objects, attribute):
|
random = ctx.random
|
||||||
if not objects:
|
temperature = ctx.temperature
|
||||||
return None
|
|
||||||
weights = [
|
weights = [
|
||||||
temperature.getAdjustedValue(
|
temperature.getAdjustedValue(
|
||||||
getattr(o, attribute)
|
getattr(o, attribute)
|
||||||
)
|
)
|
||||||
for o in objects
|
for o in objects
|
||||||
]
|
]
|
||||||
i = formulas.selectListPosition(weights)
|
return random.weighted_choice(objects, weights)
|
||||||
return objects[i]
|
|
||||||
|
|
||||||
|
|
||||||
def chooseUnmodifiedObject(attribute, inObjects):
|
def chooseUnmodifiedObject(attribute, inObjects):
|
||||||
from context import context as ctx
|
from context import context as ctx
|
||||||
temperature = ctx.temperature
|
|
||||||
workspace = ctx.workspace
|
workspace = ctx.workspace
|
||||||
objects = [o for o in inObjects if o.string != workspace.modified]
|
objects = [o for o in inObjects if o.string != workspace.modified]
|
||||||
if not len(objects):
|
if not len(objects):
|
||||||
print 'no objects available in initial or target strings'
|
print 'no objects available in initial or target strings'
|
||||||
return __chooseObjectFromList(temperature, objects, attribute)
|
return __chooseObjectFromList(ctx, objects, attribute)
|
||||||
|
|
||||||
|
|
||||||
def chooseNeighbor(source):
|
def chooseNeighbor(source):
|
||||||
from context import context as ctx
|
from context import context as ctx
|
||||||
temperature = ctx.temperature
|
|
||||||
workspace = ctx.workspace
|
workspace = ctx.workspace
|
||||||
objects = []
|
objects = []
|
||||||
for objekt in workspace.objects:
|
for objekt in workspace.objects:
|
||||||
@ -38,7 +33,7 @@ def chooseNeighbor(source):
|
|||||||
objects += [objekt]
|
objects += [objekt]
|
||||||
elif source.leftIndex == objekt.rightIndex + 1:
|
elif source.leftIndex == objekt.rightIndex + 1:
|
||||||
objects += [objekt]
|
objects += [objekt]
|
||||||
return __chooseObjectFromList(temperature, objects, "intraStringSalience")
|
return __chooseObjectFromList(ctx, objects, "intraStringSalience")
|
||||||
|
|
||||||
|
|
||||||
def chooseDirectedNeighbor(source, direction):
|
def chooseDirectedNeighbor(source, direction):
|
||||||
@ -53,7 +48,6 @@ def chooseDirectedNeighbor(source, direction):
|
|||||||
|
|
||||||
def __chooseLeftNeighbor(source):
|
def __chooseLeftNeighbor(source):
|
||||||
from context import context as ctx
|
from context import context as ctx
|
||||||
temperature = ctx.temperature
|
|
||||||
workspace = ctx.workspace
|
workspace = ctx.workspace
|
||||||
objects = []
|
objects = []
|
||||||
for o in workspace.objects:
|
for o in workspace.objects:
|
||||||
@ -64,32 +58,29 @@ def __chooseLeftNeighbor(source):
|
|||||||
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 __chooseObjectFromList(temperature, objects, 'intraStringSalience')
|
return __chooseObjectFromList(ctx, objects, 'intraStringSalience')
|
||||||
|
|
||||||
|
|
||||||
def __chooseRightNeighbor(source):
|
def __chooseRightNeighbor(source):
|
||||||
from context import context as ctx
|
from context import context as ctx
|
||||||
temperature = ctx.temperature
|
|
||||||
workspace = ctx.workspace
|
workspace = ctx.workspace
|
||||||
objects = [o for o in workspace.objects
|
objects = [o for o in workspace.objects
|
||||||
if o.string == source.string
|
if o.string == source.string
|
||||||
and o.leftIndex == source.rightIndex + 1]
|
and o.leftIndex == source.rightIndex + 1]
|
||||||
return __chooseObjectFromList(temperature, objects, 'intraStringSalience')
|
return __chooseObjectFromList(ctx, objects, 'intraStringSalience')
|
||||||
|
|
||||||
|
|
||||||
def chooseBondFacet(source, destination):
|
def chooseBondFacet(source, destination):
|
||||||
from context import context as ctx
|
from context import context as ctx
|
||||||
|
random = ctx.random
|
||||||
slipnet = ctx.slipnet
|
slipnet = ctx.slipnet
|
||||||
sourceFacets = [d.descriptionType for d in source.descriptions
|
sourceFacets = [d.descriptionType for d in source.descriptions
|
||||||
if d.descriptionType in slipnet.bondFacets]
|
if d.descriptionType in slipnet.bondFacets]
|
||||||
bondFacets = [d.descriptionType for d in destination.descriptions
|
bondFacets = [d.descriptionType for d in destination.descriptions
|
||||||
if d.descriptionType in sourceFacets]
|
if d.descriptionType in sourceFacets]
|
||||||
if not bondFacets:
|
|
||||||
return None
|
|
||||||
supports = [__supportForDescriptionType(f, source.string)
|
supports = [__supportForDescriptionType(f, source.string)
|
||||||
for f in bondFacets]
|
for f in bondFacets]
|
||||||
i = formulas.selectListPosition(supports)
|
return random.weighted_choice(bondFacets, supports)
|
||||||
return bondFacets[i]
|
|
||||||
|
|
||||||
|
|
||||||
def __supportForDescriptionType(descriptionType, string):
|
def __supportForDescriptionType(descriptionType, string):
|
||||||
|
|||||||
Reference in New Issue
Block a user