You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

7836 lines
280 KiB
Plaintext

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

{
"cells": [
{
"cell_type": "markdown",
"id": "3df9ce6e-3722-4334-abf9-703d62c27eab",
"metadata": {},
"source": [
"# The Cozo database tutorial"
]
},
{
"cell_type": "markdown",
"id": "63c695dc-6e85-42bb-b39b-1f0fd14ed5eb",
"metadata": {},
"source": [
"This tutorial will teach you the basics of using the Cozo database."
]
},
{
"cell_type": "markdown",
"id": "eb1fefcf-81b5-4ccf-8179-631fdb011bae",
"metadata": {},
"source": [
"The best way to learn from this tutorial is to run the queries as they are introduced.\n",
"For this, you need to install Cozo on your local machine."
]
},
{
"cell_type": "markdown",
"id": "7f26f0f5-a3ff-4145-a9d5-84c65e368afa",
"metadata": {},
"source": [
"Cozo is distributed as a single gzipped/zipped binary. \n",
"Go to https://github.com/cozodb/cozo/releases and download the latest release for your operating system to a local directory.\n",
"\n",
"If your operating system is Linux/Mac, \n",
"open a terminal command prompt, \n",
"`cd` into the directory of your download and run"
]
},
{
"cell_type": "markdown",
"id": "341d8539-d6e1-4610-bd1e-6c29568573a8",
"metadata": {},
"source": [
"```bash\n",
"gunzip cozoserver-*.gz\n",
"mv cozoserver-* cozoserver\n",
"chmod +x cozoserver\n",
"```"
]
},
{
"cell_type": "markdown",
"id": "536fb265-e25f-469d-843e-935b272c7298",
"metadata": {},
"source": [
"If you are on Windows instead, open a PowerShell and run"
]
},
{
"cell_type": "markdown",
"id": "9809d37e-b1b3-4419-8c19-5fe7bc8994a6",
"metadata": {},
"source": [
"```powershell\n",
"Expand-Archive -Path .\\cozoserver-*.zip -DestinationPath .\n",
"```"
]
},
{
"cell_type": "markdown",
"id": "12da9726-3c18-4011-98ea-e2aae105ee08",
"metadata": {},
"source": [
"To run the server, you need to specify a directory to store persistent data on your file system. \n",
"In the following, we will use a directory called `tutorial-data` in the same directory as the binary executable.\n",
"Run:"
]
},
{
"cell_type": "markdown",
"id": "59c6fdfc-1a3c-4da3-8138-6c653592995f",
"metadata": {},
"source": [
"```bash\n",
"./cozoserver ./tutorial-data\n",
"```"
]
},
{
"cell_type": "markdown",
"id": "41820cf5-a800-4c81-8a17-227e9692aae2",
"metadata": {},
"source": [
"The same command should work in PowerShell as well.\n",
"\n",
"If you see something like `Database web API running at ...` displayed in your terminal, \n",
"then the server is successfully started. \n",
"Keep the server running when you are following the rest of the tutorial.\n",
"When you are done, `CTRL-C` will stop the server."
]
},
{
"cell_type": "markdown",
"id": "2ec06d2e-1187-48c8-8777-f84b4c71c741",
"metadata": {},
"source": [
"## A place to run queries\n",
"\n",
"Cozo exposes an HTTP API, so theoretically you can follow along using tools like `curl`, as described [here](https://cozodb.github.io/current/manual/setup.html#making-http-requests).\n",
"But for a better user experience, we suggest following one of the following two subsections instead."
]
},
{
"cell_type": "markdown",
"id": "c4e8b790-7c0f-4538-b20e-2c3fb4065dc8",
"metadata": {},
"source": [
"### Option 1: the JupyterLab notebook\n",
"\n",
"This option provides the best user experience but requires you to install [Python](https://www.python.org/downloads/) and some other stuff.\n",
"After you have Python installed, install [JupyterLab](https://jupyter.org/install).\n",
"Next, run the following in a terminal to install a Jupyter extension to help query Cozo:"
]
},
{
"cell_type": "markdown",
"id": "37b47a25-3708-490d-ba08-975771dc469d",
"metadata": {},
"source": [
"```bash\n",
"pip install pycozo pandas\n",
"```"
]
},
{
"cell_type": "markdown",
"id": "9c07f306-9abc-4dd2-b78c-5b46a823982e",
"metadata": {},
"source": [
"While you are at it, right-click on https://raw.githubusercontent.com/cozodb/cozo/main/docs/tutorial/tutorial.ipynb \n",
"and save the notebook of this tutorial to your disk.\n",
"\n",
"Then run Jupyter Lab and open the saved tutorial document."
]
},
{
"cell_type": "markdown",
"id": "5154e084-d997-4f22-97fb-ce5808fb1da3",
"metadata": {},
"source": [
"We need to enable the extension in the notebook. Run"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "2e0d11d7-64d7-4577-a28d-7541ee8875fa",
"metadata": {},
"outputs": [],
"source": [
"%load_ext pycozo.ipyext_direct"
]
},
{
"cell_type": "markdown",
"id": "c3f0d80d-9854-4a21-9121-3220e7bcc73b",
"metadata": {},
"source": [
"Then run the \"hello world\" query to verify everything works:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "f3dfb8a1-35f0-4dc2-b8d7-e81fa3d45b75",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_d2f0e_row0_col0, #T_d2f0e_row0_col1, #T_d2f0e_row0_col2 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_d2f0e\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_d2f0e_level0_col0\" class=\"col_heading level0 col0\" >0</th>\n",
" <th id=\"T_d2f0e_level0_col1\" class=\"col_heading level0 col1\" >1</th>\n",
" <th id=\"T_d2f0e_level0_col2\" class=\"col_heading level0 col2\" >2</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_d2f0e_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_d2f0e_row0_col0\" class=\"data row0 col0\" >hello</td>\n",
" <td id=\"T_d2f0e_row0_col1\" class=\"data row0 col1\" >world</td>\n",
" <td id=\"T_d2f0e_row0_col2\" class=\"data row0 col2\" >Cozo!</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x10419b3a0>"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[] <- [['hello', 'world', 'Cozo!']]"
]
},
{
"cell_type": "markdown",
"id": "7e6dda2a-393a-4d87-8ba1-41c5d0b229d5",
"metadata": {},
"source": [
"If you get the same words back formatted in a table, congratulations! \n",
"You can skip to the next section where we start learning CozoScript proper."
]
},
{
"cell_type": "markdown",
"id": "ac86f14f-72c7-4206-9e6b-6daf9e77b67a",
"metadata": {},
"source": [
"### Option 2: the JavaScript console in your browser"
]
},
{
"cell_type": "markdown",
"id": "8ddc55d2-604b-4218-af45-8c62d79db201",
"metadata": {},
"source": [
"If you have never used Python before, the first option may be overwhelming. "
]
},
{
"cell_type": "markdown",
"id": "1147466d-d925-4c32-8b6c-28bdabc656fb",
"metadata": {},
"source": [
"Whatever your reason for not wanting to install the whole python toolchain, \n",
"if your local machine has a modern web browser such as a recent version of Firefox, Chrome, or Edge, \n",
"you can use this option.\n",
"\n",
"Use your browser to navigate to http://127.0.0.1:9070 (the address shown in your terminal when you run `cozoserver`).\n",
"You should be greeted by a page saying that the server is running.\n",
"Now open the developer tools of your browser by right-clicking the page and selecting \"Inspect\" from the menu \n",
"(if you cannot find it, you may need to fiddle with your browser settings to enable the developer tools).\n",
"Switch to the \"Console\" tab of the developer tools if it is not already open. \n",
"\n",
"If you see some messages where \n",
"the `Cozo Makeshift Javascript Console` welcomes you, you are ready. Run the \"hello world\" query by typing the following into the console and pressing enter:"
]
},
{
"cell_type": "markdown",
"id": "97547c5d-e2b4-4205-ac10-b2aeb5855782",
"metadata": {},
"source": [
"```javascript\n",
"await run(`?[] <- [['hello', 'world', 'Cozo!']]`)\n",
"```"
]
},
{
"cell_type": "markdown",
"id": "81fe58e2-3c52-4859-828d-533b25a62468",
"metadata": {},
"source": [
"If you see the three words echoed back in a table, you are successful. When following the tutorial, you have to wrap all queries within the backticks `` in the above command to run them in the JavaScript console."
]
},
{
"cell_type": "markdown",
"id": "545ed77c-eeb9-4008-972e-0bdc1d6b7478",
"metadata": {},
"source": [
"## Your first relations"
]
},
{
"cell_type": "markdown",
"id": "61d8ce38-d2e0-4b5f-a9f7-64e9a65e0fe0",
"metadata": {},
"source": [
"Cozo is a relational database. The \"hello world\" query"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "30b8148b-4daa-4de0-a844-d8254a07d990",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_4bee8_row0_col0, #T_4bee8_row0_col1, #T_4bee8_row0_col2 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_4bee8\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_4bee8_level0_col0\" class=\"col_heading level0 col0\" >0</th>\n",
" <th id=\"T_4bee8_level0_col1\" class=\"col_heading level0 col1\" >1</th>\n",
" <th id=\"T_4bee8_level0_col2\" class=\"col_heading level0 col2\" >2</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_4bee8_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_4bee8_row0_col0\" class=\"data row0 col0\" >hello</td>\n",
" <td id=\"T_4bee8_row0_col1\" class=\"data row0 col1\" >world</td>\n",
" <td id=\"T_4bee8_row0_col2\" class=\"data row0 col2\" >Cozo!</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x1041c7e20>"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[] <- [['hello', 'world', 'Cozo!']]"
]
},
{
"cell_type": "markdown",
"id": "a7de1353-7970-41ee-843e-cbe6287ded8d",
"metadata": {},
"source": [
"simply passes an ad hoc relation represented by a list of lists to the database, and the database echoes it back.\n",
"\n",
"You can pass more rows, or a different number of columns:"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "27995b4b-35b3-427f-af32-c3945d177463",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_58a87_row0_col0, #T_58a87_row0_col1, #T_58a87_row0_col2 {\n",
" color: #307fc1;\n",
"}\n",
"#T_58a87_row1_col0, #T_58a87_row1_col1, #T_58a87_row1_col2 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_58a87\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_58a87_level0_col0\" class=\"col_heading level0 col0\" >0</th>\n",
" <th id=\"T_58a87_level0_col1\" class=\"col_heading level0 col1\" >1</th>\n",
" <th id=\"T_58a87_level0_col2\" class=\"col_heading level0 col2\" >2</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_58a87_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_58a87_row0_col0\" class=\"data row0 col0\" >1</td>\n",
" <td id=\"T_58a87_row0_col1\" class=\"data row0 col1\" >2</td>\n",
" <td id=\"T_58a87_row0_col2\" class=\"data row0 col2\" >3</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_58a87_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
" <td id=\"T_58a87_row1_col0\" class=\"data row1 col0\" >a</td>\n",
" <td id=\"T_58a87_row1_col1\" class=\"data row1 col1\" >b</td>\n",
" <td id=\"T_58a87_row1_col2\" class=\"data row1 col2\" >c</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x11998c220>"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[] <- [[1, 2, 3], ['a', 'b', 'c']]"
]
},
{
"cell_type": "markdown",
"id": "f56c15a0-8359-4d90-b35d-aa21991acb96",
"metadata": {},
"source": [
"This example shows how to enter literals for numbers, strings, booleans and `null`:"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "54901c40-ff7e-4c26-bfed-0d38aa7a80dc",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_4e10f_row0_col0, #T_4e10f_row0_col1, #T_4e10f_row0_col3, #T_4e10f_row1_col0, #T_4e10f_row1_col1, #T_4e10f_row1_col2, #T_4e10f_row1_col3, #T_4e10f_row1_col4 {\n",
" color: #307fc1;\n",
"}\n",
"#T_4e10f_row0_col2 {\n",
" color: #bf5b3d;\n",
"}\n",
"#T_4e10f_row0_col4, #T_4e10f_row2_col0, #T_4e10f_row2_col1, #T_4e10f_row2_col2, #T_4e10f_row2_col3, #T_4e10f_row2_col4 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_4e10f\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_4e10f_level0_col0\" class=\"col_heading level0 col0\" >0</th>\n",
" <th id=\"T_4e10f_level0_col1\" class=\"col_heading level0 col1\" >1</th>\n",
" <th id=\"T_4e10f_level0_col2\" class=\"col_heading level0 col2\" >2</th>\n",
" <th id=\"T_4e10f_level0_col3\" class=\"col_heading level0 col3\" >3</th>\n",
" <th id=\"T_4e10f_level0_col4\" class=\"col_heading level0 col4\" >4</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_4e10f_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_4e10f_row0_col0\" class=\"data row0 col0\" >True</td>\n",
" <td id=\"T_4e10f_row0_col1\" class=\"data row0 col1\" >False</td>\n",
" <td id=\"T_4e10f_row0_col2\" class=\"data row0 col2\" >None</td>\n",
" <td id=\"T_4e10f_row0_col3\" class=\"data row0 col3\" >-0.014000</td>\n",
" <td id=\"T_4e10f_row0_col4\" class=\"data row0 col4\" >A string with double quotes</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_4e10f_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
" <td id=\"T_4e10f_row1_col0\" class=\"data row1 col0\" >1.500000</td>\n",
" <td id=\"T_4e10f_row1_col1\" class=\"data row1 col1\" >2.500000</td>\n",
" <td id=\"T_4e10f_row1_col2\" class=\"data row1 col2\" >3</td>\n",
" <td id=\"T_4e10f_row1_col3\" class=\"data row1 col3\" >4</td>\n",
" <td id=\"T_4e10f_row1_col4\" class=\"data row1 col4\" >5.500000</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_4e10f_level0_row2\" class=\"row_heading level0 row2\" >2</th>\n",
" <td id=\"T_4e10f_row2_col0\" class=\"data row2 col0\" >aA</td>\n",
" <td id=\"T_4e10f_row2_col1\" class=\"data row2 col1\" >bB</td>\n",
" <td id=\"T_4e10f_row2_col2\" class=\"data row2 col2\" >cC</td>\n",
" <td id=\"T_4e10f_row2_col3\" class=\"data row2 col3\" >dD</td>\n",
" <td id=\"T_4e10f_row2_col4\" class=\"data row2 col4\" >eE</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x11993ff70>"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[] <- [[1.5, 2.5, 3, 4, 5.5], \n",
" ['aA', 'bB', 'cC', 'dD', 'eE'], \n",
" [true, false, null, -1.4e-2, \"A string with double quotes\"]]"
]
},
{
"cell_type": "markdown",
"id": "615e35d7-f5c0-4d71-ac62-6934c658a715",
"metadata": {},
"source": [
"The input literal representations are similar to those in JavaScript. \n",
"In particular, strings in double quotes are guaranteed to be interpreted in the same way as in JSON.\n",
"The output are in JSON, but how they appear on your screen depends on your setup.\n",
"For example, if you are using a Python setup, booleans are displayed as `True` and `False` instead of in lowercase,\n",
"since they are converted to the native Python datatypes for display."
]
},
{
"cell_type": "markdown",
"id": "1d76ab84-36a3-4d1d-9da2-a891de52b011",
"metadata": {},
"source": [
"In the last example, you may have noticed that the returned order is not the same as the input order.\n",
"This is because in Cozo relations are always stored as trees, and trees are always sorted.\n",
"\n",
"Another consequence of relations as trees is that you can have no duplicate rows:"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "28ab3f6e-0e32-486d-83fb-4fd5581e20dc",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_c5064_row0_col0, #T_c5064_row1_col0 {\n",
" color: #307fc1;\n",
"}\n",
"</style>\n",
"<table id=\"T_c5064\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_c5064_level0_col0\" class=\"col_heading level0 col0\" >0</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_c5064_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_c5064_row0_col0\" class=\"data row0 col0\" >1</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_c5064_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
" <td id=\"T_c5064_row1_col0\" class=\"data row1 col0\" >2</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x11998c580>"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[] <- [[1], [2], [1], [2], [1]]"
]
},
{
"cell_type": "markdown",
"id": "5a5d9022-c9b2-48c9-b447-ae69a2fc3a21",
"metadata": {},
"source": [
"Relations in Cozo follow _set semantics_ where de-duplication is automatic. \n",
"By contrast, SQL usually follows _bag semantics_ (some databases do this by secretly having a unique internal key for every row, in Cozo you must do this explicitly if you need to simulate duplicate rows).\n",
"\n",
"Why does Cozo break tradition and go with set semantics?\n",
"Set semantics is much more convenient when you have recursions between relations involved,\n",
"and Cozo is designed to deal with complex recursions."
]
},
{
"cell_type": "markdown",
"id": "bcdfc9e4-1bc4-4473-8dd5-44097a164fbe",
"metadata": {},
"source": [
"## Expressions"
]
},
{
"cell_type": "markdown",
"id": "09dd8c4c-fb0e-4f53-9dec-b3fbcb6dce5b",
"metadata": {},
"source": [
"The next example shows the use of various expressions and comments:"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "dff14dab-2cc1-4917-aaa5-8feb1f075cf9",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_24cd6_row0_col0, #T_24cd6_row0_col1, #T_24cd6_row0_col2, #T_24cd6_row0_col3, #T_24cd6_row0_col4, #T_24cd6_row0_col5, #T_24cd6_row0_col7 {\n",
" color: #307fc1;\n",
"}\n",
"#T_24cd6_row0_col6 {\n",
" color: black;\n",
"}\n",
"#T_24cd6_row0_col8 {\n",
" color: #bf5b3d;\n",
"}\n",
"</style>\n",
"<table id=\"T_24cd6\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_24cd6_level0_col0\" class=\"col_heading level0 col0\" >0</th>\n",
" <th id=\"T_24cd6_level0_col1\" class=\"col_heading level0 col1\" >1</th>\n",
" <th id=\"T_24cd6_level0_col2\" class=\"col_heading level0 col2\" >2</th>\n",
" <th id=\"T_24cd6_level0_col3\" class=\"col_heading level0 col3\" >3</th>\n",
" <th id=\"T_24cd6_level0_col4\" class=\"col_heading level0 col4\" >4</th>\n",
" <th id=\"T_24cd6_level0_col5\" class=\"col_heading level0 col5\" >5</th>\n",
" <th id=\"T_24cd6_level0_col6\" class=\"col_heading level0 col6\" >6</th>\n",
" <th id=\"T_24cd6_level0_col7\" class=\"col_heading level0 col7\" >7</th>\n",
" <th id=\"T_24cd6_level0_col8\" class=\"col_heading level0 col8\" >8</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_24cd6_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_24cd6_row0_col0\" class=\"data row0 col0\" >3</td>\n",
" <td id=\"T_24cd6_row0_col1\" class=\"data row0 col1\" >0.750000</td>\n",
" <td id=\"T_24cd6_row0_col2\" class=\"data row0 col2\" >False</td>\n",
" <td id=\"T_24cd6_row0_col3\" class=\"data row0 col3\" >False</td>\n",
" <td id=\"T_24cd6_row0_col4\" class=\"data row0 col4\" >True</td>\n",
" <td id=\"T_24cd6_row0_col5\" class=\"data row0 col5\" >False</td>\n",
" <td id=\"T_24cd6_row0_col6\" class=\"data row0 col6\" >hello</td>\n",
" <td id=\"T_24cd6_row0_col7\" class=\"data row0 col7\" >0.454613</td>\n",
" <td id=\"T_24cd6_row0_col8\" class=\"data row0 col8\" >[1, 2, 3, 4, 5, 6, 7]</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x1041c4610>"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[] <- [[\n",
" 1 + 2, # addition\n",
" 3 / 4, # division\n",
" 5 == 6, # equality\n",
" 7 > 8, # greater\n",
" true || false, # or\n",
" false && true, # and\n",
" lowercase('HELLO'), # function\n",
" rand_float(), # function taking no argument\n",
" union([1, 2, 3], [3, 4, 5], [5, 6, 7]), # variadic function\n",
" ]]"
]
},
{
"cell_type": "markdown",
"id": "4c5ee182-2ca8-49b3-8937-19da63124143",
"metadata": {},
"source": [
"See [here](https://cozodb.github.io/current/manual/functions.html) for the full list of functions you can use to build expressions.\n",
"The syntax is deliberately C-like."
]
},
{
"cell_type": "markdown",
"id": "1bcc26ff-9901-4d6e-a895-cb77dbfafe3a",
"metadata": {},
"source": [
"## Rules and relations"
]
},
{
"cell_type": "markdown",
"id": "0eefa79d-a14e-4179-81b0-04da2b47c498",
"metadata": {},
"source": [
"Previous examples all start with `?[] <-`.\n",
"The notation denotes a _rule_ named `?`. It is a _constant rule_ since it uses `<-`.\n",
"The part after `?` and before `<-` is the _head_ of the rule, and the part after `<-` is the _body_.\n",
"\n",
"Rules can have other names, but the rule named `?` is special in that its evaluation determines the return relation of the query.\n",
"\n",
"We can give _bindings_ in the _head_ of rules:"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "2a35a414-7037-4a2a-a07b-086463a4d4ef",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_3df08_row0_col0, #T_3df08_row0_col1, #T_3df08_row0_col2 {\n",
" color: #307fc1;\n",
"}\n",
"#T_3df08_row1_col0, #T_3df08_row1_col1, #T_3df08_row1_col2 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_3df08\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_3df08_level0_col0\" class=\"col_heading level0 col0\" >first</th>\n",
" <th id=\"T_3df08_level0_col1\" class=\"col_heading level0 col1\" >second</th>\n",
" <th id=\"T_3df08_level0_col2\" class=\"col_heading level0 col2\" >third</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_3df08_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_3df08_row0_col0\" class=\"data row0 col0\" >1</td>\n",
" <td id=\"T_3df08_row0_col1\" class=\"data row0 col1\" >2</td>\n",
" <td id=\"T_3df08_row0_col2\" class=\"data row0 col2\" >3</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_3df08_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
" <td id=\"T_3df08_row1_col0\" class=\"data row1 col0\" >a</td>\n",
" <td id=\"T_3df08_row1_col1\" class=\"data row1 col1\" >b</td>\n",
" <td id=\"T_3df08_row1_col2\" class=\"data row1 col2\" >c</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x1041c7040>"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[first, second, third] <- [[1, 2, 3], ['a', 'b', 'c']]"
]
},
{
"cell_type": "markdown",
"id": "ba32d27c-0787-48d3-94fb-79e77a8cce0c",
"metadata": {},
"source": [
"For constant rules, the number of bindings must match the actual data (the _arity_), otherwise, you will get an error:"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "b25901e4-fc6a-4cb0-9ca2-b9aeac80cc83",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"\u001b[31mparser::fixed_rule_head_arity_mismatch\u001b[0m\n",
"\n",
" \u001b[31m×\u001b[0m Fixed rule head arity mismatch\n",
" ╭────\n",
" \u001b[2m1\u001b[0m │ ?[first, second] <- [[1, 2, 3], ['a', 'b', 'c']]\n",
" · \u001b[35;1m─────────────────────────────────────────────────\u001b[0m\n",
" ╰────\n",
"\u001b[36m help: \u001b[0mExpected arity: 3, number of arguments given: 2\n"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[first, second] <- [[1, 2, 3], ['a', 'b', 'c']]"
]
},
{
"cell_type": "markdown",
"id": "c71fb449-6a9c-4a7e-bed9-44230a41d5dd",
"metadata": {},
"source": [
"Now let's define rules that _apply_ (use) other rules:"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "bc63b0b2-fa28-4d02-be90-23690f6021aa",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_3af6d_row0_col0, #T_3af6d_row0_col1, #T_3af6d_row0_col2 {\n",
" color: #307fc1;\n",
"}\n",
"#T_3af6d_row1_col0, #T_3af6d_row1_col1, #T_3af6d_row1_col2 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_3af6d\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_3af6d_level0_col0\" class=\"col_heading level0 col0\" >a</th>\n",
" <th id=\"T_3af6d_level0_col1\" class=\"col_heading level0 col1\" >b</th>\n",
" <th id=\"T_3af6d_level0_col2\" class=\"col_heading level0 col2\" >c</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_3af6d_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_3af6d_row0_col0\" class=\"data row0 col0\" >1</td>\n",
" <td id=\"T_3af6d_row0_col1\" class=\"data row0 col1\" >2</td>\n",
" <td id=\"T_3af6d_row0_col2\" class=\"data row0 col2\" >3</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_3af6d_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
" <td id=\"T_3af6d_row1_col0\" class=\"data row1 col0\" >a</td>\n",
" <td id=\"T_3af6d_row1_col1\" class=\"data row1 col1\" >b</td>\n",
" <td id=\"T_3af6d_row1_col2\" class=\"data row1 col2\" >c</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x11993fe50>"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"rule[first, second, third] <- [[1, 2, 3], ['a', 'b', 'c']]\n",
"?[a, b, c] := rule[a, b, c]"
]
},
{
"cell_type": "markdown",
"id": "d86d57af-fadb-441a-926f-142c613ca1f7",
"metadata": {},
"source": [
"This first line defines a constant rule named `rule`. The `?` rule is now an _inline rule_, denoted by the connecting symbol `:=`. In its body it applies the fixed rule, by giving the name of the rule followed by three _fresh bindings_, which are the _variables_ `a`, `b` and `c`.\n",
"\n",
"With inline rules, you can manipulate the order of the columns, or specify which columns are returned:"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "d5d52704-e2ed-430c-b9da-939964f7b8e0",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_e35b4_row0_col0, #T_e35b4_row0_col1 {\n",
" color: #307fc1;\n",
"}\n",
"#T_e35b4_row1_col0, #T_e35b4_row1_col1 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_e35b4\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_e35b4_level0_col0\" class=\"col_heading level0 col0\" >c</th>\n",
" <th id=\"T_e35b4_level0_col1\" class=\"col_heading level0 col1\" >b</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_e35b4_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_e35b4_row0_col0\" class=\"data row0 col0\" >3</td>\n",
" <td id=\"T_e35b4_row0_col1\" class=\"data row0 col1\" >2</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_e35b4_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
" <td id=\"T_e35b4_row1_col0\" class=\"data row1 col0\" >c</td>\n",
" <td id=\"T_e35b4_row1_col1\" class=\"data row1 col1\" >b</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119cfead0>"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"rule[first, second, third] <- [[1, 2, 3], ['a', 'b', 'c']]\n",
"?[c, b] := rule[a, b, c]"
]
},
{
"cell_type": "markdown",
"id": "fb8a68dc-ab27-494b-86cd-b38502ea1a7c",
"metadata": {},
"source": [
"The body of an inline rule consists of _atoms_. \n",
"The previous example has a single _application atom_ as the body. Multiple atoms are connected by commas:"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "657050ce-5c99-494b-b2e7-283ae73de8fe",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_67dab_row0_col0, #T_67dab_row0_col1 {\n",
" color: #307fc1;\n",
"}\n",
"</style>\n",
"<table id=\"T_67dab\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_67dab_level0_col0\" class=\"col_heading level0 col0\" >c</th>\n",
" <th id=\"T_67dab_level0_col1\" class=\"col_heading level0 col1\" >b</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_67dab_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_67dab_row0_col0\" class=\"data row0 col0\" >3</td>\n",
" <td id=\"T_67dab_row0_col1\" class=\"data row0 col1\" >2</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119cffdc0>"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[c, b] := rule[a, b, c], is_num(a)\n",
"rule[first, second, third] <- [[1, 2, 3], ['a', 'b', 'c']]"
]
},
{
"cell_type": "markdown",
"id": "15c68fce-5318-453d-9e59-aee862ed5036",
"metadata": {},
"source": [
"Here the second atom is an _expression_ `is_num(a)`. \n",
"Expression atoms act as filters, so only rows for which the expression evaluates to `true` are returned. \n",
"The order in which the rules are given is immaterial."
]
},
{
"cell_type": "markdown",
"id": "7793c44a-302c-4ed1-985e-4951c0a78b20",
"metadata": {},
"source": [
"You can also bind constants to rule applications directly:"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "44745ced-563b-41ce-aace-ce43f7ada7f7",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_942ad_row0_col0, #T_942ad_row0_col1 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_942ad\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_942ad_level0_col0\" class=\"col_heading level0 col0\" >c</th>\n",
" <th id=\"T_942ad_level0_col1\" class=\"col_heading level0 col1\" >b</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_942ad_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_942ad_row0_col0\" class=\"data row0 col0\" >c</td>\n",
" <td id=\"T_942ad_row0_col1\" class=\"data row0 col1\" >b</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119cfe2f0>"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"rule[first, second, third] <- [[1, 2, 3], ['a', 'b', 'c']]\n",
"?[c, b] := rule['a', b, c]"
]
},
{
"cell_type": "markdown",
"id": "40b1fc69-c118-4876-a2d5-5fd2d8931811",
"metadata": {},
"source": [
"You introduce additional bindings with the _unification operator_ `=`:"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "cf32547a-7def-4dec-8d05-77c7c910be2c",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_b06fd_row0_col0, #T_b06fd_row0_col1, #T_b06fd_row0_col2 {\n",
" color: #307fc1;\n",
"}\n",
"</style>\n",
"<table id=\"T_b06fd\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_b06fd_level0_col0\" class=\"col_heading level0 col0\" >c</th>\n",
" <th id=\"T_b06fd_level0_col1\" class=\"col_heading level0 col1\" >b</th>\n",
" <th id=\"T_b06fd_level0_col2\" class=\"col_heading level0 col2\" >d</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_b06fd_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_b06fd_row0_col0\" class=\"data row0 col0\" >3</td>\n",
" <td id=\"T_b06fd_row0_col1\" class=\"data row0 col1\" >2</td>\n",
" <td id=\"T_b06fd_row0_col2\" class=\"data row0 col2\" >9</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119cfd480>"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"rule[first, second, third] <- [[1, 2, 3], ['a', 'b', 'c']]\n",
"?[c, b, d] := rule[a, b, c], is_num(a), d = a + b + 2*c"
]
},
{
"cell_type": "markdown",
"id": "c5384db7-8cab-4262-94f5-a2b7298417e8",
"metadata": {},
"source": [
"Having multiple rule applications in the body generates every combination of the bindings:"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "59d2a912-50d6-474a-ae9b-74f024a58bdc",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_0358e_row0_col0, #T_0358e_row0_col1, #T_0358e_row1_col0, #T_0358e_row1_col1, #T_0358e_row2_col0, #T_0358e_row2_col1, #T_0358e_row3_col0, #T_0358e_row3_col1 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_0358e\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_0358e_level0_col0\" class=\"col_heading level0 col0\" >l1</th>\n",
" <th id=\"T_0358e_level0_col1\" class=\"col_heading level0 col1\" >l2</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_0358e_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_0358e_row0_col0\" class=\"data row0 col0\" >a</td>\n",
" <td id=\"T_0358e_row0_col1\" class=\"data row0 col1\" >B</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_0358e_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
" <td id=\"T_0358e_row1_col0\" class=\"data row1 col0\" >a</td>\n",
" <td id=\"T_0358e_row1_col1\" class=\"data row1 col1\" >C</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_0358e_level0_row2\" class=\"row_heading level0 row2\" >2</th>\n",
" <td id=\"T_0358e_row2_col0\" class=\"data row2 col0\" >b</td>\n",
" <td id=\"T_0358e_row2_col1\" class=\"data row2 col1\" >B</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_0358e_level0_row3\" class=\"row_heading level0 row3\" >3</th>\n",
" <td id=\"T_0358e_row3_col0\" class=\"data row3 col0\" >b</td>\n",
" <td id=\"T_0358e_row3_col1\" class=\"data row3 col1\" >C</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119cfc0d0>"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"r1[] <- [[1, 'a'], [2, 'b']]\n",
"r2[] <- [[2, 'B'], [3, 'C']]\n",
"\n",
"?[l1, l2] := r1[a, l1], \n",
" r2[b, l2]"
]
},
{
"cell_type": "markdown",
"id": "b26be73d-dc5c-400b-9af4-d3aa9af0c430",
"metadata": {},
"source": [
"This is a Cartesian join in relational algebra, as bindings in the rule applications are all distinct.\n",
"If bindings are reused, _implicit unification_ occurs, \n",
"which is a join in relational algebra:"
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "20256fd6-b5c0-4947-a860-021846bef5fa",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_23a14_row0_col0, #T_23a14_row0_col1 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_23a14\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_23a14_level0_col0\" class=\"col_heading level0 col0\" >l1</th>\n",
" <th id=\"T_23a14_level0_col1\" class=\"col_heading level0 col1\" >l2</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_23a14_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_23a14_row0_col0\" class=\"data row0 col0\" >b</td>\n",
" <td id=\"T_23a14_row0_col1\" class=\"data row0 col1\" >B</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119cfe950>"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"r1[] <- [[1, 'a'], [2, 'b']]\n",
"r2[] <- [[2, 'B'], [3, 'C']]\n",
"\n",
"?[l1, l2] := r1[a, l1], \n",
" r2[a, l2] # reused `a`"
]
},
{
"cell_type": "markdown",
"id": "bf4be53c-118f-46b8-9c42-cb259aed6e87",
"metadata": {},
"source": [
"The unification `=` unifies with a single value. Use `in` to unify with each value within a list in turn:"
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "5c7d2b90-8494-4521-aac6-2445473e50d7",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_babae_row0_col0, #T_babae_row1_col0, #T_babae_row2_col0, #T_babae_row3_col0, #T_babae_row4_col0, #T_babae_row5_col0 {\n",
" color: #307fc1;\n",
"}\n",
"#T_babae_row0_col1, #T_babae_row1_col1, #T_babae_row2_col1, #T_babae_row3_col1, #T_babae_row4_col1, #T_babae_row5_col1 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_babae\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_babae_level0_col0\" class=\"col_heading level0 col0\" >x</th>\n",
" <th id=\"T_babae_level0_col1\" class=\"col_heading level0 col1\" >y</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_babae_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_babae_row0_col0\" class=\"data row0 col0\" >1</td>\n",
" <td id=\"T_babae_row0_col1\" class=\"data row0 col1\" >x</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_babae_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
" <td id=\"T_babae_row1_col0\" class=\"data row1 col0\" >1</td>\n",
" <td id=\"T_babae_row1_col1\" class=\"data row1 col1\" >y</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_babae_level0_row2\" class=\"row_heading level0 row2\" >2</th>\n",
" <td id=\"T_babae_row2_col0\" class=\"data row2 col0\" >2</td>\n",
" <td id=\"T_babae_row2_col1\" class=\"data row2 col1\" >x</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_babae_level0_row3\" class=\"row_heading level0 row3\" >3</th>\n",
" <td id=\"T_babae_row3_col0\" class=\"data row3 col0\" >2</td>\n",
" <td id=\"T_babae_row3_col1\" class=\"data row3 col1\" >y</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_babae_level0_row4\" class=\"row_heading level0 row4\" >4</th>\n",
" <td id=\"T_babae_row4_col0\" class=\"data row4 col0\" >3</td>\n",
" <td id=\"T_babae_row4_col1\" class=\"data row4 col1\" >x</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_babae_level0_row5\" class=\"row_heading level0 row5\" >5</th>\n",
" <td id=\"T_babae_row5_col0\" class=\"data row5 col0\" >3</td>\n",
" <td id=\"T_babae_row5_col1\" class=\"data row5 col1\" >y</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119cfc610>"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[x, y] := x in [1, 2, 3], y in ['x', 'y']"
]
},
{
"cell_type": "markdown",
"id": "af092ab5-2692-4b12-a6a7-eae8def60cac",
"metadata": {},
"source": [
"The head of inline rules does not need to use all variables that appear in the body. \n",
"However, any variable in the head must appear in the body at least once (the _safety rule_):"
]
},
{
"cell_type": "code",
"execution_count": 18,
"id": "5a13303d-4f61-4bc5-85d1-391773a9bc7b",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"\u001b[31meval::unbound_symb_in_head\u001b[0m\n",
"\n",
" \u001b[31m×\u001b[0m Symbol 'x' in rule head is unbound\n",
" ╭─[3:1]\n",
" \u001b[2m3\u001b[0m │ \n",
" \u001b[2m4\u001b[0m │ ?[l1, l2, x] := r1[a, l1], \n",
" · \u001b[35;1m ─\u001b[0m\n",
" \u001b[2m5\u001b[0m │ r2[a, l2]\n",
" ╰────\n",
"\u001b[36m help: \u001b[0mNote that symbols occurring only in negated positions are not considered bound\n"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"r1[] <- [[1, 'a'], [2, 'b']]\n",
"r2[] <- [[2, 'B'], [3, 'C']]\n",
"\n",
"?[l1, l2, x] := r1[a, l1], \n",
" r2[a, l2]"
]
},
{
"cell_type": "markdown",
"id": "e0c1b973-4ecf-459d-99d9-bab9665a7d23",
"metadata": {},
"source": [
"## Stored relations"
]
},
{
"cell_type": "markdown",
"id": "cb7e8795-7b95-4653-958c-c9682f25e137",
"metadata": {},
"source": [
"Persistent relations in Cozo are called _stored relations_.\n",
"Creating them are simple:"
]
},
{
"cell_type": "code",
"execution_count": 19,
"id": "2944f226-c865-4fd6-b412-cb34e2e50705",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_bfa05_row0_col0 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_bfa05\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_bfa05_level0_col0\" class=\"col_heading level0 col0\" >status</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_bfa05_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_bfa05_row0_col0\" class=\"data row0 col0\" >OK</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119cfeb00>"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"r1[] <- [[1, 'a'], [2, 'b']]\n",
"r2[] <- [[2, 'B'], [3, 'C']]\n",
"\n",
"?[l1, l2] := r1[a, l1], \n",
" r2[a, l2]\n",
" \n",
":create stored {l1, l2}"
]
},
{
"cell_type": "markdown",
"id": "6e911e87-a80e-4b1b-a878-613b61e339bc",
"metadata": {},
"source": [
"The `:create` query option instructs the database to store the result in a stored relation named `stored`, containing the columns `l1` and `l2`.\n",
"\n",
"If you just want to create the relation without adding any data, you can omit the queries. No need to have an empty `?` query."
]
},
{
"cell_type": "markdown",
"id": "60c8509a-0aea-4d0b-9ca3-e8d0b00e73ad",
"metadata": {},
"source": [
"You can verify that you now have the required stored relation in your system by running a _system op_:"
]
},
{
"cell_type": "code",
"execution_count": 20,
"id": "e151e2e6-f185-4659-89c6-a274c643a03a",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_bf28e_row0_col0, #T_bf28e_row0_col2 {\n",
" color: black;\n",
"}\n",
"#T_bf28e_row0_col1, #T_bf28e_row0_col3, #T_bf28e_row0_col4, #T_bf28e_row0_col5, #T_bf28e_row0_col6, #T_bf28e_row0_col7 {\n",
" color: #307fc1;\n",
"}\n",
"</style>\n",
"<table id=\"T_bf28e\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_bf28e_level0_col0\" class=\"col_heading level0 col0\" >name</th>\n",
" <th id=\"T_bf28e_level0_col1\" class=\"col_heading level0 col1\" >arity</th>\n",
" <th id=\"T_bf28e_level0_col2\" class=\"col_heading level0 col2\" >access_level</th>\n",
" <th id=\"T_bf28e_level0_col3\" class=\"col_heading level0 col3\" >n_keys</th>\n",
" <th id=\"T_bf28e_level0_col4\" class=\"col_heading level0 col4\" >n_non_keys</th>\n",
" <th id=\"T_bf28e_level0_col5\" class=\"col_heading level0 col5\" >n_put_triggers</th>\n",
" <th id=\"T_bf28e_level0_col6\" class=\"col_heading level0 col6\" >n_rm_triggers</th>\n",
" <th id=\"T_bf28e_level0_col7\" class=\"col_heading level0 col7\" >n_replace_triggers</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_bf28e_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_bf28e_row0_col0\" class=\"data row0 col0\" >stored</td>\n",
" <td id=\"T_bf28e_row0_col1\" class=\"data row0 col1\" >2</td>\n",
" <td id=\"T_bf28e_row0_col2\" class=\"data row0 col2\" >normal</td>\n",
" <td id=\"T_bf28e_row0_col3\" class=\"data row0 col3\" >2</td>\n",
" <td id=\"T_bf28e_row0_col4\" class=\"data row0 col4\" >0</td>\n",
" <td id=\"T_bf28e_row0_col5\" class=\"data row0 col5\" >0</td>\n",
" <td id=\"T_bf28e_row0_col6\" class=\"data row0 col6\" >0</td>\n",
" <td id=\"T_bf28e_row0_col7\" class=\"data row0 col7\" >0</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119cff940>"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"::relations"
]
},
{
"cell_type": "markdown",
"id": "30d7999f-6939-497d-98d6-e5edc6af44a1",
"metadata": {},
"source": [
"You can also investigate the columns of the stored relation:"
]
},
{
"cell_type": "code",
"execution_count": 21,
"id": "fd8c4f13-96c8-4f3c-b295-ea493d3875f6",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_72e1b_row0_col0, #T_72e1b_row0_col3, #T_72e1b_row1_col0, #T_72e1b_row1_col3 {\n",
" color: black;\n",
"}\n",
"#T_72e1b_row0_col1, #T_72e1b_row0_col2, #T_72e1b_row0_col4, #T_72e1b_row1_col1, #T_72e1b_row1_col2, #T_72e1b_row1_col4 {\n",
" color: #307fc1;\n",
"}\n",
"</style>\n",
"<table id=\"T_72e1b\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_72e1b_level0_col0\" class=\"col_heading level0 col0\" >column</th>\n",
" <th id=\"T_72e1b_level0_col1\" class=\"col_heading level0 col1\" >is_key</th>\n",
" <th id=\"T_72e1b_level0_col2\" class=\"col_heading level0 col2\" >index</th>\n",
" <th id=\"T_72e1b_level0_col3\" class=\"col_heading level0 col3\" >type</th>\n",
" <th id=\"T_72e1b_level0_col4\" class=\"col_heading level0 col4\" >has_default</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_72e1b_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_72e1b_row0_col0\" class=\"data row0 col0\" >l1</td>\n",
" <td id=\"T_72e1b_row0_col1\" class=\"data row0 col1\" >True</td>\n",
" <td id=\"T_72e1b_row0_col2\" class=\"data row0 col2\" >0</td>\n",
" <td id=\"T_72e1b_row0_col3\" class=\"data row0 col3\" >Any?</td>\n",
" <td id=\"T_72e1b_row0_col4\" class=\"data row0 col4\" >False</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_72e1b_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
" <td id=\"T_72e1b_row1_col0\" class=\"data row1 col0\" >l2</td>\n",
" <td id=\"T_72e1b_row1_col1\" class=\"data row1 col1\" >True</td>\n",
" <td id=\"T_72e1b_row1_col2\" class=\"data row1 col2\" >1</td>\n",
" <td id=\"T_72e1b_row1_col3\" class=\"data row1 col3\" >Any?</td>\n",
" <td id=\"T_72e1b_row1_col4\" class=\"data row1 col4\" >False</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119cfcc40>"
]
},
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"::columns stored "
]
},
{
"cell_type": "markdown",
"id": "79d320aa-bf41-4676-a778-7ff00b704ced",
"metadata": {},
"source": [
"Stored relations can be applied by using an asterisk `*` before the name:"
]
},
{
"cell_type": "code",
"execution_count": 22,
"id": "3d4a2c70-7ed3-403b-9528-a696fe7b08a6",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_23ff9_row0_col0, #T_23ff9_row0_col1 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_23ff9\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_23ff9_level0_col0\" class=\"col_heading level0 col0\" >a</th>\n",
" <th id=\"T_23ff9_level0_col1\" class=\"col_heading level0 col1\" >b</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_23ff9_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_23ff9_row0_col0\" class=\"data row0 col0\" >b</td>\n",
" <td id=\"T_23ff9_row0_col1\" class=\"data row0 col1\" >B</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119cfd810>"
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[a, b] := *stored[a, b]"
]
},
{
"cell_type": "markdown",
"id": "821c1a1f-ef11-4429-ba99-c2599bc18857",
"metadata": {},
"source": [
"Unlike relations defined inline, the columns of stored relations have fixed names. \n",
"You can take advantage of this by selectively referring to columns by name,\n",
"especially if you have a lot of columns:"
]
},
{
"cell_type": "code",
"execution_count": 23,
"id": "dba56d3f-8162-4519-8934-12d5c6935239",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_da856_row0_col0, #T_da856_row0_col1 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_da856\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_da856_level0_col0\" class=\"col_heading level0 col0\" >a</th>\n",
" <th id=\"T_da856_level0_col1\" class=\"col_heading level0 col1\" >b</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_da856_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_da856_row0_col0\" class=\"data row0 col0\" >b</td>\n",
" <td id=\"T_da856_row0_col1\" class=\"data row0 col1\" >B</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119cffe80>"
]
},
"execution_count": 23,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[a, b] := *stored{l2: b, l1: a}"
]
},
{
"cell_type": "markdown",
"id": "135b9fb5-96fd-444b-aa44-ad8dd754318d",
"metadata": {},
"source": [
"If the binding is the same as the column name, you can omit the binding:"
]
},
{
"cell_type": "code",
"execution_count": 24,
"id": "a5a29a9c-5320-4c9f-a153-a96c662cf5d6",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_0c93e_row0_col0 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_0c93e\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_0c93e_level0_col0\" class=\"col_heading level0 col0\" >l2</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_0c93e_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_0c93e_row0_col0\" class=\"data row0 col0\" >B</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119cea980>"
]
},
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[l2] := *stored{l2}"
]
},
{
"cell_type": "markdown",
"id": "2424a684-89fb-449e-a5e6-931353bb482f",
"metadata": {},
"source": [
"After a stored relation is created, use `:put` to insert more data:"
]
},
{
"cell_type": "code",
"execution_count": 25,
"id": "eb8b4f2c-a2e7-45e3-8c18-6b6b8329344c",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_a30ba_row0_col0 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_a30ba\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_a30ba_level0_col0\" class=\"col_heading level0 col0\" >status</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_a30ba_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_a30ba_row0_col0\" class=\"data row0 col0\" >OK</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119cea500>"
]
},
"execution_count": 25,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[l1, l2] <- [['e', 'E']]\n",
" \n",
":put stored {l1, l2}"
]
},
{
"cell_type": "code",
"execution_count": 26,
"id": "ef21c6f3-ce5c-434c-a580-3d1442ebe7c6",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_a7154_row0_col0, #T_a7154_row0_col1, #T_a7154_row1_col0, #T_a7154_row1_col1 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_a7154\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_a7154_level0_col0\" class=\"col_heading level0 col0\" >l1</th>\n",
" <th id=\"T_a7154_level0_col1\" class=\"col_heading level0 col1\" >l2</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_a7154_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_a7154_row0_col0\" class=\"data row0 col0\" >b</td>\n",
" <td id=\"T_a7154_row0_col1\" class=\"data row0 col1\" >B</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_a7154_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
" <td id=\"T_a7154_row1_col0\" class=\"data row1 col0\" >e</td>\n",
" <td id=\"T_a7154_row1_col1\" class=\"data row1 col1\" >E</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119cfcd30>"
]
},
"execution_count": 26,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[l1, l2] := *stored[l1, l2]"
]
},
{
"cell_type": "markdown",
"id": "a58b487a-6a44-43c7-9351-b78a49770a46",
"metadata": {},
"source": [
"Use `:rm` to remove data:"
]
},
{
"cell_type": "code",
"execution_count": 27,
"id": "2c1d522b-286f-41be-9796-da165999e1df",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_f6576_row0_col0 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_f6576\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_f6576_level0_col0\" class=\"col_heading level0 col0\" >status</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_f6576_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_f6576_row0_col0\" class=\"data row0 col0\" >OK</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119cea4a0>"
]
},
"execution_count": 27,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[l1, l2] <- [['e', 'E']]\n",
" \n",
":rm stored {l1, l2}"
]
},
{
"cell_type": "code",
"execution_count": 28,
"id": "d9ce93f8-dc37-4c37-9f47-904066c1341a",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_6aab9_row0_col0, #T_6aab9_row0_col1 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_6aab9\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_6aab9_level0_col0\" class=\"col_heading level0 col0\" >l1</th>\n",
" <th id=\"T_6aab9_level0_col1\" class=\"col_heading level0 col1\" >l2</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_6aab9_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_6aab9_row0_col0\" class=\"data row0 col0\" >b</td>\n",
" <td id=\"T_6aab9_row0_col1\" class=\"data row0 col1\" >B</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119ceab90>"
]
},
"execution_count": 28,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[l1, l2] := *stored[l1, l2]"
]
},
{
"cell_type": "markdown",
"id": "1f70e3b5-0b96-42ce-8a34-9d45beaf1772",
"metadata": {},
"source": [
"Use `::remove` (double colon!) to get rid of a stored relation:"
]
},
{
"cell_type": "code",
"execution_count": 29,
"id": "f27e0eb3-711f-4d68-bd02-1e4cfddfd9ac",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_a72a1_row0_col0 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_a72a1\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_a72a1_level0_col0\" class=\"col_heading level0 col0\" >status</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_a72a1_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_a72a1_row0_col0\" class=\"data row0 col0\" >OK</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119cead10>"
]
},
"execution_count": 29,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"::remove stored"
]
},
{
"cell_type": "code",
"execution_count": 30,
"id": "c938ecd5-8166-4f78-8fa1-234c75691d5e",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"</style>\n",
"<table id=\"T_17c42\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_17c42_level0_col0\" class=\"col_heading level0 col0\" >name</th>\n",
" <th id=\"T_17c42_level0_col1\" class=\"col_heading level0 col1\" >arity</th>\n",
" <th id=\"T_17c42_level0_col2\" class=\"col_heading level0 col2\" >access_level</th>\n",
" <th id=\"T_17c42_level0_col3\" class=\"col_heading level0 col3\" >n_keys</th>\n",
" <th id=\"T_17c42_level0_col4\" class=\"col_heading level0 col4\" >n_non_keys</th>\n",
" <th id=\"T_17c42_level0_col5\" class=\"col_heading level0 col5\" >n_put_triggers</th>\n",
" <th id=\"T_17c42_level0_col6\" class=\"col_heading level0 col6\" >n_rm_triggers</th>\n",
" <th id=\"T_17c42_level0_col7\" class=\"col_heading level0 col7\" >n_replace_triggers</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119cfc910>"
]
},
"execution_count": 30,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"::relations"
]
},
{
"cell_type": "markdown",
"id": "df2bff7d-3164-409a-a7fd-4e074be7ecbc",
"metadata": {},
"source": [
"So far, all stored relations store all the data in their _keys_.\n",
"You can instruct Cozo to only treat some of the data as keys, thereby indicating a _functional dependency_:"
]
},
{
"cell_type": "code",
"execution_count": 31,
"id": "3a133dc0-5334-4acb-972a-305b5927941a",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_03fc6_row0_col0 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_03fc6\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_03fc6_level0_col0\" class=\"col_heading level0 col0\" >status</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_03fc6_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_03fc6_row0_col0\" class=\"data row0 col0\" >OK</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119ceacb0>"
]
},
"execution_count": 31,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[a, b, c] <- [[1, 'a', 'A'],\n",
" [2, 'b', 'B'],\n",
" [3, 'c', 'C'],\n",
" [4, 'd', 'D']]\n",
"\n",
":create fd {a, b => c}"
]
},
{
"cell_type": "code",
"execution_count": 32,
"id": "3ff9ac04-531d-4726-aeb2-d8feab7bc149",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_49466_row0_col0, #T_49466_row1_col0, #T_49466_row2_col0, #T_49466_row3_col0 {\n",
" color: #307fc1;\n",
"}\n",
"#T_49466_row0_col1, #T_49466_row0_col2, #T_49466_row1_col1, #T_49466_row1_col2, #T_49466_row2_col1, #T_49466_row2_col2, #T_49466_row3_col1, #T_49466_row3_col2 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_49466\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_49466_level0_col0\" class=\"col_heading level0 col0\" >a</th>\n",
" <th id=\"T_49466_level0_col1\" class=\"col_heading level0 col1\" >b</th>\n",
" <th id=\"T_49466_level0_col2\" class=\"col_heading level0 col2\" >c</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_49466_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_49466_row0_col0\" class=\"data row0 col0\" >1</td>\n",
" <td id=\"T_49466_row0_col1\" class=\"data row0 col1\" >a</td>\n",
" <td id=\"T_49466_row0_col2\" class=\"data row0 col2\" >A</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_49466_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
" <td id=\"T_49466_row1_col0\" class=\"data row1 col0\" >2</td>\n",
" <td id=\"T_49466_row1_col1\" class=\"data row1 col1\" >b</td>\n",
" <td id=\"T_49466_row1_col2\" class=\"data row1 col2\" >B</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_49466_level0_row2\" class=\"row_heading level0 row2\" >2</th>\n",
" <td id=\"T_49466_row2_col0\" class=\"data row2 col0\" >3</td>\n",
" <td id=\"T_49466_row2_col1\" class=\"data row2 col1\" >c</td>\n",
" <td id=\"T_49466_row2_col2\" class=\"data row2 col2\" >C</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_49466_level0_row3\" class=\"row_heading level0 row3\" >3</th>\n",
" <td id=\"T_49466_row3_col0\" class=\"data row3 col0\" >4</td>\n",
" <td id=\"T_49466_row3_col1\" class=\"data row3 col1\" >d</td>\n",
" <td id=\"T_49466_row3_col2\" class=\"data row3 col2\" >D</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119ceae00>"
]
},
"execution_count": 32,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[a, b, c] := *fd[a, b, c]"
]
},
{
"cell_type": "markdown",
"id": "53128ced-3edb-4f8a-bbff-506e7139711f",
"metadata": {},
"source": [
"Now if you insert another row with an existing key, that row will be updated:"
]
},
{
"cell_type": "code",
"execution_count": 33,
"id": "fd442640-4664-4f1c-a0a7-0a265d19ca74",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_f2cee_row0_col0 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_f2cee\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_f2cee_level0_col0\" class=\"col_heading level0 col0\" >status</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_f2cee_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_f2cee_row0_col0\" class=\"data row0 col0\" >OK</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119ceae60>"
]
},
"execution_count": 33,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[a, b, c] <- [[3, 'c', 'CCCCCCC']]\n",
"\n",
":put fd {a, b => c}"
]
},
{
"cell_type": "code",
"execution_count": 34,
"id": "980e4530-baec-40c5-9d68-e60d3dd8fb73",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_e80bc_row0_col0, #T_e80bc_row1_col0, #T_e80bc_row2_col0, #T_e80bc_row3_col0 {\n",
" color: #307fc1;\n",
"}\n",
"#T_e80bc_row0_col1, #T_e80bc_row0_col2, #T_e80bc_row1_col1, #T_e80bc_row1_col2, #T_e80bc_row2_col1, #T_e80bc_row2_col2, #T_e80bc_row3_col1, #T_e80bc_row3_col2 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_e80bc\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_e80bc_level0_col0\" class=\"col_heading level0 col0\" >a</th>\n",
" <th id=\"T_e80bc_level0_col1\" class=\"col_heading level0 col1\" >b</th>\n",
" <th id=\"T_e80bc_level0_col2\" class=\"col_heading level0 col2\" >c</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_e80bc_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_e80bc_row0_col0\" class=\"data row0 col0\" >1</td>\n",
" <td id=\"T_e80bc_row0_col1\" class=\"data row0 col1\" >a</td>\n",
" <td id=\"T_e80bc_row0_col2\" class=\"data row0 col2\" >A</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_e80bc_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
" <td id=\"T_e80bc_row1_col0\" class=\"data row1 col0\" >2</td>\n",
" <td id=\"T_e80bc_row1_col1\" class=\"data row1 col1\" >b</td>\n",
" <td id=\"T_e80bc_row1_col2\" class=\"data row1 col2\" >B</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_e80bc_level0_row2\" class=\"row_heading level0 row2\" >2</th>\n",
" <td id=\"T_e80bc_row2_col0\" class=\"data row2 col0\" >3</td>\n",
" <td id=\"T_e80bc_row2_col1\" class=\"data row2 col1\" >c</td>\n",
" <td id=\"T_e80bc_row2_col2\" class=\"data row2 col2\" >CCCCCCC</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_e80bc_level0_row3\" class=\"row_heading level0 row3\" >3</th>\n",
" <td id=\"T_e80bc_row3_col0\" class=\"data row3 col0\" >4</td>\n",
" <td id=\"T_e80bc_row3_col1\" class=\"data row3 col1\" >d</td>\n",
" <td id=\"T_e80bc_row3_col2\" class=\"data row3 col2\" >D</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119ceb8e0>"
]
},
"execution_count": 34,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[a, b, c] := *fd[a, b, c]"
]
},
{
"cell_type": "markdown",
"id": "4f84ee9b-46b2-448a-b399-914cf5d4d810",
"metadata": {},
"source": [
"You can check whether a column is in a key position by looking at the `is_key` column in:"
]
},
{
"cell_type": "code",
"execution_count": 35,
"id": "07bdf041-6b4f-4686-9aa5-3d95f323a397",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_8f431_row0_col0, #T_8f431_row0_col3, #T_8f431_row1_col0, #T_8f431_row1_col3, #T_8f431_row2_col0, #T_8f431_row2_col3 {\n",
" color: black;\n",
"}\n",
"#T_8f431_row0_col1, #T_8f431_row0_col2, #T_8f431_row0_col4, #T_8f431_row1_col1, #T_8f431_row1_col2, #T_8f431_row1_col4, #T_8f431_row2_col1, #T_8f431_row2_col2, #T_8f431_row2_col4 {\n",
" color: #307fc1;\n",
"}\n",
"</style>\n",
"<table id=\"T_8f431\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_8f431_level0_col0\" class=\"col_heading level0 col0\" >column</th>\n",
" <th id=\"T_8f431_level0_col1\" class=\"col_heading level0 col1\" >is_key</th>\n",
" <th id=\"T_8f431_level0_col2\" class=\"col_heading level0 col2\" >index</th>\n",
" <th id=\"T_8f431_level0_col3\" class=\"col_heading level0 col3\" >type</th>\n",
" <th id=\"T_8f431_level0_col4\" class=\"col_heading level0 col4\" >has_default</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_8f431_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_8f431_row0_col0\" class=\"data row0 col0\" >a</td>\n",
" <td id=\"T_8f431_row0_col1\" class=\"data row0 col1\" >True</td>\n",
" <td id=\"T_8f431_row0_col2\" class=\"data row0 col2\" >0</td>\n",
" <td id=\"T_8f431_row0_col3\" class=\"data row0 col3\" >Any?</td>\n",
" <td id=\"T_8f431_row0_col4\" class=\"data row0 col4\" >False</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_8f431_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
" <td id=\"T_8f431_row1_col0\" class=\"data row1 col0\" >b</td>\n",
" <td id=\"T_8f431_row1_col1\" class=\"data row1 col1\" >True</td>\n",
" <td id=\"T_8f431_row1_col2\" class=\"data row1 col2\" >1</td>\n",
" <td id=\"T_8f431_row1_col3\" class=\"data row1 col3\" >Any?</td>\n",
" <td id=\"T_8f431_row1_col4\" class=\"data row1 col4\" >False</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_8f431_level0_row2\" class=\"row_heading level0 row2\" >2</th>\n",
" <td id=\"T_8f431_row2_col0\" class=\"data row2 col0\" >c</td>\n",
" <td id=\"T_8f431_row2_col1\" class=\"data row2 col1\" >False</td>\n",
" <td id=\"T_8f431_row2_col2\" class=\"data row2 col2\" >2</td>\n",
" <td id=\"T_8f431_row2_col3\" class=\"data row2 col3\" >Any?</td>\n",
" <td id=\"T_8f431_row2_col4\" class=\"data row2 col4\" >False</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119ce91e0>"
]
},
"execution_count": 35,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"::columns fd"
]
},
{
"cell_type": "markdown",
"id": "183002b2-1041-4843-a3a8-d1496ec6a4b6",
"metadata": {},
"source": [
"You may have noticed that columns also have types and default values associated with them, and stored relations can have triggers. These are discussed in the [manual](https://cozodb.github.io/current/manual/stored.html).\n",
"We won't overload you with all the complexities in this tutorial."
]
},
{
"cell_type": "markdown",
"id": "30504cd6-7fb6-4ae3-ba2c-79eefa288095",
"metadata": {},
"source": [
"Before continuing, let's remove the stored relation we introduced:"
]
},
{
"cell_type": "code",
"execution_count": 36,
"id": "8e70a093-600c-48c5-90f5-ff3f340287d2",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_f31b9_row0_col0 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_f31b9\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_f31b9_level0_col0\" class=\"col_heading level0 col0\" >status</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_f31b9_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_f31b9_row0_col0\" class=\"data row0 col0\" >OK</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119ce9600>"
]
},
"execution_count": 36,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"::remove fd"
]
},
{
"cell_type": "markdown",
"id": "4b702c08-b59a-451c-826c-919a533b9094",
"metadata": {},
"source": [
"## Graphs"
]
},
{
"cell_type": "markdown",
"id": "f22421f2-6492-4e0a-a66b-672ff7a3d3b5",
"metadata": {},
"source": [
"Now let's consider a graph stored as a relation:"
]
},
{
"cell_type": "code",
"execution_count": 37,
"id": "fba82f6e-124b-478d-893d-b69bc79680cc",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_f620e_row0_col0 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_f620e\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_f620e_level0_col0\" class=\"col_heading level0 col0\" >status</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_f620e_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_f620e_row0_col0\" class=\"data row0 col0\" >OK</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119d21510>"
]
},
"execution_count": 37,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[loving, loved] <- [['alice', 'eve'],\n",
" ['bob', 'alice'],\n",
" ['eve', 'alice'],\n",
" ['eve', 'bob'],\n",
" ['eve', 'charlie'],\n",
" ['charlie', 'eve'],\n",
" ['david', 'george'],\n",
" ['george', 'george']]\n",
"\n",
":replace love {loving, loved}"
]
},
{
"cell_type": "markdown",
"id": "8b1cf760-0989-48b3-aaed-3270c2d188bf",
"metadata": {},
"source": [
"The graph we have created reads like \"Alice loves Eve, Bob loves Alice\", \"nobody loves David, David loves George, but George only loves himself\", and so on. \n",
"Here we used `:replace` instead of `:create`. The difference is that if `love` already exists, it will be wiped and replaced with the new data given."
]
},
{
"cell_type": "markdown",
"id": "59d559f0-3325-4bee-b209-3dbe26c3b90c",
"metadata": {},
"source": [
"We can investigate competing interests:"
]
},
{
"cell_type": "code",
"execution_count": 38,
"id": "64fb79e4-381e-4190-ac19-05b53e76cf6b",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_bbe61_row0_col0 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_bbe61\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_bbe61_level0_col0\" class=\"col_heading level0 col0\" >loved_by_b_e</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_bbe61_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_bbe61_row0_col0\" class=\"data row0 col0\" >alice</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119d232b0>"
]
},
"execution_count": 38,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[loved_by_b_e] := *love['eve', loved_by_b_e], *love['bob', loved_by_b_e]"
]
},
{
"cell_type": "markdown",
"id": "48fa9636-5727-4984-af6e-f318c3e98b85",
"metadata": {},
"source": [
"So far we rule bodies consist of _conjunction_ of atoms only. Disjunction is also available, by using the `or` keyword:"
]
},
{
"cell_type": "code",
"execution_count": 39,
"id": "132c8855-cca2-4cb3-ae53-53d2ff92f4a9",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_02cc0_row0_col0, #T_02cc0_row1_col0 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_02cc0\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_02cc0_level0_col0\" class=\"col_heading level0 col0\" >loved_by_b_e</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_02cc0_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_02cc0_row0_col0\" class=\"data row0 col0\" >alice</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_02cc0_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
" <td id=\"T_02cc0_row1_col0\" class=\"data row1 col0\" >charlie</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119d20a00>"
]
},
"execution_count": 39,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[loved_by_b_e] := *love['eve', loved_by_b_e] or *love['bob', loved_by_b_e], \n",
" loved_by_b_e != 'bob', \n",
" loved_by_b_e != 'eve'"
]
},
{
"cell_type": "markdown",
"id": "d8ebc9a1-356e-4ba1-952c-c66920551381",
"metadata": {},
"source": [
"Another way to write the same query is to have multiple rule definitions under the same name:"
]
},
{
"cell_type": "code",
"execution_count": 40,
"id": "4e7ba20f-2a10-41f0-9062-cc269b36554d",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_ec8d9_row0_col0, #T_ec8d9_row1_col0 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_ec8d9\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_ec8d9_level0_col0\" class=\"col_heading level0 col0\" >loved_by_b_e</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_ec8d9_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_ec8d9_row0_col0\" class=\"data row0 col0\" >alice</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_ec8d9_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
" <td id=\"T_ec8d9_row1_col0\" class=\"data row1 col0\" >charlie</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119d215a0>"
]
},
"execution_count": 40,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[loved_by_b_e] := *love['eve', loved_by_b_e], \n",
" loved_by_b_e != 'bob', \n",
" loved_by_b_e != 'eve'\n",
"?[loved_by_b_e] := *love['bob', loved_by_b_e], \n",
" loved_by_b_e != 'bob', \n",
" loved_by_b_e != 'eve'"
]
},
{
"cell_type": "markdown",
"id": "0b859b50-a748-4e20-9900-7ee053078a7f",
"metadata": {},
"source": [
"When you have multiple definitions of the same inline rule, the rule heads must be compatible. Only inline rules can have multiple definitions."
]
},
{
"cell_type": "markdown",
"id": "5f357511-fb25-441f-bf9f-d1e583368928",
"metadata": {},
"source": [
"## Negation"
]
},
{
"cell_type": "markdown",
"id": "78242c93-bf6e-4e72-84e1-e7706f84e633",
"metadata": {},
"source": [
"Negation of _expressions_ should be familiar:"
]
},
{
"cell_type": "code",
"execution_count": 41,
"id": "ff02b41d-d3aa-4267-b7e9-b56874f37bf9",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_f330c_row0_col0, #T_f330c_row1_col0 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_f330c\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_f330c_level0_col0\" class=\"col_heading level0 col0\" >loved</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_f330c_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_f330c_row0_col0\" class=\"data row0 col0\" >alice</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_f330c_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
" <td id=\"T_f330c_row1_col0\" class=\"data row1 col0\" >george</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119ceab00>"
]
},
"execution_count": 41,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[loved] := *love[person, loved], !ends_with(person, 'e')"
]
},
{
"cell_type": "markdown",
"id": "433386de-59b5-4169-b0fb-20ad28df401b",
"metadata": {},
"source": [
"Rule applications can also be negated, not with the `!` operator, but with the `not` keyword:"
]
},
{
"cell_type": "code",
"execution_count": 42,
"id": "5eda38db-ddba-45e1-8bd5-4b39116fd81f",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_70bf7_row0_col0, #T_70bf7_row1_col0 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_70bf7\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_70bf7_level0_col0\" class=\"col_heading level0 col0\" >loved_by_e_not_b</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_70bf7_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_70bf7_row0_col0\" class=\"data row0 col0\" >bob</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_70bf7_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
" <td id=\"T_70bf7_row1_col0\" class=\"data row1 col0\" >charlie</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119d22ce0>"
]
},
"execution_count": 42,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[loved_by_e_not_b] := *love['eve', loved_by_e_not_b], not *love['bob', loved_by_e_not_b]"
]
},
{
"cell_type": "markdown",
"id": "5b2c4fa2-1f07-440a-a7fa-1f9a3cbfdc3c",
"metadata": {},
"source": [
"There are two sets of logical operations in Cozo, one set that acts on the level of expressions, and another set that acts on the level of atoms:\n",
"\n",
"* For atoms: `,` or `and` (conjunction), `or` (disjunction), `not` (negation)\n",
"* For expressions: `&&` (conjunction), `||` (disjunction), `!` (negation)\n",
"\n",
"The difference between `,` and `and` is operator precedence: `and` has higher precedence than `or`, whereas `,` has lower precedence than `or`."
]
},
{
"cell_type": "markdown",
"id": "0d382525-25a5-49d1-9d8e-4a057de933a0",
"metadata": {},
"source": [
"There is a _safety rule_ for negation:"
]
},
{
"cell_type": "code",
"execution_count": 43,
"id": "7db09fb7-25a5-424a-a66a-0bc24d6d4fc1",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"\u001b[31meval::unbound_symb_in_head\u001b[0m\n",
"\n",
" \u001b[31m×\u001b[0m Symbol 'not_loved_by_b' in rule head is unbound\n",
" ╭────\n",
" \u001b[2m1\u001b[0m │ ?[not_loved_by_b] := not *love['bob', not_loved_by_b]\n",
" · \u001b[35;1m ──────────────\u001b[0m\n",
" ╰────\n",
"\u001b[36m help: \u001b[0mNote that symbols occurring only in negated positions are not considered bound\n"
]
},
"execution_count": 43,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[not_loved_by_b] := not *love['bob', not_loved_by_b]"
]
},
{
"cell_type": "markdown",
"id": "44d83981-21eb-406c-9287-0e50aff5c423",
"metadata": {},
"source": [
"This query is forbidden because the resulting relation is infinite.\n",
"For example, 'gold' should be in the result, since _according to the facts stored in the database_, \n",
"Bob has no interest in 'gold'."
]
},
{
"cell_type": "markdown",
"id": "204fbb34-293e-4c63-a1c4-14e5a48491d7",
"metadata": {},
"source": [
"To make our query finite, we have to explicitly give our query a _closed world_:"
]
},
{
"cell_type": "code",
"execution_count": 44,
"id": "225a4625-b99a-41a8-a2ef-fa553065e8aa",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_6ec19_row0_col0, #T_6ec19_row1_col0, #T_6ec19_row2_col0, #T_6ec19_row3_col0, #T_6ec19_row4_col0 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_6ec19\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_6ec19_level0_col0\" class=\"col_heading level0 col0\" >not_loved_by_b</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_6ec19_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_6ec19_row0_col0\" class=\"data row0 col0\" >bob</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_6ec19_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
" <td id=\"T_6ec19_row1_col0\" class=\"data row1 col0\" >charlie</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_6ec19_level0_row2\" class=\"row_heading level0 row2\" >2</th>\n",
" <td id=\"T_6ec19_row2_col0\" class=\"data row2 col0\" >david</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_6ec19_level0_row3\" class=\"row_heading level0 row3\" >3</th>\n",
" <td id=\"T_6ec19_row3_col0\" class=\"data row3 col0\" >eve</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_6ec19_level0_row4\" class=\"row_heading level0 row4\" >4</th>\n",
" <td id=\"T_6ec19_row4_col0\" class=\"data row4 col0\" >george</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119d21390>"
]
},
"execution_count": 44,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"the_population[p] := *love[p, _a]\n",
"the_population[p] := *love[_a, p]\n",
"\n",
"?[not_loved_by_b] := the_population[not_loved_by_b], not *love['bob', not_loved_by_b]"
]
},
{
"cell_type": "markdown",
"id": "5ac5f2cd-5a05-4b84-898d-f5a08c15907a",
"metadata": {},
"source": [
"## Recursion"
]
},
{
"cell_type": "markdown",
"id": "6a61abee-f5ae-4447-ae7b-d857bfe5b870",
"metadata": {},
"source": [
"Inline rules can applying other rules, and can have multiple definitions. If you combine these two, you get recursions:"
]
},
{
"cell_type": "code",
"execution_count": 45,
"id": "7a63d36e-a03d-4b4a-a825-cdc3ed036f1b",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_7f31f_row0_col0, #T_7f31f_row1_col0, #T_7f31f_row2_col0, #T_7f31f_row3_col0 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_7f31f\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_7f31f_level0_col0\" class=\"col_heading level0 col0\" >chained</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_7f31f_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_7f31f_row0_col0\" class=\"data row0 col0\" >alice</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_7f31f_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
" <td id=\"T_7f31f_row1_col0\" class=\"data row1 col0\" >bob</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_7f31f_level0_row2\" class=\"row_heading level0 row2\" >2</th>\n",
" <td id=\"T_7f31f_row2_col0\" class=\"data row2 col0\" >charlie</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_7f31f_level0_row3\" class=\"row_heading level0 row3\" >3</th>\n",
" <td id=\"T_7f31f_row3_col0\" class=\"data row3 col0\" >eve</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119d20e80>"
]
},
"execution_count": 45,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"alice_love_chain[person] := *love['alice', person]\n",
"alice_love_chain[person] := alice_love_chain[in_person], *love[in_person, person]\n",
"\n",
"?[chained] := alice_love_chain[chained]"
]
},
{
"cell_type": "markdown",
"id": "1666bf8f-4e41-4428-bdc8-c1d05f6783df",
"metadata": {},
"source": [
"You may object that you only need to be able to apply other rules to have recursion, \n",
"without multiple definitions. \n",
"Technically correct, but the resulting queries are not useful::"
]
},
{
"cell_type": "code",
"execution_count": 46,
"id": "cbf96780-d71b-471e-8add-dbd2d0f13f24",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"</style>\n",
"<table id=\"T_752ef\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_752ef_level0_col0\" class=\"col_heading level0 col0\" >chained</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119d23610>"
]
},
"execution_count": 46,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"alice_love_chain[person] := alice_love_chain[in_person], *love[in_person, person]\n",
"\n",
"?[chained] := alice_love_chain[chained]"
]
},
{
"cell_type": "markdown",
"id": "ac4a9d13-3360-487d-81c8-8da33f781bae",
"metadata": {},
"source": [
"Similar to the negation case, if there is no way to _deduce_ a fact from the given facts, \n",
"then the fact itself is considered false. \n",
"You need multiple definitions to \"bootstrap\" the query."
]
},
{
"cell_type": "markdown",
"id": "72cfad4e-20de-4700-a191-03647fd6cdf8",
"metadata": {},
"source": [
"## Aggregation"
]
},
{
"cell_type": "markdown",
"id": "62149092-fb2f-47b2-bb0d-404fc17c28c1",
"metadata": {},
"source": [
"_Aggregations_ are usually used to compute statistics. In Cozo, aggregations are applied in the head of inline rules:"
]
},
{
"cell_type": "code",
"execution_count": 47,
"id": "70705529-80be-4990-9ea5-9f7842ba1543",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_4806b_row0_col0, #T_4806b_row1_col0, #T_4806b_row2_col0, #T_4806b_row3_col0, #T_4806b_row4_col0 {\n",
" color: black;\n",
"}\n",
"#T_4806b_row0_col1, #T_4806b_row1_col1, #T_4806b_row2_col1, #T_4806b_row3_col1, #T_4806b_row4_col1 {\n",
" color: #307fc1;\n",
"}\n",
"</style>\n",
"<table id=\"T_4806b\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_4806b_level0_col0\" class=\"col_heading level0 col0\" >person</th>\n",
" <th id=\"T_4806b_level0_col1\" class=\"col_heading level0 col1\" >count(loved_by)</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_4806b_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_4806b_row0_col0\" class=\"data row0 col0\" >alice</td>\n",
" <td id=\"T_4806b_row0_col1\" class=\"data row0 col1\" >2</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_4806b_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
" <td id=\"T_4806b_row1_col0\" class=\"data row1 col0\" >bob</td>\n",
" <td id=\"T_4806b_row1_col1\" class=\"data row1 col1\" >1</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_4806b_level0_row2\" class=\"row_heading level0 row2\" >2</th>\n",
" <td id=\"T_4806b_row2_col0\" class=\"data row2 col0\" >charlie</td>\n",
" <td id=\"T_4806b_row2_col1\" class=\"data row2 col1\" >1</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_4806b_level0_row3\" class=\"row_heading level0 row3\" >3</th>\n",
" <td id=\"T_4806b_row3_col0\" class=\"data row3 col0\" >eve</td>\n",
" <td id=\"T_4806b_row3_col1\" class=\"data row3 col1\" >2</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_4806b_level0_row4\" class=\"row_heading level0 row4\" >4</th>\n",
" <td id=\"T_4806b_row4_col0\" class=\"data row4 col0\" >george</td>\n",
" <td id=\"T_4806b_row4_col1\" class=\"data row4 col1\" >2</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119d22950>"
]
},
"execution_count": 47,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[person, count(loved_by)] := *love[loved_by, person]"
]
},
{
"cell_type": "markdown",
"id": "19f47c1e-ffb6-4531-b181-0995bfeb63df",
"metadata": {},
"source": [
"The usual `sum`, `mean`, etc. are all available. \n",
"Aggregations in the head instead of in the body may seem strange, but is powerful, as we will see later.\n",
"\n",
"Here is the [full list](https://cozodb.github.io/current/manual/aggregations.html) of aggregations for you to play with."
]
},
{
"cell_type": "markdown",
"id": "9e39b8d9-0d52-433e-bec4-d856afd83606",
"metadata": {},
"source": [
"## Query options"
]
},
{
"cell_type": "markdown",
"id": "921d1c1a-3396-41d2-9010-1f3b9318cce8",
"metadata": {},
"source": [
"We have seem query options like `:create`, `:put`, `:rm` for manipulating stored relations. \n",
"There are also query options for controlling what is returned:"
]
},
{
"cell_type": "code",
"execution_count": 48,
"id": "58f1d43f-3f50-42df-8e27-8f6e549cbc6e",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_e3177_row0_col0, #T_e3177_row0_col1 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_e3177\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_e3177_level0_col0\" class=\"col_heading level0 col0\" >loving</th>\n",
" <th id=\"T_e3177_level0_col1\" class=\"col_heading level0 col1\" >loved</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_e3177_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_e3177_row0_col0\" class=\"data row0 col0\" >alice</td>\n",
" <td id=\"T_e3177_row0_col1\" class=\"data row0 col1\" >eve</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119d20e20>"
]
},
"execution_count": 48,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[loving, loved] := *love{ loving, loved }\n",
"\n",
":limit 1"
]
},
{
"cell_type": "markdown",
"id": "fe622726-e0b0-4ea3-878a-75e7de93a669",
"metadata": {},
"source": [
"Next we want the result to be sorted by `loved` in descending order, then `loving` in ascending order, and skip the first row:"
]
},
{
"cell_type": "code",
"execution_count": 49,
"id": "60f3673b-3273-49a3-b893-1236faf64490",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_300f5_row0_col0, #T_300f5_row0_col1, #T_300f5_row1_col0, #T_300f5_row1_col1, #T_300f5_row2_col0, #T_300f5_row2_col1, #T_300f5_row3_col0, #T_300f5_row3_col1, #T_300f5_row4_col0, #T_300f5_row4_col1, #T_300f5_row5_col0, #T_300f5_row5_col1, #T_300f5_row6_col0, #T_300f5_row6_col1 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_300f5\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_300f5_level0_col0\" class=\"col_heading level0 col0\" >loving</th>\n",
" <th id=\"T_300f5_level0_col1\" class=\"col_heading level0 col1\" >loved</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_300f5_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_300f5_row0_col0\" class=\"data row0 col0\" >george</td>\n",
" <td id=\"T_300f5_row0_col1\" class=\"data row0 col1\" >george</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_300f5_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
" <td id=\"T_300f5_row1_col0\" class=\"data row1 col0\" >alice</td>\n",
" <td id=\"T_300f5_row1_col1\" class=\"data row1 col1\" >eve</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_300f5_level0_row2\" class=\"row_heading level0 row2\" >2</th>\n",
" <td id=\"T_300f5_row2_col0\" class=\"data row2 col0\" >charlie</td>\n",
" <td id=\"T_300f5_row2_col1\" class=\"data row2 col1\" >eve</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_300f5_level0_row3\" class=\"row_heading level0 row3\" >3</th>\n",
" <td id=\"T_300f5_row3_col0\" class=\"data row3 col0\" >eve</td>\n",
" <td id=\"T_300f5_row3_col1\" class=\"data row3 col1\" >charlie</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_300f5_level0_row4\" class=\"row_heading level0 row4\" >4</th>\n",
" <td id=\"T_300f5_row4_col0\" class=\"data row4 col0\" >eve</td>\n",
" <td id=\"T_300f5_row4_col1\" class=\"data row4 col1\" >bob</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_300f5_level0_row5\" class=\"row_heading level0 row5\" >5</th>\n",
" <td id=\"T_300f5_row5_col0\" class=\"data row5 col0\" >bob</td>\n",
" <td id=\"T_300f5_row5_col1\" class=\"data row5 col1\" >alice</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_300f5_level0_row6\" class=\"row_heading level0 row6\" >6</th>\n",
" <td id=\"T_300f5_row6_col0\" class=\"data row6 col0\" >eve</td>\n",
" <td id=\"T_300f5_row6_col1\" class=\"data row6 col1\" >alice</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119d21930>"
]
},
"execution_count": 49,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[loving, loved] := *love{ loving, loved }\n",
"\n",
":order -loved, loving\n",
":offset 1"
]
},
{
"cell_type": "markdown",
"id": "2c481e69-9640-4246-8ab8-e66549653c0d",
"metadata": {},
"source": [
"Putting `-` in front of variables in `:order` clause denotes reverse order. Nothing or `+` denotes the ascending order."
]
},
{
"cell_type": "markdown",
"id": "40e456b1-2030-4013-894d-a45e81e6b74e",
"metadata": {},
"source": [
"The full list of query options are explained [here](https://cozodb.github.io/current/manual/queries.html#query-options)."
]
},
{
"cell_type": "markdown",
"id": "f6aebc44-2523-4bc6-8c65-3554e985aef1",
"metadata": {},
"source": [
"## Fixed rules"
]
},
{
"cell_type": "markdown",
"id": "cf08e8f6-ce6a-4212-a456-98fa57d457b4",
"metadata": {},
"source": [
"The `<-` syntax for constant rules is syntax sugar. The full syntax is:"
]
},
{
"cell_type": "code",
"execution_count": 50,
"id": "91414374-23cb-4310-ac36-a372e151ef6c",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_a4c00_row0_col0, #T_a4c00_row0_col1, #T_a4c00_row0_col2 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_a4c00\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_a4c00_level0_col0\" class=\"col_heading level0 col0\" >0</th>\n",
" <th id=\"T_a4c00_level0_col1\" class=\"col_heading level0 col1\" >1</th>\n",
" <th id=\"T_a4c00_level0_col2\" class=\"col_heading level0 col2\" >2</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_a4c00_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_a4c00_row0_col0\" class=\"data row0 col0\" >hello</td>\n",
" <td id=\"T_a4c00_row0_col1\" class=\"data row0 col1\" >world</td>\n",
" <td id=\"T_a4c00_row0_col2\" class=\"data row0 col2\" >Cozo!</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119d23ca0>"
]
},
"execution_count": 50,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[] <~ Constant(data: [['hello', 'world', 'Cozo!']])"
]
},
{
"cell_type": "markdown",
"id": "5b836e0b-1b38-485a-ade2-69742b29d09f",
"metadata": {},
"source": [
"Here we are using the _fixed rule_ `Constant`, which takes one _option_ named `data`. The curly tail `<~` denotes a fixed rule.\n",
"\n",
"Fixed rules take input relations as arguments, apply custom logic to them and produce its output relation. \n",
"The `Constant` fixed rule take zero input relations.\n",
"\n",
"As an example of another fixed rule, let's find out who is most popular in the `love` graph. \n",
"How to define popularity? \n",
"One way is to say that the higher [PageRank](https://en.wikipedia.org/wiki/PageRank) a person has, the more popular. \n",
"Calculating PageRank using inline rules\n",
"is very awkward (but doable). Fortunately, one of the fixed rules is an optimized PageRank implementation:"
]
},
{
"cell_type": "code",
"execution_count": 51,
"id": "f596d73d-1879-49e7-834a-5c489752a152",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_11484_row0_col0, #T_11484_row1_col0, #T_11484_row2_col0, #T_11484_row3_col0, #T_11484_row4_col0, #T_11484_row5_col0 {\n",
" color: black;\n",
"}\n",
"#T_11484_row0_col1, #T_11484_row1_col1, #T_11484_row2_col1, #T_11484_row3_col1, #T_11484_row4_col1, #T_11484_row5_col1 {\n",
" color: #307fc1;\n",
"}\n",
"</style>\n",
"<table id=\"T_11484\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_11484_level0_col0\" class=\"col_heading level0 col0\" >person</th>\n",
" <th id=\"T_11484_level0_col1\" class=\"col_heading level0 col1\" >page_rank</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_11484_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_11484_row0_col0\" class=\"data row0 col0\" >alice</td>\n",
" <td id=\"T_11484_row0_col1\" class=\"data row0 col1\" >1.191497</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_11484_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
" <td id=\"T_11484_row1_col0\" class=\"data row1 col0\" >eve</td>\n",
" <td id=\"T_11484_row1_col1\" class=\"data row1 col1\" >1.191497</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_11484_level0_row2\" class=\"row_heading level0 row2\" >2</th>\n",
" <td id=\"T_11484_row2_col0\" class=\"data row2 col0\" >george</td>\n",
" <td id=\"T_11484_row2_col1\" class=\"data row2 col1\" >1.064742</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_11484_level0_row3\" class=\"row_heading level0 row3\" >3</th>\n",
" <td id=\"T_11484_row3_col0\" class=\"data row3 col0\" >bob</td>\n",
" <td id=\"T_11484_row3_col1\" class=\"data row3 col1\" >0.921087</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_11484_level0_row4\" class=\"row_heading level0 row4\" >4</th>\n",
" <td id=\"T_11484_row4_col0\" class=\"data row4 col0\" >charlie</td>\n",
" <td id=\"T_11484_row4_col1\" class=\"data row4 col1\" >0.921087</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_11484_level0_row5\" class=\"row_heading level0 row5\" >5</th>\n",
" <td id=\"T_11484_row5_col0\" class=\"data row5 col0\" >david</td>\n",
" <td id=\"T_11484_row5_col1\" class=\"data row5 col1\" >0.574623</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119d22230>"
]
},
"execution_count": 51,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[person, page_rank] <~ PageRank(*love[])\n",
"\n",
":order -page_rank"
]
},
{
"cell_type": "markdown",
"id": "394a62e3-ad1c-49a0-944f-f0de0150d2e0",
"metadata": {},
"source": [
"Here the input relation is the stored relation `*love`. \n",
"\n",
"Each fixed rule is different. Read [this](https://cozodb.github.io/current/manual/algorithms.html) to learn how to use them."
]
},
{
"cell_type": "code",
"execution_count": 52,
"id": "db73e2f7-61a1-4824-9c47-c6da461b632b",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_4253d_row0_col0 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_4253d\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_4253d_level0_col0\" class=\"col_heading level0 col0\" >status</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_4253d_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_4253d_row0_col0\" class=\"data row0 col0\" >OK</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119d23880>"
]
},
"execution_count": 52,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"::remove love"
]
},
{
"cell_type": "markdown",
"id": "a16bee55-9802-4089-a0c2-c6f85213cf13",
"metadata": {},
"source": [
"## Extended example: the air routes dataset"
]
},
{
"cell_type": "markdown",
"id": "72e46708-93cd-45de-8d9e-79adb8cc1da0",
"metadata": {},
"source": [
"Now you have a basic understanding of using the various constructs of Cozo, let's deal with a less trivial dataset.\n",
"\n",
"The data we are going to use, and many examples that we will present, are adapted from the book [Practical Gremlin](https://kelvinlawrence.net/book/Gremlin-Graph-Guide.html). Gremlin is an imperative query language for graphs, a very different take compared to Datalog."
]
},
{
"cell_type": "markdown",
"id": "cc4819fe-91b1-4efc-863e-f8c3df67be43",
"metadata": {},
"source": [
"We will download the data directly from the Internet. First let us set up some _parameters_ to be used in queries:"
]
},
{
"cell_type": "code",
"execution_count": 53,
"id": "9ab0eaff-2cb2-4d1c-b1a7-054f5ead414b",
"metadata": {},
"outputs": [],
"source": [
"%cozo_set AIR_ROUTES_NODES_URL 'https://raw.githubusercontent.com/cozodb/cozo/main/tests/air-routes-latest-nodes.csv'\n",
"%cozo_set AIR_ROUTES_EDGES_URL 'https://raw.githubusercontent.com/cozodb/cozo/main/tests/air-routes-latest-edges.csv'\n",
"# %cozo_set AIR_ROUTES_NODES_URL 'file://./tests/air-routes-latest-nodes.csv'\n",
"# %cozo_set AIR_ROUTES_EDGES_URL 'file://./tests/air-routes-latest-edges.csv'"
]
},
{
"cell_type": "markdown",
"id": "5a360c16-2495-4bc9-b199-f100499819dc",
"metadata": {},
"source": [
"If you want, you can manually download the files and refer to them locally. The commented lines show how to do it."
]
},
{
"cell_type": "markdown",
"id": "5e08132c-18bc-44ca-875a-c44596717bf4",
"metadata": {},
"source": [
"If you are not using Jupyter, pass parameters to queries in a map. For example, in the JavaScript console:"
]
},
{
"cell_type": "markdown",
"id": "fba7362d-d31d-4c01-a239-1f8924bd0280",
"metadata": {},
"source": [
"```js\n",
"await run(`<QUERY>`, {'AIR_ROUTES_NODES_URL': 'https://...', 'AIR_ROUTES_EDGES_URL': 'https://...'})\n",
"```"
]
},
{
"cell_type": "markdown",
"id": "54e3ec1d-c139-48ab-8205-49b71aba4c67",
"metadata": {},
"source": [
"Let's import the data into our database. First, the `airport` relation:"
]
},
{
"cell_type": "code",
"execution_count": 54,
"id": "dd70c091-063d-4f0e-995d-06b7f428a4b9",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 40ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_41a07_row0_col0 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_41a07\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_41a07_level0_col0\" class=\"col_heading level0 col0\" >status</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_41a07_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_41a07_row0_col0\" class=\"data row0 col0\" >OK</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119d22a70>"
]
},
"execution_count": 54,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"res[idx, label, typ, code, icao, desc, region, runways, longest, elev, country, city, lat, lon] <~\n",
" CsvReader(types: ['Int', 'Any', 'Any', 'Any', 'Any', 'Any', 'Any', 'Int?', 'Float?', 'Float?', 'Any', 'Any', 'Float?', 'Float?'],\n",
" url: $AIR_ROUTES_NODES_URL, \n",
" has_headers: true)\n",
"\n",
"?[code, icao, desc, region, runways, longest, elev, country, city, lat, lon] :=\n",
" res[idx, label, typ, code, icao, desc, region, runways, longest, elev, country, city, lat, lon],\n",
" label == 'airport'\n",
"\n",
":replace airport {\n",
" code: String \n",
" => \n",
" icao: String, \n",
" desc: String, \n",
" region: String, \n",
" runways: Int, \n",
" longest: Float, \n",
" elev: Float, \n",
" country: String, \n",
" city: String, \n",
" lat: Float, \n",
" lon: Float\n",
"}"
]
},
{
"cell_type": "markdown",
"id": "708cd3df-4da7-42e2-a1a3-f36e37fed7f4",
"metadata": {},
"source": [
"The `CsvReader` utility downloads a CSV file from the internet and attempts to parse its content into a relation.\n",
"When we store the relation, we specified types for the columns. The `code` column acts as a primary key for the `airport` stored relation."
]
},
{
"cell_type": "markdown",
"id": "79d41137-1936-4023-a870-91158693c6bb",
"metadata": {},
"source": [
"Next is `country`:"
]
},
{
"cell_type": "code",
"execution_count": 55,
"id": "51e71275-3911-42c0-b993-8916ba953fdc",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 12ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_7ab16_row0_col0 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_7ab16\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_7ab16_level0_col0\" class=\"col_heading level0 col0\" >status</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_7ab16_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_7ab16_row0_col0\" class=\"data row0 col0\" >OK</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119d62b60>"
]
},
"execution_count": 55,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"res[idx, label, typ, code, icao, desc] <~\n",
" CsvReader(types: ['Int', 'Any', 'Any', 'Any', 'Any', 'Any'],\n",
" url: $AIR_ROUTES_NODES_URL, \n",
" has_headers: true)\n",
"?[code, desc] :=\n",
" res[idx, label, typ, code, icao, desc],\n",
" label == 'country'\n",
"\n",
":replace country {\n",
" code: String\n",
" =>\n",
" desc: String\n",
"}"
]
},
{
"cell_type": "markdown",
"id": "72901087-cebd-472e-ba31-adee8dc72abc",
"metadata": {},
"source": [
"`continent`:"
]
},
{
"cell_type": "code",
"execution_count": 56,
"id": "d5660e58-0fec-4929-941d-0debb9234e50",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 10ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_54fc8_row0_col0 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_54fc8\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_54fc8_level0_col0\" class=\"col_heading level0 col0\" >status</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_54fc8_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_54fc8_row0_col0\" class=\"data row0 col0\" >OK</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119d23370>"
]
},
"execution_count": 56,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"res[idx, label, typ, code, icao, desc] <~\n",
" CsvReader(types: ['Int', 'Any', 'Any', 'Any', 'Any', 'Any'],\n",
" url: $AIR_ROUTES_NODES_URL, \n",
" has_headers: true)\n",
"?[idx, code, desc] :=\n",
" res[idx, label, typ, code, icao, desc],\n",
" label == 'continent'\n",
"\n",
":replace continent {\n",
" code: String\n",
" =>\n",
" desc: String\n",
"}"
]
},
{
"cell_type": "markdown",
"id": "6e2d30c1-90d3-4403-b816-a21d0baf0670",
"metadata": {},
"source": [
"We need to make a translation table for the indices the data use:"
]
},
{
"cell_type": "code",
"execution_count": 57,
"id": "49433f68-afcd-4788-9e82-a8f57c24ee78",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 25ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_aa819_row0_col0 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_aa819\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_aa819_level0_col0\" class=\"col_heading level0 col0\" >status</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_aa819_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_aa819_row0_col0\" class=\"data row0 col0\" >OK</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119d22590>"
]
},
"execution_count": 57,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"res[idx, label, typ, code] <~\n",
" CsvReader(types: ['Int', 'Any', 'Any', 'Any'],\n",
" url: $AIR_ROUTES_NODES_URL, \n",
" has_headers: true)\n",
"?[idx, code] :=\n",
" res[idx, label, typ, code],\n",
"\n",
":replace idx2code { idx => code }"
]
},
{
"cell_type": "markdown",
"id": "af261df6-ce89-47a0-b7d9-2efe794767fb",
"metadata": {},
"source": [
"The `contain` relation contains information on the geographical inclusion of entities:"
]
},
{
"cell_type": "code",
"execution_count": 58,
"id": "2ec122ba-a72b-4ee8-bd57-e6c9db7f6e15",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 100ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_7464b_row0_col0 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_7464b\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_7464b_level0_col0\" class=\"col_heading level0 col0\" >status</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_7464b_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_7464b_row0_col0\" class=\"data row0 col0\" >OK</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119d629e0>"
]
},
"execution_count": 58,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"res[] <~\n",
" CsvReader(types: ['Int', 'Int', 'Int', 'String'],\n",
" url: $AIR_ROUTES_EDGES_URL, \n",
" has_headers: true)\n",
"?[entity, contained] :=\n",
" res[idx, fr_i, to_i, typ],\n",
" typ == 'contains',\n",
" *idx2code[fr_i, entity],\n",
" *idx2code[to_i, contained]\n",
"\n",
"\n",
":replace contain { entity: String, contained: String }"
]
},
{
"cell_type": "markdown",
"id": "ddc41b91-021a-4ab4-b92f-63013dd655bf",
"metadata": {},
"source": [
"Finally, the `route`s between the airports. This relation is much larger than the rest and contains about 60k rows:"
]
},
{
"cell_type": "code",
"execution_count": 59,
"id": "a916cb80-7463-44eb-8f15-c12cbe8091d4",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 364ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_66b82_row0_col0 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_66b82\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_66b82_level0_col0\" class=\"col_heading level0 col0\" >status</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_66b82_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_66b82_row0_col0\" class=\"data row0 col0\" >OK</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119d607c0>"
]
},
"execution_count": 59,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"res[] <~\n",
" CsvReader(types: ['Int', 'Int', 'Int', 'String', 'Float?'],\n",
" url: $AIR_ROUTES_EDGES_URL, \n",
" has_headers: true)\n",
"?[fr, to, dist] :=\n",
" res[idx, fr_i, to_i, typ, dist],\n",
" typ == 'route',\n",
" *idx2code[fr_i, fr],\n",
" *idx2code[to_i, to]\n",
"\n",
":replace route { fr: String, to: String => dist: Float }"
]
},
{
"cell_type": "markdown",
"id": "c1ce4c36-d196-414b-b7f4-295708849e19",
"metadata": {},
"source": [
"We no longer need the `idx2code` relation:"
]
},
{
"cell_type": "code",
"execution_count": 60,
"id": "5938a20c-56d7-41ec-b3b2-4ca2f5bd835b",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_a2bf4_row0_col0 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_a2bf4\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_a2bf4_level0_col0\" class=\"col_heading level0 col0\" >status</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_a2bf4_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_a2bf4_row0_col0\" class=\"data row0 col0\" >OK</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119d60d90>"
]
},
"execution_count": 60,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"::remove idx2code"
]
},
{
"cell_type": "markdown",
"id": "65cb9b9d-79ce-4814-8f75-e6c22fe1d98d",
"metadata": {},
"source": [
"Let's verify all the relations we want are there:"
]
},
{
"cell_type": "code",
"execution_count": 61,
"id": "5c067dd0-7052-46c6-823b-ddf6cbb1b516",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_26516_row0_col0, #T_26516_row0_col2, #T_26516_row1_col0, #T_26516_row1_col2, #T_26516_row2_col0, #T_26516_row2_col2, #T_26516_row3_col0, #T_26516_row3_col2, #T_26516_row4_col0, #T_26516_row4_col2 {\n",
" color: black;\n",
"}\n",
"#T_26516_row0_col1, #T_26516_row0_col3, #T_26516_row0_col4, #T_26516_row0_col5, #T_26516_row0_col6, #T_26516_row0_col7, #T_26516_row1_col1, #T_26516_row1_col3, #T_26516_row1_col4, #T_26516_row1_col5, #T_26516_row1_col6, #T_26516_row1_col7, #T_26516_row2_col1, #T_26516_row2_col3, #T_26516_row2_col4, #T_26516_row2_col5, #T_26516_row2_col6, #T_26516_row2_col7, #T_26516_row3_col1, #T_26516_row3_col3, #T_26516_row3_col4, #T_26516_row3_col5, #T_26516_row3_col6, #T_26516_row3_col7, #T_26516_row4_col1, #T_26516_row4_col3, #T_26516_row4_col4, #T_26516_row4_col5, #T_26516_row4_col6, #T_26516_row4_col7 {\n",
" color: #307fc1;\n",
"}\n",
"</style>\n",
"<table id=\"T_26516\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_26516_level0_col0\" class=\"col_heading level0 col0\" >name</th>\n",
" <th id=\"T_26516_level0_col1\" class=\"col_heading level0 col1\" >arity</th>\n",
" <th id=\"T_26516_level0_col2\" class=\"col_heading level0 col2\" >access_level</th>\n",
" <th id=\"T_26516_level0_col3\" class=\"col_heading level0 col3\" >n_keys</th>\n",
" <th id=\"T_26516_level0_col4\" class=\"col_heading level0 col4\" >n_non_keys</th>\n",
" <th id=\"T_26516_level0_col5\" class=\"col_heading level0 col5\" >n_put_triggers</th>\n",
" <th id=\"T_26516_level0_col6\" class=\"col_heading level0 col6\" >n_rm_triggers</th>\n",
" <th id=\"T_26516_level0_col7\" class=\"col_heading level0 col7\" >n_replace_triggers</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_26516_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_26516_row0_col0\" class=\"data row0 col0\" >airport</td>\n",
" <td id=\"T_26516_row0_col1\" class=\"data row0 col1\" >11</td>\n",
" <td id=\"T_26516_row0_col2\" class=\"data row0 col2\" >normal</td>\n",
" <td id=\"T_26516_row0_col3\" class=\"data row0 col3\" >1</td>\n",
" <td id=\"T_26516_row0_col4\" class=\"data row0 col4\" >10</td>\n",
" <td id=\"T_26516_row0_col5\" class=\"data row0 col5\" >0</td>\n",
" <td id=\"T_26516_row0_col6\" class=\"data row0 col6\" >0</td>\n",
" <td id=\"T_26516_row0_col7\" class=\"data row0 col7\" >0</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_26516_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
" <td id=\"T_26516_row1_col0\" class=\"data row1 col0\" >contain</td>\n",
" <td id=\"T_26516_row1_col1\" class=\"data row1 col1\" >2</td>\n",
" <td id=\"T_26516_row1_col2\" class=\"data row1 col2\" >normal</td>\n",
" <td id=\"T_26516_row1_col3\" class=\"data row1 col3\" >2</td>\n",
" <td id=\"T_26516_row1_col4\" class=\"data row1 col4\" >0</td>\n",
" <td id=\"T_26516_row1_col5\" class=\"data row1 col5\" >0</td>\n",
" <td id=\"T_26516_row1_col6\" class=\"data row1 col6\" >0</td>\n",
" <td id=\"T_26516_row1_col7\" class=\"data row1 col7\" >0</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_26516_level0_row2\" class=\"row_heading level0 row2\" >2</th>\n",
" <td id=\"T_26516_row2_col0\" class=\"data row2 col0\" >continent</td>\n",
" <td id=\"T_26516_row2_col1\" class=\"data row2 col1\" >2</td>\n",
" <td id=\"T_26516_row2_col2\" class=\"data row2 col2\" >normal</td>\n",
" <td id=\"T_26516_row2_col3\" class=\"data row2 col3\" >1</td>\n",
" <td id=\"T_26516_row2_col4\" class=\"data row2 col4\" >1</td>\n",
" <td id=\"T_26516_row2_col5\" class=\"data row2 col5\" >0</td>\n",
" <td id=\"T_26516_row2_col6\" class=\"data row2 col6\" >0</td>\n",
" <td id=\"T_26516_row2_col7\" class=\"data row2 col7\" >0</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_26516_level0_row3\" class=\"row_heading level0 row3\" >3</th>\n",
" <td id=\"T_26516_row3_col0\" class=\"data row3 col0\" >country</td>\n",
" <td id=\"T_26516_row3_col1\" class=\"data row3 col1\" >2</td>\n",
" <td id=\"T_26516_row3_col2\" class=\"data row3 col2\" >normal</td>\n",
" <td id=\"T_26516_row3_col3\" class=\"data row3 col3\" >1</td>\n",
" <td id=\"T_26516_row3_col4\" class=\"data row3 col4\" >1</td>\n",
" <td id=\"T_26516_row3_col5\" class=\"data row3 col5\" >0</td>\n",
" <td id=\"T_26516_row3_col6\" class=\"data row3 col6\" >0</td>\n",
" <td id=\"T_26516_row3_col7\" class=\"data row3 col7\" >0</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_26516_level0_row4\" class=\"row_heading level0 row4\" >4</th>\n",
" <td id=\"T_26516_row4_col0\" class=\"data row4 col0\" >route</td>\n",
" <td id=\"T_26516_row4_col1\" class=\"data row4 col1\" >3</td>\n",
" <td id=\"T_26516_row4_col2\" class=\"data row4 col2\" >normal</td>\n",
" <td id=\"T_26516_row4_col3\" class=\"data row4 col3\" >2</td>\n",
" <td id=\"T_26516_row4_col4\" class=\"data row4 col4\" >1</td>\n",
" <td id=\"T_26516_row4_col5\" class=\"data row4 col5\" >0</td>\n",
" <td id=\"T_26516_row4_col6\" class=\"data row4 col6\" >0</td>\n",
" <td id=\"T_26516_row4_col7\" class=\"data row4 col7\" >0</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119d61540>"
]
},
"execution_count": 61,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"::relations"
]
},
{
"cell_type": "markdown",
"id": "e3a13d9e-6ff0-445f-9a75-86f373de2b28",
"metadata": {},
"source": [
"While we are at it, let's lock all these tables to prevent accidentally changing their contents:"
]
},
{
"cell_type": "code",
"execution_count": 62,
"id": "667b2099-a71e-423d-b0b2-9a35bc8c5a6d",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_06757_row0_col0 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_06757\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_06757_level0_col0\" class=\"col_heading level0 col0\" >status</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_06757_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_06757_row0_col0\" class=\"data row0 col0\" >OK</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119d61330>"
]
},
"execution_count": 62,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"::access_level read_only airport, contain, continent, country, route"
]
},
{
"cell_type": "markdown",
"id": "191c8f21-b8c0-4730-979f-c7135e762eff",
"metadata": {},
"source": [
"More information about what this does is explained [here](https://cozodb.github.io/current/manual/sysops.html#ops-for-stored-relations)."
]
},
{
"cell_type": "markdown",
"id": "0d33e9f4-0876-46cd-bc6e-7ae42ce587dd",
"metadata": {},
"source": [
"Let's just look at some data. Start with airports:"
]
},
{
"cell_type": "code",
"execution_count": 63,
"id": "fefbae3c-3b06-43ca-82b6-a10ee9174edf",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_56016_row0_col0, #T_56016_row0_col1, #T_56016_row0_col2, #T_56016_row0_col3, #T_56016_row1_col0, #T_56016_row1_col1, #T_56016_row1_col2, #T_56016_row1_col3, #T_56016_row2_col0, #T_56016_row2_col1, #T_56016_row2_col2, #T_56016_row2_col3, #T_56016_row3_col0, #T_56016_row3_col1, #T_56016_row3_col2, #T_56016_row3_col3, #T_56016_row4_col0, #T_56016_row4_col1, #T_56016_row4_col2, #T_56016_row4_col3 {\n",
" color: black;\n",
"}\n",
"#T_56016_row0_col4, #T_56016_row0_col5, #T_56016_row0_col6, #T_56016_row1_col4, #T_56016_row1_col5, #T_56016_row1_col6, #T_56016_row2_col4, #T_56016_row2_col5, #T_56016_row2_col6, #T_56016_row3_col4, #T_56016_row3_col5, #T_56016_row3_col6, #T_56016_row4_col4, #T_56016_row4_col5, #T_56016_row4_col6 {\n",
" color: #307fc1;\n",
"}\n",
"</style>\n",
"<table id=\"T_56016\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_56016_level0_col0\" class=\"col_heading level0 col0\" >code</th>\n",
" <th id=\"T_56016_level0_col1\" class=\"col_heading level0 col1\" >city</th>\n",
" <th id=\"T_56016_level0_col2\" class=\"col_heading level0 col2\" >desc</th>\n",
" <th id=\"T_56016_level0_col3\" class=\"col_heading level0 col3\" >region</th>\n",
" <th id=\"T_56016_level0_col4\" class=\"col_heading level0 col4\" >runways</th>\n",
" <th id=\"T_56016_level0_col5\" class=\"col_heading level0 col5\" >lat</th>\n",
" <th id=\"T_56016_level0_col6\" class=\"col_heading level0 col6\" >lon</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_56016_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_56016_row0_col0\" class=\"data row0 col0\" >AAA</td>\n",
" <td id=\"T_56016_row0_col1\" class=\"data row0 col1\" >Anaa</td>\n",
" <td id=\"T_56016_row0_col2\" class=\"data row0 col2\" >Anaa Airport</td>\n",
" <td id=\"T_56016_row0_col3\" class=\"data row0 col3\" >PF-U-A</td>\n",
" <td id=\"T_56016_row0_col4\" class=\"data row0 col4\" >1</td>\n",
" <td id=\"T_56016_row0_col5\" class=\"data row0 col5\" >-17.352600</td>\n",
" <td id=\"T_56016_row0_col6\" class=\"data row0 col6\" >-145.509995</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_56016_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
" <td id=\"T_56016_row1_col0\" class=\"data row1 col0\" >AAE</td>\n",
" <td id=\"T_56016_row1_col1\" class=\"data row1 col1\" >Annabah</td>\n",
" <td id=\"T_56016_row1_col2\" class=\"data row1 col2\" >Annaba Airport</td>\n",
" <td id=\"T_56016_row1_col3\" class=\"data row1 col3\" >DZ-36</td>\n",
" <td id=\"T_56016_row1_col4\" class=\"data row1 col4\" >2</td>\n",
" <td id=\"T_56016_row1_col5\" class=\"data row1 col5\" >36.822201</td>\n",
" <td id=\"T_56016_row1_col6\" class=\"data row1 col6\" >7.809170</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_56016_level0_row2\" class=\"row_heading level0 row2\" >2</th>\n",
" <td id=\"T_56016_row2_col0\" class=\"data row2 col0\" >AAL</td>\n",
" <td id=\"T_56016_row2_col1\" class=\"data row2 col1\" >Aalborg</td>\n",
" <td id=\"T_56016_row2_col2\" class=\"data row2 col2\" >Aalborg Airport</td>\n",
" <td id=\"T_56016_row2_col3\" class=\"data row2 col3\" >DK-81</td>\n",
" <td id=\"T_56016_row2_col4\" class=\"data row2 col4\" >2</td>\n",
" <td id=\"T_56016_row2_col5\" class=\"data row2 col5\" >57.092759</td>\n",
" <td id=\"T_56016_row2_col6\" class=\"data row2 col6\" >9.849243</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_56016_level0_row3\" class=\"row_heading level0 row3\" >3</th>\n",
" <td id=\"T_56016_row3_col0\" class=\"data row3 col0\" >AAN</td>\n",
" <td id=\"T_56016_row3_col1\" class=\"data row3 col1\" >Al Ain</td>\n",
" <td id=\"T_56016_row3_col2\" class=\"data row3 col2\" >Al Ain International Airport</td>\n",
" <td id=\"T_56016_row3_col3\" class=\"data row3 col3\" >AE-AZ</td>\n",
" <td id=\"T_56016_row3_col4\" class=\"data row3 col4\" >1</td>\n",
" <td id=\"T_56016_row3_col5\" class=\"data row3 col5\" >24.261700</td>\n",
" <td id=\"T_56016_row3_col6\" class=\"data row3 col6\" >55.609200</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_56016_level0_row4\" class=\"row_heading level0 row4\" >4</th>\n",
" <td id=\"T_56016_row4_col0\" class=\"data row4 col0\" >AAQ</td>\n",
" <td id=\"T_56016_row4_col1\" class=\"data row4 col1\" >Anapa</td>\n",
" <td id=\"T_56016_row4_col2\" class=\"data row4 col2\" >Anapa Airport</td>\n",
" <td id=\"T_56016_row4_col3\" class=\"data row4 col3\" >RU-KDA</td>\n",
" <td id=\"T_56016_row4_col4\" class=\"data row4 col4\" >1</td>\n",
" <td id=\"T_56016_row4_col5\" class=\"data row4 col5\" >45.002102</td>\n",
" <td id=\"T_56016_row4_col6\" class=\"data row4 col6\" >37.347301</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119d635b0>"
]
},
"execution_count": 63,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[code, city, desc, region, runways, lat, lon] := *airport{code, city, desc, region, runways, lat, lon}\n",
" \n",
":limit 5"
]
},
{
"cell_type": "markdown",
"id": "b645ed53-c80a-4b50-8e4d-f5080c48de2d",
"metadata": {},
"source": [
"Airports with the most runways:"
]
},
{
"cell_type": "code",
"execution_count": 64,
"id": "b733fffd-e292-4af9-9810-7010b87c2d09",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 16ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_0d369_row0_col0, #T_0d369_row0_col1, #T_0d369_row0_col2, #T_0d369_row0_col3, #T_0d369_row1_col0, #T_0d369_row1_col1, #T_0d369_row1_col2, #T_0d369_row1_col3, #T_0d369_row2_col0, #T_0d369_row2_col1, #T_0d369_row2_col2, #T_0d369_row2_col3, #T_0d369_row3_col0, #T_0d369_row3_col1, #T_0d369_row3_col2, #T_0d369_row3_col3, #T_0d369_row4_col0, #T_0d369_row4_col1, #T_0d369_row4_col2, #T_0d369_row4_col3, #T_0d369_row5_col0, #T_0d369_row5_col1, #T_0d369_row5_col2, #T_0d369_row5_col3, #T_0d369_row6_col0, #T_0d369_row6_col1, #T_0d369_row6_col2, #T_0d369_row6_col3, #T_0d369_row7_col0, #T_0d369_row7_col1, #T_0d369_row7_col2, #T_0d369_row7_col3, #T_0d369_row8_col0, #T_0d369_row8_col1, #T_0d369_row8_col2, #T_0d369_row8_col3, #T_0d369_row9_col0, #T_0d369_row9_col1, #T_0d369_row9_col2, #T_0d369_row9_col3 {\n",
" color: black;\n",
"}\n",
"#T_0d369_row0_col4, #T_0d369_row0_col5, #T_0d369_row0_col6, #T_0d369_row1_col4, #T_0d369_row1_col5, #T_0d369_row1_col6, #T_0d369_row2_col4, #T_0d369_row2_col5, #T_0d369_row2_col6, #T_0d369_row3_col4, #T_0d369_row3_col5, #T_0d369_row3_col6, #T_0d369_row4_col4, #T_0d369_row4_col5, #T_0d369_row4_col6, #T_0d369_row5_col4, #T_0d369_row5_col5, #T_0d369_row5_col6, #T_0d369_row6_col4, #T_0d369_row6_col5, #T_0d369_row6_col6, #T_0d369_row7_col4, #T_0d369_row7_col5, #T_0d369_row7_col6, #T_0d369_row8_col4, #T_0d369_row8_col5, #T_0d369_row8_col6, #T_0d369_row9_col4, #T_0d369_row9_col5, #T_0d369_row9_col6 {\n",
" color: #307fc1;\n",
"}\n",
"</style>\n",
"<table id=\"T_0d369\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_0d369_level0_col0\" class=\"col_heading level0 col0\" >code</th>\n",
" <th id=\"T_0d369_level0_col1\" class=\"col_heading level0 col1\" >city</th>\n",
" <th id=\"T_0d369_level0_col2\" class=\"col_heading level0 col2\" >desc</th>\n",
" <th id=\"T_0d369_level0_col3\" class=\"col_heading level0 col3\" >region</th>\n",
" <th id=\"T_0d369_level0_col4\" class=\"col_heading level0 col4\" >runways</th>\n",
" <th id=\"T_0d369_level0_col5\" class=\"col_heading level0 col5\" >lat</th>\n",
" <th id=\"T_0d369_level0_col6\" class=\"col_heading level0 col6\" >lon</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_0d369_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_0d369_row0_col0\" class=\"data row0 col0\" >DFW</td>\n",
" <td id=\"T_0d369_row0_col1\" class=\"data row0 col1\" >Dallas</td>\n",
" <td id=\"T_0d369_row0_col2\" class=\"data row0 col2\" >Dallas/Fort Worth International Airport</td>\n",
" <td id=\"T_0d369_row0_col3\" class=\"data row0 col3\" >US-TX</td>\n",
" <td id=\"T_0d369_row0_col4\" class=\"data row0 col4\" >7</td>\n",
" <td id=\"T_0d369_row0_col5\" class=\"data row0 col5\" >32.896801</td>\n",
" <td id=\"T_0d369_row0_col6\" class=\"data row0 col6\" >-97.038002</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_0d369_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
" <td id=\"T_0d369_row1_col0\" class=\"data row1 col0\" >ORD</td>\n",
" <td id=\"T_0d369_row1_col1\" class=\"data row1 col1\" >Chicago</td>\n",
" <td id=\"T_0d369_row1_col2\" class=\"data row1 col2\" >Chicago O'Hare International Airport</td>\n",
" <td id=\"T_0d369_row1_col3\" class=\"data row1 col3\" >US-IL</td>\n",
" <td id=\"T_0d369_row1_col4\" class=\"data row1 col4\" >7</td>\n",
" <td id=\"T_0d369_row1_col5\" class=\"data row1 col5\" >41.978600</td>\n",
" <td id=\"T_0d369_row1_col6\" class=\"data row1 col6\" >-87.904800</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_0d369_level0_row2\" class=\"row_heading level0 row2\" >2</th>\n",
" <td id=\"T_0d369_row2_col0\" class=\"data row2 col0\" >AMS</td>\n",
" <td id=\"T_0d369_row2_col1\" class=\"data row2 col1\" >Amsterdam</td>\n",
" <td id=\"T_0d369_row2_col2\" class=\"data row2 col2\" >Amsterdam Airport Schiphol</td>\n",
" <td id=\"T_0d369_row2_col3\" class=\"data row2 col3\" >NL-NH</td>\n",
" <td id=\"T_0d369_row2_col4\" class=\"data row2 col4\" >6</td>\n",
" <td id=\"T_0d369_row2_col5\" class=\"data row2 col5\" >52.308601</td>\n",
" <td id=\"T_0d369_row2_col6\" class=\"data row2 col6\" >4.763890</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_0d369_level0_row3\" class=\"row_heading level0 row3\" >3</th>\n",
" <td id=\"T_0d369_row3_col0\" class=\"data row3 col0\" >BOS</td>\n",
" <td id=\"T_0d369_row3_col1\" class=\"data row3 col1\" >Boston</td>\n",
" <td id=\"T_0d369_row3_col2\" class=\"data row3 col2\" >Boston Logan</td>\n",
" <td id=\"T_0d369_row3_col3\" class=\"data row3 col3\" >US-MA</td>\n",
" <td id=\"T_0d369_row3_col4\" class=\"data row3 col4\" >6</td>\n",
" <td id=\"T_0d369_row3_col5\" class=\"data row3 col5\" >42.364300</td>\n",
" <td id=\"T_0d369_row3_col6\" class=\"data row3 col6\" >-71.005203</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_0d369_level0_row4\" class=\"row_heading level0 row4\" >4</th>\n",
" <td id=\"T_0d369_row4_col0\" class=\"data row4 col0\" >DEN</td>\n",
" <td id=\"T_0d369_row4_col1\" class=\"data row4 col1\" >Denver</td>\n",
" <td id=\"T_0d369_row4_col2\" class=\"data row4 col2\" >Denver International Airport</td>\n",
" <td id=\"T_0d369_row4_col3\" class=\"data row4 col3\" >US-CO</td>\n",
" <td id=\"T_0d369_row4_col4\" class=\"data row4 col4\" >6</td>\n",
" <td id=\"T_0d369_row4_col5\" class=\"data row4 col5\" >39.861698</td>\n",
" <td id=\"T_0d369_row4_col6\" class=\"data row4 col6\" >-104.672997</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_0d369_level0_row5\" class=\"row_heading level0 row5\" >5</th>\n",
" <td id=\"T_0d369_row5_col0\" class=\"data row5 col0\" >DTW</td>\n",
" <td id=\"T_0d369_row5_col1\" class=\"data row5 col1\" >Detroit</td>\n",
" <td id=\"T_0d369_row5_col2\" class=\"data row5 col2\" >Detroit Metropolitan, Wayne County</td>\n",
" <td id=\"T_0d369_row5_col3\" class=\"data row5 col3\" >US-MI</td>\n",
" <td id=\"T_0d369_row5_col4\" class=\"data row5 col4\" >6</td>\n",
" <td id=\"T_0d369_row5_col5\" class=\"data row5 col5\" >42.212399</td>\n",
" <td id=\"T_0d369_row5_col6\" class=\"data row5 col6\" >-83.353401</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_0d369_level0_row6\" class=\"row_heading level0 row6\" >6</th>\n",
" <td id=\"T_0d369_row6_col0\" class=\"data row6 col0\" >ATL</td>\n",
" <td id=\"T_0d369_row6_col1\" class=\"data row6 col1\" >Atlanta</td>\n",
" <td id=\"T_0d369_row6_col2\" class=\"data row6 col2\" >Hartsfield - Jackson Atlanta International Airport</td>\n",
" <td id=\"T_0d369_row6_col3\" class=\"data row6 col3\" >US-GA</td>\n",
" <td id=\"T_0d369_row6_col4\" class=\"data row6 col4\" >5</td>\n",
" <td id=\"T_0d369_row6_col5\" class=\"data row6 col5\" >33.636700</td>\n",
" <td id=\"T_0d369_row6_col6\" class=\"data row6 col6\" >-84.428101</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_0d369_level0_row7\" class=\"row_heading level0 row7\" >7</th>\n",
" <td id=\"T_0d369_row7_col0\" class=\"data row7 col0\" >GIS</td>\n",
" <td id=\"T_0d369_row7_col1\" class=\"data row7 col1\" >Gisborne</td>\n",
" <td id=\"T_0d369_row7_col2\" class=\"data row7 col2\" >Gisborne Airport</td>\n",
" <td id=\"T_0d369_row7_col3\" class=\"data row7 col3\" >NZ-GIS</td>\n",
" <td id=\"T_0d369_row7_col4\" class=\"data row7 col4\" >5</td>\n",
" <td id=\"T_0d369_row7_col5\" class=\"data row7 col5\" >-38.663300</td>\n",
" <td id=\"T_0d369_row7_col6\" class=\"data row7 col6\" >177.977997</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_0d369_level0_row8\" class=\"row_heading level0 row8\" >8</th>\n",
" <td id=\"T_0d369_row8_col0\" class=\"data row8 col0\" >HLZ</td>\n",
" <td id=\"T_0d369_row8_col1\" class=\"data row8 col1\" >Hamilton</td>\n",
" <td id=\"T_0d369_row8_col2\" class=\"data row8 col2\" >Hamilton International Airport</td>\n",
" <td id=\"T_0d369_row8_col3\" class=\"data row8 col3\" >NZ-WKO</td>\n",
" <td id=\"T_0d369_row8_col4\" class=\"data row8 col4\" >5</td>\n",
" <td id=\"T_0d369_row8_col5\" class=\"data row8 col5\" >-37.866699</td>\n",
" <td id=\"T_0d369_row8_col6\" class=\"data row8 col6\" >175.332001</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_0d369_level0_row9\" class=\"row_heading level0 row9\" >9</th>\n",
" <td id=\"T_0d369_row9_col0\" class=\"data row9 col0\" >IAH</td>\n",
" <td id=\"T_0d369_row9_col1\" class=\"data row9 col1\" >Houston</td>\n",
" <td id=\"T_0d369_row9_col2\" class=\"data row9 col2\" >George Bush Intercontinental</td>\n",
" <td id=\"T_0d369_row9_col3\" class=\"data row9 col3\" >US-TX</td>\n",
" <td id=\"T_0d369_row9_col4\" class=\"data row9 col4\" >5</td>\n",
" <td id=\"T_0d369_row9_col5\" class=\"data row9 col5\" >29.984400</td>\n",
" <td id=\"T_0d369_row9_col6\" class=\"data row9 col6\" >-95.341400</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119d63190>"
]
},
"execution_count": 64,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[code, city, desc, region, runways, lat, lon] := *airport{code, city, desc, region, runways, lat, lon}\n",
"\n",
":order -runways\n",
":limit 10"
]
},
{
"cell_type": "markdown",
"id": "db45f1d4-e89a-449e-beb8-a9301acfa86c",
"metadata": {},
"source": [
"How many airports are there in total?"
]
},
{
"cell_type": "code",
"execution_count": 65,
"id": "9cd0a6ba-4808-4812-b760-ac389c435610",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 14ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_d7fa0_row0_col0 {\n",
" color: #307fc1;\n",
"}\n",
"</style>\n",
"<table id=\"T_d7fa0\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_d7fa0_level0_col0\" class=\"col_heading level0 col0\" >count(code)</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_d7fa0_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_d7fa0_row0_col0\" class=\"data row0 col0\" >3504</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119d62c50>"
]
},
"execution_count": 65,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[count(code)] := *airport{code}"
]
},
{
"cell_type": "markdown",
"id": "e7bf2676-4e79-49f0-9401-4bf60f2dc313",
"metadata": {},
"source": [
"Let's get a distribution of the initials of the airport codes:"
]
},
{
"cell_type": "code",
"execution_count": 66,
"id": "d9878f9c-1b43-426b-a8f5-5060f2476d86",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 18ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_c35dc_row0_col0, #T_c35dc_row1_col0, #T_c35dc_row2_col0, #T_c35dc_row3_col0, #T_c35dc_row4_col0, #T_c35dc_row5_col0, #T_c35dc_row6_col0, #T_c35dc_row7_col0, #T_c35dc_row8_col0, #T_c35dc_row9_col0, #T_c35dc_row10_col0, #T_c35dc_row11_col0, #T_c35dc_row12_col0, #T_c35dc_row13_col0, #T_c35dc_row14_col0, #T_c35dc_row15_col0, #T_c35dc_row16_col0, #T_c35dc_row17_col0, #T_c35dc_row18_col0, #T_c35dc_row19_col0, #T_c35dc_row20_col0, #T_c35dc_row21_col0, #T_c35dc_row22_col0, #T_c35dc_row23_col0, #T_c35dc_row24_col0, #T_c35dc_row25_col0 {\n",
" color: #307fc1;\n",
"}\n",
"#T_c35dc_row0_col1, #T_c35dc_row1_col1, #T_c35dc_row2_col1, #T_c35dc_row3_col1, #T_c35dc_row4_col1, #T_c35dc_row5_col1, #T_c35dc_row6_col1, #T_c35dc_row7_col1, #T_c35dc_row8_col1, #T_c35dc_row9_col1, #T_c35dc_row10_col1, #T_c35dc_row11_col1, #T_c35dc_row12_col1, #T_c35dc_row13_col1, #T_c35dc_row14_col1, #T_c35dc_row15_col1, #T_c35dc_row16_col1, #T_c35dc_row17_col1, #T_c35dc_row18_col1, #T_c35dc_row19_col1, #T_c35dc_row20_col1, #T_c35dc_row21_col1, #T_c35dc_row22_col1, #T_c35dc_row23_col1, #T_c35dc_row24_col1, #T_c35dc_row25_col1 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_c35dc\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_c35dc_level0_col0\" class=\"col_heading level0 col0\" >count(initial)</th>\n",
" <th id=\"T_c35dc_level0_col1\" class=\"col_heading level0 col1\" >initial</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_c35dc_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_c35dc_row0_col0\" class=\"data row0 col0\" >212</td>\n",
" <td id=\"T_c35dc_row0_col1\" class=\"data row0 col1\" >A</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_c35dc_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
" <td id=\"T_c35dc_row1_col0\" class=\"data row1 col0\" >235</td>\n",
" <td id=\"T_c35dc_row1_col1\" class=\"data row1 col1\" >B</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_c35dc_level0_row2\" class=\"row_heading level0 row2\" >2</th>\n",
" <td id=\"T_c35dc_row2_col0\" class=\"data row2 col0\" >214</td>\n",
" <td id=\"T_c35dc_row2_col1\" class=\"data row2 col1\" >C</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_c35dc_level0_row3\" class=\"row_heading level0 row3\" >3</th>\n",
" <td id=\"T_c35dc_row3_col0\" class=\"data row3 col0\" >116</td>\n",
" <td id=\"T_c35dc_row3_col1\" class=\"data row3 col1\" >D</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_c35dc_level0_row4\" class=\"row_heading level0 row4\" >4</th>\n",
" <td id=\"T_c35dc_row4_col0\" class=\"data row4 col0\" >95</td>\n",
" <td id=\"T_c35dc_row4_col1\" class=\"data row4 col1\" >E</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_c35dc_level0_row5\" class=\"row_heading level0 row5\" >5</th>\n",
" <td id=\"T_c35dc_row5_col0\" class=\"data row5 col0\" >76</td>\n",
" <td id=\"T_c35dc_row5_col1\" class=\"data row5 col1\" >F</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_c35dc_level0_row6\" class=\"row_heading level0 row6\" >6</th>\n",
" <td id=\"T_c35dc_row6_col0\" class=\"data row6 col0\" >135</td>\n",
" <td id=\"T_c35dc_row6_col1\" class=\"data row6 col1\" >G</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_c35dc_level0_row7\" class=\"row_heading level0 row7\" >7</th>\n",
" <td id=\"T_c35dc_row7_col0\" class=\"data row7 col0\" >129</td>\n",
" <td id=\"T_c35dc_row7_col1\" class=\"data row7 col1\" >H</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_c35dc_level0_row8\" class=\"row_heading level0 row8\" >8</th>\n",
" <td id=\"T_c35dc_row8_col0\" class=\"data row8 col0\" >112</td>\n",
" <td id=\"T_c35dc_row8_col1\" class=\"data row8 col1\" >I</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_c35dc_level0_row9\" class=\"row_heading level0 row9\" >9</th>\n",
" <td id=\"T_c35dc_row9_col0\" class=\"data row9 col0\" >80</td>\n",
" <td id=\"T_c35dc_row9_col1\" class=\"data row9 col1\" >J</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_c35dc_level0_row10\" class=\"row_heading level0 row10\" >10</th>\n",
" <td id=\"T_c35dc_row10_col0\" class=\"data row10 col0\" >197</td>\n",
" <td id=\"T_c35dc_row10_col1\" class=\"data row10 col1\" >K</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_c35dc_level0_row11\" class=\"row_heading level0 row11\" >11</th>\n",
" <td id=\"T_c35dc_row11_col0\" class=\"data row11 col0\" >184</td>\n",
" <td id=\"T_c35dc_row11_col1\" class=\"data row11 col1\" >L</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_c35dc_level0_row12\" class=\"row_heading level0 row12\" >12</th>\n",
" <td id=\"T_c35dc_row12_col0\" class=\"data row12 col0\" >228</td>\n",
" <td id=\"T_c35dc_row12_col1\" class=\"data row12 col1\" >M</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_c35dc_level0_row13\" class=\"row_heading level0 row13\" >13</th>\n",
" <td id=\"T_c35dc_row13_col0\" class=\"data row13 col0\" >111</td>\n",
" <td id=\"T_c35dc_row13_col1\" class=\"data row13 col1\" >N</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_c35dc_level0_row14\" class=\"row_heading level0 row14\" >14</th>\n",
" <td id=\"T_c35dc_row14_col0\" class=\"data row14 col0\" >89</td>\n",
" <td id=\"T_c35dc_row14_col1\" class=\"data row14 col1\" >O</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_c35dc_level0_row15\" class=\"row_heading level0 row15\" >15</th>\n",
" <td id=\"T_c35dc_row15_col0\" class=\"data row15 col0\" >203</td>\n",
" <td id=\"T_c35dc_row15_col1\" class=\"data row15 col1\" >P</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_c35dc_level0_row16\" class=\"row_heading level0 row16\" >16</th>\n",
" <td id=\"T_c35dc_row16_col0\" class=\"data row16 col0\" >7</td>\n",
" <td id=\"T_c35dc_row16_col1\" class=\"data row16 col1\" >Q</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_c35dc_level0_row17\" class=\"row_heading level0 row17\" >17</th>\n",
" <td id=\"T_c35dc_row17_col0\" class=\"data row17 col0\" >121</td>\n",
" <td id=\"T_c35dc_row17_col1\" class=\"data row17 col1\" >R</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_c35dc_level0_row18\" class=\"row_heading level0 row18\" >18</th>\n",
" <td id=\"T_c35dc_row18_col0\" class=\"data row18 col0\" >245</td>\n",
" <td id=\"T_c35dc_row18_col1\" class=\"data row18 col1\" >S</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_c35dc_level0_row19\" class=\"row_heading level0 row19\" >19</th>\n",
" <td id=\"T_c35dc_row19_col0\" class=\"data row19 col0\" >205</td>\n",
" <td id=\"T_c35dc_row19_col1\" class=\"data row19 col1\" >T</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_c35dc_level0_row20\" class=\"row_heading level0 row20\" >20</th>\n",
" <td id=\"T_c35dc_row20_col0\" class=\"data row20 col0\" >77</td>\n",
" <td id=\"T_c35dc_row20_col1\" class=\"data row20 col1\" >U</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_c35dc_level0_row21\" class=\"row_heading level0 row21\" >21</th>\n",
" <td id=\"T_c35dc_row21_col0\" class=\"data row21 col0\" >86</td>\n",
" <td id=\"T_c35dc_row21_col1\" class=\"data row21 col1\" >V</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_c35dc_level0_row22\" class=\"row_heading level0 row22\" >22</th>\n",
" <td id=\"T_c35dc_row22_col0\" class=\"data row22 col0\" >59</td>\n",
" <td id=\"T_c35dc_row22_col1\" class=\"data row22 col1\" >W</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_c35dc_level0_row23\" class=\"row_heading level0 row23\" >23</th>\n",
" <td id=\"T_c35dc_row23_col0\" class=\"data row23 col0\" >28</td>\n",
" <td id=\"T_c35dc_row23_col1\" class=\"data row23 col1\" >X</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_c35dc_level0_row24\" class=\"row_heading level0 row24\" >24</th>\n",
" <td id=\"T_c35dc_row24_col0\" class=\"data row24 col0\" >211</td>\n",
" <td id=\"T_c35dc_row24_col1\" class=\"data row24 col1\" >Y</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_c35dc_level0_row25\" class=\"row_heading level0 row25\" >25</th>\n",
" <td id=\"T_c35dc_row25_col0\" class=\"data row25 col0\" >49</td>\n",
" <td id=\"T_c35dc_row25_col1\" class=\"data row25 col1\" >Z</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119d63670>"
]
},
"execution_count": 66,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[count(initial), initial] := *airport{code}, initial = first(chars(code))\n",
"\n",
":order initial"
]
},
{
"cell_type": "markdown",
"id": "34283880-46bb-4759-965e-5e3de5128c15",
"metadata": {},
"source": [
"More useful are the statistics of runways:"
]
},
{
"cell_type": "code",
"execution_count": 67,
"id": "4d509508-02fa-4ec3-94a9-905dde2dda41",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 18ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_58c2a_row0_col0, #T_58c2a_row0_col1, #T_58c2a_row0_col2, #T_58c2a_row0_col3, #T_58c2a_row0_col4, #T_58c2a_row0_col5, #T_58c2a_row0_col6 {\n",
" color: #307fc1;\n",
"}\n",
"</style>\n",
"<table id=\"T_58c2a\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_58c2a_level0_col0\" class=\"col_heading level0 col0\" >count(r)</th>\n",
" <th id=\"T_58c2a_level0_col1\" class=\"col_heading level0 col1\" >count_unique(r)</th>\n",
" <th id=\"T_58c2a_level0_col2\" class=\"col_heading level0 col2\" >sum(r)</th>\n",
" <th id=\"T_58c2a_level0_col3\" class=\"col_heading level0 col3\" >min(r)</th>\n",
" <th id=\"T_58c2a_level0_col4\" class=\"col_heading level0 col4\" >max(r)</th>\n",
" <th id=\"T_58c2a_level0_col5\" class=\"col_heading level0 col5\" >mean(r)</th>\n",
" <th id=\"T_58c2a_level0_col6\" class=\"col_heading level0 col6\" >std_dev(r)</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_58c2a_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_58c2a_row0_col0\" class=\"data row0 col0\" >3504</td>\n",
" <td id=\"T_58c2a_row0_col1\" class=\"data row0 col1\" >7</td>\n",
" <td id=\"T_58c2a_row0_col2\" class=\"data row0 col2\" >4980.000000</td>\n",
" <td id=\"T_58c2a_row0_col3\" class=\"data row0 col3\" >1</td>\n",
" <td id=\"T_58c2a_row0_col4\" class=\"data row0 col4\" >7</td>\n",
" <td id=\"T_58c2a_row0_col5\" class=\"data row0 col5\" >1.421233</td>\n",
" <td id=\"T_58c2a_row0_col6\" class=\"data row0 col6\" >0.743083</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119d63220>"
]
},
"execution_count": 67,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[count(r), count_unique(r), sum(r), min(r), max(r), mean(r), std_dev(r)] := \n",
" *airport{runways: r}"
]
},
{
"cell_type": "markdown",
"id": "c62269c6-9c23-4766-918d-aedb5cfe4bc3",
"metadata": {},
"source": [
"Using `country`, we can find countries with no airports:"
]
},
{
"cell_type": "code",
"execution_count": 68,
"id": "739902f6-902f-4261-878f-826291596399",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 11ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_c4c31_row0_col0, #T_c4c31_row1_col0, #T_c4c31_row2_col0, #T_c4c31_row3_col0, #T_c4c31_row4_col0 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_c4c31\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_c4c31_level0_col0\" class=\"col_heading level0 col0\" >desc</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_c4c31_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_c4c31_row0_col0\" class=\"data row0 col0\" >Andorra</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_c4c31_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
" <td id=\"T_c4c31_row1_col0\" class=\"data row1 col0\" >Liechtenstein</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_c4c31_level0_row2\" class=\"row_heading level0 row2\" >2</th>\n",
" <td id=\"T_c4c31_row2_col0\" class=\"data row2 col0\" >Monaco</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_c4c31_level0_row3\" class=\"row_heading level0 row3\" >3</th>\n",
" <td id=\"T_c4c31_row3_col0\" class=\"data row3 col0\" >Pitcairn</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_c4c31_level0_row4\" class=\"row_heading level0 row4\" >4</th>\n",
" <td id=\"T_c4c31_row4_col0\" class=\"data row4 col0\" >San Marino</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119d62cb0>"
]
},
"execution_count": 68,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[desc] := *country{code, desc}, not *airport{country: code}"
]
},
{
"cell_type": "markdown",
"id": "6f65e01a-b43f-48d2-9afa-0021262e6ada",
"metadata": {},
"source": [
"The `route` relation by itself is rather boring:"
]
},
{
"cell_type": "code",
"execution_count": 69,
"id": "9d297cc5-ba50-44d7-b834-46ffaa6c748d",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_28b7e_row0_col0, #T_28b7e_row0_col1, #T_28b7e_row1_col0, #T_28b7e_row1_col1, #T_28b7e_row2_col0, #T_28b7e_row2_col1, #T_28b7e_row3_col0, #T_28b7e_row3_col1, #T_28b7e_row4_col0, #T_28b7e_row4_col1, #T_28b7e_row5_col0, #T_28b7e_row5_col1, #T_28b7e_row6_col0, #T_28b7e_row6_col1, #T_28b7e_row7_col0, #T_28b7e_row7_col1, #T_28b7e_row8_col0, #T_28b7e_row8_col1, #T_28b7e_row9_col0, #T_28b7e_row9_col1 {\n",
" color: black;\n",
"}\n",
"#T_28b7e_row0_col2, #T_28b7e_row1_col2, #T_28b7e_row2_col2, #T_28b7e_row3_col2, #T_28b7e_row4_col2, #T_28b7e_row5_col2, #T_28b7e_row6_col2, #T_28b7e_row7_col2, #T_28b7e_row8_col2, #T_28b7e_row9_col2 {\n",
" color: #307fc1;\n",
"}\n",
"</style>\n",
"<table id=\"T_28b7e\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_28b7e_level0_col0\" class=\"col_heading level0 col0\" >fr</th>\n",
" <th id=\"T_28b7e_level0_col1\" class=\"col_heading level0 col1\" >to</th>\n",
" <th id=\"T_28b7e_level0_col2\" class=\"col_heading level0 col2\" >dist</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_28b7e_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_28b7e_row0_col0\" class=\"data row0 col0\" >AAA</td>\n",
" <td id=\"T_28b7e_row0_col1\" class=\"data row0 col1\" >FAC</td>\n",
" <td id=\"T_28b7e_row0_col2\" class=\"data row0 col2\" >48.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_28b7e_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
" <td id=\"T_28b7e_row1_col0\" class=\"data row1 col0\" >AAA</td>\n",
" <td id=\"T_28b7e_row1_col1\" class=\"data row1 col1\" >MKP</td>\n",
" <td id=\"T_28b7e_row1_col2\" class=\"data row1 col2\" >133.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_28b7e_level0_row2\" class=\"row_heading level0 row2\" >2</th>\n",
" <td id=\"T_28b7e_row2_col0\" class=\"data row2 col0\" >AAA</td>\n",
" <td id=\"T_28b7e_row2_col1\" class=\"data row2 col1\" >PPT</td>\n",
" <td id=\"T_28b7e_row2_col2\" class=\"data row2 col2\" >270.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_28b7e_level0_row3\" class=\"row_heading level0 row3\" >3</th>\n",
" <td id=\"T_28b7e_row3_col0\" class=\"data row3 col0\" >AAA</td>\n",
" <td id=\"T_28b7e_row3_col1\" class=\"data row3 col1\" >RAR</td>\n",
" <td id=\"T_28b7e_row3_col2\" class=\"data row3 col2\" >968.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_28b7e_level0_row4\" class=\"row_heading level0 row4\" >4</th>\n",
" <td id=\"T_28b7e_row4_col0\" class=\"data row4 col0\" >AAE</td>\n",
" <td id=\"T_28b7e_row4_col1\" class=\"data row4 col1\" >ALG</td>\n",
" <td id=\"T_28b7e_row4_col2\" class=\"data row4 col2\" >254.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_28b7e_level0_row5\" class=\"row_heading level0 row5\" >5</th>\n",
" <td id=\"T_28b7e_row5_col0\" class=\"data row5 col0\" >AAE</td>\n",
" <td id=\"T_28b7e_row5_col1\" class=\"data row5 col1\" >CDG</td>\n",
" <td id=\"T_28b7e_row5_col2\" class=\"data row5 col2\" >882.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_28b7e_level0_row6\" class=\"row_heading level0 row6\" >6</th>\n",
" <td id=\"T_28b7e_row6_col0\" class=\"data row6 col0\" >AAE</td>\n",
" <td id=\"T_28b7e_row6_col1\" class=\"data row6 col1\" >IST</td>\n",
" <td id=\"T_28b7e_row6_col2\" class=\"data row6 col2\" >1161.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_28b7e_level0_row7\" class=\"row_heading level0 row7\" >7</th>\n",
" <td id=\"T_28b7e_row7_col0\" class=\"data row7 col0\" >AAE</td>\n",
" <td id=\"T_28b7e_row7_col1\" class=\"data row7 col1\" >LYS</td>\n",
" <td id=\"T_28b7e_row7_col2\" class=\"data row7 col2\" >631.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_28b7e_level0_row8\" class=\"row_heading level0 row8\" >8</th>\n",
" <td id=\"T_28b7e_row8_col0\" class=\"data row8 col0\" >AAE</td>\n",
" <td id=\"T_28b7e_row8_col1\" class=\"data row8 col1\" >MRS</td>\n",
" <td id=\"T_28b7e_row8_col2\" class=\"data row8 col2\" >477.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_28b7e_level0_row9\" class=\"row_heading level0 row9\" >9</th>\n",
" <td id=\"T_28b7e_row9_col0\" class=\"data row9 col0\" >AAE</td>\n",
" <td id=\"T_28b7e_row9_col1\" class=\"data row9 col1\" >ORN</td>\n",
" <td id=\"T_28b7e_row9_col2\" class=\"data row9 col2\" >477.000000</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119d60e50>"
]
},
"execution_count": 69,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[fr, to, dist] := *route{fr, to, dist}\n",
"\n",
":limit 10"
]
},
{
"cell_type": "markdown",
"id": "9f037a30-6f67-4fd9-ba3a-968ebfe811ff",
"metadata": {},
"source": [
"It just records the starting and ending airports of each route, together with the distance. This relation only becomes useful when used as a graph."
]
},
{
"cell_type": "markdown",
"id": "44135ecf-045e-41c2-9c76-fb8eaac8b15b",
"metadata": {},
"source": [
"Airports with no routes:"
]
},
{
"cell_type": "code",
"execution_count": 70,
"id": "e58de060-2f75-46fb-9ce0-98068e338c09",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 56ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_a4a13_row0_col0, #T_a4a13_row0_col1, #T_a4a13_row1_col0, #T_a4a13_row1_col1, #T_a4a13_row2_col0, #T_a4a13_row2_col1, #T_a4a13_row3_col0, #T_a4a13_row3_col1, #T_a4a13_row4_col0, #T_a4a13_row4_col1, #T_a4a13_row5_col0, #T_a4a13_row5_col1, #T_a4a13_row6_col0, #T_a4a13_row6_col1, #T_a4a13_row7_col0, #T_a4a13_row7_col1, #T_a4a13_row8_col0, #T_a4a13_row8_col1, #T_a4a13_row9_col0, #T_a4a13_row9_col1, #T_a4a13_row10_col0, #T_a4a13_row10_col1, #T_a4a13_row11_col0, #T_a4a13_row11_col1, #T_a4a13_row12_col0, #T_a4a13_row12_col1, #T_a4a13_row13_col0, #T_a4a13_row13_col1, #T_a4a13_row14_col0, #T_a4a13_row14_col1, #T_a4a13_row15_col0, #T_a4a13_row15_col1, #T_a4a13_row16_col0, #T_a4a13_row16_col1, #T_a4a13_row17_col0, #T_a4a13_row17_col1, #T_a4a13_row18_col0, #T_a4a13_row18_col1, #T_a4a13_row19_col0, #T_a4a13_row19_col1, #T_a4a13_row20_col0, #T_a4a13_row20_col1, #T_a4a13_row21_col0, #T_a4a13_row21_col1, #T_a4a13_row22_col0, #T_a4a13_row22_col1, #T_a4a13_row23_col0, #T_a4a13_row23_col1, #T_a4a13_row24_col0, #T_a4a13_row24_col1, #T_a4a13_row25_col0, #T_a4a13_row25_col1, #T_a4a13_row26_col0, #T_a4a13_row26_col1, #T_a4a13_row27_col0, #T_a4a13_row27_col1 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_a4a13\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_a4a13_level0_col0\" class=\"col_heading level0 col0\" >code</th>\n",
" <th id=\"T_a4a13_level0_col1\" class=\"col_heading level0 col1\" >desc</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_a4a13_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_a4a13_row0_col0\" class=\"data row0 col0\" >AFW</td>\n",
" <td id=\"T_a4a13_row0_col1\" class=\"data row0 col1\" >Fort Worth Alliance Airport</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_a4a13_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
" <td id=\"T_a4a13_row1_col0\" class=\"data row1 col0\" >APA</td>\n",
" <td id=\"T_a4a13_row1_col1\" class=\"data row1 col1\" >Centennial Airport</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_a4a13_level0_row2\" class=\"row_heading level0 row2\" >2</th>\n",
" <td id=\"T_a4a13_row2_col0\" class=\"data row2 col0\" >APK</td>\n",
" <td id=\"T_a4a13_row2_col1\" class=\"data row2 col1\" >Apataki Airport</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_a4a13_level0_row3\" class=\"row_heading level0 row3\" >3</th>\n",
" <td id=\"T_a4a13_row3_col0\" class=\"data row3 col0\" >BID</td>\n",
" <td id=\"T_a4a13_row3_col1\" class=\"data row3 col1\" >Block Island State Airport</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_a4a13_level0_row4\" class=\"row_heading level0 row4\" >4</th>\n",
" <td id=\"T_a4a13_row4_col0\" class=\"data row4 col0\" >BVS</td>\n",
" <td id=\"T_a4a13_row4_col1\" class=\"data row4 col1\" >Breves Airport</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_a4a13_level0_row5\" class=\"row_heading level0 row5\" >5</th>\n",
" <td id=\"T_a4a13_row5_col0\" class=\"data row5 col0\" >BWU</td>\n",
" <td id=\"T_a4a13_row5_col1\" class=\"data row5 col1\" >Sydney Bankstown Airport</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_a4a13_level0_row6\" class=\"row_heading level0 row6\" >6</th>\n",
" <td id=\"T_a4a13_row6_col0\" class=\"data row6 col0\" >CRC</td>\n",
" <td id=\"T_a4a13_row6_col1\" class=\"data row6 col1\" >Santa Ana Airport</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_a4a13_level0_row7\" class=\"row_heading level0 row7\" >7</th>\n",
" <td id=\"T_a4a13_row7_col0\" class=\"data row7 col0\" >CVT</td>\n",
" <td id=\"T_a4a13_row7_col1\" class=\"data row7 col1\" >Coventry Airport</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_a4a13_level0_row8\" class=\"row_heading level0 row8\" >8</th>\n",
" <td id=\"T_a4a13_row8_col0\" class=\"data row8 col0\" >EKA</td>\n",
" <td id=\"T_a4a13_row8_col1\" class=\"data row8 col1\" >Murray Field</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_a4a13_level0_row9\" class=\"row_heading level0 row9\" >9</th>\n",
" <td id=\"T_a4a13_row9_col0\" class=\"data row9 col0\" >GYZ</td>\n",
" <td id=\"T_a4a13_row9_col1\" class=\"data row9 col1\" >Gruyere Airport</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_a4a13_level0_row10\" class=\"row_heading level0 row10\" >10</th>\n",
" <td id=\"T_a4a13_row10_col0\" class=\"data row10 col0\" >HFN</td>\n",
" <td id=\"T_a4a13_row10_col1\" class=\"data row10 col1\" >Hornafjordur Airport</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_a4a13_level0_row11\" class=\"row_heading level0 row11\" >11</th>\n",
" <td id=\"T_a4a13_row11_col0\" class=\"data row11 col0\" >HZK</td>\n",
" <td id=\"T_a4a13_row11_col1\" class=\"data row11 col1\" >Husavik Airport</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_a4a13_level0_row12\" class=\"row_heading level0 row12\" >12</th>\n",
" <td id=\"T_a4a13_row12_col0\" class=\"data row12 col0\" >ILG</td>\n",
" <td id=\"T_a4a13_row12_col1\" class=\"data row12 col1\" >New Castle Airport</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_a4a13_level0_row13\" class=\"row_heading level0 row13\" >13</th>\n",
" <td id=\"T_a4a13_row13_col0\" class=\"data row13 col0\" >INT</td>\n",
" <td id=\"T_a4a13_row13_col1\" class=\"data row13 col1\" >Smith Reynolds Airport</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_a4a13_level0_row14\" class=\"row_heading level0 row14\" >14</th>\n",
" <td id=\"T_a4a13_row14_col0\" class=\"data row14 col0\" >ISL</td>\n",
" <td id=\"T_a4a13_row14_col1\" class=\"data row14 col1\" >Ataturk International Airport</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_a4a13_level0_row15\" class=\"row_heading level0 row15\" >15</th>\n",
" <td id=\"T_a4a13_row15_col0\" class=\"data row15 col0\" >KGG</td>\n",
" <td id=\"T_a4a13_row15_col1\" class=\"data row15 col1\" >Kédougou Airport</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_a4a13_level0_row16\" class=\"row_heading level0 row16\" >16</th>\n",
" <td id=\"T_a4a13_row16_col0\" class=\"data row16 col0\" >NBW</td>\n",
" <td id=\"T_a4a13_row16_col1\" class=\"data row16 col1\" >Leeward Point Field</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_a4a13_level0_row17\" class=\"row_heading level0 row17\" >17</th>\n",
" <td id=\"T_a4a13_row17_col0\" class=\"data row17 col0\" >NFO</td>\n",
" <td id=\"T_a4a13_row17_col1\" class=\"data row17 col1\" >Mata'aho Airport</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_a4a13_level0_row18\" class=\"row_heading level0 row18\" >18</th>\n",
" <td id=\"T_a4a13_row18_col0\" class=\"data row18 col0\" >PSY</td>\n",
" <td id=\"T_a4a13_row18_col1\" class=\"data row18 col1\" >Stanley Airport</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_a4a13_level0_row19\" class=\"row_heading level0 row19\" >19</th>\n",
" <td id=\"T_a4a13_row19_col0\" class=\"data row19 col0\" >RIG</td>\n",
" <td id=\"T_a4a13_row19_col1\" class=\"data row19 col1\" >Rio Grande Airport</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_a4a13_level0_row20\" class=\"row_heading level0 row20\" >20</th>\n",
" <td id=\"T_a4a13_row20_col0\" class=\"data row20 col0\" >SFD</td>\n",
" <td id=\"T_a4a13_row20_col1\" class=\"data row20 col1\" >San Fernando De Apure Airport</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_a4a13_level0_row21\" class=\"row_heading level0 row21\" >21</th>\n",
" <td id=\"T_a4a13_row21_col0\" class=\"data row21 col0\" >SFH</td>\n",
" <td id=\"T_a4a13_row21_col1\" class=\"data row21 col1\" >San Felipe International Airport</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_a4a13_level0_row22\" class=\"row_heading level0 row22\" >22</th>\n",
" <td id=\"T_a4a13_row22_col0\" class=\"data row22 col0\" >SXF</td>\n",
" <td id=\"T_a4a13_row22_col1\" class=\"data row22 col1\" >Berlin-Schönefeld International Airport *Closed*</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_a4a13_level0_row23\" class=\"row_heading level0 row23\" >23</th>\n",
" <td id=\"T_a4a13_row23_col0\" class=\"data row23 col0\" >TUA</td>\n",
" <td id=\"T_a4a13_row23_col1\" class=\"data row23 col1\" >Teniente Coronel Luis a Mantilla Airport</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_a4a13_level0_row24\" class=\"row_heading level0 row24\" >24</th>\n",
" <td id=\"T_a4a13_row24_col0\" class=\"data row24 col0\" >TWB</td>\n",
" <td id=\"T_a4a13_row24_col1\" class=\"data row24 col1\" >Toowoomba Airport</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_a4a13_level0_row25\" class=\"row_heading level0 row25\" >25</th>\n",
" <td id=\"T_a4a13_row25_col0\" class=\"data row25 col0\" >TXL</td>\n",
" <td id=\"T_a4a13_row25_col1\" class=\"data row25 col1\" >Berlin, Tegel International Airport *Closed*</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_a4a13_level0_row26\" class=\"row_heading level0 row26\" >26</th>\n",
" <td id=\"T_a4a13_row26_col0\" class=\"data row26 col0\" >VCV</td>\n",
" <td id=\"T_a4a13_row26_col1\" class=\"data row26 col1\" >Southern California Logistics Airport</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_a4a13_level0_row27\" class=\"row_heading level0 row27\" >27</th>\n",
" <td id=\"T_a4a13_row27_col0\" class=\"data row27 col0\" >YEI</td>\n",
" <td id=\"T_a4a13_row27_col1\" class=\"data row27 col1\" >Bursa Yenişehir Airport</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119ddd360>"
]
},
"execution_count": 70,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[code, desc] := *airport{code, desc}, not *route{fr: code}, not *route{to: code}"
]
},
{
"cell_type": "markdown",
"id": "e26b06c3-3919-4a72-861d-e63318708496",
"metadata": {},
"source": [
"Airports with the most out routes:"
]
},
{
"cell_type": "code",
"execution_count": 71,
"id": "1b0a075d-5968-41e6-90df-27ee2034dc84",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 91ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_8a70b_row0_col0, #T_8a70b_row1_col0, #T_8a70b_row2_col0, #T_8a70b_row3_col0, #T_8a70b_row4_col0 {\n",
" color: black;\n",
"}\n",
"#T_8a70b_row0_col1, #T_8a70b_row1_col1, #T_8a70b_row2_col1, #T_8a70b_row3_col1, #T_8a70b_row4_col1 {\n",
" color: #307fc1;\n",
"}\n",
"</style>\n",
"<table id=\"T_8a70b\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_8a70b_level0_col0\" class=\"col_heading level0 col0\" >code</th>\n",
" <th id=\"T_8a70b_level0_col1\" class=\"col_heading level0 col1\" >n</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_8a70b_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_8a70b_row0_col0\" class=\"data row0 col0\" >FRA</td>\n",
" <td id=\"T_8a70b_row0_col1\" class=\"data row0 col1\" >310</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_8a70b_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
" <td id=\"T_8a70b_row1_col0\" class=\"data row1 col0\" >IST</td>\n",
" <td id=\"T_8a70b_row1_col1\" class=\"data row1 col1\" >309</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_8a70b_level0_row2\" class=\"row_heading level0 row2\" >2</th>\n",
" <td id=\"T_8a70b_row2_col0\" class=\"data row2 col0\" >CDG</td>\n",
" <td id=\"T_8a70b_row2_col1\" class=\"data row2 col1\" >293</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_8a70b_level0_row3\" class=\"row_heading level0 row3\" >3</th>\n",
" <td id=\"T_8a70b_row3_col0\" class=\"data row3 col0\" >AMS</td>\n",
" <td id=\"T_8a70b_row3_col1\" class=\"data row3 col1\" >283</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_8a70b_level0_row4\" class=\"row_heading level0 row4\" >4</th>\n",
" <td id=\"T_8a70b_row4_col0\" class=\"data row4 col0\" >MUC</td>\n",
" <td id=\"T_8a70b_row4_col1\" class=\"data row4 col1\" >270</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119ddefb0>"
]
},
"execution_count": 71,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"route_count[fr, count(fr)] := *route{fr}\n",
"?[code, n] := route_count[code, n]\n",
"\n",
":sort -n\n",
":limit 5"
]
},
{
"cell_type": "markdown",
"id": "b4154c1e-78f8-4621-9a32-05363d1b13cf",
"metadata": {},
"source": [
"How many routes are there from the European Union to the US?"
]
},
{
"cell_type": "code",
"execution_count": 72,
"id": "7de94407-206b-42d9-ac3b-cd9a3277bfe3",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 43ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_bc947_row0_col0 {\n",
" color: #307fc1;\n",
"}\n",
"</style>\n",
"<table id=\"T_bc947\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_bc947_level0_col0\" class=\"col_heading level0 col0\" >n</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_bc947_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_bc947_row0_col0\" class=\"data row0 col0\" >435</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119ddfd90>"
]
},
"execution_count": 72,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"routes[unique(r)] := *contain['EU', fr],\n",
" *route{fr, to},\n",
" *airport{code: to, country: 'US'},\n",
" r = [fr, to]\n",
"?[n] := routes[rs], n = length(rs)"
]
},
{
"cell_type": "markdown",
"id": "528bc6eb-064d-418f-8aa1-98aeedd64ace",
"metadata": {},
"source": [
"How many airports are there in the US with routes from the EU?"
]
},
{
"cell_type": "code",
"execution_count": 73,
"id": "7ecfd10d-f05f-443e-a0e9-73480d67dcf1",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 43ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_ad1ed_row0_col0 {\n",
" color: #307fc1;\n",
"}\n",
"</style>\n",
"<table id=\"T_ad1ed\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_ad1ed_level0_col0\" class=\"col_heading level0 col0\" >count_unique(to)</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_ad1ed_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_ad1ed_row0_col0\" class=\"data row0 col0\" >45</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119ddd7e0>"
]
},
"execution_count": 73,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[count_unique(to)] := *contain['EU', fr],\n",
" *route{fr, to},\n",
" *airport{code: to, country: 'US'}\n"
]
},
{
"cell_type": "markdown",
"id": "3a13fa07-aaa4-47c1-aefb-0a93c80e3c18",
"metadata": {},
"source": [
"How many routes are there for each airport in London, UK?"
]
},
{
"cell_type": "code",
"execution_count": 74,
"id": "52f6c021-1ac7-42a6-910a-7686eb2c653d",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 15ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_93a23_row0_col0, #T_93a23_row1_col0, #T_93a23_row2_col0, #T_93a23_row3_col0, #T_93a23_row4_col0 {\n",
" color: black;\n",
"}\n",
"#T_93a23_row0_col1, #T_93a23_row1_col1, #T_93a23_row2_col1, #T_93a23_row3_col1, #T_93a23_row4_col1 {\n",
" color: #307fc1;\n",
"}\n",
"</style>\n",
"<table id=\"T_93a23\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_93a23_level0_col0\" class=\"col_heading level0 col0\" >code</th>\n",
" <th id=\"T_93a23_level0_col1\" class=\"col_heading level0 col1\" >count(code)</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_93a23_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_93a23_row0_col0\" class=\"data row0 col0\" >LCY</td>\n",
" <td id=\"T_93a23_row0_col1\" class=\"data row0 col1\" >51</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_93a23_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
" <td id=\"T_93a23_row1_col0\" class=\"data row1 col0\" >LGW</td>\n",
" <td id=\"T_93a23_row1_col1\" class=\"data row1 col1\" >232</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_93a23_level0_row2\" class=\"row_heading level0 row2\" >2</th>\n",
" <td id=\"T_93a23_row2_col0\" class=\"data row2 col0\" >LHR</td>\n",
" <td id=\"T_93a23_row2_col1\" class=\"data row2 col1\" >221</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_93a23_level0_row3\" class=\"row_heading level0 row3\" >3</th>\n",
" <td id=\"T_93a23_row3_col0\" class=\"data row3 col0\" >LTN</td>\n",
" <td id=\"T_93a23_row3_col1\" class=\"data row3 col1\" >130</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_93a23_level0_row4\" class=\"row_heading level0 row4\" >4</th>\n",
" <td id=\"T_93a23_row4_col0\" class=\"data row4 col0\" >STN</td>\n",
" <td id=\"T_93a23_row4_col1\" class=\"data row4 col1\" >211</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119ddd990>"
]
},
"execution_count": 74,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[code, count(code)] := *airport{code, city: 'London', region: 'GB-ENG'}, *route{fr: code}"
]
},
{
"cell_type": "markdown",
"id": "19ecd6fa-04e0-4a03-9834-f0dfea861e9a",
"metadata": {},
"source": [
"We need to specify the region, because there is another city called London, not in the UK."
]
},
{
"cell_type": "markdown",
"id": "d393dfbb-5ceb-412d-bc71-24db4bcf3261",
"metadata": {},
"source": [
"How many airports are reachable from London, UK in two hops?"
]
},
{
"cell_type": "code",
"execution_count": 75,
"id": "0689fddc-e02d-4b4c-a621-b17f0431ccf4",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 69ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_96fd3_row0_col0 {\n",
" color: #307fc1;\n",
"}\n",
"</style>\n",
"<table id=\"T_96fd3\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_96fd3_level0_col0\" class=\"col_heading level0 col0\" >count_unique(a3)</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_96fd3_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_96fd3_row0_col0\" class=\"data row0 col0\" >2353</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119dde650>"
]
},
"execution_count": 75,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"lon_uk_airports[code] := *airport{code, city: 'London', region: 'GB-ENG'}\n",
"one_hop[to] := lon_uk_airports[fr], *route{fr, to}, not lon_uk_airports[to];\n",
"?[count_unique(a3)] := one_hop[a2], *route{fr: a2, to: a3}, not lon_uk_airports[a3];"
]
},
{
"cell_type": "markdown",
"id": "4be5b2d5-8aa9-4109-94f4-ccb75e109935",
"metadata": {},
"source": [
"What are the cities directly reachable from LGW (London Gatwick), but furthermost away?"
]
},
{
"cell_type": "code",
"execution_count": 76,
"id": "9ac99669-84dc-4a7a-b985-d1e333a41065",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 3ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_4a873_row0_col0, #T_4a873_row1_col0, #T_4a873_row2_col0, #T_4a873_row3_col0, #T_4a873_row4_col0, #T_4a873_row5_col0, #T_4a873_row6_col0, #T_4a873_row7_col0, #T_4a873_row8_col0, #T_4a873_row9_col0 {\n",
" color: black;\n",
"}\n",
"#T_4a873_row0_col1, #T_4a873_row1_col1, #T_4a873_row2_col1, #T_4a873_row3_col1, #T_4a873_row4_col1, #T_4a873_row5_col1, #T_4a873_row6_col1, #T_4a873_row7_col1, #T_4a873_row8_col1, #T_4a873_row9_col1 {\n",
" color: #307fc1;\n",
"}\n",
"</style>\n",
"<table id=\"T_4a873\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_4a873_level0_col0\" class=\"col_heading level0 col0\" >city</th>\n",
" <th id=\"T_4a873_level0_col1\" class=\"col_heading level0 col1\" >dist</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_4a873_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_4a873_row0_col0\" class=\"data row0 col0\" >Buenos Aires</td>\n",
" <td id=\"T_4a873_row0_col1\" class=\"data row0 col1\" >6908.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_4a873_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
" <td id=\"T_4a873_row1_col0\" class=\"data row1 col0\" >Singapore</td>\n",
" <td id=\"T_4a873_row1_col1\" class=\"data row1 col1\" >6751.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_4a873_level0_row2\" class=\"row_heading level0 row2\" >2</th>\n",
" <td id=\"T_4a873_row2_col0\" class=\"data row2 col0\" >Langkawi</td>\n",
" <td id=\"T_4a873_row2_col1\" class=\"data row2 col1\" >6299.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_4a873_level0_row3\" class=\"row_heading level0 row3\" >3</th>\n",
" <td id=\"T_4a873_row3_col0\" class=\"data row3 col0\" >Duong Dong</td>\n",
" <td id=\"T_4a873_row3_col1\" class=\"data row3 col1\" >6264.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_4a873_level0_row4\" class=\"row_heading level0 row4\" >4</th>\n",
" <td id=\"T_4a873_row4_col0\" class=\"data row4 col0\" >Taipei</td>\n",
" <td id=\"T_4a873_row4_col1\" class=\"data row4 col1\" >6080.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_4a873_level0_row5\" class=\"row_heading level0 row5\" >5</th>\n",
" <td id=\"T_4a873_row5_col0\" class=\"data row5 col0\" >Port Louis</td>\n",
" <td id=\"T_4a873_row5_col1\" class=\"data row5 col1\" >6053.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_4a873_level0_row6\" class=\"row_heading level0 row6\" >6</th>\n",
" <td id=\"T_4a873_row6_col0\" class=\"data row6 col0\" >Rayong</td>\n",
" <td id=\"T_4a873_row6_col1\" class=\"data row6 col1\" >6008.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_4a873_level0_row7\" class=\"row_heading level0 row7\" >7</th>\n",
" <td id=\"T_4a873_row7_col0\" class=\"data row7 col0\" >Cape Town</td>\n",
" <td id=\"T_4a873_row7_col1\" class=\"data row7 col1\" >5987.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_4a873_level0_row8\" class=\"row_heading level0 row8\" >8</th>\n",
" <td id=\"T_4a873_row8_col0\" class=\"data row8 col0\" >Hong Kong</td>\n",
" <td id=\"T_4a873_row8_col1\" class=\"data row8 col1\" >5982.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_4a873_level0_row9\" class=\"row_heading level0 row9\" >9</th>\n",
" <td id=\"T_4a873_row9_col0\" class=\"data row9 col0\" >Shanghai</td>\n",
" <td id=\"T_4a873_row9_col1\" class=\"data row9 col1\" >5745.000000</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119ddd240>"
]
},
"execution_count": 76,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[city, dist] := *route{fr: 'LGW', to, dist},\n",
" *airport{code: to, city}\n",
":order -dist\n",
":limit 10"
]
},
{
"cell_type": "markdown",
"id": "121df2dd-1926-47eb-80d3-c90fe56b253d",
"metadata": {},
"source": [
"What airports are within 0.1 degrees of the Greenwich meridian?"
]
},
{
"cell_type": "code",
"execution_count": 77,
"id": "5ac6dee6-c475-4db9-824d-2cbcc774aa23",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 9ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_31770_row0_col0, #T_31770_row0_col1, #T_31770_row1_col0, #T_31770_row1_col1, #T_31770_row2_col0, #T_31770_row2_col1, #T_31770_row3_col0, #T_31770_row3_col1 {\n",
" color: black;\n",
"}\n",
"#T_31770_row0_col2, #T_31770_row0_col3, #T_31770_row1_col2, #T_31770_row1_col3, #T_31770_row2_col2, #T_31770_row2_col3, #T_31770_row3_col2, #T_31770_row3_col3 {\n",
" color: #307fc1;\n",
"}\n",
"</style>\n",
"<table id=\"T_31770\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_31770_level0_col0\" class=\"col_heading level0 col0\" >code</th>\n",
" <th id=\"T_31770_level0_col1\" class=\"col_heading level0 col1\" >desc</th>\n",
" <th id=\"T_31770_level0_col2\" class=\"col_heading level0 col2\" >lon</th>\n",
" <th id=\"T_31770_level0_col3\" class=\"col_heading level0 col3\" >lat</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_31770_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_31770_row0_col0\" class=\"data row0 col0\" >CDT</td>\n",
" <td id=\"T_31770_row0_col1\" class=\"data row0 col1\" >Castellon De La Plana Airport</td>\n",
" <td id=\"T_31770_row0_col2\" class=\"data row0 col2\" >0.026111</td>\n",
" <td id=\"T_31770_row0_col3\" class=\"data row0 col3\" >39.999199</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_31770_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
" <td id=\"T_31770_row1_col0\" class=\"data row1 col0\" >LCY</td>\n",
" <td id=\"T_31770_row1_col1\" class=\"data row1 col1\" >London City Airport</td>\n",
" <td id=\"T_31770_row1_col2\" class=\"data row1 col2\" >0.055278</td>\n",
" <td id=\"T_31770_row1_col3\" class=\"data row1 col3\" >51.505278</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_31770_level0_row2\" class=\"row_heading level0 row2\" >2</th>\n",
" <td id=\"T_31770_row2_col0\" class=\"data row2 col0\" >LDE</td>\n",
" <td id=\"T_31770_row2_col1\" class=\"data row2 col1\" >Tarbes-Lourdes-Pyrénées Airport</td>\n",
" <td id=\"T_31770_row2_col2\" class=\"data row2 col2\" >-0.006439</td>\n",
" <td id=\"T_31770_row2_col3\" class=\"data row2 col3\" >43.178699</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_31770_level0_row3\" class=\"row_heading level0 row3\" >3</th>\n",
" <td id=\"T_31770_row3_col0\" class=\"data row3 col0\" >LEH</td>\n",
" <td id=\"T_31770_row3_col1\" class=\"data row3 col1\" >Le Havre Octeville Airport</td>\n",
" <td id=\"T_31770_row3_col2\" class=\"data row3 col2\" >0.088056</td>\n",
" <td id=\"T_31770_row3_col3\" class=\"data row3 col3\" >49.533901</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119dde9e0>"
]
},
"execution_count": 77,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[code, desc, lon, lat] := *airport{lon, lat, code, desc}, lon > -0.1, lon < 0.1"
]
},
{
"cell_type": "markdown",
"id": "015a1743-edd4-490d-b02f-462fa2506bed",
"metadata": {},
"source": [
"Airports in a box drawn around London Heathrow, UK:"
]
},
{
"cell_type": "code",
"execution_count": 78,
"id": "9ced92e0-ced4-4e55-a547-c8b06fa50756",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 15ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_4c406_row0_col0, #T_4c406_row0_col1, #T_4c406_row1_col0, #T_4c406_row1_col1, #T_4c406_row2_col0, #T_4c406_row2_col1, #T_4c406_row3_col0, #T_4c406_row3_col1, #T_4c406_row4_col0, #T_4c406_row4_col1, #T_4c406_row5_col0, #T_4c406_row5_col1 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_4c406\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_4c406_level0_col0\" class=\"col_heading level0 col0\" >code</th>\n",
" <th id=\"T_4c406_level0_col1\" class=\"col_heading level0 col1\" >desc</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_4c406_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_4c406_row0_col0\" class=\"data row0 col0\" >LCY</td>\n",
" <td id=\"T_4c406_row0_col1\" class=\"data row0 col1\" >London City Airport</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_4c406_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
" <td id=\"T_4c406_row1_col0\" class=\"data row1 col0\" >LGW</td>\n",
" <td id=\"T_4c406_row1_col1\" class=\"data row1 col1\" >London Gatwick</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_4c406_level0_row2\" class=\"row_heading level0 row2\" >2</th>\n",
" <td id=\"T_4c406_row2_col0\" class=\"data row2 col0\" >LHR</td>\n",
" <td id=\"T_4c406_row2_col1\" class=\"data row2 col1\" >London Heathrow</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_4c406_level0_row3\" class=\"row_heading level0 row3\" >3</th>\n",
" <td id=\"T_4c406_row3_col0\" class=\"data row3 col0\" >LTN</td>\n",
" <td id=\"T_4c406_row3_col1\" class=\"data row3 col1\" >London Luton Airport</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_4c406_level0_row4\" class=\"row_heading level0 row4\" >4</th>\n",
" <td id=\"T_4c406_row4_col0\" class=\"data row4 col0\" >SOU</td>\n",
" <td id=\"T_4c406_row4_col1\" class=\"data row4 col1\" >Southampton Airport</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_4c406_level0_row5\" class=\"row_heading level0 row5\" >5</th>\n",
" <td id=\"T_4c406_row5_col0\" class=\"data row5 col0\" >STN</td>\n",
" <td id=\"T_4c406_row5_col1\" class=\"data row5 col1\" >London Stansted Airport</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119ddcf70>"
]
},
"execution_count": 78,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"h_box[lon, lat] := *airport{code: 'LHR', lon, lat}\n",
"?[code, desc] := h_box[lhr_lon, lhr_lat], *airport{code, lon, lat, desc},\n",
" abs(lhr_lon - lon) < 1, abs(lhr_lat - lat) < 1"
]
},
{
"cell_type": "markdown",
"id": "20046b0e-cd8f-4de6-8f87-a49dcc8b8f7f",
"metadata": {},
"source": [
"For some spherical geometry: what is the angle subtended by SFO and NRT on the surface of the earth?"
]
},
{
"cell_type": "code",
"execution_count": 79,
"id": "6d133cc5-23cb-47c6-9cc0-2c6bebf049eb",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_f1ca5_row0_col0 {\n",
" color: #307fc1;\n",
"}\n",
"</style>\n",
"<table id=\"T_f1ca5\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_f1ca5_level0_col0\" class=\"col_heading level0 col0\" >deg_diff</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_f1ca5_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_f1ca5_row0_col0\" class=\"data row0 col0\" >73.992112</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119ddd6f0>"
]
},
"execution_count": 79,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[deg_diff] := *airport{code: 'SFO', lat: a_lat, lon: a_lon},\n",
" *airport{code: 'NRT', lat: b_lat, lon: b_lon},\n",
" deg_diff = rad_to_deg(haversine_deg_input(a_lat, a_lon, b_lat, b_lon))"
]
},
{
"cell_type": "markdown",
"id": "184bc863-b2a7-4dd3-9d27-648315098ec8",
"metadata": {},
"source": [
"We mentioned before that aggregations in Cozo are powerful. They are powerful because they can be used in recursions (some restrictions apply).\n",
"\n",
"Let's find the distance of the _shortest route_ between two airports. One wayis to enumerate all the routes between the two airports, and then apply `min` aggregation to the results. This cannot be implemented as stated, since the routes may contain cycles and hence there can be an infinite number of routes between two airports.\n",
"\n",
"Instead, think recursively. If we already have all the shortest routes between all nodes, we derive an _equation_ satisfied by the shortest route: the shortest route between `a` and `b` is either the distance of a direct route, or the sum of the shortest distance from `a` to `c` and the distance of a direct route from `c` to `d`. We apply our `min` aggregation to this recursive set instead.\n",
"\n",
"Write it out and it works. For exmaple, the shortest routes between the airports `LHR` and `YPO`:"
]
},
{
"cell_type": "code",
"execution_count": 80,
"id": "207a6e99-1e4a-466d-9492-859a680d9207",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 104ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_1b309_row0_col0 {\n",
" color: #307fc1;\n",
"}\n",
"</style>\n",
"<table id=\"T_1b309\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_1b309_level0_col0\" class=\"col_heading level0 col0\" >dist</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_1b309_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_1b309_row0_col0\" class=\"data row0 col0\" >4147.000000</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119ddd9c0>"
]
},
"execution_count": 80,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"shortest[b, min(dist)] := *route{fr: 'LHR', to: b, dist} \n",
" # Start with the airport 'LHR', retrieve a direct route from 'LHR' to b\n",
"\n",
"shortest[b, min(dist)] := shortest[c, d1], # Start with an existing shortest route from 'LHR' to c\n",
" *route{fr: c, to: b, dist: d2}, # Retrieve a direct route from c to b\n",
" dist = d1 + d2 # Add the distances\n",
"\n",
"?[dist] := shortest['YPO', dist] # Extract the answer for 'YPO'. \n",
" # We chose it since it is the hardest airport to get to from 'LHR'."
]
},
{
"cell_type": "markdown",
"id": "73d28120-ee91-4893-a796-6cddec3426ad",
"metadata": {},
"source": [
"Since path-finding is such a common operation on graphs, Cozo has several fixed rules for that:"
]
},
{
"cell_type": "code",
"execution_count": 81,
"id": "e1d8328f-87e5-4884-9f77-f6379c46465b",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 54ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_aac0d_row0_col0, #T_aac0d_row0_col1 {\n",
" color: black;\n",
"}\n",
"#T_aac0d_row0_col2 {\n",
" color: #307fc1;\n",
"}\n",
"#T_aac0d_row0_col3 {\n",
" color: #bf5b3d;\n",
"}\n",
"</style>\n",
"<table id=\"T_aac0d\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_aac0d_level0_col0\" class=\"col_heading level0 col0\" >starting</th>\n",
" <th id=\"T_aac0d_level0_col1\" class=\"col_heading level0 col1\" >goal</th>\n",
" <th id=\"T_aac0d_level0_col2\" class=\"col_heading level0 col2\" >distance</th>\n",
" <th id=\"T_aac0d_level0_col3\" class=\"col_heading level0 col3\" >path</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_aac0d_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_aac0d_row0_col0\" class=\"data row0 col0\" >LHR</td>\n",
" <td id=\"T_aac0d_row0_col1\" class=\"data row0 col1\" >YPO</td>\n",
" <td id=\"T_aac0d_row0_col2\" class=\"data row0 col2\" >4147.000000</td>\n",
" <td id=\"T_aac0d_row0_col3\" class=\"data row0 col3\" >['LHR', 'YUL', 'YVO', 'YKQ', 'YMO', 'YFA', 'ZKE', 'YAT', 'YPO']</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119ddf850>"
]
},
"execution_count": 81,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"starting[] <- [['LHR']]\n",
"goal[] <- [['YPO']]\n",
"?[starting, goal, distance, path] <~ ShortestPathDijkstra(*route[], starting[], goal[])"
]
},
{
"cell_type": "markdown",
"id": "af89a4d7-2260-466c-a119-bb0ae0a84ebf",
"metadata": {},
"source": [
"Not only is it more efficient, but we also get a path for the shortest route.\n",
"\n",
"Not content with the shortest path, the following calculates ten the shortest paths:"
]
},
{
"cell_type": "code",
"execution_count": 82,
"id": "050a7fe1-9b6f-4cc8-96b7-9cebac55bdbb",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 87ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_5ae71_row0_col0, #T_5ae71_row0_col1, #T_5ae71_row1_col0, #T_5ae71_row1_col1, #T_5ae71_row2_col0, #T_5ae71_row2_col1, #T_5ae71_row3_col0, #T_5ae71_row3_col1, #T_5ae71_row4_col0, #T_5ae71_row4_col1, #T_5ae71_row5_col0, #T_5ae71_row5_col1, #T_5ae71_row6_col0, #T_5ae71_row6_col1, #T_5ae71_row7_col0, #T_5ae71_row7_col1, #T_5ae71_row8_col0, #T_5ae71_row8_col1, #T_5ae71_row9_col0, #T_5ae71_row9_col1 {\n",
" color: black;\n",
"}\n",
"#T_5ae71_row0_col2, #T_5ae71_row1_col2, #T_5ae71_row2_col2, #T_5ae71_row3_col2, #T_5ae71_row4_col2, #T_5ae71_row5_col2, #T_5ae71_row6_col2, #T_5ae71_row7_col2, #T_5ae71_row8_col2, #T_5ae71_row9_col2 {\n",
" color: #307fc1;\n",
"}\n",
"#T_5ae71_row0_col3, #T_5ae71_row1_col3, #T_5ae71_row2_col3, #T_5ae71_row3_col3, #T_5ae71_row4_col3, #T_5ae71_row5_col3, #T_5ae71_row6_col3, #T_5ae71_row7_col3, #T_5ae71_row8_col3, #T_5ae71_row9_col3 {\n",
" color: #bf5b3d;\n",
"}\n",
"</style>\n",
"<table id=\"T_5ae71\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_5ae71_level0_col0\" class=\"col_heading level0 col0\" >starting</th>\n",
" <th id=\"T_5ae71_level0_col1\" class=\"col_heading level0 col1\" >goal</th>\n",
" <th id=\"T_5ae71_level0_col2\" class=\"col_heading level0 col2\" >distance</th>\n",
" <th id=\"T_5ae71_level0_col3\" class=\"col_heading level0 col3\" >path</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_5ae71_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_5ae71_row0_col0\" class=\"data row0 col0\" >LHR</td>\n",
" <td id=\"T_5ae71_row0_col1\" class=\"data row0 col1\" >YPO</td>\n",
" <td id=\"T_5ae71_row0_col2\" class=\"data row0 col2\" >4147.000000</td>\n",
" <td id=\"T_5ae71_row0_col3\" class=\"data row0 col3\" >['LHR', 'YUL', 'YVO', 'YKQ', 'YMO', 'YFA', 'ZKE', 'YAT', 'YPO']</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_5ae71_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
" <td id=\"T_5ae71_row1_col0\" class=\"data row1 col0\" >LHR</td>\n",
" <td id=\"T_5ae71_row1_col1\" class=\"data row1 col1\" >YPO</td>\n",
" <td id=\"T_5ae71_row1_col2\" class=\"data row1 col2\" >4150.000000</td>\n",
" <td id=\"T_5ae71_row1_col3\" class=\"data row1 col3\" >['LHR', 'DUB', 'YUL', 'YVO', 'YKQ', 'YMO', 'YFA', 'ZKE', 'YAT', 'YPO']</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_5ae71_level0_row2\" class=\"row_heading level0 row2\" >2</th>\n",
" <td id=\"T_5ae71_row2_col0\" class=\"data row2 col0\" >LHR</td>\n",
" <td id=\"T_5ae71_row2_col1\" class=\"data row2 col1\" >YPO</td>\n",
" <td id=\"T_5ae71_row2_col2\" class=\"data row2 col2\" >4164.000000</td>\n",
" <td id=\"T_5ae71_row2_col3\" class=\"data row2 col3\" >['LHR', 'YUL', 'YMT', 'YKQ', 'YMO', 'YFA', 'ZKE', 'YAT', 'YPO']</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_5ae71_level0_row3\" class=\"row_heading level0 row3\" >3</th>\n",
" <td id=\"T_5ae71_row3_col0\" class=\"data row3 col0\" >LHR</td>\n",
" <td id=\"T_5ae71_row3_col1\" class=\"data row3 col1\" >YPO</td>\n",
" <td id=\"T_5ae71_row3_col2\" class=\"data row3 col2\" >4167.000000</td>\n",
" <td id=\"T_5ae71_row3_col3\" class=\"data row3 col3\" >['LHR', 'DUB', 'YUL', 'YMT', 'YKQ', 'YMO', 'YFA', 'ZKE', 'YAT', 'YPO']</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_5ae71_level0_row4\" class=\"row_heading level0 row4\" >4</th>\n",
" <td id=\"T_5ae71_row4_col0\" class=\"data row4 col0\" >LHR</td>\n",
" <td id=\"T_5ae71_row4_col1\" class=\"data row4 col1\" >YPO</td>\n",
" <td id=\"T_5ae71_row4_col2\" class=\"data row4 col2\" >4187.000000</td>\n",
" <td id=\"T_5ae71_row4_col3\" class=\"data row4 col3\" >['LHR', 'MAN', 'DUB', 'YUL', 'YVO', 'YKQ', 'YMO', 'YFA', 'ZKE', 'YAT', 'YPO']</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_5ae71_level0_row5\" class=\"row_heading level0 row5\" >5</th>\n",
" <td id=\"T_5ae71_row5_col0\" class=\"data row5 col0\" >LHR</td>\n",
" <td id=\"T_5ae71_row5_col1\" class=\"data row5 col1\" >YPO</td>\n",
" <td id=\"T_5ae71_row5_col2\" class=\"data row5 col2\" >4202.000000</td>\n",
" <td id=\"T_5ae71_row5_col3\" class=\"data row5 col3\" >['LHR', 'IOM', 'DUB', 'YUL', 'YVO', 'YKQ', 'YMO', 'YFA', 'ZKE', 'YAT', 'YPO']</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_5ae71_level0_row6\" class=\"row_heading level0 row6\" >6</th>\n",
" <td id=\"T_5ae71_row6_col0\" class=\"data row6 col0\" >LHR</td>\n",
" <td id=\"T_5ae71_row6_col1\" class=\"data row6 col1\" >YPO</td>\n",
" <td id=\"T_5ae71_row6_col2\" class=\"data row6 col2\" >4204.000000</td>\n",
" <td id=\"T_5ae71_row6_col3\" class=\"data row6 col3\" >['LHR', 'MAN', 'DUB', 'YUL', 'YMT', 'YKQ', 'YMO', 'YFA', 'ZKE', 'YAT', 'YPO']</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_5ae71_level0_row7\" class=\"row_heading level0 row7\" >7</th>\n",
" <td id=\"T_5ae71_row7_col0\" class=\"data row7 col0\" >LHR</td>\n",
" <td id=\"T_5ae71_row7_col1\" class=\"data row7 col1\" >YPO</td>\n",
" <td id=\"T_5ae71_row7_col2\" class=\"data row7 col2\" >4209.000000</td>\n",
" <td id=\"T_5ae71_row7_col3\" class=\"data row7 col3\" >['LHR', 'YUL', 'YMT', 'YNS', 'YKQ', 'YMO', 'YFA', 'ZKE', 'YAT', 'YPO']</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_5ae71_level0_row8\" class=\"row_heading level0 row8\" >8</th>\n",
" <td id=\"T_5ae71_row8_col0\" class=\"data row8 col0\" >LHR</td>\n",
" <td id=\"T_5ae71_row8_col1\" class=\"data row8 col1\" >YPO</td>\n",
" <td id=\"T_5ae71_row8_col2\" class=\"data row8 col2\" >4211.000000</td>\n",
" <td id=\"T_5ae71_row8_col3\" class=\"data row8 col3\" >['LHR', 'MAN', 'IOM', 'DUB', 'YUL', 'YVO', 'YKQ', 'YMO', 'YFA', 'ZKE', 'YAT', 'YPO']</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_5ae71_level0_row9\" class=\"row_heading level0 row9\" >9</th>\n",
" <td id=\"T_5ae71_row9_col0\" class=\"data row9 col0\" >LHR</td>\n",
" <td id=\"T_5ae71_row9_col1\" class=\"data row9 col1\" >YPO</td>\n",
" <td id=\"T_5ae71_row9_col2\" class=\"data row9 col2\" >4212.000000</td>\n",
" <td id=\"T_5ae71_row9_col3\" class=\"data row9 col3\" >['LHR', 'DUB', 'YUL', 'YMT', 'YNS', 'YKQ', 'YMO', 'YFA', 'ZKE', 'YAT', 'YPO']</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119ddf7c0>"
]
},
"execution_count": 82,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"starting[] <- [['LHR']]\n",
"goal[] <- [['YPO']]\n",
"?[starting, goal, distance, path] <~ KShortestPathYen(*route[], starting[], goal[], k: 10)"
]
},
{
"cell_type": "markdown",
"id": "5b3a398d-95ee-4e4f-91a7-5c95f82c8bd3",
"metadata": {},
"source": [
"If efficiency is really important to you, you can use the A* algorithm with a good heuristic function:"
]
},
{
"cell_type": "code",
"execution_count": 83,
"id": "311a46cf-ba33-483a-ae60-c9a4ff2a071b",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 25ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_5fe3c_row0_col0, #T_5fe3c_row0_col1 {\n",
" color: black;\n",
"}\n",
"#T_5fe3c_row0_col2 {\n",
" color: #307fc1;\n",
"}\n",
"#T_5fe3c_row0_col3 {\n",
" color: #bf5b3d;\n",
"}\n",
"</style>\n",
"<table id=\"T_5fe3c\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_5fe3c_level0_col0\" class=\"col_heading level0 col0\" >0</th>\n",
" <th id=\"T_5fe3c_level0_col1\" class=\"col_heading level0 col1\" >1</th>\n",
" <th id=\"T_5fe3c_level0_col2\" class=\"col_heading level0 col2\" >2</th>\n",
" <th id=\"T_5fe3c_level0_col3\" class=\"col_heading level0 col3\" >3</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_5fe3c_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_5fe3c_row0_col0\" class=\"data row0 col0\" >LHR</td>\n",
" <td id=\"T_5fe3c_row0_col1\" class=\"data row0 col1\" >YPO</td>\n",
" <td id=\"T_5fe3c_row0_col2\" class=\"data row0 col2\" >4147.000000</td>\n",
" <td id=\"T_5fe3c_row0_col3\" class=\"data row0 col3\" >['LHR', 'YUL', 'YVO', 'YKQ', 'YMO', 'YFA', 'ZKE', 'YAT', 'YPO']</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119e02080>"
]
},
"execution_count": 83,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"code_lat_lon[code, lat, lon] := *airport{code, lat, lon}\n",
"starting[code, lat, lon] := code = 'LHR', *airport{code, lat, lon};\n",
"goal[code, lat, lon] := code = 'YPO', *airport{code, lat, lon};\n",
"?[] <~ ShortestPathAStar(*route[], \n",
" code_lat_lon[node, lat1, lon1], \n",
" starting[], \n",
" goal[goal, lat2, lon2], \n",
" heuristic: haversine_deg_input(lat1, lon1, lat2, lon2) * 3963);"
]
},
{
"cell_type": "markdown",
"id": "18a35f6d-7d31-412d-9ab0-abb79655b0d9",
"metadata": {},
"source": [
"There's a lot more setup required in this case: we need to retrieve the latitudes and longitudes of airports and do processing on them first.\n",
"The number `3963` above is the radius of the earth in miles."
]
},
{
"cell_type": "markdown",
"id": "c522cee1-d4ad-4c75-aa91-9c5e2852eecd",
"metadata": {},
"source": [
"The most important airports, by PageRank:"
]
},
{
"cell_type": "code",
"execution_count": 84,
"id": "a42d018b-ba09-4e27-9b1a-e780ca0bcc1e",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 78ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_cc9f7_row0_col0, #T_cc9f7_row0_col1, #T_cc9f7_row1_col0, #T_cc9f7_row1_col1, #T_cc9f7_row2_col0, #T_cc9f7_row2_col1, #T_cc9f7_row3_col0, #T_cc9f7_row3_col1, #T_cc9f7_row4_col0, #T_cc9f7_row4_col1, #T_cc9f7_row5_col0, #T_cc9f7_row5_col1, #T_cc9f7_row6_col0, #T_cc9f7_row6_col1, #T_cc9f7_row7_col0, #T_cc9f7_row7_col1, #T_cc9f7_row8_col0, #T_cc9f7_row8_col1, #T_cc9f7_row9_col0, #T_cc9f7_row9_col1 {\n",
" color: black;\n",
"}\n",
"#T_cc9f7_row0_col2, #T_cc9f7_row1_col2, #T_cc9f7_row2_col2, #T_cc9f7_row3_col2, #T_cc9f7_row4_col2, #T_cc9f7_row5_col2, #T_cc9f7_row6_col2, #T_cc9f7_row7_col2, #T_cc9f7_row8_col2, #T_cc9f7_row9_col2 {\n",
" color: #307fc1;\n",
"}\n",
"</style>\n",
"<table id=\"T_cc9f7\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_cc9f7_level0_col0\" class=\"col_heading level0 col0\" >code</th>\n",
" <th id=\"T_cc9f7_level0_col1\" class=\"col_heading level0 col1\" >desc</th>\n",
" <th id=\"T_cc9f7_level0_col2\" class=\"col_heading level0 col2\" >score</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_cc9f7_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_cc9f7_row0_col0\" class=\"data row0 col0\" >FRA</td>\n",
" <td id=\"T_cc9f7_row0_col1\" class=\"data row0 col1\" >Frankfurt am Main</td>\n",
" <td id=\"T_cc9f7_row0_col2\" class=\"data row0 col2\" >1.265292</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_cc9f7_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
" <td id=\"T_cc9f7_row1_col0\" class=\"data row1 col0\" >IST</td>\n",
" <td id=\"T_cc9f7_row1_col1\" class=\"data row1 col1\" >Istanbul International Airport</td>\n",
" <td id=\"T_cc9f7_row1_col2\" class=\"data row1 col2\" >1.260846</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_cc9f7_level0_row2\" class=\"row_heading level0 row2\" >2</th>\n",
" <td id=\"T_cc9f7_row2_col0\" class=\"data row2 col0\" >CDG</td>\n",
" <td id=\"T_cc9f7_row2_col1\" class=\"data row2 col1\" >Paris Charles de Gaulle</td>\n",
" <td id=\"T_cc9f7_row2_col2\" class=\"data row2 col2\" >1.251049</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_cc9f7_level0_row3\" class=\"row_heading level0 row3\" >3</th>\n",
" <td id=\"T_cc9f7_row3_col0\" class=\"data row3 col0\" >AMS</td>\n",
" <td id=\"T_cc9f7_row3_col1\" class=\"data row3 col1\" >Amsterdam Airport Schiphol</td>\n",
" <td id=\"T_cc9f7_row3_col2\" class=\"data row3 col2\" >1.243261</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_cc9f7_level0_row4\" class=\"row_heading level0 row4\" >4</th>\n",
" <td id=\"T_cc9f7_row4_col0\" class=\"data row4 col0\" >MUC</td>\n",
" <td id=\"T_cc9f7_row4_col1\" class=\"data row4 col1\" >Munich International Airport</td>\n",
" <td id=\"T_cc9f7_row4_col2\" class=\"data row4 col2\" >1.230537</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_cc9f7_level0_row5\" class=\"row_heading level0 row5\" >5</th>\n",
" <td id=\"T_cc9f7_row5_col0\" class=\"data row5 col0\" >ORD</td>\n",
" <td id=\"T_cc9f7_row5_col1\" class=\"data row5 col1\" >Chicago O'Hare International Airport</td>\n",
" <td id=\"T_cc9f7_row5_col2\" class=\"data row5 col2\" >1.220283</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_cc9f7_level0_row6\" class=\"row_heading level0 row6\" >6</th>\n",
" <td id=\"T_cc9f7_row6_col0\" class=\"data row6 col0\" >DFW</td>\n",
" <td id=\"T_cc9f7_row6_col1\" class=\"data row6 col1\" >Dallas/Fort Worth International Airport</td>\n",
" <td id=\"T_cc9f7_row6_col2\" class=\"data row6 col2\" >1.208827</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_cc9f7_level0_row7\" class=\"row_heading level0 row7\" >7</th>\n",
" <td id=\"T_cc9f7_row7_col0\" class=\"data row7 col0\" >DXB</td>\n",
" <td id=\"T_cc9f7_row7_col1\" class=\"data row7 col1\" >Dubai International Airport</td>\n",
" <td id=\"T_cc9f7_row7_col2\" class=\"data row7 col2\" >1.208430</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_cc9f7_level0_row8\" class=\"row_heading level0 row8\" >8</th>\n",
" <td id=\"T_cc9f7_row8_col0\" class=\"data row8 col0\" >PEK</td>\n",
" <td id=\"T_cc9f7_row8_col1\" class=\"data row8 col1\" >Beijing Capital International Airport</td>\n",
" <td id=\"T_cc9f7_row8_col2\" class=\"data row8 col2\" >1.208074</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_cc9f7_level0_row9\" class=\"row_heading level0 row9\" >9</th>\n",
" <td id=\"T_cc9f7_row9_col0\" class=\"data row9 col0\" >ATL</td>\n",
" <td id=\"T_cc9f7_row9_col1\" class=\"data row9 col1\" >Hartsfield - Jackson Atlanta International Airport</td>\n",
" <td id=\"T_cc9f7_row9_col2\" class=\"data row9 col2\" >1.199858</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119e01db0>"
]
},
"execution_count": 84,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"rank[code, score] <~ PageRank(*route[a, b])\n",
"?[code, desc, score] := rank[code, score], *airport{code, desc}\n",
"\n",
":limit 10;\n",
":order -score"
]
},
{
"cell_type": "markdown",
"id": "c2be4f97-5173-456e-a0d9-b7cf99bf9786",
"metadata": {},
"source": [
"The following example takes a long time to run since it calculates the betweenness centrality.\n",
"Algorithms for calculating the betweenness centrality have high complexity."
]
},
{
"cell_type": "code",
"execution_count": 85,
"id": "aaad3658-f2c2-4dde-bfe4-9b52e2b3f589",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 2908ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_2ac48_row0_col0, #T_2ac48_row0_col1, #T_2ac48_row1_col0, #T_2ac48_row1_col1, #T_2ac48_row2_col0, #T_2ac48_row2_col1, #T_2ac48_row3_col0, #T_2ac48_row3_col1, #T_2ac48_row4_col0, #T_2ac48_row4_col1, #T_2ac48_row5_col0, #T_2ac48_row5_col1, #T_2ac48_row6_col0, #T_2ac48_row6_col1, #T_2ac48_row7_col0, #T_2ac48_row7_col1, #T_2ac48_row8_col0, #T_2ac48_row8_col1, #T_2ac48_row9_col0, #T_2ac48_row9_col1 {\n",
" color: black;\n",
"}\n",
"#T_2ac48_row0_col2, #T_2ac48_row1_col2, #T_2ac48_row2_col2, #T_2ac48_row3_col2, #T_2ac48_row4_col2, #T_2ac48_row5_col2, #T_2ac48_row6_col2, #T_2ac48_row7_col2, #T_2ac48_row8_col2, #T_2ac48_row9_col2 {\n",
" color: #307fc1;\n",
"}\n",
"</style>\n",
"<table id=\"T_2ac48\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_2ac48_level0_col0\" class=\"col_heading level0 col0\" >code</th>\n",
" <th id=\"T_2ac48_level0_col1\" class=\"col_heading level0 col1\" >desc</th>\n",
" <th id=\"T_2ac48_level0_col2\" class=\"col_heading level0 col2\" >score</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_2ac48_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_2ac48_row0_col0\" class=\"data row0 col0\" >ANC</td>\n",
" <td id=\"T_2ac48_row0_col1\" class=\"data row0 col1\" >Anchorage Ted Stevens</td>\n",
" <td id=\"T_2ac48_row0_col2\" class=\"data row0 col2\" >1074869.260952</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_2ac48_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
" <td id=\"T_2ac48_row1_col0\" class=\"data row1 col0\" >KEF</td>\n",
" <td id=\"T_2ac48_row1_col1\" class=\"data row1 col1\" >Reykjavik, Keflavik International Airport</td>\n",
" <td id=\"T_2ac48_row1_col2\" class=\"data row1 col2\" >928449.975037</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_2ac48_level0_row2\" class=\"row_heading level0 row2\" >2</th>\n",
" <td id=\"T_2ac48_row2_col0\" class=\"data row2 col0\" >HEL</td>\n",
" <td id=\"T_2ac48_row2_col1\" class=\"data row2 col1\" >Helsinki Ventaa</td>\n",
" <td id=\"T_2ac48_row2_col2\" class=\"data row2 col2\" >581588.490562</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_2ac48_level0_row3\" class=\"row_heading level0 row3\" >3</th>\n",
" <td id=\"T_2ac48_row3_col0\" class=\"data row3 col0\" >PEK</td>\n",
" <td id=\"T_2ac48_row3_col1\" class=\"data row3 col1\" >Beijing Capital International Airport</td>\n",
" <td id=\"T_2ac48_row3_col2\" class=\"data row3 col2\" >532020.425300</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_2ac48_level0_row4\" class=\"row_heading level0 row4\" >4</th>\n",
" <td id=\"T_2ac48_row4_col0\" class=\"data row4 col0\" >DEL</td>\n",
" <td id=\"T_2ac48_row4_col1\" class=\"data row4 col1\" >Indira Gandhi International Airport</td>\n",
" <td id=\"T_2ac48_row4_col2\" class=\"data row4 col2\" >472979.963291</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_2ac48_level0_row5\" class=\"row_heading level0 row5\" >5</th>\n",
" <td id=\"T_2ac48_row5_col0\" class=\"data row5 col0\" >IST</td>\n",
" <td id=\"T_2ac48_row5_col1\" class=\"data row5 col1\" >Istanbul International Airport</td>\n",
" <td id=\"T_2ac48_row5_col2\" class=\"data row5 col2\" >457882.076744</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_2ac48_level0_row6\" class=\"row_heading level0 row6\" >6</th>\n",
" <td id=\"T_2ac48_row6_col0\" class=\"data row6 col0\" >PKC</td>\n",
" <td id=\"T_2ac48_row6_col1\" class=\"data row6 col1\" >Yelizovo Airport</td>\n",
" <td id=\"T_2ac48_row6_col2\" class=\"data row6 col2\" >408571.027619</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_2ac48_level0_row7\" class=\"row_heading level0 row7\" >7</th>\n",
" <td id=\"T_2ac48_row7_col0\" class=\"data row7 col0\" >MSP</td>\n",
" <td id=\"T_2ac48_row7_col1\" class=\"data row7 col1\" >Minneapolis-St.Paul International Airport</td>\n",
" <td id=\"T_2ac48_row7_col2\" class=\"data row7 col2\" >396433.049206</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_2ac48_level0_row8\" class=\"row_heading level0 row8\" >8</th>\n",
" <td id=\"T_2ac48_row8_col0\" class=\"data row8 col0\" >LAX</td>\n",
" <td id=\"T_2ac48_row8_col1\" class=\"data row8 col1\" >Los Angeles International Airport</td>\n",
" <td id=\"T_2ac48_row8_col2\" class=\"data row8 col2\" >393310.114286</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_2ac48_level0_row9\" class=\"row_heading level0 row9\" >9</th>\n",
" <td id=\"T_2ac48_row9_col0\" class=\"data row9 col0\" >DEN</td>\n",
" <td id=\"T_2ac48_row9_col1\" class=\"data row9 col1\" >Denver International Airport</td>\n",
" <td id=\"T_2ac48_row9_col2\" class=\"data row9 col2\" >374339.835975</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119ddfbb0>"
]
},
"execution_count": 85,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"centrality[code, score] <~ BetweennessCentrality(*route[a, b])\n",
"?[code, desc, score] := centrality[code, score], *airport{code, desc}\n",
"\n",
":limit 10;\n",
":order -score"
]
},
{
"cell_type": "markdown",
"id": "02ef7f3e-50c5-41bd-8879-17127a0369cc",
"metadata": {},
"source": [
"These are the airports that, if disconnected from the network, cause the most disruption.\n",
"As this example shows, some of the algorithms really struggle when you go beyond small or medium sized dataset."
]
},
{
"cell_type": "markdown",
"id": "1bdf46ff-a930-421f-b76b-273c118f3153",
"metadata": {},
"source": [
"Community detection can collapse a graph into a _supergraph_.\n",
"Here we store the result, since it has too many rows to display nicely:"
]
},
{
"cell_type": "code",
"execution_count": 86,
"id": "4968276a-e871-409e-9470-987b10a73f9a",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 587ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_44bc8_row0_col0 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_44bc8\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_44bc8_level0_col0\" class=\"col_heading level0 col0\" >status</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_44bc8_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_44bc8_row0_col0\" class=\"data row0 col0\" >OK</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119ddcee0>"
]
},
"execution_count": 86,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"community[detailed_cluster, code] <~ CommunityDetectionLouvain(*route[a, b])\n",
"?[code, cluster, detailed_cluster] := community[detailed_cluster, code], cluster = first(detailed_cluster)\n",
"\n",
":replace community {code => cluster, detailed_cluster}"
]
},
{
"cell_type": "markdown",
"id": "a315fd3f-326d-4376-907b-c5cf96191d5c",
"metadata": {},
"source": [
"We can look at the supernodes containing specific nodes. For example, the supernode for London Gatwick consists of mainly UK and other European airports, as you would expect:"
]
},
{
"cell_type": "code",
"execution_count": 87,
"id": "b41de092-a40d-463d-89f2-db3e62cbf93f",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 16ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_88e2f_row0_col0, #T_88e2f_row1_col0, #T_88e2f_row2_col0, #T_88e2f_row3_col0, #T_88e2f_row4_col0 {\n",
" color: black;\n",
"}\n",
"#T_88e2f_row0_col1, #T_88e2f_row1_col1, #T_88e2f_row2_col1, #T_88e2f_row3_col1, #T_88e2f_row4_col1 {\n",
" color: #307fc1;\n",
"}\n",
"</style>\n",
"<table id=\"T_88e2f\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_88e2f_level0_col0\" class=\"col_heading level0 col0\" >country</th>\n",
" <th id=\"T_88e2f_level0_col1\" class=\"col_heading level0 col1\" >count(code)</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_88e2f_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_88e2f_row0_col0\" class=\"data row0 col0\" >United Kingdom</td>\n",
" <td id=\"T_88e2f_row0_col1\" class=\"data row0 col1\" >54</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_88e2f_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
" <td id=\"T_88e2f_row1_col0\" class=\"data row1 col0\" >France</td>\n",
" <td id=\"T_88e2f_row1_col1\" class=\"data row1 col1\" >50</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_88e2f_level0_row2\" class=\"row_heading level0 row2\" >2</th>\n",
" <td id=\"T_88e2f_row2_col0\" class=\"data row2 col0\" >Norway</td>\n",
" <td id=\"T_88e2f_row2_col1\" class=\"data row2 col1\" >49</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_88e2f_level0_row3\" class=\"row_heading level0 row3\" >3</th>\n",
" <td id=\"T_88e2f_row3_col0\" class=\"data row3 col0\" >Spain</td>\n",
" <td id=\"T_88e2f_row3_col1\" class=\"data row3 col1\" >40</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_88e2f_level0_row4\" class=\"row_heading level0 row4\" >4</th>\n",
" <td id=\"T_88e2f_row4_col0\" class=\"data row4 col0\" >Greece</td>\n",
" <td id=\"T_88e2f_row4_col1\" class=\"data row4 col1\" >38</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119e03bb0>"
]
},
"execution_count": 87,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"community[code] := *community{code: 'LGW', cluster}, *community{code, cluster}\n",
"?[country, count(code)] := \n",
" community[code], \n",
" *airport{code, desc, country: country_code}, \n",
" *country{code: country_code, desc: country},\n",
"\n",
":order -count(code)\n",
":limit 5"
]
},
{
"cell_type": "markdown",
"id": "2e3f13b7-0fc9-4585-ac68-9354c2fc1f5c",
"metadata": {},
"source": [
"For `JFK` on the other hand, its supernode consists of mainly US airports:"
]
},
{
"cell_type": "code",
"execution_count": 88,
"id": "65ed109d-146d-4d3d-8ea5-9cd5de2c6400",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 21ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_e9006_row0_col0, #T_e9006_row1_col0, #T_e9006_row2_col0, #T_e9006_row3_col0, #T_e9006_row4_col0 {\n",
" color: black;\n",
"}\n",
"#T_e9006_row0_col1, #T_e9006_row1_col1, #T_e9006_row2_col1, #T_e9006_row3_col1, #T_e9006_row4_col1 {\n",
" color: #307fc1;\n",
"}\n",
"</style>\n",
"<table id=\"T_e9006\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_e9006_level0_col0\" class=\"col_heading level0 col0\" >country</th>\n",
" <th id=\"T_e9006_level0_col1\" class=\"col_heading level0 col1\" >count(code)</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_e9006_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_e9006_row0_col0\" class=\"data row0 col0\" >United States</td>\n",
" <td id=\"T_e9006_row0_col1\" class=\"data row0 col1\" >444</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_e9006_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
" <td id=\"T_e9006_row1_col0\" class=\"data row1 col0\" >Canada</td>\n",
" <td id=\"T_e9006_row1_col1\" class=\"data row1 col1\" >111</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_e9006_level0_row2\" class=\"row_heading level0 row2\" >2</th>\n",
" <td id=\"T_e9006_row2_col0\" class=\"data row2 col0\" >Brazil</td>\n",
" <td id=\"T_e9006_row2_col1\" class=\"data row2 col1\" >108</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_e9006_level0_row3\" class=\"row_heading level0 row3\" >3</th>\n",
" <td id=\"T_e9006_row3_col0\" class=\"data row3 col0\" >Mexico</td>\n",
" <td id=\"T_e9006_row3_col1\" class=\"data row3 col1\" >57</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_e9006_level0_row4\" class=\"row_heading level0 row4\" >4</th>\n",
" <td id=\"T_e9006_row4_col0\" class=\"data row4 col0\" >Colombia</td>\n",
" <td id=\"T_e9006_row4_col1\" class=\"data row4 col1\" >50</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119e00f70>"
]
},
"execution_count": 88,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"community[code] := *community{code: 'JFK', cluster}, *community{code, cluster}\n",
"?[country, count(code)] := \n",
" community[code], \n",
" *airport{code, desc, country: country_code}, \n",
" *country{code: country_code, desc: country},\n",
"\n",
":order -count(code)\n",
":limit 5"
]
},
{
"cell_type": "markdown",
"id": "be5890a8-94b3-4093-afe6-4b7cba1faeb4",
"metadata": {},
"source": [
"But it does not always work according to geography. For example, Frankfurt airport is in Germany:"
]
},
{
"cell_type": "code",
"execution_count": 89,
"id": "938dd92b-f59f-4008-a486-828443bca18f",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_015cf_row0_col0, #T_015cf_row0_col1 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_015cf\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_015cf_level0_col0\" class=\"col_heading level0 col0\" >desc</th>\n",
" <th id=\"T_015cf_level0_col1\" class=\"col_heading level0 col1\" >country_desc</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_015cf_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_015cf_row0_col0\" class=\"data row0 col0\" >Frankfurt am Main</td>\n",
" <td id=\"T_015cf_row0_col1\" class=\"data row0 col1\" >Germany</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119e03100>"
]
},
"execution_count": 89,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[desc, country_desc] := *airport{code: 'FRA', desc, country: country_code}, *country{code: country_code, desc: country_desc}"
]
},
{
"cell_type": "markdown",
"id": "961e4cc5-f55d-45be-a554-4a8d7b276b0c",
"metadata": {},
"source": [
"But its supernode:"
]
},
{
"cell_type": "code",
"execution_count": 90,
"id": "2ab311ba-b925-46b4-8c96-cb8a5e6bd3bd",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 20ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_6d726_row0_col0, #T_6d726_row1_col0, #T_6d726_row2_col0, #T_6d726_row3_col0, #T_6d726_row4_col0 {\n",
" color: black;\n",
"}\n",
"#T_6d726_row0_col1, #T_6d726_row1_col1, #T_6d726_row2_col1, #T_6d726_row3_col1, #T_6d726_row4_col1 {\n",
" color: #307fc1;\n",
"}\n",
"</style>\n",
"<table id=\"T_6d726\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_6d726_level0_col0\" class=\"col_heading level0 col0\" >country</th>\n",
" <th id=\"T_6d726_level0_col1\" class=\"col_heading level0 col1\" >count(code)</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_6d726_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_6d726_row0_col0\" class=\"data row0 col0\" >United States</td>\n",
" <td id=\"T_6d726_row0_col1\" class=\"data row0 col1\" >444</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_6d726_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
" <td id=\"T_6d726_row1_col0\" class=\"data row1 col0\" >Canada</td>\n",
" <td id=\"T_6d726_row1_col1\" class=\"data row1 col1\" >111</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_6d726_level0_row2\" class=\"row_heading level0 row2\" >2</th>\n",
" <td id=\"T_6d726_row2_col0\" class=\"data row2 col0\" >Brazil</td>\n",
" <td id=\"T_6d726_row2_col1\" class=\"data row2 col1\" >108</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_6d726_level0_row3\" class=\"row_heading level0 row3\" >3</th>\n",
" <td id=\"T_6d726_row3_col0\" class=\"data row3 col0\" >Mexico</td>\n",
" <td id=\"T_6d726_row3_col1\" class=\"data row3 col1\" >57</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_6d726_level0_row4\" class=\"row_heading level0 row4\" >4</th>\n",
" <td id=\"T_6d726_row4_col0\" class=\"data row4 col0\" >Colombia</td>\n",
" <td id=\"T_6d726_row4_col1\" class=\"data row4 col1\" >50</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119e02530>"
]
},
"execution_count": 90,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"community[code] := *community{code: 'FRA', cluster}, *community{code, cluster}\n",
"?[country, count(code)] := \n",
" community[code], \n",
" *airport{code, desc, country: country_code}, \n",
" *country{code: country_code, desc: country},\n",
"\n",
":order -count(code)\n",
":limit 5"
]
},
{
"cell_type": "markdown",
"id": "78a7d1cf-8051-40cd-b9d9-df7c0822f4b8",
"metadata": {},
"source": [
"Germany does not even appear in the top five. In fact, `FRA` is in the same supernode as `JFK`. What matters is the connectivity in the graph, not the geography.\n",
"As another example:"
]
},
{
"cell_type": "code",
"execution_count": 91,
"id": "84284f9d-f7e7-4675-9c1e-f83cb4f7cae9",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 20ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_9c265_row0_col0, #T_9c265_row1_col0, #T_9c265_row2_col0, #T_9c265_row3_col0, #T_9c265_row4_col0 {\n",
" color: black;\n",
"}\n",
"#T_9c265_row0_col1, #T_9c265_row1_col1, #T_9c265_row2_col1, #T_9c265_row3_col1, #T_9c265_row4_col1 {\n",
" color: #307fc1;\n",
"}\n",
"</style>\n",
"<table id=\"T_9c265\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_9c265_level0_col0\" class=\"col_heading level0 col0\" >country</th>\n",
" <th id=\"T_9c265_level0_col1\" class=\"col_heading level0 col1\" >count(code)</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_9c265_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_9c265_row0_col0\" class=\"data row0 col0\" >China</td>\n",
" <td id=\"T_9c265_row0_col1\" class=\"data row0 col1\" >216</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_9c265_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
" <td id=\"T_9c265_row1_col0\" class=\"data row1 col0\" >Australia</td>\n",
" <td id=\"T_9c265_row1_col1\" class=\"data row1 col1\" >125</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_9c265_level0_row2\" class=\"row_heading level0 row2\" >2</th>\n",
" <td id=\"T_9c265_row2_col0\" class=\"data row2 col0\" >Indonesia</td>\n",
" <td id=\"T_9c265_row2_col1\" class=\"data row2 col1\" >68</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_9c265_level0_row3\" class=\"row_heading level0 row3\" >3</th>\n",
" <td id=\"T_9c265_row3_col0\" class=\"data row3 col0\" >Japan</td>\n",
" <td id=\"T_9c265_row3_col1\" class=\"data row3 col1\" >65</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_9c265_level0_row4\" class=\"row_heading level0 row4\" >4</th>\n",
" <td id=\"T_9c265_row4_col0\" class=\"data row4 col0\" >Philippines</td>\n",
" <td id=\"T_9c265_row4_col1\" class=\"data row4 col1\" >40</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119e030a0>"
]
},
"execution_count": 91,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"community[code] := *community{code: 'SIN', cluster}, *community{code, cluster}\n",
"?[country, count(code)] := \n",
" community[code], \n",
" *airport{code, desc, country: country_code}, \n",
" *country{code: country_code, desc: country},\n",
"\n",
":order -count(code)\n",
":limit 5"
]
},
{
"cell_type": "markdown",
"id": "1dc2a5cc-62f9-488b-8520-570122148ec7",
"metadata": {},
"source": [
"You'd expect `SIN` to be a Chinese airport. Wrong:"
]
},
{
"cell_type": "code",
"execution_count": 92,
"id": "d2adbdb9-14b9-4b07-83e8-9888ee984ff9",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<p style=\"font-size: 75%\">Completed in 0ms</p>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_86b01_row0_col0, #T_86b01_row0_col1 {\n",
" color: black;\n",
"}\n",
"</style>\n",
"<table id=\"T_86b01\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_86b01_level0_col0\" class=\"col_heading level0 col0\" >desc</th>\n",
" <th id=\"T_86b01_level0_col1\" class=\"col_heading level0 col1\" >country_desc</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_86b01_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
" <td id=\"T_86b01_row0_col0\" class=\"data row0 col0\" >Singapore, Changi International Airport</td>\n",
" <td id=\"T_86b01_row0_col1\" class=\"data row0 col1\" >Singapore</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x119e02500>"
]
},
"execution_count": 92,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"?[desc, country_desc] := *airport{code: 'SIN', desc, country: country_code}, *country{code: country_code, desc: country_desc}"
]
},
{
"cell_type": "markdown",
"id": "27763722-f643-42cb-af4e-1f56277e194b",
"metadata": {},
"source": [
"That's it for the tutorial. Continue with the [Manual](https://cozodb.github.io/current/manual/index.html) if you want more details."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4f2c6f0c-e6a4-4eeb-b33b-288bdfc8863d",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"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.10.6"
}
},
"nbformat": 4,
"nbformat_minor": 5
}