Logical Networks

class neet.boolean.LogicNetwork(table, reduced=False, names=None, metadata=None)[source]

LogicNetwork represents a network of logic functions. This type of Boolean network model is common in biological modeling.

Inheritance diagram of LogicNetwork

In addition to methods inherited from neet.boolean.BooleanNetwork, LogicNetwork exposes the following attributes

table The network’s truth table.

and methods:

is_dependent Is the target node dependent on the state of source?
reduce_table Reduce truth table by removing input nodes which have no logic influence from the truth table of each node.
read_table Read a network from a truth table file.
read_logic Read a network from a file of logic equations.

At a minimum, LogicNetworks accept a truth table at initialization. A truth table stores a list of tuples, one for each node in order. A tuple of the form (A, {C1, C2, ...}) at index i provides the activation conditions for the node of index i. A is a tuple marking the indices of the nodes which influence the state of node i via logic relations. {C1, C2, ...} is a set, each element of which is the collection of binary states of these influencing nodes that would activate node i, setting it to 1. Any other collection of states of nodes in A are assumed to deactivate node i, setting it to 0.

C1, C2, etc. are sequences (tuple or str) of binary digits, each being the binary state of corresponding node in A.

The following network has a single node, which is only activates when it is in the 0 state. That is, it alternates between 0 and 1.

>>> net = LogicNetwork([((0,), {'0'})])
>>> net.size
1
>>> net.table
[((0,), {'0'})]

A more complicated network, with three nodes. Here, node 0 activates in the next state whenever node 1 is deactivated; node 1 activates based on the state of nodes 1 and 2; and node 2 activates based on its own state.

>>> net = LogicNetwork([((1,), {'0'}), ((1,2), {'10', '11'}), ((2,), {'1'})])
>>> net.size
3
>>> net.table == [((1,), {'0'}), ((1, 2), {'10', '11'}), ((2,), {'1'})]
True

Notice that node 1 will fall into the activated state regardless of what node 2 is doing. In other words, the edge \(2 \rightarrow 1\) is not a real edge. The table can be reduced to remove such an “fake” edge using the reduced argument:

>>> net = LogicNetwork([((1,), {'0'}), ((1,2), {'10', '11'}), ((2,), {'1'})])
>>> net.table == [((1,), {'0'}), ((1, 2), {'10', '11'}), ((2,), {'1'})]
True
>>> net = LogicNetwork([((1,), {'0'}), ((1,2), {'10', '11'}), ((2,), {'1'})], reduced=True)
>>> net.table == [((1,), {'0'}), ((1,), {'1'}), ((2,), {'1'})]
True
Parameters:
  • table (list, tuple) – the logic table
  • reduced (bool) – reduce the table
  • names (seq) – an iterable object of the names of the nodes in the network
  • metadata (dict) – metadata dictionary for the network
Raises:
  • TypeError – if the rows of the table are neither list nor tuple
  • IndexError – if a node depends another which doesn’t have a row in the table
  • TypeError – if the truth conditions are neither list, tuple nor set.
table

The network’s truth table.

A truth table is a list of tuples, one for each node in order. A tuple of the form (A, {C1, C2, ...}) at index i provides the activation conditions for the node of index i. A is a tuple marking the indices of the nodes which influence the state of node i via logic relations. {C1, C2, ...} is a set, each element of which is the collection of binary states of these influencing nodes that would activate node i, setting it to 1. Any other collection of states of nodes in A are assumed to deactivate node i, setting it to 0.

C1, C2, etc. are sequences (tuple or str) of binary digits, each being the binary state of corresponding node in A.

>>> from neet.boolean.examples import myeloid
>>> myeloid.table == [((0, 1, 2, 7), {'1000', '1100', '1010'}),
... ((1, 0, 4, 7), {'0010', '1100', '1010', '1110', '0110', '0100', '1000'}),
... ((1,), {'1'}),
... ((1, 4), {'10'}),
... ((1, 3), {'10'}),
... ((1, 7), {'10'}),
... ((6, 1, 2, 5), {'1011', '1100', '1010', '1110', '1101', '1000', '1001'}),
... ((6, 7, 1, 0), {'1000', '1100', '0100'}),
... ((7, 10), {'10'}),
... ((7, 8, 10), {'110'}),
... ((6, 9), {'10'})]
True
Type:list of tuples of type (list, set)
is_dependent(target, source)[source]

Is the target node dependent on the state of source?

>>> net = LogicNetwork([((1, 2), {'01', '10'}),
... ((0, 2), {'01', '10', '11'}),
... ((0, 1), {'11'})])
>>> net.is_dependent(0, 0)
False
>>> net.is_dependent(0, 2)
True
Parameters:
  • target (int) – index of the target node
  • source (int) – index of the source node
Returns:

whether the target node is dependent on the source

reduce_table()[source]

Reduce truth table by removing input nodes which have no logic influence from the truth table of each node.

Note

This function introduces the identity function for all nodes which have no inputs. This ensure that every node has a well-defined logical function. The example below demonstrates this with node 1.

>>> net = LogicNetwork([((0,1), {'00', '10'}), ((0,), {'0', '1'})])
>>> net.table == [((0,1), {'00', '10'}), ((0,), {'0', '1'})]
True
>>> net.reduce_table()
>>> net.table == [((1,), {'0'}), ((1,), {'0', '1'})]
True
classmethod read_table(table_path, reduced=False, metadata=None)[source]

Read a network from a truth table file.

