{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "9f1bad2d",
   "metadata": {},
   "source": [
    "# Command line interface\n",
    "\n",
    "This Jupyter notebook gives an overview of the command line interface (CLI) that comes with the Python package [mevis](https://pypi.org/project/mevis) after installation with pip. The .ipynb file can be found [here](https://github.com/robert-haas/mevis/tree/master/examples)."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e0437c08",
   "metadata": {},
   "source": [
    "## Show the help text"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7073a631",
   "metadata": {},
   "outputs": [],
   "source": [
    "!mevis -h"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5d1f7634",
   "metadata": {},
   "source": [
    "## Use it minimalistically\n",
    "\n",
    "- `-i`: An **input file** (.scm) to load an AtomSpace from.\n",
    "- `-o`: An optional **output file**.\n",
    "\n",
    "Following three cases are possible."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "98b91821",
   "metadata": {},
   "source": [
    "1. No output file: Creates a graph visualization and **displays it** in the default webbrowser."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5e9bce8b",
   "metadata": {},
   "outputs": [],
   "source": [
    "!mevis -i moses.scm"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "82cc2b14",
   "metadata": {},
   "source": [
    "2. Output file ending with `.html`: Creates a graph visualization and stores it to a **HTML file**."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "96c1e0a0",
   "metadata": {},
   "outputs": [],
   "source": [
    "!mevis -i moses.scm -o moses.html"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "236471e4",
   "metadata": {},
   "source": [
    "3. Output file ending with `.gml`, `.gml.gz` or `.gml.bz2`: Creates a graph representation and stores it to a **GML file** that can be **compressed with gzip or bzip2** to considerably reduce size."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "86811fad",
   "metadata": {},
   "outputs": [],
   "source": [
    "!mevis -i moses.scm -o moses.gml\n",
    "!mevis -i moses.scm -o moses.gml.gz\n",
    "!mevis -i moses.scm -o moses.gml.bz2"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c74b2b2d",
   "metadata": {},
   "source": [
    "## Show status messages and overwrite existing files\n",
    "\n",
    "- `--verbose`: If provided, messages are printed about individual steps and their intermediate results.\n",
    "- `--force`: If provided, output files are overwritten if they already exist."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d1311ac0",
   "metadata": {},
   "outputs": [],
   "source": [
    "!mevis -i moses.scm -o moses.html --force --verbose"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "442a4d02",
   "metadata": {},
   "source": [
    "## Choose another backend\n",
    "\n",
    "- `-b`: If provided, the chosen backend is used to create the visualization. For available options, please look at the help text."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8b423356",
   "metadata": {},
   "outputs": [],
   "source": [
    "!mevis -i moses.scm -o moses_d3.html -b d3\n",
    "!mevis -i moses.scm -o moses_three.html -b three\n",
    "!mevis -i moses.scm -o moses_vis.html -b vis"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1b7e3a08",
   "metadata": {},
   "source": [
    "## Calculate a layout\n",
    "\n",
    "- `-l`: If provided, the chosen method is used for calculating x and y coordinates for nodes. For available options, please look at the help text."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7c370ea6",
   "metadata": {},
   "outputs": [],
   "source": [
    "!mevis -i moses.scm -o moses_layout1.html -l dot --verbose"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8c1bb629",
   "metadata": {},
   "outputs": [],
   "source": [
    "!mevis -i moses.scm -o moses_layout2.html -l neato\n",
    "!mevis -i moses.scm -o moses_layout3.html -l twopi\n",
    "!mevis -i moses.scm -o moses_layout4.html -l bipartite\n",
    "!mevis -i moses.scm -o moses_layout5.html -l shell"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d8a9f7a5",
   "metadata": {},
   "source": [
    "## Filter the AtomSpace\n",
    "\n",
    "- `-t`: Filter target which selects Atoms. There are three options on the command line:\n",
    "  - Name that is compared against Atom name and type name.\n",
    "  - List of multiple names\n",
    "  - Lambda function that gets an Atom as input and must return True or False to select or deselect it.\n",
    "- `-c`: Filter context which can expand the selection.\n",
    "- `-m`: Filter mode which decides whether the selection is included or excluded from the result"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8df97a29",
   "metadata": {},
   "source": [
    "Some possible targets"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "023a41f7",
   "metadata": {},
   "outputs": [],
   "source": [
    "!mevis -i moses.scm -o moses_filtered1.html -ft PredicateNode --verbose\n",
    "!mevis -i moses.scm -o moses_filtered2.html -ft \"['AndLink', 'OrLink', 'NotLink']\"\n",
    "!mevis -i moses.scm -o moses_filtered3.html -ft \"lambda atom: atom.is_link()\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6a5820f3",
   "metadata": {},
   "source": [
    "Some possible contexts"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "88fa9875",
   "metadata": {},
   "outputs": [],
   "source": [
    "!mevis -i moses.scm -o moses_filtered4.html -ft PredicateNode -fc both\n",
    "!mevis -i moses.scm -o moses_filtered5.html -ft PredicateNode -fc \"('in', 2)\"\n",
    "!mevis -i moses.scm -o moses_filtered6.html -ft OrLink -fc \"out-tree\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ea535c73",
   "metadata": {},
   "source": [
    "Two possible modes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4cae9be7",
   "metadata": {},
   "outputs": [],
   "source": [
    "!mevis -i moses.scm -o moses_filtered7.html -ft PredicateNode -fc both -fm include\n",
    "!mevis -i moses.scm -o moses_filtered8.html -ft PredicateNode -fc both -fm exclude"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "739aebad",
   "metadata": {},
   "source": [
    "## Annotate the graph to modify visual elements"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f3c8fd0e",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create an unannotated graph\n",
    "!mevis -i moses.scm -o moses_unannotated.html -gua"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f7923344",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create an undirected graph and set its node color, node size, edge color, edge size with constants\n",
    "!mevis -i moses.scm -o moses_annotated1.html -gud -nc blue -ns 20 -ec blue -es 4"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f527725a",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Set node color, node size, edge color, edge size with lambda functions\n",
    "!mevis -i moses.scm -o moses_annotated2.html \\\n",
    "    -nc \"lambda atom: '#33339a' if atom.is_link() else 'green'\" \\\n",
    "    -ec \"lambda atom1, atom2: '#33339a' if atom2.is_link() else 'green'\" \\\n",
    "    -ns \"lambda atom: 12 if atom.is_node() else 18\" \\\n",
    "    -es \"lambda atom1, atom2: 1 if atom2.is_node() else 3\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cd23c9e0",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Adjust all possible annotations (see advanced.ipynb for the same example in Python instead of Bash)\n",
    "!mevis -i moses.scm -o moses_annotated3.html -f \\\n",
    "    -b d3 \\\n",
    "    -gud \\\n",
    "    -nl \"lambda atom: atom.name if atom.is_node() else atom.type_name.replace('Link', '')\" \\\n",
    "    -nc \"lambda atom: 'red' if atom.is_node() \\\n",
    "         else 'blue' if atom.type_name == 'AndLink' \\\n",
    "         else 'green' if atom.type_name == 'OrLink' \\\n",
    "         else 'orange'\" \\\n",
    "    -no 0.9 \\\n",
    "    -ns \"lambda atom: 20 if atom.type_name in ['AndLink', 'OrLink'] else 12\" \\\n",
    "    -nsh \"lambda atom: 'rectangle' if atom.type_name == 'AndLink' \\\n",
    "          else 'hexagon' if atom.type_name == 'OrLink' \\\n",
    "          else 'circle'\" \\\n",
    "    -nbc white \\\n",
    "    -nbs 2.0 \\\n",
    "    -nlc \"lambda atom: 'red' if atom.is_node() \\\n",
    "          else 'blue' if atom.type_name == 'AndLink' \\\n",
    "          else 'green' if atom.type_name == 'OrLink' \\\n",
    "          else 'orange'\" \\\n",
    "    -nls 12.0 \\\n",
    "    -nh \"lambda atom: 'A {} with Atomese code:\\n{}'.format(atom.type_name, atom.short_string())\" \\\n",
    "    -ncl \"lambda atom: atom.short_string()\" \\\n",
    "    -np \"lambda atom: dict(x=-300) if atom.is_node() else dict(x=-300+200*len(atom.out))\"\\\n",
    "    -el \"lambda atom1, atom2: '{}{}'.format(atom1.type_name[0], atom2.type_name[0])\" \\\n",
    "    -ec \"lambda atom1, atom2: 'lightgray' if atom2.is_node() \\\n",
    "         else 'red' if atom1.is_node() \\\n",
    "         else 'blue' if atom1.type_name == 'AndLink' \\\n",
    "         else 'green' if atom1.type_name == 'OrLink' \\\n",
    "         else 'orange'\" \\\n",
    "    -eo 0.5 \\\n",
    "    -es \"lambda atom1, atom2: 5 if atom2.is_node() else 2.5\" \\\n",
    "    -elc \"lambda atom1, atom2: 'red' if atom1.is_node() \\\n",
    "          else 'blue' if atom1.type_name == 'AndLink' \\\n",
    "          else 'green' if atom1.type_name == 'OrLink' \\\n",
    "          else 'orange'\" \\\n",
    "    -els 8 \\\n",
    "    -eh \"lambda atom1, atom2: '{} to {}'.format(atom1.type_name, atom2.type_name)\" \\\n",
    "    -ecl \"lambda atom1, atom2: 'Edge connects {} with {}'.format(atom1.type_name, atom2.type_name)\" \\\n",
    "    --kwargs edge_curvature=0.2 show_edge_label=True many_body_force_strength=-1000"
   ]
  }
 ],
 "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.8.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}