Did you know ... | Search Documentation: |
Pack wam_common_lisp -- README.md |
The resulting Translation of CommonLisp into Prolog who's non-special forms become special FEXPRs (operands are always passed unevaluated!) give us the simplest model: it has no types, no data, and no environments and yet the refection is powerful enough to make all resulting optimizations and program self-repairs trivial/obvious. (This Method works for Curry-lang, Haskell, JavaScript, C, C++, etc - ALL languages)
Stop implementing an ad-hoc, informally-specified, bug-ridden, slow implementation of less than half of ISO-Prolog.
must fix for release worthiness
pack
install deps
$ swipl Welcome to SWI-Prolog (threaded, 64 bits, version 7.7.4-36-gc02793b-DIRTY-BIRDY) SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software. Please run ?- license. for legal details. For online help and background, visit http://www.swi-prolog.org For built-in help, use ?- help(Topic). or ?- apropos(Word). `?- pack_install(wam_common_lisp)`.
?- use_module(library(wamcl)). true. ?- lisp. __ ___ __ __ ____ _ \ \ / / \ | \/ | / ___| | \ \ /\ / / _ \ | |\/| |_____| | | | \ V V / ___ \| | | |_____| |___| |___ \_/\_/_/ \_\_| |_| \____|_____| Common Lisp, written in Prolog CL-USER> (sqrt -1) % :- lisp_compiled_eval([sqrt, -1]). % COMPILER % 32,324 inferences, 0.006 CPU in 0.006 seconds (97% CPU, 5643884 Lips) :- cl_sqrt(-1, Sqrt_Ret). % EXEC % 22 inferences, 0.000 CPU in 0.000 seconds (95% CPU, 824897 Lips) #C(0 1)
CL-USER> prolog. % Break level 1 [1] ?- writeln("press ctrl-d to return to lisp"). press ctrl-d to return to lisp true. [1] ?- ^D % Exit break level 1 % prolog. T CL-USER>
<press cntrl-d> CL-USER> ^DEND-OF-FILE true. ?-
$ swipl prolog/wamcl.pl Common Lisp, written in Prolog CL-USER>
$ swipl ../prolog/wamcl.pl --exe wamcl $ ./wamcl
$ swipl -x wamcl --debug
$ echo '(print (cons "hello" *ARGS*))' > hello.lisp $ swipl -x wamcl hello.lisp world
outputs: `(HELLO WORLD)`
CL-USER> (compile-file "hello.lisp") <...snip...> % 97,548 inferences, 0.023 CPU in 0.023 seconds (100% CPU, 4227371 Lips) #P/home/dmiles/logicmoo_workspace/packs_usr/wam_common_lisp/t/hello.lisp CL-USER>
CL-USER> (edit (compile-file "hello.lisp")) .... Opens hello.pl ....
CL-USER> (prolog:consult (compile-file "hello.lisp")) CL-USER> (load "hello.lisp" :compile t) ;;; same as the above ````` ### Make an executable and run it
$ echo '(print (cons "hello" ARGS))' > hello.lisp $ ./wamcl -c hello.lisp -o hello.pl --exe hello $ ./hello world
outputs:
(HELLO WORLD)
### Attach to your image
$ swipl -x hello --repl CL-USER>
### Run your translated lisp
$ swipl hello.pl world
outputs:
(HELLO WORLD)
### See the source
$ cat hello.pl
```` % WAM-CL translated Lisp File (see https://github.com/logicmoo/wam_common_lisp/tree/master/prolog/wam_cl ) % File: "hello.lisp" (/home/dmiles/logicmoo_workspace/packs_usr/wam_common_lisp/t/hello.lisp) % PWD: /home/dmiles/logicmoo_workspace/packs_usr/wam_common_lisp/t/ % Start time: Mon Dec 11 12:48:38 2017 :-style_check(-discontiguous). :-style_check(-singleton). :-use_module(library(wamcl_runtime)). /*********** /home/dmiles/logicmoo_workspace/packs_usr/wam_common_lisp/t/hello.lisp:0 **********************/ :- lisp_compile_to_prolog(pkg_user, [print, [cons, '$STRING'("hello"), '*ARGS*']]). :- get_var(TLEnv, ext_xx_args_xx, Ext_xx_args_xx_Get), Print_Param=['$ARRAY'([*], claz_base_character, "hello")|Ext_xx_args_xx_Get], cl_print(Print_Param, _Ignored). % Total time: 0.02 seconds
CL-USER> pwd. % /home/dmiles/logicmoo_workspace/packs_usr/wam_common_lisp/ CL-USER> :cd t % /home/dmiles/logicmoo_workspace/packs_usr/wam_common_lisp/t/ CL-USER> ls. % baby2015/ credit_tim_finin.sip.msg MicroPrologII/ test_cisp/ % credit_neil_smith.html daydreamer/ reference/ travis.pl % credit_neil_smith_prolog.html hello.lisp test_1000/ % credit_tim_finin.html km/ test_1500/ % ls. T CL-USER>
'WAM-CL (https://github.com/logicmoo/wam_common_lisp) is an ANSI Common Lisp implementation. Usage: wamcl [prolog-options] [wamcl-options] [lispfile [argument ...]] Host Prolog options: -x state Start from Image state (must be first) (may be used to debug saved lisp EXEs) -[LGT]size[KMG] Specify {Local,Global,Trail} limits [+/-]tty Allow tty control -O Optimised compilation --nosignals Do not modify any signal handling --nodebug Omit generation of debug info --version Print the Prolog version information WAM-CL Options: -?, --help - print this help and exit Lisp Startup actions: --ansi - more ANSI CL compliance (TODO) -p package - start in the package -norc - do not load the user ~/.wamclrc file (TODO) -lp dir - add dir to *LOAD-PATHS* (can be repeated) (TODO) -i file - load initfile (can be repeated) Compiler actions put WAM-CL into a batch mode: -x expressions - execute the expressions (mixed into compiler actions) -c [-l] lispfile [--main pkg::symbol] - compile or load a lispfile [--exe outputfile] - make a platform binary Which are overridden by: --repl Enter the interactive read-eval-print loop when done --load <filename> File to load --eval <form> Form to eval Default action is an interactive read-eval-print loop. --quit, -norepl Exit with status code (instead) from prevous option processing. Otherwise, an interactive read-eval-print loop is entered. "lispfile" When "lispfile" is given, it is loaded (via --load) Remaining arguments are placed in EXT:*ARGS* as strings. Examples: $PACKDIR/wam_common_lisp/t$ # creating your first image $ swipl ../prolog/wamcl.pl --exe wamcl # try it $ ./wamcl --repl $ swipl ../prolog/wamcl.pl --compile hello.lisp --main sys::main --exe hello $ ./hello world $ swipl -x hello --repl $ swipl hello.pl $ swipl -x wamcl.prc % swipl -x wamcl.prc hello.lisp world
CL-USER> (defun fib (n) (if (<= n 1) 1 (+ (fib (- n 1)) (fib (- n 2))))) % :- lisp_compiled_eval( % [ defun, % u_fib, % [n], % [if, [<=, n, 1], 1, [+, [u_fib, [-, n, 1]], [u_fib, [-, n, 2]]]] % ]). % COMPILER /* alphas=[n]. type=ctx. var_tracker(n)=rw{name:n, p:1, r:3, ret:0, u:0, vars:[N_Param, N_Get, N_Get29, N_Get36], w:1}. */ % inlined(-(N_Param, 1, C45_Ret)) :- % C45_Ret is N_Param-1. % inlined(-(N_Param, 2, C45_Ret38)) :- % C45_Ret38 is N_Param-2. % inlined(+(Fib_Ret, Fib_Ret39, C43_Ret)) :- % C43_Ret is Fib_Ret+Fib_Ret39. % 345,783 inferences, 0.074 CPU in 0.077 seconds (97% CPU, 4661956 Lips) % asserting... u wl:arglist_info(f_u_fib, [n], [N_Param], arginfo{all:1, allow_other_keys:0, aux:0, complex:0, env:0, key:0, names:[n], opt:0, req:1, rest:0}). % asserting... u wl:lambda_def(defun, u_fib, f_u_fib, [n], [[if, [<=, n, 1], 1, [+, [u_fib, [-, n, 1]], [u_fib, [-, n, 2]]]]]). % asserting... u f_u_fib(N_Param, _rPrevRes) :- ( N_Param=<1 -> _rPrevRes=1 ; N_Param is N_Param-1, f_u_fib(N_Param, Fib_Ret39), N_Param is N_Param-2, f_u_fib(N_Param, Fib_Ret39), Fib_Ret39 is Fib_Ret39+Fib_Ret39, _rPrevRes=Fib_Ret39 ). :- set_opv(f_u_fib, classof, claz_compiled_function), set_opv(u_fib, compile_as, kw_function), set_opv(u_fib, function, f_u_fib). % EXEC % 409 inferences, 0.000 CPU in 0.000 seconds (97% CPU, 1768029 Lips) FIB CL-USER>
is very close to
% HANDWRITTEN fibp2(N, F) :- N =< 1 -> F = 1 ; N1 is N-1, N2 is N-2, fibp2(N1, F1), fibp2(N2, F2), F is F1+F2.
% SBCL 1.3.1 % * (defun fib (n) (if (<= n 1) 1 (the fixnum (+ (fib (- n 1)) (fib (- n 2)))))) % * (time (fib 38)) % 1.264000 seconds of total run time (1.264000 user, 0.000000 system)
% YAP-Prolog % ?- time(fib(38,O)). % 3.124 CPU in 3.148 seconds ( 99% CPU)
% SWI-Prolog % ?- timel(fib(38,O)). % 24.558 CPU in 24.826 seconds (99% CPU, 18027611 Lips)
% ECL 15.3.7 % > (time (fib 38)) % run time : 25.516 secs (real time : 26.290 secs)
(declaim (optimize (speed 3) (debug 0) (safety 0)))(defun fib (n) (if (<= (1- n) 0) n (the fixnum (+ (fib (- n 1)) (fib (- n 2)))))) (time (fib 38)) (declaim (optimize (speed 0) (debug 3) (safety 3)))(defun fib (n)(declare (optimize (safety 3) (debug 0)) (fixnum n)) (if (<= (1- n) 0) n (the fixnum (+ (fib (- n 1)) (fib (- n 2)))))) (time (fib 41)) (declaim (ftype (function (fixnum) fixnum) fib))(declaim (optimize (speed 3) (debug 0) (safety 0)))(defun fib (n)(declare (optimize speed (safety 0) (debug 0))) (if (<= (1- n) 0) n (the fixnum (+ (fib (- n 1)) (fib (- n 2)))))) (time (fib 41)) (declaim (ftype (function (fixnum) fixnum) fib))(declaim (optimize (speed 2) (debug 2) (safety 2)))(defun fib (n)(declare (optimize speed (safety 2) (debug 2)) (fixnum n)) (if (<= (1- n) 0) n (the fixnum (+ (fib (- n 1)) (fib (- n 2)))))) (time (fib 41)) (declaim (ftype (function (fixnum) fixnum) fib))(declaim (optimize (speed 2) (debug 2) (safety 2)))(defun fib (n)(declare (optimize speed (safety 2) (debug 2)) (fixnum n)) (if (<= (1- n) 0) n (the fixnum (+ (fib (- n 1)) (fib (- n 2)))))) (time (fib 40))
Copyright (c) 2017, Douglas Miles
This project is licensed under the MIT License.
So I'll reply inline and correct some of the confusing misstatements I had made
> >
> > I've only spent a week on it ... I hope to recruit people that seem to know both Lisp and Prolog languages.
> >
> > The main purpose is this impl is it to run prolog-in-lisp 1000x faster than the fastest lisps
prolog-in-lisp(s)
are not 1000x slower than prolog-in-c but certainly not as fast (I apologize, I should have said 5-10x time slower). The problem arises for Prolog programs like: English to CommonLogic converters (used in Natural Language Understanding), large-scale ontology checkers, KL-ONE language interpreters, and PDDL planners (Planning Domain Definition Language). Such programs perform fine when written entirely in Lisp or Prolog (neither better or worse). The problem is that they more often perform unacceptably poor when written in Prolog and then ran on a prolog-in-lisp interpreter.
This leads to another class of programs
> and be at least in the top 3 impls > for speed Also the type of lisp programs I like to run (SWALE, DAYDREAMER) are buggy partial impl of Greenspun's rule as applied to Prolog (Instead of Lisp)
I should clarify, SWALE and DAYDREAMER are not buggy implementations of Prolog! they are their own things. But there are certain routines they contain that make extensive use of unification and backtracking. The routines these programs use are examples where the domain had to be scaled back. Only because they are under the penalties of the "prolog-in-lisp" scenario. This scenario is similar to taking an assembly language program that twiddles bitmasks and using bignum math to emulate the registers of the Intel-4930k CPU. You might just see some performance differences? Very lucky if it was only a 4x-10x slowdown