{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# pyCAT" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Picat language model implementation in metaL/Python" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "github: https://github.com/ponyatov/pycat\n", "\n", "Jupyter notebook render: https://nbviewer.jupyter.org/github/ponyatov/pycat/blob/master/pycat.ipynb\n", "\n", "[](https://mybinder.org/v2/gh/ponyatov/pycat/master?filepath=pycat.ipynb)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This manual is about learning Picat programming language by reimplementing it yourself from scratch. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This method is not for a total newbie in programming as you must know Python a bit to start, and have some entry-level programming skills. The Python was selected as it is the most popular programming language now for programming learning, and because this language implementation is so dynamic, as you can implement your own language system atop of PVM runtime. The advantage of learning by reimplementing is you are able not only embed this scripting engine to any software system you are doing but also deeply understand the original Picat." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "But it is not the end as this Picat implementation uses not pure Python but the `metaL`: homoiconic hypergraph model written itself in Python -- *executable data structure (EDS)* built from some sort of Marvin Minsky frames [minsky]. It was mostly selected to make this language to be not visual but **visualizable**: it is important for the newbies that a learning programming system to be Smalltalk-like interactive and deeply researchable." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### MIT License\n", "\n", "Copyright (c) 2019 Dmitry Ponyatov <<dponyatov@gmail.com>>\n", "\n", "Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n", "\n", "The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.\n", "\n", "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Install" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```sh\n", " ~$ git clone -o gh https://github.com/ponyatov/pycat ; cd pycat\n", "~/pycat$ make install\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Run" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```sh\n", "~/pycat$ .bin/activate\n", " (venv)$ jupyter notebook pycat.ipynb &\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Links" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* [minsky] [A Framework for Representing Knowledge](https://courses.media.mit.edu/2004spring/mas966/Minsky%201974%20Framework%20for%20knowledge.pdf) (c) Marvin Minsky, 1974\n", " * [Фреймы для представления знаний](https://royallib.com/book/minskiy_marvin/freymi_dlya_predstavleniya_znaniy.html) (c) Марвин Минский, М.: Мир, 1979\n", "\n", "* **Programming Python, 4th Edition** (c) Mark Lutz, O'Reilly 2019\n", " * [Изучаем Python. Том 1](https://www.ozon.ru/context/detail/id/156082566/) (c) Марк Лутц, М.: Вильямс, 2019\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Picat language" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* [Picat Google group](https://groups.google.com/forum/#!forum/picat-lang)\n", " * http://picat-lang.org/\n", " * [Constraint Solving and Planning with Picat](http://picat-lang.org/picatbook2015.html) (c) Neng-Fa Zhou, Håkan Kjellerstrand, Jonathan Fruhman\n", " * [Hakan Kjellerstrand page](http://hakank.org/picat/)\n", "\n", "* [Picat code samples](https://github.com/claudiosa/CCS/tree/master/picat) (c) Claudio Cesar de Sá\n", " * [Udemy course in Portuguese](https://www.udemy.com/course/picat-uma-linguagem-de-programacao-multiparadigma/)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Prolog implementation" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* [Yield Prolog](http://yieldprolog.sourceforge.net/)\n", "* [Warren's Abstract Machine: A Tutorial Reconstruction](http://wambook.sourceforge.net/)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Graph visualization" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This Jupyter notebook is packed with `graphviz` binding to show data structures we'll make later. To make it work locally, or [via Binder from the `master` branch on the GitHub](https://mybinder.org/v2/gh/ponyatov/pycat/master?filepath=pycat.ipynb) your host system must be preinstalled with some APT packages:\n" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "graphviz\r\n" ] } ], "source": [ "! cat apt.txt" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "graphviz==0.13.2\r\n" ] } ], "source": [ "! grep graphviz requirements.txt" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n", "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n", " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n", "<!-- Generated by graphviz version 2.38.0 (20140413.2041)\n", " -->\n", "<!-- Title: %3 Pages: 1 -->\n", "<svg width=\"203pt\" height=\"44pt\"\n", " viewBox=\"0.00 0.00 202.69 44.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n", "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 40)\">\n", "<title>%3</title>\n", "<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-40 198.689,-40 198.689,4 -4,4\"/>\n", "<!-- Hello -->\n", "<g id=\"node1\" class=\"node\"><title>Hello</title>\n", "<ellipse fill=\"none\" stroke=\"black\" cx=\"30.5473\" cy=\"-18\" rx=\"30.5947\" ry=\"18\"/>\n", "<text text-anchor=\"middle\" x=\"30.5473\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">Hello</text>\n", "</g>\n", "<!-- World -->\n", "<g id=\"node2\" class=\"node\"><title>World</title>\n", "<ellipse fill=\"none\" stroke=\"black\" cx=\"160.892\" cy=\"-18\" rx=\"33.5952\" ry=\"18\"/>\n", "<text text-anchor=\"middle\" x=\"160.892\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">World</text>\n", "</g>\n", "<!-- Hello->World -->\n", "<g id=\"edge1\" class=\"edge\"><title>Hello->World</title>\n", "<path fill=\"none\" stroke=\"black\" d=\"M61.3146,-18C77.7332,-18 98.4177,-18 116.595,-18\"/>\n", "<polygon fill=\"black\" stroke=\"black\" points=\"116.673,-21.5001 126.673,-18 116.673,-14.5001 116.673,-21.5001\"/>\n", "<text text-anchor=\"middle\" x=\"94.0946\" y=\"-21.8\" font-family=\"Times,serif\" font-size=\"14.00\">pycat</text>\n", "</g>\n", "</g>\n", "</svg>\n" ], "text/plain": [ "<graphviz.dot.Digraph at 0x7fa3a46fe400>" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import graphviz\n", "viz = graphviz.Digraph(graph_attr={'rankdir':'LR'})\n", "viz.edge('Hello','World',label='pycat')\n", "viz" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Frame" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The hypothesis: **directed hypergraph is a universal knowledge representation** that can describe anything including software specifications, programs, data and documentation in the same universal form. As we use the *same structure for program and data* representation, and this structure can be executed by interpretation, we have a **homoiconic metaprogramming system**." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `Frame` is a root object class that is implemented on ideas of a [minsky] book. The original frame model was *extended* to support **ordered storage** is definitely required for representing\n", "* *attribute grammar* widely known in programming languages design, and\n", "* ordered data containers itself.\n", "\n", "The presence of an ordered collection is definitively required for representing program source code in any programming language, as this is very close to classical attribute grammar, parsing and abstract syntax trees, and graphs used in compiler design. The frame (object) hypergraph representation of a program as an executable form is clear and native for any work involved with source code transformations: synthesis, modifications, analysis, cross-language translation, etc." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### EDS: Executable Data Structure method" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In software design in a case when our programming language or computing platform does not provide some features, we can add a layer of interpretation for some data structure to get more dynamics or extra features such as metaprogramming, program self-modification, compact low memory bytecode, etc. For example, in the Lisp language, all programs are represented in the form of executable lists. Java uses bytecode as the main program form, which does not require, but often uses JIT for runtime compilation as a way to make the program run faster." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `metaL` homoiconic layer uses attributed hypergraph as an *executable data structure*:\n", "* every hypergraph **frame defines N-ary relations between operands** in `nest[]` and named attributes in `slot{}`s the way close to Prolog predicates\n", "* **frames are typed** so every frame class can describe different behavior and properties\n", "* the graph has the advantage to be not visual but **visualizable language**, which can be used for multiparadigm programming" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Homoiconic programming languages" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> **Homoiconicity** (homoiconic) \\\n", "is a property of some programming languages in which *data and program representation is the same*\n", "and defined in core types of the same language. In other words, homoiconicity is when the *program source code* is written *as the reflectable (and mutable) data structure* and the programming language provides transparent access to the program as data in runtime.\n", "\n", "In homoiconic language, **metaprogramming** *is the main software development technique*, which is also used to expand the language to the capabilities that a particular programmer needs. As the metaprogramming language, the Lisp language is the first sample, which was created to process data presented in the form of nested lists. Lisp programs are also recorded, stored, and executed as lists; as a result, it makes the running program able to access its own source code as a native data structure, as well as automatically change itself on the fly. Homoiconic languages, as a rule, include full support for *syntactic macros*, allowing the programmer to define new syntactic structures and express transformations of programs in a compact form." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n", "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n", " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n", "<!-- Generated by graphviz version 2.38.0 (20140413.2041)\n", " -->\n", "<!-- Title: %3 Pages: 1 -->\n", "<svg width=\"76pt\" height=\"44pt\"\n", " viewBox=\"0.00 0.00 75.59 44.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n", "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 40)\">\n", "<title>%3</title>\n", "<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-40 71.594,-40 71.594,4 -4,4\"/>\n", "<!-- Frame -->\n", "<g id=\"node1\" class=\"node\"><title>Frame</title>\n", "<ellipse fill=\"none\" stroke=\"black\" cx=\"33.797\" cy=\"-18\" rx=\"33.5952\" ry=\"18\"/>\n", "<text text-anchor=\"middle\" x=\"33.797\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">Frame</text>\n", "</g>\n", "</g>\n", "</svg>\n" ], "text/plain": [ "<graphviz.dot.Digraph at 0x7fa3a4062c18>" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "viz = graphviz.Digraph(graph_attr={'rankdir':'LR'}) ; viz.node('Frame') ; viz" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "## Marvin Minsky's extended frame model\n", "\n", "class Frame:\n", "\n", " def __init__(self,V):\n", "\n", " # type/class tag /required for lexer using PLY library/\n", " self.type = self.__class__.__name__.lower()\n", "\n", " # scalar value: frame name, string, number,..\n", " self.val = V\n", "\n", " # slots = attributes = vocabulary\n", " self.slot = {}\n", "\n", " # nested AST = universal ordered container = stack\n", " self.nest = []" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "<__main__.Frame at 0x7fa3a4070048>" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Frame('Hello World')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Tree dump to plain text" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We'll use tree dump as an easy to use method to see any frame graph in a text form." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "class Frame(Frame):\n", "\n", " ## dump\n", "\n", " # print/str conversion\n", " def __repr__(self):\n", " return self.dump()\n", "\n", " # full tree dump\n", " def dump(self,depth=0,prefix=''):\n", "\n", " # subtree header: tab padding and <T:V> header\n", " tree = self._pad(depth) + self.head(prefix)\n", "\n", " # block infinite recursion if we have cycles in a graph\n", " if not depth: Frame._dump = [] # recursion root -- zero depth\n", " if self in Frame._dump: return tree + ' _/'\n", " else: Frame._dump.append(self)\n", "\n", " # slot{}s: recursive traversal via hypergraph references\n", " for i in self.slot:\n", " tree += self.slot[i].dump(depth+1,'%s = '%i)\n", "\n", " # nest[]ed: recursive traversal via ordered subgraphs\n", " idx = 0\n", " for j in self.nest:\n", " tree += j.dump(depth+1,'%i: '%idx) ; idx +=1\n", "\n", " # resulting subtree dump\n", " return tree\n", "\n", " # short <T:V> header-only dump\n", " def head(self,prefix=''):\n", " return '%s<%s:%s> id:%x' % (prefix,self.type,self._val(),id(self))\n", "\n", " # tree dump padding\n", " def _pad(self,depth):\n", " return '\\n' + '\\t' * depth\n", "\n", " # .val in dump must be overridable for strings, numbers,..\n", " def _val(self):\n", " return '%s' % self.val" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "prefix = <frame:Hello World> id:7fa3a4070a58\n" ] } ], "source": [ "print(Frame('Hello World').dump(prefix='prefix = '))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**`<T:V>` header** contains\n", "* `T` type/*class tag*\n", "* `V` scalar *value*\n", "* optional `prefix` used for *slot names printing in tree dump*\n", "* `idx` counter shows index of every element in the universal ordered container *mostly used as a stack*\n", "* `id:hex` a pointer is unique for every object in a system lets to *distinct objects with the same `T:V` pair*" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Graph plot" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As we pretend to make not visual but **visualizable programming language**, we must have a graph plotting tool to see any part of an EDS program graph as a diagram." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "class Frame(Frame):\n", "\n", " ## plot\n", "\n", " # recursive traversal with graphviz calls\n", " def plot(self,dot=None,parent=None,link='',color='black'):\n", "\n", " if not dot: # plotter must be initialized in a recursion root\n", " dot = graphviz.Digraph(graph_attr={'rankdir':'LR'}) # horizontal layout\n", " Frame._plot = [] # skip visited branches\n", "\n", " # plot node and optional edge from parent / like header in .dump() /\n", " dot.node('%s'%id(self),label='%s:%s'%(self.type,self._val())) # ref via id()\n", " if parent: dot.edge('%s'%id(parent),'%s'%id(self),label='%s'%link,color=color)\n", "\n", " # rings/infinite recursion block\n", " if self in Frame._plot: return dot\n", " else: Frame._plot.append(self)\n", "\n", " # slot{}s with blue edges and slot names\n", " for i in self.slot:\n", " dot = self.slot[i].plot(dot,parent=self,link=i,color='blue')\n", "\n", " # nest[]ed with green edges and integer indexes\n", " idx = 0\n", " for j in self.nest:\n", " dot = j.plot(dot,parent=self,link=idx,color='green') ; idx += 1\n", "\n", " # return resulting subtree plot\n", " return dot" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n", "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n", " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n", "<!-- Generated by graphviz version 2.38.0 (20140413.2041)\n", " -->\n", "<!-- Title: %3 Pages: 1 -->\n", "<svg width=\"167pt\" height=\"44pt\"\n", " viewBox=\"0.00 0.00 166.59 44.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n", "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 40)\">\n", "<title>%3</title>\n", "<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-40 162.586,-40 162.586,4 -4,4\"/>\n", "<!-- 140340808320840 -->\n", "<g id=\"node1\" class=\"node\"><title>140340808320840</title>\n", "<ellipse fill=\"none\" stroke=\"black\" cx=\"79.293\" cy=\"-18\" rx=\"79.0865\" ry=\"18\"/>\n", "<text text-anchor=\"middle\" x=\"79.293\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">frame:Hello World</text>\n", "</g>\n", "</g>\n", "</svg>\n" ], "text/plain": [ "<graphviz.dot.Digraph at 0x7fa3a4070908>" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Frame('Hello World').plot()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Operators" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To manipulate frames in a pythonic way we need to define some used operators to do frame combinations:" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "class Frame(Frame):\n", "\n", " ## operators\n", "\n", " # automatic type cast\n", " def cast(self,that):\n", " if isinstance(that,Frame): return that\n", " return {\n", " str : lambda x:Str(x),\n", " float: lambda x:Num(x),\n", " int : lambda x:Int(x)\n", " }[that.__class__](that)\n", "\n", " # ` A[key] ` get frame by slot name (vocabulary lookup/fetch)\n", " def __getitem__(self,key):\n", " return self.slot[key]\n", "\n", " # ` A[key] = B ` set/create slot with name and frame (vocabulary write)\n", " def __setitem__(self,key,that):\n", " self.slot[key] = self.cast(that) ; return self\n", "\n", " # ` A << B ` set slot with operand type A[B.type] = B\n", " def __lshift__(self,that):\n", " that = self.cast(that) ; self[that.type] = that ; return self\n", "\n", " # ` A << B ` set slot with operand value A[B.val] = B\n", " def __rshift__(self,that):\n", " that = self.cast(that) ; self[that.val] = that ; return self\n", "\n", " # ` A // B ` push to nest[]ed\n", " def __floordiv__(self,that):\n", " self.nest.append(self.cast(that)) ; return self" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Primitives" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n", "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n", " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n", "<!-- Generated by graphviz version 2.38.0 (20140413.2041)\n", " -->\n", "<!-- Title: %3 Pages: 1 -->\n", "<svg width=\"442pt\" height=\"179pt\"\n", " viewBox=\"0.00 0.00 441.98 179.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n", "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 175)\">\n", "<title>%3</title>\n", "<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-175 437.984,-175 437.984,4 -4,4\"/>\n", "<!-- Frame -->\n", "<g id=\"node1\" class=\"node\"><title>Frame</title>\n", "<ellipse fill=\"none\" stroke=\"black\" cx=\"33.797\" cy=\"-99\" rx=\"33.5952\" ry=\"18\"/>\n", "<text text-anchor=\"middle\" x=\"33.797\" y=\"-95.3\" font-family=\"Times,serif\" font-size=\"14.00\">Frame</text>\n", "</g>\n", "<!-- Prim -->\n", "<g id=\"node2\" class=\"node\"><title>Prim</title>\n", "<ellipse fill=\"none\" stroke=\"black\" cx=\"132.191\" cy=\"-99\" rx=\"28.6953\" ry=\"18\"/>\n", "<text text-anchor=\"middle\" x=\"132.191\" y=\"-95.3\" font-family=\"Times,serif\" font-size=\"14.00\">Prim</text>\n", "</g>\n", "<!-- Frame->Prim -->\n", "<g id=\"edge1\" class=\"edge\"><title>Frame->Prim</title>\n", "<path fill=\"none\" stroke=\"black\" d=\"M67.7009,-99C75.9987,-99 84.9712,-99 93.4848,-99\"/>\n", "<polygon fill=\"black\" stroke=\"black\" points=\"93.5657,-102.5 103.566,-99 93.5656,-95.5001 93.5657,-102.5\"/>\n", "</g>\n", "<!-- Sym -->\n", "<g id=\"node3\" class=\"node\"><title>Sym</title>\n", "<ellipse fill=\"none\" stroke=\"black\" cx=\"225.386\" cy=\"-153\" rx=\"27.0966\" ry=\"18\"/>\n", "<text text-anchor=\"middle\" x=\"225.386\" y=\"-149.3\" font-family=\"Times,serif\" font-size=\"14.00\">Sym</text>\n", "</g>\n", "<!-- Prim->Sym -->\n", "<g id=\"edge2\" class=\"edge\"><title>Prim->Sym</title>\n", "<path fill=\"none\" stroke=\"black\" d=\"M153.885,-111.253C166.182,-118.535 181.965,-127.881 195.479,-135.883\"/>\n", "<polygon fill=\"black\" stroke=\"black\" points=\"194.014,-139.083 204.401,-141.166 197.58,-133.059 194.014,-139.083\"/>\n", "</g>\n", "<!-- Str -->\n", "<g id=\"node4\" class=\"node\"><title>Str</title>\n", "<ellipse fill=\"none\" stroke=\"black\" cx=\"225.386\" cy=\"-99\" rx=\"27\" ry=\"18\"/>\n", "<text text-anchor=\"middle\" x=\"225.386\" y=\"-95.3\" font-family=\"Times,serif\" font-size=\"14.00\">Str</text>\n", "</g>\n", "<!-- Prim->Str -->\n", "<g id=\"edge3\" class=\"edge\"><title>Prim->Str</title>\n", "<path fill=\"none\" stroke=\"black\" d=\"M161.048,-99C169.557,-99 179.042,-99 188.027,-99\"/>\n", "<polygon fill=\"black\" stroke=\"black\" points=\"188.257,-102.5 198.257,-99 188.257,-95.5001 188.257,-102.5\"/>\n", "</g>\n", "<!-- Num -->\n", "<g id=\"node5\" class=\"node\"><title>Num</title>\n", "<ellipse fill=\"none\" stroke=\"black\" cx=\"225.386\" cy=\"-45\" rx=\"28.6953\" ry=\"18\"/>\n", "<text text-anchor=\"middle\" x=\"225.386\" y=\"-41.3\" font-family=\"Times,serif\" font-size=\"14.00\">Num</text>\n", "</g>\n", "<!-- Prim->Num -->\n", "<g id=\"edge4\" class=\"edge\"><title>Prim->Num</title>\n", "<path fill=\"none\" stroke=\"black\" d=\"M153.885,-86.7466C166.097,-79.5156 181.746,-70.249 195.197,-62.2841\"/>\n", "<polygon fill=\"black\" stroke=\"black\" points=\"197.268,-65.1257 204.089,-57.0189 193.701,-59.1025 197.268,-65.1257\"/>\n", "</g>\n", "<!-- Int -->\n", "<g id=\"node6\" class=\"node\"><title>Int</title>\n", "<ellipse fill=\"none\" stroke=\"black\" cx=\"316.984\" cy=\"-45\" rx=\"27\" ry=\"18\"/>\n", "<text text-anchor=\"middle\" x=\"316.984\" y=\"-41.3\" font-family=\"Times,serif\" font-size=\"14.00\">Int</text>\n", "</g>\n", "<!-- Num->Int -->\n", "<g id=\"edge5\" class=\"edge\"><title>Num->Int</title>\n", "<path fill=\"none\" stroke=\"black\" d=\"M254.244,-45C262.352,-45 271.328,-45 279.866,-45\"/>\n", "<polygon fill=\"black\" stroke=\"black\" points=\"279.976,-48.5001 289.976,-45 279.976,-41.5001 279.976,-48.5001\"/>\n", "</g>\n", "<!-- Hex -->\n", "<g id=\"node7\" class=\"node\"><title>Hex</title>\n", "<ellipse fill=\"none\" stroke=\"black\" cx=\"406.984\" cy=\"-72\" rx=\"27\" ry=\"18\"/>\n", "<text text-anchor=\"middle\" x=\"406.984\" y=\"-68.3\" font-family=\"Times,serif\" font-size=\"14.00\">Hex</text>\n", "</g>\n", "<!-- Int->Hex -->\n", "<g id=\"edge6\" class=\"edge\"><title>Int->Hex</title>\n", "<path fill=\"none\" stroke=\"black\" d=\"M342.03,-52.3779C351.419,-55.2586 362.346,-58.6112 372.483,-61.7215\"/>\n", "<polygon fill=\"black\" stroke=\"black\" points=\"371.684,-65.1373 382.271,-64.7245 373.738,-58.4452 371.684,-65.1373\"/>\n", "</g>\n", "<!-- Bin -->\n", "<g id=\"node8\" class=\"node\"><title>Bin</title>\n", "<ellipse fill=\"none\" stroke=\"black\" cx=\"406.984\" cy=\"-18\" rx=\"27\" ry=\"18\"/>\n", "<text text-anchor=\"middle\" x=\"406.984\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">Bin</text>\n", "</g>\n", "<!-- Int->Bin -->\n", "<g id=\"edge7\" class=\"edge\"><title>Int->Bin</title>\n", "<path fill=\"none\" stroke=\"black\" d=\"M342.03,-37.6221C351.419,-34.7414 362.346,-31.3888 372.483,-28.2785\"/>\n", "<polygon fill=\"black\" stroke=\"black\" points=\"373.738,-31.5548 382.271,-25.2755 371.684,-24.8627 373.738,-31.5548\"/>\n", "</g>\n", "</g>\n", "</svg>\n" ], "text/plain": [ "<graphviz.dot.Digraph at 0x7fa3a4062c18>" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "viz.edge('Frame','Prim')\n", "viz.edge('Prim','Sym')\n", "viz.edge('Prim','Str')\n", "viz.edge('Prim','Num')\n", "viz.edge('Num','Int')\n", "viz.edge('Int','Hex')\n", "viz.edge('Int','Bin')\n", "viz" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "class Prim(Frame): pass\n", "class Sym(Prim): pass\n", "class Str(Prim): pass\n", "class Num(Prim): pass\n", "class Int(Num): pass\n", "class Hex(Int): pass\n", "class Bin(Int): pass" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "<frame:Hello> id:7fa3a407f048\n", "\tself = <frame:Hello> id:7fa3a407f048 _/\n", "\tstring = <str:typecasted> id:7fa3a407f208\n", "\tsome = <frame:attribute> id:7fa3a4087fd0\n", "\t\tframe = <frame:slot> id:7fa3a407f198\n", "\t0: <frame:World> id:7fa3a407f0b8\n", "\t1: <frame:Hello> id:7fa3a407f048 _/\n", "\t2: <str:string> id:7fa3a407f128\n" ] }, { "data": { "image/svg+xml": [ "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n", "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n", " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n", "<!-- Generated by graphviz version 2.38.0 (20140413.2041)\n", " -->\n", "<!-- Title: %3 Pages: 1 -->\n", "<svg width=\"473pt\" height=\"206pt\"\n", " viewBox=\"0.00 0.00 472.87 206.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n", "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 202)\">\n", "<title>%3</title>\n", "<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-202 468.871,-202 468.871,4 -4,4\"/>\n", "<!-- 140340808380488 -->\n", "<g id=\"node1\" class=\"node\"><title>140340808380488</title>\n", "<ellipse fill=\"none\" stroke=\"black\" cx=\"53.9452\" cy=\"-95\" rx=\"53.8905\" ry=\"18\"/>\n", "<text text-anchor=\"middle\" x=\"53.9452\" y=\"-91.3\" font-family=\"Times,serif\" font-size=\"14.00\">frame:Hello</text>\n", "</g>\n", "<!-- 140340808380488->140340808380488 -->\n", "<g id=\"edge1\" class=\"edge\"><title>140340808380488->140340808380488</title>\n", "<path fill=\"none\" stroke=\"blue\" d=\"M46.1662,-113.153C44.9694,-122.539 47.5624,-131 53.9452,-131 57.8347,-131 60.317,-127.858 61.3919,-123.28\"/>\n", "<polygon fill=\"blue\" stroke=\"blue\" points=\"64.8943,-123.262 61.7243,-113.153 57.898,-123.032 64.8943,-123.262\"/>\n", "<text text-anchor=\"middle\" x=\"53.9452\" y=\"-134.8\" font-family=\"Times,serif\" font-size=\"14.00\">self</text>\n", "</g>\n", "<!-- 140340808380488->140340808380488 -->\n", "<g id=\"edge6\" class=\"edge\"><title>140340808380488->140340808380488</title>\n", "<path fill=\"none\" stroke=\"green\" d=\"M41.131,-112.699C34.0527,-129.996 38.3241,-149 53.9452,-149 66.6374,-149 71.8369,-136.454 69.5439,-122.472\"/>\n", "<polygon fill=\"green\" stroke=\"green\" points=\"72.8656,-121.357 66.7594,-112.699 66.1336,-123.275 72.8656,-121.357\"/>\n", "<text text-anchor=\"middle\" x=\"53.9452\" y=\"-152.8\" font-family=\"Times,serif\" font-size=\"14.00\">1</text>\n", "</g>\n", "<!-- 140340808380936 -->\n", "<g id=\"node2\" class=\"node\"><title>140340808380936</title>\n", "<ellipse fill=\"none\" stroke=\"black\" cx=\"238.585\" cy=\"-180\" rx=\"59.2899\" ry=\"18\"/>\n", "<text text-anchor=\"middle\" x=\"238.585\" y=\"-176.3\" font-family=\"Times,serif\" font-size=\"14.00\">str:typecasted</text>\n", "</g>\n", "<!-- 140340808380488->140340808380936 -->\n", "<g id=\"edge2\" class=\"edge\"><title>140340808380488->140340808380936</title>\n", "<path fill=\"none\" stroke=\"blue\" d=\"M83.01,-110.253C95.9517,-117.127 111.585,-125.208 125.89,-132 147.617,-142.316 172.132,-152.959 192.649,-161.594\"/>\n", "<polygon fill=\"blue\" stroke=\"blue\" points=\"191.493,-164.904 202.069,-165.536 194.195,-158.446 191.493,-164.904\"/>\n", "<text text-anchor=\"middle\" x=\"141.39\" y=\"-148.8\" font-family=\"Times,serif\" font-size=\"14.00\">string</text>\n", "</g>\n", "<!-- 140340808417232 -->\n", "<g id=\"node3\" class=\"node\"><title>140340808417232</title>\n", "<ellipse fill=\"none\" stroke=\"black\" cx=\"238.585\" cy=\"-126\" rx=\"63.8893\" ry=\"18\"/>\n", "<text text-anchor=\"middle\" x=\"238.585\" y=\"-122.3\" font-family=\"Times,serif\" font-size=\"14.00\">frame:attribute</text>\n", "</g>\n", "<!-- 140340808380488->140340808417232 -->\n", "<g id=\"edge3\" class=\"edge\"><title>140340808380488->140340808417232</title>\n", "<path fill=\"none\" stroke=\"blue\" d=\"M102.455,-103.064C124.091,-106.736 150.027,-111.139 173.367,-115.1\"/>\n", "<polygon fill=\"blue\" stroke=\"blue\" points=\"173.09,-118.603 183.535,-116.826 174.262,-111.702 173.09,-118.603\"/>\n", "<text text-anchor=\"middle\" x=\"141.39\" y=\"-116.8\" font-family=\"Times,serif\" font-size=\"14.00\">some</text>\n", "</g>\n", "<!-- 140340808380600 -->\n", "<g id=\"node5\" class=\"node\"><title>140340808380600</title>\n", "<ellipse fill=\"none\" stroke=\"black\" cx=\"238.585\" cy=\"-72\" rx=\"57.3905\" ry=\"18\"/>\n", "<text text-anchor=\"middle\" x=\"238.585\" y=\"-68.3\" font-family=\"Times,serif\" font-size=\"14.00\">frame:World</text>\n", "</g>\n", "<!-- 140340808380488->140340808380600 -->\n", "<g id=\"edge5\" class=\"edge\"><title>140340808380488->140340808380600</title>\n", "<path fill=\"none\" stroke=\"green\" d=\"M99.8511,-85.3334C108.465,-83.7079 117.434,-82.1711 125.89,-81 140.686,-78.9509 156.655,-77.3213 171.761,-76.044\"/>\n", "<polygon fill=\"green\" stroke=\"green\" points=\"172.369,-79.5064 182.056,-75.2151 171.808,-72.529 172.369,-79.5064\"/>\n", "<text text-anchor=\"middle\" x=\"141.39\" y=\"-84.8\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n", "</g>\n", "<!-- 140340808380712 -->\n", "<g id=\"node6\" class=\"node\"><title>140340808380712</title>\n", "<ellipse fill=\"none\" stroke=\"black\" cx=\"238.585\" cy=\"-18\" rx=\"42.4939\" ry=\"18\"/>\n", "<text text-anchor=\"middle\" x=\"238.585\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">str:string</text>\n", "</g>\n", "<!-- 140340808380488->140340808380712 -->\n", "<g id=\"edge7\" class=\"edge\"><title>140340808380488->140340808380712</title>\n", "<path fill=\"none\" stroke=\"green\" d=\"M83.2298,-79.6833C96.081,-72.9756 111.581,-65.2311 125.89,-59 148.289,-49.2464 173.832,-39.7541 194.832,-32.3634\"/>\n", "<polygon fill=\"green\" stroke=\"green\" points=\"196.145,-35.6123 204.437,-29.0174 193.843,-29.0019 196.145,-35.6123\"/>\n", "<text text-anchor=\"middle\" x=\"141.39\" y=\"-62.8\" font-family=\"Times,serif\" font-size=\"14.00\">2</text>\n", "</g>\n", "<!-- 140340808380824 -->\n", "<g id=\"node4\" class=\"node\"><title>140340808380824</title>\n", "<ellipse fill=\"none\" stroke=\"black\" cx=\"418.075\" cy=\"-126\" rx=\"46.5926\" ry=\"18\"/>\n", "<text text-anchor=\"middle\" x=\"418.075\" y=\"-122.3\" font-family=\"Times,serif\" font-size=\"14.00\">frame:slot</text>\n", "</g>\n", "<!-- 140340808417232->140340808380824 -->\n", "<g id=\"edge4\" class=\"edge\"><title>140340808417232->140340808380824</title>\n", "<path fill=\"none\" stroke=\"blue\" d=\"M302.661,-126C321.745,-126 342.562,-126 361.145,-126\"/>\n", "<polygon fill=\"blue\" stroke=\"blue\" points=\"361.214,-129.5 371.214,-126 361.214,-122.5 361.214,-129.5\"/>\n", "<text text-anchor=\"middle\" x=\"336.779\" y=\"-129.8\" font-family=\"Times,serif\" font-size=\"14.00\">frame</text>\n", "</g>\n", "</g>\n", "</svg>\n" ], "text/plain": [ "<graphviz.dot.Digraph at 0x7fa3a407f2e8>" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "hello = Frame('Hello') // Frame('World')\n", "hello['some'] = Frame('attribute') << Frame('slot')\n", "hello['self'] = hello // hello # self ring\n", "hello['string'] = 'typecasted' ; hello // 'string'\n", "print(hello)\n", "hello.plot()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Picat object classes" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n", "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n", " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n", "<!-- Generated by graphviz version 2.38.0 (20140413.2041)\n", " -->\n", "<!-- Title: %3 Pages: 1 -->\n", "<svg width=\"533pt\" height=\"260pt\"\n", " viewBox=\"0.00 0.00 532.87 260.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n", "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 256)\">\n", "<title>%3</title>\n", "<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-256 528.866,-256 528.866,4 -4,4\"/>\n", "<!-- Frame -->\n", "<g id=\"node1\" class=\"node\"><title>Frame</title>\n", "<ellipse fill=\"none\" stroke=\"black\" cx=\"33.797\" cy=\"-180\" rx=\"33.5952\" ry=\"18\"/>\n", "<text text-anchor=\"middle\" x=\"33.797\" y=\"-176.3\" font-family=\"Times,serif\" font-size=\"14.00\">Frame</text>\n", "</g>\n", "<!-- Term -->\n", "<g id=\"node2\" class=\"node\"><title>Term</title>\n", "<ellipse fill=\"none\" stroke=\"black\" cx=\"134.141\" cy=\"-180\" rx=\"30.5947\" ry=\"18\"/>\n", "<text text-anchor=\"middle\" x=\"134.141\" y=\"-176.3\" font-family=\"Times,serif\" font-size=\"14.00\">Term</text>\n", "</g>\n", "<!-- Frame->Term -->\n", "<g id=\"edge1\" class=\"edge\"><title>Frame->Term</title>\n", "<path fill=\"none\" stroke=\"black\" d=\"M67.8178,-180C75.99,-180 84.8318,-180 93.2914,-180\"/>\n", "<polygon fill=\"black\" stroke=\"black\" points=\"93.3502,-183.5 103.35,-180 93.3501,-176.5 93.3502,-183.5\"/>\n", "</g>\n", "<!-- Var -->\n", "<g id=\"node3\" class=\"node\"><title>Var</title>\n", "<ellipse fill=\"none\" stroke=\"black\" cx=\"250.734\" cy=\"-234\" rx=\"27\" ry=\"18\"/>\n", "<text text-anchor=\"middle\" x=\"250.734\" y=\"-230.3\" font-family=\"Times,serif\" font-size=\"14.00\">Var</text>\n", "</g>\n", "<!-- Term->Var -->\n", "<g id=\"edge2\" class=\"edge\"><title>Term->Var</title>\n", "<path fill=\"none\" stroke=\"black\" d=\"M158.607,-191.058C176.084,-199.294 200.104,-210.613 219.095,-219.562\"/>\n", "<polygon fill=\"black\" stroke=\"black\" points=\"217.697,-222.772 228.235,-223.869 220.681,-216.44 217.697,-222.772\"/>\n", "</g>\n", "<!-- Atomic -->\n", "<g id=\"node4\" class=\"node\"><title>Atomic</title>\n", "<ellipse fill=\"none\" stroke=\"black\" cx=\"250.734\" cy=\"-180\" rx=\"37.8943\" ry=\"18\"/>\n", "<text text-anchor=\"middle\" x=\"250.734\" y=\"-176.3\" font-family=\"Times,serif\" font-size=\"14.00\">Atomic</text>\n", "</g>\n", "<!-- Term->Atomic -->\n", "<g id=\"edge3\" class=\"edge\"><title>Term->Atomic</title>\n", "<path fill=\"none\" stroke=\"black\" d=\"M164.95,-180C176.462,-180 189.914,-180 202.667,-180\"/>\n", "<polygon fill=\"black\" stroke=\"black\" points=\"202.695,-183.5 212.695,-180 202.695,-176.5 202.695,-183.5\"/>\n", "</g>\n", "<!-- Compound -->\n", "<g id=\"node9\" class=\"node\"><title>Compound</title>\n", "<ellipse fill=\"none\" stroke=\"black\" cx=\"250.734\" cy=\"-126\" rx=\"50.0912\" ry=\"18\"/>\n", "<text text-anchor=\"middle\" x=\"250.734\" y=\"-122.3\" font-family=\"Times,serif\" font-size=\"14.00\">Compound</text>\n", "</g>\n", "<!-- Term->Compound -->\n", "<g id=\"edge8\" class=\"edge\"><title>Term->Compound</title>\n", "<path fill=\"none\" stroke=\"black\" d=\"M158.607,-168.942C173.414,-161.965 192.917,-152.774 210.079,-144.687\"/>\n", "<polygon fill=\"black\" stroke=\"black\" points=\"211.775,-147.757 219.329,-140.328 208.791,-141.425 211.775,-147.757\"/>\n", "</g>\n", "<!-- Atom -->\n", "<g id=\"node5\" class=\"node\"><title>Atom</title>\n", "<ellipse fill=\"none\" stroke=\"black\" cx=\"377.076\" cy=\"-234\" rx=\"31.3957\" ry=\"18\"/>\n", "<text text-anchor=\"middle\" x=\"377.076\" y=\"-230.3\" font-family=\"Times,serif\" font-size=\"14.00\">Atom</text>\n", "</g>\n", "<!-- Atomic->Atom -->\n", "<g id=\"edge4\" class=\"edge\"><title>Atomic->Atom</title>\n", "<path fill=\"none\" stroke=\"black\" d=\"M279.33,-191.984C297.898,-200.048 322.501,-210.733 342.249,-219.309\"/>\n", "<polygon fill=\"black\" stroke=\"black\" points=\"340.939,-222.556 351.506,-223.329 343.727,-216.136 340.939,-222.556\"/>\n", "</g>\n", "<!-- Number -->\n", "<g id=\"node6\" class=\"node\"><title>Number</title>\n", "<ellipse fill=\"none\" stroke=\"black\" cx=\"377.076\" cy=\"-180\" rx=\"40.0939\" ry=\"18\"/>\n", "<text text-anchor=\"middle\" x=\"377.076\" y=\"-176.3\" font-family=\"Times,serif\" font-size=\"14.00\">Number</text>\n", "</g>\n", "<!-- Atomic->Number -->\n", "<g id=\"edge5\" class=\"edge\"><title>Atomic->Number</title>\n", "<path fill=\"none\" stroke=\"black\" d=\"M288.704,-180C300.449,-180 313.638,-180 326.14,-180\"/>\n", "<polygon fill=\"black\" stroke=\"black\" points=\"326.433,-183.5 336.433,-180 326.433,-176.5 326.433,-183.5\"/>\n", "</g>\n", "<!-- Integer -->\n", "<g id=\"node7\" class=\"node\"><title>Integer</title>\n", "<ellipse fill=\"none\" stroke=\"black\" cx=\"489.119\" cy=\"-234\" rx=\"35.9954\" ry=\"18\"/>\n", "<text text-anchor=\"middle\" x=\"489.119\" y=\"-230.3\" font-family=\"Times,serif\" font-size=\"14.00\">Integer</text>\n", "</g>\n", "<!-- Number->Integer -->\n", "<g id=\"edge6\" class=\"edge\"><title>Number->Integer</title>\n", "<path fill=\"none\" stroke=\"black\" d=\"M404.996,-193.21C419.644,-200.398 437.926,-209.369 453.611,-217.066\"/>\n", "<polygon fill=\"black\" stroke=\"black\" points=\"452.467,-220.404 462.986,-221.667 455.551,-214.119 452.467,-220.404\"/>\n", "</g>\n", "<!-- Real -->\n", "<g id=\"node8\" class=\"node\"><title>Real</title>\n", "<ellipse fill=\"none\" stroke=\"black\" cx=\"489.119\" cy=\"-180\" rx=\"27\" ry=\"18\"/>\n", "<text text-anchor=\"middle\" x=\"489.119\" y=\"-176.3\" font-family=\"Times,serif\" font-size=\"14.00\">Real</text>\n", "</g>\n", "<!-- Number->Real -->\n", "<g id=\"edge7\" class=\"edge\"><title>Number->Real</title>\n", "<path fill=\"none\" stroke=\"black\" d=\"M417.493,-180C428.71,-180 440.87,-180 451.887,-180\"/>\n", "<polygon fill=\"black\" stroke=\"black\" points=\"452.032,-183.5 462.032,-180 452.032,-176.5 452.032,-183.5\"/>\n", "</g>\n", "<!-- List -->\n", "<g id=\"node10\" class=\"node\"><title>List</title>\n", "<ellipse fill=\"none\" stroke=\"black\" cx=\"377.076\" cy=\"-126\" rx=\"27\" ry=\"18\"/>\n", "<text text-anchor=\"middle\" x=\"377.076\" y=\"-122.3\" font-family=\"Times,serif\" font-size=\"14.00\">List</text>\n", "</g>\n", "<!-- Compound->List -->\n", "<g id=\"edge9\" class=\"edge\"><title>Compound->List</title>\n", "<path fill=\"none\" stroke=\"black\" d=\"M300.877,-126C313.793,-126 327.494,-126 339.613,-126\"/>\n", "<polygon fill=\"black\" stroke=\"black\" points=\"339.797,-129.5 349.797,-126 339.797,-122.5 339.797,-129.5\"/>\n", "</g>\n", "<!-- Struct -->\n", "<g id=\"node12\" class=\"node\"><title>Struct</title>\n", "<ellipse fill=\"none\" stroke=\"black\" cx=\"377.076\" cy=\"-72\" rx=\"31.6951\" ry=\"18\"/>\n", "<text text-anchor=\"middle\" x=\"377.076\" y=\"-68.3\" font-family=\"Times,serif\" font-size=\"14.00\">Struct</text>\n", "</g>\n", "<!-- Compound->Struct -->\n", "<g id=\"edge11\" class=\"edge\"><title>Compound->Struct</title>\n", "<path fill=\"none\" stroke=\"black\" d=\"M283.433,-112.234C301.242,-104.499 323.483,-94.8404 341.709,-86.925\"/>\n", "<polygon fill=\"black\" stroke=\"black\" points=\"343.32,-90.0414 351.098,-82.8475 340.532,-83.6207 343.32,-90.0414\"/>\n", "</g>\n", "<!-- String -->\n", "<g id=\"node11\" class=\"node\"><title>String</title>\n", "<ellipse fill=\"none\" stroke=\"black\" cx=\"489.119\" cy=\"-126\" rx=\"32.4942\" ry=\"18\"/>\n", "<text text-anchor=\"middle\" x=\"489.119\" y=\"-122.3\" font-family=\"Times,serif\" font-size=\"14.00\">String</text>\n", "</g>\n", "<!-- List->String -->\n", "<g id=\"edge10\" class=\"edge\"><title>List->String</title>\n", "<path fill=\"none\" stroke=\"black\" d=\"M404.155,-126C416.736,-126 432.14,-126 446.303,-126\"/>\n", "<polygon fill=\"black\" stroke=\"black\" points=\"446.339,-129.5 456.339,-126 446.339,-122.5 446.339,-129.5\"/>\n", "</g>\n", "<!-- Array -->\n", "<g id=\"node13\" class=\"node\"><title>Array</title>\n", "<ellipse fill=\"none\" stroke=\"black\" cx=\"489.119\" cy=\"-72\" rx=\"31.3957\" ry=\"18\"/>\n", "<text text-anchor=\"middle\" x=\"489.119\" y=\"-68.3\" font-family=\"Times,serif\" font-size=\"14.00\">Array</text>\n", "</g>\n", "<!-- Struct->Array -->\n", "<g id=\"edge12\" class=\"edge\"><title>Struct->Array</title>\n", "<path fill=\"none\" stroke=\"black\" d=\"M409.022,-72C420.942,-72 434.739,-72 447.44,-72\"/>\n", "<polygon fill=\"black\" stroke=\"black\" points=\"447.786,-75.5001 457.786,-72 447.786,-68.5001 447.786,-75.5001\"/>\n", "</g>\n", "<!-- Map -->\n", "<g id=\"node14\" class=\"node\"><title>Map</title>\n", "<ellipse fill=\"none\" stroke=\"black\" cx=\"489.119\" cy=\"-18\" rx=\"27.0966\" ry=\"18\"/>\n", "<text text-anchor=\"middle\" x=\"489.119\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">Map</text>\n", "</g>\n", "<!-- Struct->Map -->\n", "<g id=\"edge13\" class=\"edge\"><title>Struct->Map</title>\n", "<path fill=\"none\" stroke=\"black\" d=\"M401.683,-60.4156C417.988,-52.4144 439.829,-41.6968 457.476,-33.0372\"/>\n", "<polygon fill=\"black\" stroke=\"black\" points=\"459.351,-36.0157 466.787,-28.4683 456.267,-29.7316 459.351,-36.0157\"/>\n", "</g>\n", "</g>\n", "</svg>\n" ], "text/plain": [ "<graphviz.dot.Digraph at 0x7fa3a407e4e0>" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "picat = graphviz.Digraph(graph_attr={'rankdir':'LR'})\n", "picat.edge('Frame','Term')\n", "picat.edge('Term','Var') ; picat.edge('Term','Atomic') ; picat.edge('Atomic','Atom')\n", "picat.edge('Atomic','Number') ; picat.edge('Number','Integer') ; picat.edge('Number','Real')\n", "picat.edge('Term','Compound') ; picat.edge('Compound','List') ; picat.edge('List','String')\n", "picat.edge('Compound','Struct') ; picat.edge('Struct','Array') ; picat.edge('Struct','Map')\n", "picat" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Picat class tree is isolated from `metaL` class tree and have some aliases in atoms. It is done to follow Pical model as close as possible, and then map resulting structures to `metaL` classes the way like cross-model translation." ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "class Term(Frame): pass\n", "class Var(Term): pass" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [], "source": [ "class Atomic(Term): pass\n", "class Atom(Atomic): pass\n", "class Number(Atomic): pass\n", "class Integer(Number): pass\n", "class Real(Number): pass" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [], "source": [ "class Compound(Term): pass\n", "class List(Compound): pass\n", "class String(List): pass\n", "class Struct(Compound): pass\n", "class Array(Struct): pass\n", "class Map(Struct): pass" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Parser" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [], "source": [ "## Pycat syntax parser\n", "\n", "__file__ = 'pycat.ipynb' # required to run PLY in Jupyter\n", "\n", "import ply.lex as lex\n", "import ply.yacc as yacc\n", "\n", "# list of token types can be detected by the lexer\n", "# the token can be any object (Frame-inherited in our case) but \n", "# it must have set of required fields including .type\n", "\n", "tokens = ['var']\n", "\n", "t_ignore = ' \\t\\r'\n", "t_ignore_comment = '%.*'\n", "\n", "# end of lines (LF, line feed) must be counted obviously\n", "def t_lf(t):\n", " r'\\n+'\n", " t.lexer.lineno += len(t.value)\n", "\n", "def t_var(t):\n", " r'[A-Z][A-Za-z0-9_]*'\n", " return Var(t.value)\n", "\n", "def t_error(t):\n", " raise SyntaxError(t)\n", "\n", "lexer = lex.lex()" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "<var:Variable> id:7fa3a407e828\n" ] } ], "source": [ "lexer.input('''\n", "\n", "% line comment\n", "\n", "Variable\n", "\n", "''')\n", "\n", "while True:\n", " token = lexer.token()\n", " if not token: break\n", " print(token)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.5.3" } }, "nbformat": 4, "nbformat_minor": 2 }