Racklog is a port to more-idiomatic Racket of the Schelog system [1]
by Dorai Sitaram. The idea of Schelog was not to be a high-performance
implementation of Prolog, but to use continuations to allow smooth
integration between Prolog-style search and more conventional
computation, while maintaining a simple implementation. Maintaining
this integration (see
https://docs.racket-lang.org/racklog/racket-w-logic.html) with a
WAM-based system would be tricky. Additionally, since Racklog is not
widely used currently, I think there hasn't been much of a push to
optimize it.

Because Racklog uses continuations, I expect that it runs much faster
on Racket CS, which has a much more efficient implementation of
continuations than the traditional Racket VM.

Building a new and efficient Prolog implementation in Racket would be
a great thing to do, and I encourage you to do this, or even just to
start by porting the Common Lisp code you have.

Sam

On Wed, Dec 11, 2019 at 4:42 PM Eduardo Costa <edu50...@gmail.com> wrote:
>
> From time to time, I test Racklog, in the hope that the Racket team replaced 
> it with something more efficient. After all, there are many good 
> implementations of Prolog like languages around. I simply cannot understand 
> why Racket must be packed with a ridiculously slow piece of software, such as 
> Racklog. Therefore, in order to discover how difficult would be the 
> implementation of an efficient version of Racklog, I decided to check what I 
> could do in Common Lisp. The reason for choosing Common Lisp is that there 
> are a few inference machines in Lisp, so I did not need to start from scratch.
>
> I found a book by Patrice Boizumalt that explained how to implement  Prolog; 
> the examples are in Common Lisp. I also found the material published in 
> Japanese by Daiki Matsunaga from the Kioto Institute of Technology. The 
> implementations of Boizumalt and Matsunaga are incomplete. For instance, they 
> did not implement floating point. It took me about one hour to complete their 
> implementations. Besides this, both implementations had bugs, which I fixed, 
> and raised an issue on the github pages of the authors. Finally, I tested the 
> programs with small grammars, puzzles and loops, just to check the tail call 
> optimization. Here is the comparison between Matsunaga's Prolog and cxprolog:
>
> ```
> %% File: again.pl
> › cat again.pl
>
> loop(0, Acc, Acc) :- !.
> loop(N, Acc, F) :- A1 is Acc + 0.1, N1 is N - 1, loop(N1, A1, F).
> ```
>
> Here is the execution in cxprolog:
>
> ```
> ~/wrkLisp/wam
> › ./cxp
> CxProlog version 0.98.2 [development]
>
> [main] ?- consult('again.pl').
> % File 'again.pl' consulted, 0.000106 sec 2768 bytes
> yes
>
> [main] ?- X1 is cputime, loop(2000000, 0.1, F), T is cputime - X1.
> X1 = 0.050186
> F = 200000.1
> T = 133.843561
> ```
>
> So, cxprolog executed 2 millions of repetitions in about 130 seconds. By the 
> way, cxprolog is written in c. Now, here is the execution of Matsunaga's 
> Prolog, which is written in Lisp:
>
> ```
> ~/wrkLisp/wam› rlwrap ros run
> * (load "wam.lisp")
> T
> * (repl)
> * (repl)
> > ?- consult('again.pl').
>
> yes.
> > ?- cputime(X1), loop(2000000, 0.1, F), cputime(X2), T is X2 - X1.
> F = 197024.88
> X1 = 3804
> X2 = 11729
> T = 7925
>
> yes.
> > ?- cputime(X1), loop(2000000, 0.1, F), cputime(X2), T is X2 - X1.
> F = 197024.88
> X1 = 11730
> X2 = 19832
> T = 8102
>
> yes.
> > ?- cputime(X1), loop(2000000, 0.1, F), cputime(X2), T is X2 - X1.
> F = 197024.88
> X1 = 19833
> X2 = 28478
> T = 8645
>
> yes.
> ```
>
> I added floating point and the predicate cputime(X) to Matsunaga's code, and 
> corrected a few bugs. The modified program is about 16 times faster than 
> cxprolog. Matsunaga wrote an interpreter, in order to execute code for the 
> Warren Abstract Machine. Of course, the is very inefficient. Therefore, I 
> expanded each instruction that appear in the code into Lisp programs. 
> Consider the code below, that Matsunaga's interpreter executes. I created a 
> Lisp definition for the loop predicate, where I expanded each definition, 
> according to what appears in the interpreter. Thus, the Lisp code became 
> considerably faster than the cxprolog code.  I did this in about one day. 
> Here is my question: Since it is so easy to write an efficient Prolog in 
> Lisp, why the Racket community insists in using Racklog? I would like to 
> propose a project to implement an efficient version of Racklog, based in 
> Matsunaga's version of the Warren Abstract Machine. The first step is to fix 
> all bugs that still remain in the Lisp version, and expand the instructions 
> to eliminate the necessity of the interpreter. After obtaining a flawless 
> Lisp version, one can prepare a Scheme/Racket version.
>
> ```
> * (gethash (cons '|loop| 3) *dispatching-code-table*)
> ((TRY-ME-ELSE #:G525
>   ((TRUST-ME) (ALLOCATE) (GET-VARIABLE-PERMANENT 4 1)
>    (GET-VARIABLE-PERMANENT 3 3) (PUT-VARIABLE-PERMANENT 2 1)
>    (PUT-CONSTANT 0.1 3) (CALL (|plus| . 3) 4) (PUT-VARIABLE-PERMANENT 1 1 4)
>    (PUT-UNSAFE-VALUE 4 2) (PUT-CONSTANT 1 3) (CALL (|minus| . 3) 3)
>    (PUT-UNSAFE-VALUE 1 1 3) (PUT-UNSAFE-VALUE 2 2) (PUT-UNSAFE-VALUE 3 3)
>    (DEALLOCATE) (EXECUTE (|loop| . 3))))
>  (GET-CONSTANT 0 1) (GET-VALUE-TEMPORARY 2 3) (NECK-CUT) (PROCEED)
>  (LABEL #:G525) (TRUST-ME) (ALLOCATE) (GET-VARIABLE-PERMANENT 4 1)
>  (GET-VARIABLE-PERMANENT 3 3) (PUT-VARIABLE-PERMANENT 2 1) (PUT-CONSTANT 0.1 
> 3)
>  (CALL (|plus| . 3) 4) (PUT-VARIABLE-PERMANENT 1 1 4) (PUT-UNSAFE-VALUE 4 2)
>  (PUT-CONSTANT 1 3) (CALL (|minus| . 3) 3) (PUT-UNSAFE-VALUE 1 1 3)
>  (PUT-UNSAFE-VALUE 2 2) (PUT-UNSAFE-VALUE 3 3) (DEALLOCATE)
>  (EXECUTE (|loop| . 3)))
>
> * (show-wamcode "loop" 3)
>           try-me-else G525
>           get-constant 0,A1
>           get-value X2,A3
>           neck-cut
>           proceed
> G525:     trust-me
>           allocate
>           get-variable Y4,A1
>           get-variable Y3,A3
>           put-variable Y2,A1
>           put-constant 0.1,A3
>           call plus/3,4
>           put-variable Y1,A1
>           put-unsafe-value Y4,A2
>           put-constant 1,A3
>           call minus/3,3
>           put-unsafe-value Y1,A1
>           put-unsafe-value Y2,A2
>           put-unsafe-value Y3,A3
>           deallocate
>           execute loop/3
> NIL
> ```
>
>
>
>
> --
> You received this message because you are subscribed to the Google Groups 
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to racket-users+unsubscr...@googlegroups.com.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/racket-users/4667bdbf-b466-439f-b71e-2c836ee3d2c0%40googlegroups.com.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAK%3DHD%2BaNn1MmcqQvkjGgqFHidzoPi9D-t8nek52A_e_ND3VXmg%40mail.gmail.com.

Reply via email to