unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
* prolog code in guile
@ 2018-11-13 23:06 Stefan Israelsson Tampe
  0 siblings, 0 replies; only message in thread
From: Stefan Israelsson Tampe @ 2018-11-13 23:06 UTC (permalink / raw)
  To: guile-devel

[-- Attachment #1: Type: text/plain, Size: 3384 bytes --]

This is a feature request.

Hi all, I am studying the compiling of clpfd finite domain solver from swi
prolog. Currently it
compiles in 10 minutes giving a 14MB large go file. The same code compiles
in 1 second in swi. Which means that we do something wring in guile-log.
The scanning and parsing of the file takes 30s so the macro expansion and
compilation is a huge issue fro me atm. In my experience every lambda you
can get rid of in scheme is a net win in compilation time. And previous
experience has been that it is worthwhile to make closure making functions
and call them than directly insert the lambda to avoid inconvinient
compilation times (Actually I tend to make it configurable to do this, the
compiller can do marvelss with the closures). Anyway I do not want to
remove the optimizer because it does a heck of a work simplifying the
prolog code.

So I am tinkering with what is needed to compile prolog code and it turns
out that prolog has different needs than scheme. For one thing scheme
prolog code compiles to way more lambdas than is needed. And a lot of speed
is lost due to this. Also the variables space is somwehat stationary in the
predicate while the code path leaves and enters the predicates in multiple
ways.

To illustrate see this in action we can have a predicate f(X,Y):- X==1 ->
f(),Y==1 ; Y==X.
This currently translates to either a lot of lambdas that is not needed or
explodes in the number
lines of expanded lambdas what we would like to do is (vec is a closure var)
(define (f : vec self label)
    (if  label (goto label))
    (tagbody
         (newframe vec.fr)
         (if (== vec.s vec.x 1)
             (let ((p2 (make-p self tag)))
                 (tail-call f vec.s p2 vec.cc))
         tag:
         (unwind vec.fr)
         (if (== vec.s vec.x vec.y)
             (vec.cc vec.s vec.p)
             (vec.p))))

make-p(self tag)
    (let ((closure  (copy self)))
      closure.self   = closure
      closure.vec   = self.vec.
      closure.label =  tag

So the make-p copies the self function without the closure, and adds a link
to itself, a continue address. similarly cc closures can be made.

Everything can be kept into guile assembler appart from the ability to
store an address and goto to an adress stored in a variable.

Also I need to modify guile slightly for enabling a separate assembler or a
manual assebler to come in naturally in the compileation. I made a struct
that if it's compiled to a constant as using #`#,struct, we could make sure
to typecheck it in types.scm. At compile cps it is checked and a label is
added to it. Then in compile-bytecode.scm one can test for it and generate
the custom assembler ans also load it as a static procedure in places. Not
sure if this is the best way to do this, but sure it was not much work. I
use it as
(define f (wrapper custom-assembler))

Doing this is good enough and it compiles the assembler into the go file.

So my current request for guile is
1. enable support for writing custom assembler
2. named gotos, getting the address of it relative the procedure start and
goto the stored
address relative the function start.

Having named gotos and a tagbody construct would also serve guile well,
that would help
writing a vm in guile in a more efficient way. Currently it's a vector of
closures that is
the tool of use.

I will continue experimenting.

Regards
Stefan

[-- Attachment #2: Type: text/html, Size: 4271 bytes --]

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2018-11-13 23:06 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-11-13 23:06 prolog code in guile Stefan Israelsson Tampe

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).