added basic transaction management

git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@1260 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2006-07-09 19:38:17 +00:00
parent c0880a046e
commit e9a9e00112
5 changed files with 137 additions and 42 deletions

View file

@ -18,17 +18,29 @@ when creating a synapsis:
[] []
>>> n01.receivers == [s0102] >>> n01.receivers == [s0102]
True True
>>> n01.state.value >>> n01.getState()
1.0 <State 0.0>
>>> n02.state.value >>> n02.getState()
1.0 <State 0.0>
When we trigger a neuron, all its receivers get triggered so that the When we change the state of a neuron and notify it, all its receiver synapses
receivers' state is updated: get triggered so that the receiver neurons' states are updated:
>>> n01.trigger() >>> from cybertools.brain.state import State
>>> n01.state.value >>> n01.setState(State(1.0))
1.0 >>> n01.getState()
>>> n02.state.value <State 1.0>
2.0 >>> n01.notify()
>>> n02.getState()
<State 1.0>
To allow for concurrent (thread-safe) access to the brain all changes to
the neurons' states is under the control of a transaction. If we end the
current transaction all state changes will be forgotton:
>>> from cybertools.brain.transaction import endTransaction
>>> endTransaction()
>>> n01.getState()
<State 0.0>
>>> n02.getState()
<State 0.0>

View file

@ -34,24 +34,32 @@ class ISynapsis(Interface):
transition = Attribute("A transition changes the sender neuron's state.") transition = Attribute("A transition changes the sender neuron's state.")
def trigger(transaction=None):
""" Recalculate the receiver neuron's state by executing the
synapse's transition using the state of the sender neuron.
"""
class INeuron(Interface): class INeuron(Interface):
state = Attribute("The current state of the neuron")
senders = Attribute("The sender synapses") senders = Attribute("The sender synapses")
receivers = Attribute("The receiver synapses") receivers = Attribute("The receiver synapses")
def trigger(): def setState(state, transaction=None):
""" Set the neuron's state.
"""
def getState(transaction=None):
""" Return the neuron's state.
"""
def notify(transaction=None):
""" Notifies the neuron that something has happened. This method """ Notifies the neuron that something has happened. This method
executes all transitions from all sender synapses in order to calls the trigger() method on all downstream (receiver) synapses.
calculate the neuron's new state;
then it should call the trigger() method on all downstream
(receiver)neurons.
In addition it may perform side effects like changing In addition it may perform side effects like changing
transition properties of adjacent synapses or even create new transition properties of adjacent synapses or even create new
synapses or neurons; this side effects should happen before synapses or neurons; this side effects should happen before
triggering the receiver neurons. triggering the receiver synapses.
""" """
@ -62,7 +70,12 @@ class IState(Interface):
class ITransition(Interface): class ITransition(Interface):
def execute(state): def execute(transaction=None):
""" Transform state to a new state value and return it. """ Transform the receiver's state to a new state value and return it.
""" """
class ITransaction(Interface):
""" A transaction that keeps track of the neurons' states.
"""

View file

@ -19,12 +19,13 @@
""" """
A simple basic implementation of Neuron and Synapsis. A simple basic implementation of Neuron and Synapsis.
$Id: type.py 1129 2006-03-19 09:46:08Z helmutm $ $Id$
""" """
from zope.interface import implements from zope.interface import implements
from cybertools.brain.interfaces import INeuron, ISynapsis from cybertools.brain.interfaces import INeuron, ISynapsis
from cybertools.brain.state import State, Transition from cybertools.brain.state import State, Transition
from cybertools.brain.transaction import getTransaction
class Synapsis(object): class Synapsis(object):
@ -33,10 +34,6 @@ class Synapsis(object):
implements(ISynapsis) implements(ISynapsis)
sender = None
reciever = None
transition = None
def __init__(self, sender, receiver): def __init__(self, sender, receiver):
self.sender = sender self.sender = sender
sender.receivers.append(self) sender.receivers.append(self)
@ -44,28 +41,33 @@ class Synapsis(object):
receiver.senders.append(self) receiver.senders.append(self)
self.transition = Transition(self) self.transition = Transition(self)
def trigger(self, transaction=None):
receiver = self.receiver
receiver.setState(self.transition.execute(transaction), transaction)
receiver.notify(transaction)
class Neuron(object): class Neuron(object):
implements(INeuron) implements(INeuron)
state = None
def __init__(self): def __init__(self):
self.senders = [] self.senders = []
self.receivers = [] self.receivers = []
self.state = State() self.state = State()
self.active = False
def trigger(self): def setState(self, state, transaction=None):
if self.active: # avoid cycles transaction = getTransaction(transaction)
return transaction.setState(self, state)
self.active = True
state = self.state def getState(self, transaction=None):
for s in self.senders: if transaction is None:
state = s.transition.execute(state) transaction = getTransaction(create=False)
self.state = state if transaction is None:
return self.state
return transaction.getState(self)
def notify(self, transaction=None):
for r in self.receivers: for r in self.receivers:
r.receiver.trigger() r.trigger(transaction)
self.active = False

View file

@ -32,9 +32,12 @@ class State(object):
implements(IState) implements(IState)
def __init__(self, value=1.0): def __init__(self, value=0.0):
self.value = value self.value = value
def __repr__(self):
return '<State %0.1f>' % self.value
class Transition(object): class Transition(object):
@ -44,7 +47,9 @@ class Transition(object):
self.synapsis = synapsis self.synapsis = synapsis
self.factor = factor self.factor = factor
def execute(self, state): def execute(self, transaction=None):
return State(state.value + self.synapsis.sender.state.value * self.factor) oldState = self.synapsis.receiver.getState(transaction)
senderState = self.synapsis.sender.getState(transaction)
return State(oldState.value + senderState.value * self.factor)

63
brain/transaction.py Normal file
View file

@ -0,0 +1,63 @@
#
# Copyright (c) 2006 Helmut Merz helmutm@cy55.de
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
"""
Transaction management.
$Id$
"""
from zope.interface import implements
from cybertools.brain.interfaces import ITransaction
class Transaction(object):
implements(ITransaction)
def __init__(self):
self.states = {}
def setState(self, neuron, state):
self.states[neuron] = state
def getState(self, neuron):
return self.states.get(neuron, neuron.state)
transactions = []
def getTransaction(transaction=None, create=True):
if transaction is None:
if transactions:
transaction = transactions[0]
elif create:
transaction = Transaction()
transactions.append(transaction)
else:
return None
return transaction
def endTransaction(transaction=None):
if transaction is None:
if transactions:
del transactions[0]
else:
if transaction in transactions:
del transactions[transactions.index(transaction)]