LoginSignup
2
1

More than 1 year has passed since last update.

Dogelog Player is now Self Hosting

Last updated at Posted at 2022-05-26

Introduction

Dogelog Player is a Prolog interpreter that is 100% written in Prolog itself. It currently targets the JavaScript and the Python platform. So far there was only a cross compiler available that could be used to generate Dogelog Player. This has been improved recently, the Dogelog Player can now compile itself, making it a self hosting system.

Phylogenetic Tree

The Dogelog Player built-ins read_term/3 and write_term/3 are Prolog routines often using definite clause grammar (DCG) for their implementation. We were curious how the Dogelog Player Prolog dialect compares to other Prolog systems. We do not aim at providing ISO core standard, we rather want a living standard which is more tolerant.

We could gather some data already. In this data we produced random texts and checked what the different Prolog systems deliver. By some processing in formerly Jekejeke Prolog we could find Phylogenetic Trees that show how the Dogelog parser compares with other Prolog systems. We can use the Dogelog Players turtle to show the tree.

First we determine the heights of the branches of the tree:

heights([A|B], T, [R-X|S-Y]) :- !, 
   heights(A, R, X), 
   heights(B, S, Y), T is R+S.
heights(A, 25, A).

We then use this center the tree:

make(T) :- heights(T, R, X), S is R/2+10,
   retractall(current_position(_,_)),
   assertz(current_position(10,S)),
   draw(X).

Finally we can draw the tree:

draw([R-A|S-B]) :- !,
   current_position(P,Q),
   line(30), turn(pi/2), line(R/2), turn(-pi/2), line(30), draw(B),
   retractall(current_position(_,_)),
   assertz(current_position(P,Q)),
   move(30), turn(-pi/2), line(S/2), turn(pi/2), line(30), draw(A).
draw(A) :- 
   text(A).

Using the result of our fuzz4 test documented on medium here:

:- begin_svg, make([[trealla4, scryer4|gnu4], 
[[swi4|eclipse4]|dogelog4], ppeg4|sicstus4]), end_svg.

We get the following Phylogenetic tree display in a Browser:
Unbenannt.PNG

The tree visualizes again, that the Dogelog Player dialect is on the other side of newer Prolog systems such as Scryer Prolog and Trealla Prolog which do immitate the strict ISO core standard adherence of GNU Prolog. But still Dogelog Player does not completely match SWI-Prolog for example.

Cross Compiler

The cross compiler translates the bootload Prolog of the Dogelog Player into the intermediate code of Dogelog Player. The intermediate code is derived from the Albufeira Prolog interpreter. It therefore shares a common ancestor with SWI-Prolog, but has meanwhile quite evolved. For example we do not have a "pop" instruction anymore:

case 0: // singleton
case 1: // first_var(N)
case 2: // var(N)
case 3: // functor(F,A)
case 4: // atomic(C)
case 5: // para(N)

What remains the same is that the same code can be executed in unify and build mode. But otherwise Dogelog Player is currently more agressive in instantiating a clause body and therefore heavily relies on the garbage collection of the host programming language such as JavaScript or Python. It performs quite well on JavaScript but not so well on Python.
image.png
To speed up cross compilation, since it needs a lot of copying of files written in the host programming language, we have introduced built-ins get_atom/3 and put_atom/2. These are some ISO core standard get_code/2 and put_code/2 variants. Using formerly Jekejeke Prolog we can cross compile the Dogelog Player via Prolog itself quite quickly as shown above.

Self Hosting

To allow self hosting, i.e. cross compiling Dogelog Player by Dogelog Player itself, we add to give Dogelog Player not only built-ins such as get_atom/3 and put_atom/2, but also ISO cores standard built-ins like open/3 in mode write or append. A last hurdle was that our cross compiler used relative paths:

main :-
    transpile_clear('../drawer/bootload.js'),
    transpile_add('../../transpiler/compile.p', compile, '../drawer/bootload.js'),
    transpile_add('../../transpiler/loader.p', loader, '../drawer/bootload.js'),
    bundle_clear('../canned/dogelog.js'),
    bundle_add('../drawer/machine.js', '../canned/dogelog.js'),
    bundle_add('../drawer/unicode.js', '../canned/dogelog.js'),
    bundle_add('../drawer/special.js', '../canned/dogelog.js'),
    bundle_add('../drawer/eval.js', '../canned/dogelog.js'),
    bundle_add('../drawer/bootload.js', '../canned/dogelog.js'),
    bundle_add('../drawer/index.js', '../canned/dogelog.js').

A way to change the working directory in Dogelog Player was needed. Thankfully both JavaScript node and Python provide API to change the working directory of the underlying process. We tapped into that, but gave it the base_url Prolog flag interface as found in formerly Jekejeke Prolog. So transpiling for both JavaScript and Python reads:

run :-
   set_prolog_flag(base_url, 'dogelog/player/cross'),
   write('js '), time(main),
   set_prolog_flag(base_url, 'dogelog/playerpy/cross'),
   write('py '), time(mainpy).

The results are encouraging:
croissant.png
The Dogelog Player on node.js is currently only a factor 4-5 slower than formerly Jekejeke Prolog. This is a new welcome independence from formerly Jekejeke Prolog. We might even turn the tables in the future, and try to bootstrap a new Jekejeke Prolog solely from Dogelog Player, by investigating the Java target in addition to the existing JavaScript and Python target.

Conclusions

Dogelog Player provides a Prolog dialect that is closer to SWI-Prolog than to GNU-Prolog. Until now there was a dependency to formerly Jekejeke Prolog since we needed this Prolog systems to evolve and cross compiler the Dogelog Player. This dependency has been capped, since Dogelog Player has become able of self hosting.

Example 03: Turtle Graphics
http://www.xlog.ch/izytab/moblet/docs/18_live/10_reference/example04/package.html

Previous Post: Turtle Graphics in Dogelog Player
https://qiita.com/j4n_bur53/items/ed97c904ea0a3192b485

2
1
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
2
1