pedagogy

80 views
Skip to first unread message

Anne Ogborn

unread,
Feb 4, 2019, 4:15:36 AM2/4/19
to SWI-Prolog Mailing List
A couple small proposals to aid teaching Prolog.

1. It would be very nice to have a couple of write forms that showed the underlying representation of a term.
students in particular get confused by operators. So, a variant of write_canonical, say write_pedagogical,
that never makes operators infix, never uses ellipses, and expands lists as '[|]'/2 - and write_pedagogy_lists that does the same but shows lists in their normal form.

putting these in the system means they're available reliably when teaching, without distracting student.

2. It would be nice to have a mode in the console to allow entering a predicate. Haskell's ghci environment uses
   *Main> :{
   *Main| let askname = do
   *Main|               putStrLn "What is your name?"
   *Main|               name <- getLine
   *Main|               putStrLn $ "Hello " ++ name
   *Main| :}
   *Main>

Presumably the module would be user.

Michael Ben Yosef

unread,
Feb 5, 2019, 2:50:54 AM2/5/19
to SWI-Prolog
On Monday, 4 February 2019 11:15:36 UTC+2, Anne Ogborn wrote:
A couple small proposals to aid teaching Prolog.

1. It would be very nice to have a couple of write forms that showed the underlying representation of a term.
students in particular get confused by operators. So, a variant of write_canonical, say write_pedagogical,
that never makes operators infix, never uses ellipses, and expands lists as '[|]'/2 - and write_pedagogy_lists that does the same but shows lists in their normal form.

putting these in the system means they're available reliably when teaching, without distracting student.

This is what write_canonical/1 is supposed to do according to the standard and what it used to do in SWI-Prolog before version 7 and what it does in other Prologs, for example:

$ yap
% Restoring file /usr/lib/Yap/startup.yss
YAP 6.2.2 (i686-linux): Fri Mar 17 01:33:14 UTC 2017
   ?- write_canonical([foo, bar]).
'.'(foo,'.'(bar, []))yes
   ?-

I recall a discussion on the then-mailing-list, mostly between Richard O'Keefe and Jan about what SWI should do to preserve interoperability of canonical syntax when SWI was switching to '[|]'/2 instead of '.'/2 for the list functor. I'm too lazy to search for it in the archives, but my guess is that Jan decided to write lists in standard notation that could be read back by any Prolog rather than write the SWI-Prolog specific '[|]'/2 functor.

2. It would be nice to have a mode in the console to allow entering a predicate. Haskell's ghci environment uses
   *Main> :{
   *Main| let askname = do
   *Main|               putStrLn "What is your name?"
   *Main|               name <- getLine
   *Main|               putStrLn $ "Hello " ++ name
   *Main| :}
   *Main>

Presumably the module would be user.

Most Prologs since DEC-10 Prolog have had this, including SWI-Prolog. You enter

[user].

at the query prompt, i.e. "consult user", then type your clauses followed by end-of-file (Ctrl+D on UNIX). It's mentioned (briefly) in the manual: http://www.swi-prolog.org/pldoc/doc_for?object=consult/1

Boris Vassilev

unread,
Feb 5, 2019, 3:59:59 AM2/5/19
to SWI-Prolog
Hi, I don't know how much of a hack this is, but I put together this small module to override the way that lists and terms are printed. It seems to do what Anne is after. Not sure.

~~~
$ cat pedagogical.pl
:- module(pedagogical, []).

:- multifile user:portray/1.

user:portray(L) :- is_list(L),
    L = [H|T],
    format("'[|]'(~p,~p)", [H,T]).
user:portray(C) :- compound(C),
    compound_name_arguments(C, Name, [A|Args]),
    format("~p(~p", [Name, A]),
    forall(member(X, Args), format(",~p", [X])),
    format(")").
~~~

To use it, just use use_module:

~~~
$ swipl -q
?- use_module(pedagogical).
true.

?- numlist(1, 3, L).
L = '[|]'(1,'[|]'(2,'[|]'(3,[]))).

?- length(L, 3).
L = '[|]'(_2752,'[|]'(_2758,'[|]'(_2764,[]))).

?- X = a + b / [foo,bar,baz].
X = +(a,/(b,'[|]'(foo,'[|]'(bar,'[|]'(baz,[]))))).

?- [a+b,a-b,x^2,-3] = X.
X = '[|]'(+(a,b),'[|]'(-(a,b),'[|]'(^(x,2),'[|]'(-3,[])))).
~~~


--
You received this message because you are subscribed to the Google Groups "SWI-Prolog" group.
To unsubscribe from this group and stop receiving emails from it, send an email to swi-prolog+...@googlegroups.com.
Visit this group at https://groups.google.com/group/swi-prolog.
For more options, visit https://groups.google.com/d/optout.

Boris Vassilev

unread,
Feb 5, 2019, 5:01:16 AM2/5/19
to SWI-Prolog
Two comments:

- in the code above, the first clause is of course completely unnecessary.
- there seems to be a limit to how deeply nested calls to portray can be. Try, for example, length(L, 99) and length(L, 100).

Anne Ogborn

unread,
Feb 5, 2019, 8:41:31 PM2/5/19
to SWI-Prolog, Michael Ben Yosef
write_canonical does help with operators, but yes, it'd be useful if there was a form that expanded a list.

If interop is a problem, maybe add write_very_canonical that does '[|]'

Anne Ogborn

unread,
Feb 5, 2019, 9:09:27 PM2/5/19
to SWI-Prolog Mailing List

My reason for wanting whatever solution we come up with to be in the system and to autoload is that
it's usually being used by a complete beginner.

At functional conf I had students implement complex arithmetic. Discovered that they were quite baffled by operators.

Jan Wielemaker

unread,
Feb 6, 2019, 3:03:09 AM2/6/19
to Anne Ogborn, SWI-Prolog, Michael Ben Yosef, swip...@discoursemail.com
[Cc'ed to new forum]

On 06/02/2019 02:41, 'Anne Ogborn' via SWI-Prolog wrote:
> write_canonical does help with operators, but yes, it'd be useful if there was a form that expanded a list.
>
> If interop is a problem, maybe add write_very_canonical that does '[|]'

You can write lists in the standard canonical representation using

1 ?- write_term([a,b,c], [dotlists(true)]).
.(a,.(b,.(c,[])))

This is a very poor format. Not only does it exhibit something that
should IMO have remained hidden, but reading this is really expensive
as you only know that the .(a, ...) reduces to a ./2 cell and not a
./3 or more cell at the very end. This implies you have to carry
around a lot of information while parsing such lists. Compare that
with [a,b,c] where you can reduce after every comma.

Now working with XSB which arrived rather late on the ISO
standardization. They apparently never bothered with this and
simply write [a,b,c] for a list using write_canonical/1.

Cheers --- Jan


Reply all
Reply to author
Forward
0 new messages