{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Simple simulations with minibn\n",
"\n",
"The module `minibn` implements basic methods for computing simulation runs with usual synchronous, fully-asynchronous, and (general) asynchronous update modes. For the two latter, the `seed` argument ensures the reproducibility of traces.\n",
"The implementation also enables defining custom update modes."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"from colomoto import minibn\n",
"import pandas as pd # for displaying traces"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"bn = minibn.BooleanNetwork({\n",
" \"a\": \"c\",\n",
" \"b\": \"!a\",\n",
" \"c\": \"!b\"\n",
"})"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Run synchronous simulation from zero state, for at most 10 iterations:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" a | \n",
" b | \n",
" c | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
"
\n",
" \n",
" 1 | \n",
" 0 | \n",
" 1 | \n",
" 1 | \n",
"
\n",
" \n",
" 2 | \n",
" 1 | \n",
" 1 | \n",
" 0 | \n",
"
\n",
" \n",
" 3 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
"
\n",
" \n",
" 4 | \n",
" 0 | \n",
" 1 | \n",
" 1 | \n",
"
\n",
" \n",
" 5 | \n",
" 1 | \n",
" 1 | \n",
" 0 | \n",
"
\n",
" \n",
" 6 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
"
\n",
" \n",
" 7 | \n",
" 0 | \n",
" 1 | \n",
" 1 | \n",
"
\n",
" \n",
" 8 | \n",
" 1 | \n",
" 1 | \n",
" 0 | \n",
"
\n",
" \n",
" 9 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
"
\n",
" \n",
" 10 | \n",
" 0 | \n",
" 1 | \n",
" 1 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" a b c\n",
"0 0 0 0\n",
"1 0 1 1\n",
"2 1 1 0\n",
"3 0 0 0\n",
"4 0 1 1\n",
"5 1 1 0\n",
"6 0 0 0\n",
"7 0 1 1\n",
"8 1 1 0\n",
"9 0 0 0\n",
"10 0 1 1"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"pd.DataFrame(minibn.SyncRun(bn, bn.zero(), 10))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Run fully-aynchronous simulation from zero state, for at most 10 iterations:"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" a | \n",
" b | \n",
" c | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
"
\n",
" \n",
" 1 | \n",
" 0 | \n",
" 0 | \n",
" 1 | \n",
"
\n",
" \n",
" 2 | \n",
" 0 | \n",
" 1 | \n",
" 1 | \n",
"
\n",
" \n",
" 3 | \n",
" 0 | \n",
" 1 | \n",
" 0 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" a b c\n",
"0 0 0 0\n",
"1 0 0 1\n",
"2 0 1 1\n",
"3 0 1 0"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"pd.DataFrame(minibn.FAsyncRun(bn, bn.zero(), 10, seed=23892830))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Run (general) aynchronous simulation from zero state, for at most 10 iterations:"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" a | \n",
" b | \n",
" c | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
"
\n",
" \n",
" 1 | \n",
" 0 | \n",
" 1 | \n",
" 1 | \n",
"
\n",
" \n",
" 2 | \n",
" 0 | \n",
" 1 | \n",
" 0 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" a b c\n",
"0 0 0 0\n",
"1 0 1 1\n",
"2 0 1 0"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"pd.DataFrame(minibn.GAsyncRun(bn, bn.zero(), 10, seed=12323892))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We define a custom update mode by extending from the general asynchronous mode.\n",
"The method `select_for_update` is called to select which nodes to update from the given list of nodes which can change of value in the current state.\n",
"\n",
"In this example, we implement a simple priority mecanisms which will select the nodes with the highest priority, and then use the general asynchronous mode, i.e., picking randomly a subset of them:"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"class PrioGAsyncRun(minibn.GAsyncRun):\n",
" def __init__(self, *args, priorities=[], **kwargs):\n",
" super().__init__(*args, **kwargs)\n",
" self.priorities = priorities\n",
" def select_for_update(self, nodes):\n",
" # select nodes by priority order\n",
" for m in self.priorities:\n",
" mn = set(m).intersection(nodes)\n",
" if mn:\n",
" nodes = list(mn)\n",
" break\n",
" # use parent class to select the nodes to update\n",
" return super().select_for_update(nodes)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" a | \n",
" b | \n",
" c | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
"
\n",
" \n",
" 1 | \n",
" 0 | \n",
" 0 | \n",
" 1 | \n",
"
\n",
" \n",
" 2 | \n",
" 0 | \n",
" 1 | \n",
" 1 | \n",
"
\n",
" \n",
" 3 | \n",
" 0 | \n",
" 1 | \n",
" 0 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" a b c\n",
"0 0 0 0\n",
"1 0 0 1\n",
"2 0 1 1\n",
"3 0 1 0"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"priorities = [{\"c\"},{\"b\"},{\"a\"}]\n",
"pd.DataFrame(PrioGAsyncRun(bn, bn.zero(), 10, priorities=priorities, seed=12323892))"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.7"
}
},
"nbformat": 4,
"nbformat_minor": 2
}