A logic table file starts with a table title which contains names of all nodes. It is a line marked by ## at the begining with node names seperated by commas or spaces. This line is required. For artificial network without node names, arbitrary names must be put in place, e.g.:

## A B C D

Following are the sub-tables of logic conditions for every node. Each sub-table nominates a node and its logically connected nodes in par- enthesis as a comment line:

# A (B C)

The rest of the sub-table are states of those nodes in parenthesis (B, C) that would activate the state of A. States that would deactivate A should not be included in the sub-table.

A complete logic table with 3 nodes A, B, C would look like this:

## A B C
# A (B C)
1 0
1 1
# B (A)
1
# C (B C A)
1 0 1
0 1 0
0 1 1

Custom comments can be added above or below the table title (as long as they are preceeded with more or less than two # (e.g. # or ### but not ##)).

Examples:

print(open(MYELOID_TRUTH_TABLE, 'r').read())
## GATA-2, GATA-1, FOG-1, EKLF, Fli-1, SCL, C/EBPa, PU.1, cJun, EgrNab, Gfi-1
# GATA-2 (GATA-2, GATA-1, FOG-1, PU.1)
1 1 0 0
1 0 1 0
1 0 0 0
# GATA-1 (GATA-1, GATA-2, Fli-1, PU.1)
1 0 0 0
0 1 0 0
0 0 1 0
1 1 0 0
1 0 1 0
0 1 1 0
1 1 1 0
# FOG-1 (GATA-1)
1
...
>>> net = LogicNetwork.read_table(MYELOID_TRUTH_TABLE)
>>> net.size
11
>>> net.names
['GATA-2', 'GATA-1', 'FOG-1', 'EKLF', 'Fli-1', 'SCL', 'C/EBPa', 'PU.1', 'cJun', 'EgrNab', 'Gfi-1']
>>> net.table ==  [((0, 1, 2, 7), {'1000', '1010', '1100'}),
... ((1, 0, 4, 7), {'0010', '0100', '0110', '1000', '1010', '1100', '1110'}),
... ((1,), {'1'}),
... ((1, 4), {'10'}),
... ((1, 3), {'10'}),
... ((1, 7), {'10'}),
... ((6, 1, 2, 5), {'1000', '1001', '1010', '1011', '1100', '1101', '1110'}),
... ((6, 7, 1, 0), {'0100', '1000', '1100'}),
... ((7, 10), {'10'}),
... ((7, 8, 10), {'110'}),
... ((6, 9), {'10'})]
True
Parameters:
  • table_path (str) – a path to a table table file
  • reduced (bool) – reduce the table
  • names (seq) – an iterable object of the names of the nodes in the network
  • metadata (dict) – metadata dictionary for the network
Returns:

a LogicNetwork

classmethod read_logic(logic_path, external_nodes_path=None, reduced=False, metadata=None)[source]

Read a network from a file of logic equations.

A logic equations has the form of A = B AND ( C OR D ), each term being separated from parantheses and logic operators with at least a space. The optional external_nodes_path takes a file that contains nodes in a column whose states do not depend on any nodes. These are considered “external” nodes. Equivalently, such a node would have a logic equation A = A, for its state stays on or off unless being set externally.

Examples

print(open(MYELOID_LOGIC_EXPRESSIONS, 'r').read())
GATA-2 = GATA-2 AND NOT ( GATA-1 AND FOG-1 ) AND NOT PU.1
GATA-1 = ( GATA-1 OR GATA-2 OR Fli-1 ) AND NOT PU.1
FOG-1 = GATA-1
EKLF = GATA-1 AND NOT Fli-1
Fli-1 = GATA-1 AND NOT EKLF
SCL = GATA-1 AND NOT PU.1
C/EBPa = C/EBPa AND NOT ( GATA-1 AND FOG-1 AND SCL )
PU.1 = ( C/EBPa OR PU.1 ) AND NOT ( GATA-1 OR GATA-2 )
cJun = PU.1 AND NOT Gfi-1
EgrNab = ( PU.1 AND cJun ) AND NOT Gfi-1
Gfi-1 = C/EBPa AND NOT EgrNab
>>> net = LogicNetwork.read_logic(MYELOID_LOGIC_EXPRESSIONS)
>>> net.size
11
>>> net.names
['GATA-2', 'GATA-1', 'FOG-1', 'EKLF', 'Fli-1', 'SCL', 'C/EBPa', 'PU.1', 'cJun', 'EgrNab', 'Gfi-1']
>>> net.table ==  [((0, 1, 2, 7), {'1000', '1010', '1100'}),
... ((1, 0, 4, 7), {'0010', '0100', '0110', '1000', '1010', '1100', '1110'}),
... ((1,), {'1'}),
... ((1, 4), {'10'}),
... ((1, 3), {'10'}),
... ((1, 7), {'10'}),
... ((6, 1, 2, 5), {'1000', '1001', '1010', '1011', '1100', '1101', '1110'}),
... ((6, 7, 1, 0), {'0100', '1000', '1100'}),
... ((7, 10), {'10'}),
... ((7, 8, 10), {'110'}),
... ((6, 9), {'10'})]
True
Parameters:
  • logic_path (str) – path to a file of logial expressions
  • external_nodes_path (str) – a path to a file of external nodes
  • reduced (bool) – reduce the table
  • names (seq) – an iterable object of the names of the nodes in the network
  • metadata (dict) – metadata dictionary for the network
Returns:

a LogicNetwork