guile-devel
[Top][All Lists]
Advanced

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

Fwd: Guile 2.0 is turning 3 years old, let's hack!


From: Stefan Israelsson Tampe
Subject: Fwd: Guile 2.0 is turning 3 years old, let's hack!
Date: Fri, 14 Feb 2014 13:10:10 +0100


I forgot to attach the list to the mail.

---------- Forwarded message ----------
From: Stefan Israelsson Tampe <address@hidden>
Date: Thu, Feb 13, 2014 at 7:32 PM
Subject: Re: Guile 2.0 is turning 3 years old, let's hack!
To: Ludovic Courtès <address@hidden>


Iso prolog will need to be worked on to get it going but as a potluck I did port logic programming delimeted continuaiton for prolog. 

The prolog kontinuations behaves vary much like ordinary goals, they can fail and also
one can backtrack to them yielding a new solution e.g. one can easally produce very cool parameterized goals
where one setup the goal and then issue an abort_to_prompt ... hence can do just a minor modification
of an already present prolog program in stead of redesigning the hole lot.

The background is that we tout that one of the cool features of guile and many other schemes is that it has proper
delimited continuations, get this concept into prolog as well.

The interface,  here we goooo,

Dependencies:
current guile-syntax-parse, https://gitorious.org/guile-syntax-parse

So fire up guile-log and iso-prolog dependencies. In your file that will produce a compiled prolog program e.g. using a macro that takes a prolog files  or prolog string and outputs scheme code, make sure that the dependecy,
(use-modules (logic guile-log guile-prolog continuations))

Then you can use the ideoms

abort_to_prompt, with_prompt, re_prompt

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
abort_to_prompt(tag,data,feed)

As with normal abort-to-prompt, this will unwind the stack back to handler that matches tag with returning
'data' as one argument, 'feed' will be the data past back when the the continuation is instantiated.
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
with_prompt(tag,code,handler-data,handler)

Creates a handler point on the prompt stack where it will set up the handler and execute code. if
abort_to_prompt is executed and matched with tag the handler will be executed with handler data as
an argument. Handler data is a list of the format format [tag, next, k, data] that will be matched against 
the corresponding incoming data, tag will be the tag send by abort_to_prompt, next if used as next()
will continue to the next handler in the prompt stack that matches tag, k will be the continuation and data
will be matched to the data send with abort_to_prompt.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
re-prompt is similar, but reuses the old handler in stead of creating a new one which may cause the stack to 
grow too much, use them with e.g. generators, they have else the same semantic as with_prompt.


So how do it work in practice? Lets make a generator framework

(compile-string "yield(X) :- abort_to_prompt(generator,X,_).")
(compile-string "eat(X)   :- abort_to_prompt(generator,_,X).")
(compile-string "generator(Goal,F) :- 
                      with_prompt(generator, Goal,[generator,_,K,X],
                                 F=[K,X]).")

yield will be a data producer, eat a data consumer and generator the initial construction of the generator

The code that will use the generators should use
(compile-string 
"
next([K,X],X,F)           :- re_prompt(K,[generator,_,K2,XX],F=[K2,XX],_).
feed([K,_],Y,F)           :- re_prompt(K,[generator,_,K2,_ ],F=[K2,_ ],Y).
translate([K,X],X,Y,F) :- re_prompt(K,[generator,_,K2,XX],F=[K2,XX],Y).
")

E.g.

next(Generator, OutputData , NextGenerator)
feed(Generator, InputData , NextGenerator)
translate(Generator, OutputData, InputData , NextGenerator)

And as an example to try

(compile-string 
"
sum(S) :- write(sum(S)),nl,eat(X),write(y(X)),nl,SS is S + X,sum(SS).
run :- generator(iter(0),F),generator(sum(0),S),pr(F,S).
pr(F,S) :- next(F,X,FF) -> write(n(X)),nl, feed(S,X,SS),pr(FF,SS).
iter(N) :- write(iter(N)),nl,N < 10 -> (yield(N),N2 is N + 1, iter(N2)).
")

;; Example 2 (run2)
(compile-string 
"
iter2(N) :- write(iter2(N)),nl,N < 10 -> (yield(N) ; N2 is N + 1, iter2(N2)).
run2     :- generator(iter2(0),F),pr2(F,S).
pr2(F,S) :- next(F,X,FF),fail.
")

;; Example 3 (run3)
(compile-string 
"
iter3(S,N) :- N < 10 -> (write(iter3(S,N)),nl,N2 is N + 1, iter3(S,N2)) ; true.
run3       :- generator((eat(X),iter3(X,X)),F),pr3(F).
pr3(F)     :- call_k(F,_,0),write('--------'),nl,call_k(F,_,5).
")

;; Example 4 (run4)
(compile-string 
"
iter4(S,N) :- N < 10 -> (write(iter4(S,N)),nl;N2 is N + 1, iter4(S,N2)).
run4       :- generator((eat(X),iter4(X,X)),F),pr4(F).
pr4(F)     :- (call_k(F,_,0);call_k(F,_,5)),fail.
")

//Have fun
Stefan










On Thu, Feb 13, 2014 at 3:16 PM, Stefan Israelsson Tampe <address@hidden> wrote:
Maybe I can get iso-prolog to work ontop of guile-log to that time, maybe.


On Tue, Feb 11, 2014 at 11:46 AM, Ludovic Courtès <address@hidden> wrote:
Doug Evans <address@hidden> skribis:

> Can I offer something written while at FOSDEM (last week).
> I used my wrap-syscall package to write a gdb bug repro that was
> otherwise harder to do, and writing it *was* fun! :-)
> https://github.com/xdje42/wrap-syscall
> With it I can, via LD_PRELOAD, intercept system calls (or potentially
> any library call) with Guile and reimplement them or just monitor
> them.

Yep, neat!

> Or does it have to be something written after Feb.10.

Well, you still have 5 days left to hack since the actual birthday is on
Feb. 16th.  :-)

Cheers,
Ludo’.





reply via email to

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