Applications written in Scheme do exist. If they refrain from using implementation-dependent features, Pocket Scheme can run them.
SLIB | JACAL | Schelog | Scheme Prolog | Porting others
Pocket Scheme supports Aubrey Jaffer's SLIB portable Scheme library.
output-port-width— but it'll get you going.)
(load "/program files/pocket scheme/slibinit.scm").
(require 'random) - note the single
quote, this is SLIB's version of REQUIRE - followed by (random 100)
to see SLIB do something other than print loading prompts.
If this fails, then you probably need to modify the definition of SLIB's library-vicinity
(which is not the same thing as Pocket Scheme's own library-directory)
in slibinit.scm.
Upon being loaded,
SLIB redefines the require procedure to its own ends.
Pocket Scheme's previous definition of this procedure remains available as pscheme:require.
SLIB performs its own library management, so there is no need to set the library directory
to the slib directory.
Note that your downloaded distribution of SLIB may contain a old version of the initialization file under the name pscheme.init. Please examine your copy to ensure that you're using the most recent version.
The make-crc package as supplied in SLIB
assumes that any read-char will return a value of no more than 8 bits.
(Actually, it assumes no such thing,
hiding that assumption behind a symbol named char-code-limit;
however, its algorithm makes it effectively unusable on a palmtop computer
with that symbol set to 65536.)
There are issues about binary I/O with 3-series SLIB and Pocket Scheme 1.2.
Many portions of SLIB assume that any read-char consumes 8 bits from a backing file.
I have yet to address this.
If you'd rather keep SLIB on a storage card,
edit the definition of library-vicinity
in slibinit.scm.
Pocket Scheme can host JACAL, Aubrey Jaffer's interactive symbolic math program. This yields a powerful computer algebra system on your Windows CE device - a handheld Macsyma, if you will.
output-port-width procedure in that file.
The correct value for it to return will depend on your device, the font, the size of the font...
try 30 as a first guess.
Of course you'll need to do this before calling require.)
(load "/program files/pocket scheme/slibinit.scm").
(slib:load "/program files/pocket scheme/jacal/math.scm").
Note that this uses slib:load instead of load.
(math)
batch("/program files/pocket scheme/jacal/demo");
- note the semicolon and the parenthesis placement, as this is now JACAL syntax, not Scheme.
batch("/program files/pocket scheme/jacal/test.math");.
Alternately, you can visit Tools - Configure, enlarge the heap, Tools - Exit,
restart Pocket Scheme, and resume from the (load "slibinit.scm")
step above. 2048Kb seems enough.
Note that JACAL plus SLIB will require almost 1.3Mb of storage (uncompressed) on the device simply to store its source files. You can of course cull unused parts of SLIB to reduce this.
As a long-term goal, I want to make Pocket Scheme host JACAL more gracefully. The current tty-style user interface is acceptable on a keyboard-equipped Handheld PC, but quite unpleasant to use on a Pocket PC. I would also like to see some integration with graphing functions, such as the one I have prototyped in the sample code as plot.scm.
If you find JACAL failing simple operations such as (b-a)^(1/2),
check to make sure that the symbol char-code-limit has value 256.
The most recent version of the SLIB initialization file sets this correctly.
Pocket Scheme can host Schelog, Dorai Sitaram's embedding of Prolog-style logic programming in Scheme.
After downloading Schelog, simply follow the installation directions therein, identifying your Scheme dialect as pscheme, and your operating system (if necessary) as windows. (Versions of Schelog previous to 3h2 will require that you examine and possibly modify Schelog's makeport.scm to generate the correct syntax for Pocket Scheme.) Rename the resulting file with the extraordinarily long filename to something that won't provoke tendonitis.
To test your Schelog installation, try the map-coloring example. Be sure that you have verbosity set to 3 or less. Assuming that you renamed the ported Schelog to s.scm:
(load "/Program Files/Pocket Scheme/schelog/s.scm") (load "/Program Files/Pocket Scheme/schelog/examples/mapcol.scm") (%which (M) (%test-color 'test M))
This simple map-coloring test will yield a total of 120 non-unique permutations.
You can see them all without typing (%more) 119 times via
(do ((i 1 (+ i 1)) (f (%which (M) (%test-color 'test M)) (%more))) ((not f) "No more solutions") (display "*** Sol'n #") (display i) (display ": ") (display f) (newline))
Here's a simple Prolog program that sorts a list of numbers.
bsort(List, Slist) :- swap(List, List0), !, bsort(List0, Slist). bsort(Slist, Slist). swap([X, Y|T] , [Y, X|T]) :- not(ordered(X, Y)). swap([H|T], [H|T0]) :- swap(T, T0). ordered(X, Y) :- X < Y.
In Schelog, this bubble sort becomes
(define %bsort
(letrec
((swap
(%rel (x y t h t0)
(((cons x (cons y t)) (cons y (cons x t)))
(%not (ordered x y)))
(((cons h t) (cons h t0))
(swap t t0)) ))
(ordered
(%rel (x y)
((x y)
(%< x y)) )))
(%rel (l s l0)
((l s) (swap l l0) ! (%bsort l0 s))
((s s)) )))
Here's Prolog to solve the Eight Queens problem.
queens(N, Qs) :- range(1, N, Ns), queens(Ns, [], Qs). queens([], Qs, Qs). queens(UnplacedQs, SafeQs, Qs) :- select(Q, UnplacedQs, UnplacedQs1), not(attack(Q, SafeQs)), queens(UnplacedQs1, [Q|SafeQs], Qs). select(X, [X|Xs], Xs). select(X, [Y|Ys], [Y|Zs]) :- select(X, Ys, Zs). attack(X, Xs) :- attack(X, 1, Xs). attack(X, N, [Y|Ys]) :- X is Y + N; X is Y - N. attack(X, N, [Y|Ys]) :- N1 is N + 1, attack(X, N1, Ys). range(M, N, [M|Ns]) :- M < N, M1 is M + 1, range(M1, N, Ns). range(N, N, [N]).
In Schelog, this becomes
(define %queens
(letrec ((select
(%rel (x xs y ys zs)
((x (cons x xs) xs))
((x (cons y ys) (cons y zs))
(select x ys zs)) ))
(attack
(%rel (x xs n n1 y ys)
((x xs)
(attack x 1 xs))
((x n (cons y ys))
(%is x (+ y n)))
((x n (cons y ys))
(%is x (- y n)))
((x n (cons y ys))
(%is n1 (+ n 1)) (attack x n1 ys)) ))
(range
(%rel (m m1 n ns)
((m n (cons m ns))
(%< m n) (%is m1 (+ m 1)) (range m1 n ns))
((n n (list n))) )))
(%rel (n ns q qs uq uq1 sq)
((n qs)
(range 1 n ns) (%queens ns '() qs))
(('() qs qs))
((uq sq qs)
(select q uq uq1) (%not (attack q sq)) (%queens uq1 (cons q sq) qs)) )))
These two examples highlight a number of differences between Prolog and Schelog:
letrec to hide auxiliary routines).
In Prolog, all names are global, and all variables available throughout a relation.
%rel)
to differentiate them from Scheme variables;
an unquoted symbol is a variable, not a literal atom.
In Prolog, any capitalized symbol is a logic variable, any lowercase symbol an atom.
(cons x (cons y t)) instead of [X,Y|T]).
Schelog extensively uses reified Scheme continuations,
which are an expensive feature in Pocket Scheme.
It is possible that some instances of call-with-current-continuation
could be replaced with call-with-escape-continuation
for a performance improvement both in runtime and working-set size.
Pocket Scheme can host Scheme Prolog 1.2, John Cleary et al's implementation of pure Prolog in Scheme.
After editing prolog.ss to specify the location of the sourcefiles, you will need to add the following definitions to compatibility.ss:
(define last-pair last) (define 1+ (lambda (x) (+ x 1))) (define 1- (lambda (x) (- x 1))) (define cpu-time (lambda () 0)) (define flush-output-port force-output) (define list-copy (lambda (x) (append x '())))
This Prolog focuses on interval arithmetic operations, which makes its output for less specialized numeric operations somewhat unintuitive. Consider the following simple Prolog program that calculates the length of a list.
length([], 0). length([_|T], Len) :- length(T, Len0), Len is Len0 + 1.
In Scheme Prolog, you would express this as
(when (length ?L ?N)) (what (length () 0)) (what (length (?H . ?T) ?N) (length ?T ?N0) (add ?N0 1 ?N))
Querying the length of a list (1 2 3)
through this relation via ((length (1 2 3) ?x))
yields the answer (< 3 3 >),
the arithmetic interval whose open lower bound is 3 and open upper bound is 3.
That is, the integer 3.
For purposes of comparison,
Schelog would express the previous length relation like this:
(define %length
(%rel (h t l l0)
(('() 0))
(((cons h t) l) (%length t l0) (%is l (+ l0 1))) ))
and answer the query via (%which (X) (%length '(1 2 3) X)).
Schelog programs are Scheme programs that contain Prolog-style relations and unifications. The Schelog user works from the Scheme prompt, manipulating Scheme expressions. In contrast, Scheme Prolog programs are Prolog programs: the Scheme Prolog user starts from the Scheme prompt, starts the Scheme Prolog program with a database of Scheme Prolog relations, and works from the Prolog ?- prompt thereafter. Hence Scheme Prolog is free to use a somewhat more traditional syntax.
Sometimes a program written to a different Scheme environment needs modification before Pocket Scheme can host it. Here are some of the differences that I've observed.
define-macro,
and includes defmacro in its SLIB support.
If you need a full R5RS syntax-rules macro facility,
consider the Macro By Example implementation within SLIB,
or Macros That Work if you absolutely must have
the let-syntax and letrec-syntax forms.
(do ((i -5 (+ i 0.1))) ((= i 5) (newline)) (display i) (display #\space))
never terminates, due to an accumulation of floating-point arithmetic inaccuracies.
char->integer.
Many applications and libraries contain code
that assumes that it can use the return value of
char->integer as an index into a vector with 256 elements.
So long as that code never encounters characters outside the Latin-1 character
set, this will work;
but once the application migrates to Russia or Japan, it will fail.
Changing such code to index a vector of 65536 elements
is usually not a good idea.
define or define-macro.
Last modified: Wed Apr 05 10:34:09 Pacific Standard Time 2006
Copyright 1998-2006, Ben Goetter. All rights reserved.