PROLOG-REQUEST@SUSHI.STANFORD.EDU.UUCP (03/30/87)
PROLOG Digest Monday, 30 Mar 1987 Volume 5 : Issue 23 Today's Topics: Query - Transliteration, Programming - Programming Errors & Turtles ---------------------------------------------------------------------- Date: 24 Mar 87 18:02:26 GMT From: Michael Maxwell <ssc-vax!bcsaic!michaelm@BEAVER.CS.WASHINGTON.EDU> Subject: Transliterating into Scheme I have a copy of Technical Report #182 from Indiana University, entitled "Transliterating Prolog into Scheme," by Matthias Felleisen (1985). In section 5, he refers to some details regarding "in-line coding of the unification algorithm...[achieved] with the additon of one more syntactic extension." The extension is supposedly exhibited in the appendix. However, my copy of the paper has no appendix. Does anyone know where these "details" are published? Felleisen, are you out there? -- Mike Maxwell ------------------------------ Date: Fri 27 Mar 87 10:04:13-PST From: Ken Laws <Laws@SRI-STRIPE.ARPA> Subject: Prolog Programming Errors I am surprised at the frequency with which code submitted to the Prolog list (e.g., the 91 function) is later shown to be incorrect. Is this because the trivial-appearing applications are really very subtle, or because Prolog is an awkward and unintuitive language for anyone but a Ph.D. logician? I understand that there are problems for which a few lines of Prolog provide a quick and elegant answer, but the same can be said for almost any language. Prolog provides rapid-prototyping capability for database-access problems, and many problems can be viewed in that mold, but is it really a suitable language for ordinary mortals who have to take on whatever programming problems life gives them? -- Ken Laws ------------------------------ Date: 25 Mar 87 14:04:48 GMT From: mcvax!ukc!reading!onion!minster!laukee@seismo.css.gov Subject: Turtles The basic idea came from a colleague's thought that it would be useful to be able to show the progress of instantiations in a goal. To be really useful there needs to be some means of "unshowing" the partial groundings, so that the display is always consistent with a snapshot of the state of the system. Really this program is only an experiment on that concept. It has *lots* of rough edges and *lots* of nasty constructs... However, it does provide an interesting way of "watching" Prolog at work. A much reduced "turtle graphics" environment is presented. (Basically you can tell the turtle to turn 90 deg. clockwise or anticlockwise, and to move forward X steps.) The "interesting" feature is that backtracking over these primitives results in them being undone. For example, I have defined anysq(X) to be four sets of 'forward X steps, turn'. If I try to satisfy 'anysq(4), fail.' then all the possible solutions to: 'anysq(4).', where 'forward (drawing) X' and 'backward (erasing) X' satisfy the goal 'forward X', and 'turn clockwise' and 'turn anticlockwise' satisfy 'turn' are drawn. I wrote the program for C-Prolog 1.5, but it wouldn't require much effort to move it to other Prologs. It *is* terminal specific - I use a Microcolour m2200 in ANSII mode (basically vt100 plus colour) - but again, if your terminal has ANSII features, it won't be a problem to hack it straight. One thing may be worth thinking about: When a line is undrawn it is sometimes helpful to leave a record of it. I cope with this by switching the undo colour from black to white. This is ok on a colour terminal where the lines themselves are other than white, but it would be a bit confusing in monochrome... maybe half-intensity or something? The program is slower than it really needs to be. Previously the undo would act like paint stripper, cutting right down to the black of the background. This version paints in layers, undoing strips off a layer. (Great if you've got a lot of colours.) For a 5-fold speed increase take out the layers. N.b. Unless you have a really clever terminal you can expect strange occurences when the turtle escapes from the screen. When you 'teach' the turtle remember that the clauses are added at the top (so that new tricks can have old names) i.e., enter clauses in reverse order. Use: Cut at the line Name the program "turtle" Enter Prolog and consult turtle (it will "autoboot") ================================CUT=HERE==================================== % % Copyright (c) 1987 by David Lau-Kee, Univ. of York. % % Permission is granted to use or modify this code provided this notice is % included in all complete or partial copies. % redo :- system("${EDITOR-'/bin/vi'} turtle"),reconsult(turtle). rec :- reconsult(turtle). %%%%% % Terminal specific code - for m2200 (basically ANSII plus colour). %%%%% clr :- write('[H[2J'). % Clear the screen and home cursor. clrline :- write('[2K'). % Clear current line - don't move cursor. moveto(X,Y) :- write('['),write(X),write(';'),write(Y),write('H'). % Move cursor to line X, col. Y. restore :- write('8'), !. % Restore cursor previously saved cursor % attributes. save :- write('7'), !. % Save cursor attributes. white :- write('[37m'). % Foreground white. black :- write('[30m'). % Foreground black. cup :- write('[A'). % Cursor motions, up, down, right, left. cdn :- write('[B'). crt :- write('[C'). clt :- write('[D'). colour(0) :- write('[31m'). % Foreground red colour(1) :- write('[32m'). % ,, yellow colour(2) :- write('[33m'). % ,, green colour(3) :- write('[34m'). % ,, blue colour(7) :- black. % Default for undone lines is black. scrollon :- % Set the scrolling region to lines 1 to 22. write('[37m[1;22r'), moveto(23,1), write('-------------------------------------------------------------------------------'). scrolloff :- % Reset standard scrolling region. write('[1;24r'). horiz :- write('-'). % Draw a horizontal mark. vertical :- write('|'). % Draw a vertical mark. %%%%% %%%%% % Turtle : The turns - clockwise and anticlockwise. % The tc2 are backtrack failures. %%%%% turn(c) :- tc1(c). turn(c) :- tc2(c). turn(a) :- tc1(a). turn(a) :- tc2(a). %%%%% tc1(c) :- direction(O), Tmp is O + 1, New is Tmp mod 4, restore, indicate(New),!. tc2(c) :- direction(O), Tmp is O + 3, New is Tmp mod 4, restore, indicate(New),!,fail. tc1(a):- direction(O), Tmp is O + 3, New is Tmp mod 4, restore, indicate(New),!. tc2(a) :- direction(O), Tmp is O + 1, New is Tmp mod 4, restore, indicate(New),!, fail. indicate(0) :- write('^'),clt, setdir(0), !. indicate(1) :- write('>'),clt, setdir(1), !. indicate(2) :- write('v'),clt, setdir(2), !. indicate(3) :- !, write('<'),clt, setdir(3), !. %%%%% % turtle : The lines - may only move forward (i.e., in direction(D)). % The doline2 supplies the failing backtrack. %%%%% forward(N) :- doline1(N). forward(N) :- doline2(N). %%%%% doline1(N) :- restore, drline(N), rest,!. doline2(N) :- restore,drawline(N), rest,!, fail. rest :- direction(N), indicate(N), save,!. calc(X,Y,0,N,X,Ynew) :- Ynew is Y + N. calc(X,Y,1,N,Xnew,Y) :- Xnew is X + N. calc(X,Y,2,N,X,Ynew) :- Ynew is Y - N. calc(X,Y,3,N,Xnew,Y) :- Xnew is X - N. drline(0) :- !. drline(X) :- direction(D), do(D), Y is X - 1,!, drline(Y). drawline(0) :- !. drawline(X) :- direction(O), Tmp is O + 2, D is Tmp mod 4, undo(D), Y is X - 1, !, drawline(Y). do(0) :- pos(X,Y),Ynew is Y + 1,setpos(X,Ynew), asserta(layer(X,Ynew,0)),!,draw(0,0). do(1) :- pos(X,Y),Xnew is X + 1,setpos(Xnew,Y), asserta(layer(Xnew,Y,1)),!,draw(1,1). do(2) :- pos(X,Y),Ynew is Y - 1,setpos(X,Ynew), asserta(layer(X,Ynew,2)),!,draw(2,2). do(3) :- pos(X,Y),Xnew is X - 1,setpos(Xnew,Y), asserta(layer(Xnew,Y,3)),!,draw(3,3). undo(0) :- pos(X,Y),Ynew is Y + 1,setpos(X,Ynew), retract(layer(X,Y,_)),!,undraw(0,X,Y). undo(1) :- pos(X,Y),Xnew is X + 1,setpos(Xnew,Y), retract(layer(X,Y,_)),!,undraw(1,X,Y). undo(2) :- pos(X,Y),Ynew is Y - 1,setpos(X,Ynew), retract(layer(X,Y,_)),!,undraw(2,X,Y). undo(3) :- pos(X,Y),Xnew is X - 1,setpos(Xnew,Y), retract(layer(X,Y,_)),!,undraw(3,X,Y). draw(0,C) :- colour(C),vertical,cup,clt. draw(1,C) :- colour(C),horiz. draw(2,C) :- colour(C),vertical,cdn,clt. draw(3,C) :- colour(C),horiz, clt,clt. undraw(0,X,Y) :- layer(X,Y,D),!, colour(D),line(D),cup,clt. undraw(1,X,Y) :- layer(X,Y,D),!, colour(D),line(D). undraw(2,X,Y) :- layer(X,Y,D),!, colour(D),line(D),cdn,clt. undraw(3,X,Y) :- layer(X,Y,D),!, colour(D),line(D),clt,clt. undraw(N,X,Y) :- !,draw(N,7). line(0) :- vertical. line(1) :- horiz. line(2) :- vertical. line(3) :- horiz. %%%%% % Examples : some undoable examples %%%%% fractal(0) :- !. fractal(N) :- forward(N),turn(X), Next is N - 1,fractal(Next). realsq(N) :- pos(X,Y), direction(D),!, anysq(N), pos(X,Y), direction(D). anysq(X) :- forward(X), turn(A), forward(X), turn(B), forward(X), turn(C), forward(X), turn(D). antisq(X) :- forward(X), turn(a), forward(X), turn(a), forward(X), turn(a), forward(X), turn(a). square(X) :- forward(X), turn(c), forward(X), turn(c), forward(X), turn(c), forward(X), turn(c). allsq(0) :- !. allsq(X) :- Next is X - 1, allsq(Next), square(X). demo1:- square(3),square(5),fail. demo1. demo2:- anysq(5),fail. demo2. demo3:- realsq(5),qfail. demo3. demo4:- fractal(5), fail. demo4. demo:- clean, cmdline,write('noshow, square(3), square(5), fail.'), noshow, demo1, cmdline, write('(more) press <return>'), get0(X), clean, cmdline,write('show, square(3), square(5), fail.'), show, demo1, cmdline, write('(more) press <return>'), get0(X), clean, cmdline,write('noshow, anysq(5), fail.'), noshow, demo2, cmdline, write('(more) press <return>'), get0(X), clean, cmdline,write('show, realsq(5), qfail.'), show, demo3, cmdline, write('(more) press <return>'), get0(X), clean, cmdline,write('fractal(6).'), fractal(6), cmdline, write('(more) press <return>'), get0(X), clean, cmdline,write('noshow, fractal(5), fail.'), noshow, demo4, cmdline, write('(more) press <return>'), get0(X), clean, cmdline,write('show, fractal(5), fail.'), show, demo4, cmdline, write('press <return> to continue'), get0(X), clean. %%%%% %%%%% % Terminal : The following clauses comprise the terminal handler % and the turtle "driver". %%%%% clean :- clr, retractall(layer(_,_,_)), scrollon,restore,centre,initstat. tidy :- scrolloff, clr. setpos(X,Y) :- retractall(pos(_,_)), asserta(pos(X,Y)), status. setdir(D) :- retractall(direction(_)), asserta(direction(D)), status. status :- save, direction(D), pos(X,Y), white, moveto(1,12),write('('), write(X),write(','),write(Y),write('). '), moveto(1,42),write(D),write('.'), restore. initstat :- save, white, moveto(1,1),clrline,moveto(1,1), write('Position : '),moveto(1,30),write('Direction : '), restore, status. show :- asserta((colour(7) :- white,!)). noshow :- asserta((colour(7) :- black,!)). centre :- direction(D), moveto(12,40),setpos(0,0), save, indicate(D). cmdline :- moveto(24,1), clrline, moveto(24,1), white, write('$ '),!. run :- scrollon, setdir(0), centre, initstat, readeval, scrolloff. turtle(Outfile) :- tell(Outfile), turtle, told(Outfile). turtle :- asserta(pos(0,0)),asserta(direction(0)), clr,run. %%%%% %%%%% % Interpreter : The Pogo readeval loop %%%%% retractall(X) :- retract(X), fail. retractall(X) :- retract((X :- Y)), fail. retractall(_). flush :- get0(X), not(X = 10), flush. flush. qfail :- save, cmdline, write('Ok? y/n <return> '), get(X), flush, restore, ok(X). ok(121) :- !. ok(_) :- fail. process(go) :- clr, clean, readeval. process(X) :- asserta(X), dofun(teach). dofun(end) :- write('Ok, program ending'), nl. dofun(teach) :-!, clrline, write('Clause: '),read(X),!,process(X). dofun(X) :- X,!, readeval. dofun(_) :- readeval. readeval :- cmdline, read(F), dofun(F). %%%%% help :- tidy, write(' Help'), nl,nl, write('end. : End the session and exit Prolog.'),nl, write('redo. : Make changes to the program file, then reconsult it.'), nl, write('rec. : Reconsult the program file.'),nl, write('clr. : Clear the screen.'),nl, write('clean. : Clean up the drawing area.'),nl, write('tidy. : Clear the screen and turn off the drawing area.'),nl, write('teach. : Prepare to assert Prolog clauses (n.b. these are asserted at'),nl, write(' the head of the clause-base). Type "go" to continue the '),nl, write(' session.'),nl, write('qfail. : Query fail. Asks user whether or not to fail.'),nl, write('demo. : A demonstration of a busy turtle.'),nl,nl,nl, write('Type "clean." to clean up the drawing area.'). :- clr, write(' This is the Prolog turtle program.'), nl, nl, write('The turtle knows how to: turn(c) [clockwise]'), nl, write(' turn(a) [anticlockwise]'), nl, write(' and forward(X) [move forward X places].'), nl,nl, write('You can teach it how to do more complicated things by combining these'), nl, write('primitive actions... For example, it already knows how to square(X), and'), nl, write('fractal(X).'), nl,nl, write('For more interesting effects you can try inserting fails into your drawings.'), nl, write('If a forward(X) clause fails then a second clause is attempted. This'), nl, write('second clause has the effect of undoing the marks made by the first clause.'), nl, write('A similar undoing effect takes place for turn(a) and turn(c).'), nl,nl, write('If you use qfail instead of fail then you will be prompted as to whether or not'), nl, write('that particular clause really should fail. For example, try realsq(4),qfail'), nl, write('realsq(4) will try to draw a square of size 4, the qfail will prompt for'), nl, write('acceptability. If you answer "n" then the program will try to resatisfy'), nl, write('realsq(4).'), nl. ?- read(Continue). [return]. :- clr, write('For now the undone lines will be drawn in black. You can change this by'), nl, write('teaching the program otherwise (or simply type "show." or "noshow." for'), nl, write('white or black undone lines).'), nl, nl, write('If you type "help" in response to the $ prompt information on other useful'), nl, write('clauses will be given.'), nl, write('If you type "end" in response to the $ prompt you will leave Prolog'), moveto(23,40), write('Dave Lau-Kee, February 1987'), moveto(15,1). ?- read(Continue). [return]. :- turtle, halt. ------------------------------ End of PROLOG Digest ********************