LoginSignup
0
0

More than 1 year has passed since last update.

Coastline Paradox as a Dogelog Notebook

Last updated at Posted at 2022-12-23

Introduction

Dogelog Player is a Prolog interpreter that is written itself in 100% Prolog. It targets the JavaScript platform and the Python platform. For the JavaScript platform it is able to run in the browser.

multiply.png

So far the Dogelog Player mainly showcased writing text cells in the browser. This has changed by a new type of graphic cells that can be populated by a novel DOM Prolog API.

Text Cells

Even the Turtle Graphis example was based on raw writing a text cell. Writing a text cell is straight forward and the Dogelog Player has an output stream abstraction based on callbacks.

    function out(buf) {
        let elem = document.getElementById("demo");
        elem.insertAdjacentHTML("beforeend", xml_escape(buf));
    }

    function err(buf) {
        let elem = document.getElementById("demo");
        elem.insertAdjacentHTML("beforeend", 
           "<span style='color: #A52A2A'>"+
            xml_escape(buf)+"</span>");
    }

    set_output(out);
    set_error(err);

The above shows an approach to hook into these callbacks to provide a uncolored output stream and a colored error stream. We then made an experiment with removing the xml_escape(), and having a raw stream so that we can emit arbitrary XML content.

This is demonstrated in "Example 11: Turtle Graphics". We generated SVG graphics via the ISO core standard write predicate. There are the following drawbacks of this approach:

  • Disallowed Intermittent flush_output/0: Somebody might be used to pretty print his input via nl/0. Unfortunately nl/0 has an implicit flush_output/0, so when applied inside a tag or outside tags when tags are not closed, the insertAdjacentHTML() will produce errors or scrambled results.

  • Require Final flush_output/0: To avoid further errors or scrambling it is then required when a balanced begin and end tag pair has been written, that the text is flushed, we do it via nl/0. This means generating DOM output is at the mercy of the underlying buffer size of the raw stream, and larger output runs havoc again.

Graphic Cells

Because of the aforementioned problems we designed a new API for safe generation of DOM output. We produced the following set of JavaScript calls and Prolog foreign predicates in a new native library cells.msj, that allows incremental generation of raw output:

  • set_cursor: Set the cursor.
  • add_cell(buf): Add an element with HTML buf to the cursor.
  • down_cell: Change cursor to last element child.
  • up_cell: Change cursor to parent element.

The idea is that the add_cell/1 Prolog command generates a DOM element without any children. If then children are desired the Prolog command down_cell/0 can be used to navigate into DOM element, create the children and finally navigate out of the DOM element via up_cell/0.

:- begin_svg([width(50),height(50)]), sierpinski(200, 1), end_svg.
:- begin_svg([width(50),height(50)]), sierpinski(200, 2), end_svg.
:- nl.
:- begin_svg([width(50),height(50)]), sierpinski(200, 3), end_svg.
:- begin_svg([width(50),height(50)]), sierpinski(200, 4), end_svg.

The above shows some code usage of the new API for safe generation of DOM output. Its from the new example "Example 81: Graphics Render". The new begin_svg/1 has an option list to control the creation of the SVG element which is done via the new API. The new API is also used to realize the turtle:
image.png
Observe that SVG elements have the pleasing property that they float like IMG elements. So we can easily replicate what Python would do with so called subplots, only we don't need an extra command for subplots. Simply create a little smaller SVG element with the percentage height and/or width option, and when a new row of SVG elements is needed, use the newline nl/0.

Cell Rollback

As a next step we brought graphics output cells to Dogelog player notebooks. The interactivity of Dogelog player notebooks requires that code cells side effects can be undone client side. For undoing dynamic and static database effects the Dogelogy player has a unique Prolog knowledge base available in the browser that can snapshot rollback its clauses and predicates.

On the other hand for text output cells Dogelog player notebooks approach the rollback problem in that we cleared their inner html and/or adjust the target dom element for the text output. It was relatively straight forward to do the same for graphics output cells. As a test case we made a little Dogelog notebook about the coastline paradox:
image.png
The new "Example 84: Koch Curve" combines multiple markup, code and graphic cells on the same page. The same new API for safe generation of DOM output is used. The call that has a more prominent usage is now set_cursor(), its not a Prolog predicate but a JavaScript call used by the notebook orchestration.

It should be noted that Dogelog Player does everything client side and in 100% pure Prolog. The turtle graphics are loaded as a Prolog text 'draw.p' and the state of the turtle is Prolog dynamic facts inside the browser. This is very different from SWI-Prolog SWISH and Logtalk Jupyter, which require server roundtrip.

Conclusions

Dogelog player is the avantgard that pushes again and again the limits of browser Prolog. Whereas the snapshot rollback mechanism already differentiated the Dogelog player from SWI-Prolog WASM, Ciao Playground and Tau-Prolog. We successfully faced a new challenge in the form of graphic cells, generated by 100% pure Prolog completely client side.

Example 81: Graphics Render
https://www.dogelog.ch/littab/moblet/docs/10_novacore/02_scraping/example81/package.html

Example 84: Koch Curve
https://www.dogelog.ch/littab/moblet/docs/10_novacore/02_scraping/example84/package.html

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0