guile-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

The progress of hacking guile and prolog


From: Stefan Israelsson Tampe
Subject: The progress of hacking guile and prolog
Date: Thu, 21 Oct 2010 22:23:23 +0200
User-agent: KMail/1.13.5 (Linux/2.6.34.7-0.3-desktop; KDE/4.4.4; x86_64; ; )

Hi,

I think it's good to discuss what I do with the prolog and unifer. So this
is what I've been doing.

1. Incorporate a theorem prover for extension and playing
2. Kanren like hygienic macro package
3. Make the c-code variables printable and hence much less segfaults at bt :-)
   e.g. robustify
4. Hygienify the fast umatcher.
5. try to design a type checker mimiking typed racket.
6. Play with compiled guile vm code to check for speed
7. Redesign and unugglify and improve the main prolog compiler
8. Introduce interesting features like higher order functional behavior.
9. Move the code over closer to guile Head.

Hew oh well, thats feels like a lot, let's check it out.

1. The theorem prover (leanCop) is a nice exercise to incorporate and use 
because it uses quite a lot of prolog features and beeing able to compile that 
into working code led me back to read up about some of my ignorantic parts of 
prolog I've not setled here how to solve it. the thing is that one meld the
operator parser in prolog to whatever one may like and use that to parse 
general code. I really don't like that the core languge changes behavior as
you parse language x, and added a feature where the parser enters a new
context e.g. the parsing language x and hence one can separate the two. This 
is 
not iso behavior although you can still modify the core language. There will
be incompabilities but you can give the users some advice how to avoid these
by using parenthesises. I think that this is a design choise for the better 
though. Anyhow with some luck there will be a code prover for guile in a
couple of years :-)

2. Kanren is a nice way to program like with prolog, but using code more true
to scheme. So I've been working with a hygienic macro package that should 
give such a feature. These macros will then be used in the prolog compiler 
to beutyfy it. I reallt think that this is the right way and really like 
what I've churn out so far.

3. The speedy umatch thingy was quite terrible to work with because it entered 
these home cooked c variables into guile which just segfaulted when trying to 
print it. (ugly) Anyway the print routine was hacked in my repo to print the 
it better. Still there probably are some dragons sleeping here but at least
the coding experience is much better.

4. The umatch hackity hack was turned into a much more hygienic creature. Not 
perfect but at least it should now play much nicer with the macro system. The 
key issue was that everything was a defmacro (i did not now better then) and
the matcher introduced syntactics from outer s(pace)cope so it was not to just
bless the beast with (datum->syntax). One needed to take the x in
(syntax->datum x) and split it up, tryying to keep bits of syntactic
information to transfer it into the old macro compiler. Here comes a 
pretty cool hack actually. Consider the following module:

-----------------------------------------------------------
(define-module (ice-9 syntax-matcher)
  #:use-module (ice-9 match-phd-lookup)
  #:export     (match-syntax-hack))


(define (syntax-null?  x  ) (null? (syntax->datum1 x)))
(define (syntax-equal? x y) (equal? (syntax->datum1 x) y))
(define (syntax-id x)
  (define (syntax? x) (not (eq? x (syntax->datum1 x))))
  (if (pair? x) 
      x
      (let ((r (syntax->datum1 x)))
        (if (pair? r)
            (let ((h (if (syntax? (car r)) (car r) (datum->syntax x (car r))))
                  (l (if (syntax? (cdr r)) (cdr r) (datum->syntax x (cdr 
r)))))
              (cons h l))
            x))))

          
(make-phd-matcher match-syntax-hack ( (car cdr pair? syntax-null?
syntax-equal? syntax-id) ()))
------------------------------------------------------------


syntax->datum1 transfer a syntax object to a datum for only it's root, e.g. it 
does not try to make everything a datum.

id is a lookup creature and match-phd-lookup is a modded match generator that
uses custom lookup or syntax-id as I call it. it's just an unpacking command 
that is done befor car cdr and pair? is executes like

(let ((v (lookup v))) (if (pair? v) (f (car v) (cdr v))))

so it's a stupid efficiency hack so that we don't lookup all the time. Now
syntax id will open up a pair and if some of them it's children is not of a
syntax kind it will bless the child with the syntax of the parent syntax 
object. Now with this matcher I want to chop up the following structure 

(arg1 ... argn ((pat1, ..., patn code) ...))

and can then use:

(define (my-unsyntax X)
  (define (unsyntax2 X)
    (define (unsyntax3 X)
      (define (unsyntax4 X)
        (match-syntax-hack X
           (('unquote  X)     (list 'unquote  X))
           (('uunquote X)     (list 'uunquote X))
           (('?        X)     (list '?        X))
           (('=  X     P)     (list '=        X (unsyntax4 P)))
           (('?  X P    )     (list '?        X (unsyntax4 P)))
           ((H . L)           (cons (unsyntax4 H) (unsyntax4 L)))
           ( H                (syntax->datum1 H))))

      (match-syntax-hack X
         ((Code)     (cons Code '()))
         ((M . L)    (cons (unsyntax4 M) (unsyntax3 L)))))

          
    (match-syntax-hack X
       ((X . L)  (cons (unsyntax3 X) (unsyntax2 L)))
       (()      '())))

  (match-syntax-hack X
      ( (X)     (cons (unsyntax2 X) '()))
      ( (X . L) (cons X (my-unsyntax L)))))

It's not perfect syntaction but it is vastly better then before and the code 
is yum yum.

5) Typechecking is for safty and optimisation, in the end it can be cool to 
have and I'm working to understand all sides of this and have a pretty good 
idea what is needed. It will be a goos testcase for the code.

6) I copied the  glil->assembly compiler and modded the code to spit out 
c-code in stead of assembly. For functions which does not call other scheme
functions except in tail call manner this should be quite fast to adapt. And
of cause loops becomes wickedly fast when compiling this way. Wingo:s example 
without consing tok 7ns for each loop on my machine. (For cleaned up C it
should be less then 1 ns) Kind of interesting and a nice playground to try 
out optimisations directed by type inference.

7,8,9. No more to say but that you rock, upgrading to guile head was really
a nice experience.


Now I will continue to struggle with these topics for some time (I also hope 
to return to the postpone topic but to get the core in shape has higher 
priority)

Happy Hacking : - )
/Stefan





reply via email to

[Prev in Thread] Current Thread [Next in Thread]