diff --git a/brain/README.txt b/brain/README.txt new file mode 100644 index 0000000..ff4b203 --- /dev/null +++ b/brain/README.txt @@ -0,0 +1,29 @@ +============================================================= +A proof-of-concept Project Aiming at a sort of Neural Network +============================================================= + + ($Id$) + +Let's start with creating a few neurons and connecting them with synapses. + + >>> from cybertools.brain.neuron import Neuron, Synapsis + >>> n01 = Neuron() + >>> n02 = Neuron() + +In the simple default implementation the neurons are connected automatically +when creating a synapsis: + + >>> s0102 = Synapsis(n01, n02) + >>> n01.senders + [] + >>> n01.receivers == [s0102] + True + >>> n01.state.level + 1.0 + >>> n02.state.level + 1.0 + + >>> n01.trigger() + >>> n02.state.level + 2.0 + diff --git a/brain/__init__.py b/brain/__init__.py new file mode 100644 index 0000000..154cf81 --- /dev/null +++ b/brain/__init__.py @@ -0,0 +1,4 @@ +""" +$Id: __init__.py 1116 2006-03-07 18:00:39Z helmutm $ +""" + diff --git a/brain/interfaces.py b/brain/interfaces.py new file mode 100644 index 0000000..05d5057 --- /dev/null +++ b/brain/interfaces.py @@ -0,0 +1,79 @@ +# +# 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 +# + +""" +Interfaces for a sort of neural network. + +$Id$ +""" + +from zope.interface import Interface, Attribute + + +class ISynapsis(Interface): + """ A synapsis connects two neurons. + """ + + sender = Attribute("The sender neuron for this synapsis") + reciever = Attribute("The receiver neuron for this synapsis") + + transformation = Attribute("A transformation is used to transform " + "the sender neuron's state.") + + +class INeuron(Interface): + + state = Attribute("The current state of the neuron") + + senders = Attribute("The sender synapses") + receivers = Attribute("The receiver synapses") + + stateMerger = Attribute("Merges a state with a list of other states " + "in order to create a new state.") + + def trigger(): + """ Notifies the neuron that something has happened. This method + should get the transformed states from all sender synapses + and merge them in order to 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 + transition properties of adjacent synapses or even create new + synapses or neurons; this side effects should happen before + triggering the receiver neurons. + """ + + +class IState(Interface): + """ The state of a neuron. + """ + + +class IStateTransformation(Interface): + + def transform(state): + """ Transform state to a new state value and return it. + """ + + +class IStateMerger(Interface): + + def merge(state, senderStates): + """ Transform state to a new value by taking into account a list + of sender neurons' states. This modifies state in-place. + """ diff --git a/brain/neuron.py b/brain/neuron.py new file mode 100644 index 0000000..9e51676 --- /dev/null +++ b/brain/neuron.py @@ -0,0 +1,70 @@ +# +# 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 +# + +""" +A simple basic implementation of Neuron and Synapsis. + +$Id: type.py 1129 2006-03-19 09:46:08Z helmutm $ +""" + +from zope.interface import implements +from cybertools.brain.interfaces import INeuron, ISynapsis +from cybertools.brain.state import State, StateMerger, StateTransformation + + +class Synapsis(object): + """ A synapsis connects two neurons. + """ + + sender = None + reciever = None + transformation = None + + def __init__(self, sender, receiver): + self.sender = sender + sender.receivers.append(self) + self.receiver = receiver + receiver.senders.append(self) + self.transformation = StateTransformation(self) + + def transformSenderState(self): + return self.transformation.transform(self.sender.state) + + +class Neuron(object): + + state = None + stateMerger = None + + def __init__(self): + self.senders = [] + self.receivers = [] + self.state = State() + self.stateMerger = StateMerger(self) + self.active = False + + def trigger(self): + if self.active: # avoid cycles + return + self.active = True + senderStates = [s.transformSenderState() for s in self.senders] + self.stateMerger.merge(self.state, senderStates) + for r in self.receivers: + r.receiver.trigger() + self.active = False + diff --git a/brain/state.py b/brain/state.py new file mode 100644 index 0000000..e270559 --- /dev/null +++ b/brain/state.py @@ -0,0 +1,54 @@ +# +# 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 +# + +""" +Base classes for state and state manipulations. + +$Id$ +""" + +from zope.interface import implements +from cybertools.brain.interfaces import IState, IStateMerger, IStateTransformation + + +class State(object): + """ The state of a neuron. + """ + + def __init__(self, level=1.0): + self.level = level + + +class StateTransformation(object): + + def __init__(self, synapsis, factor=1.0): + self.synapsis = synapsis + self.factor = factor + + def transform(self, state): + return State(state.level * self.factor) + + +class StateMerger(object): + + def __init__(self, neuron): + self.neuron = neuron + + def merge(self, state, senderStates): + state.level += sum(st.level for st in senderStates) + diff --git a/brain/tests.py b/brain/tests.py new file mode 100755 index 0000000..1b09312 --- /dev/null +++ b/brain/tests.py @@ -0,0 +1,28 @@ +# $Id$ + +import unittest +from zope.testing.doctestunit import DocFileSuite +from zope.interface.verify import verifyClass +from zope.interface import implements + +from cybertools.brain.interfaces import INeuron, ISynapsis +from cybertools.brain.interfaces import IState, IStateTransformation, IStateMerger +from cybertools.brain.neuron import Neuron, Synapsis +from cybertools.brain.state import State, StateTransformation, StateMerger + + +class TestBrain(unittest.TestCase): + "Basic tests for the brain package." + + def testInterfaces(self): + pass + + +def test_suite(): + return unittest.TestSuite(( + unittest.makeSuite(TestBrain), + DocFileSuite('README.txt'), + )) + +if __name__ == '__main__': + unittest.main(defaultTest='test_suite')