# Some ideas on how to present our PEG examples

**URL:** <https://discourse.prolog-lang.org/t/some-ideas-on-how-to-present-our-peg-examples/131>\
**Category:** Teaching Prolog\
**Created:** [December 17, 2024, 3:14pm UTC](https://discourse.prolog-lang.org/t/some-ideas-on-how-to-present-our-peg-examples/131 "2024-12-17T15:14:28Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![herme](https://discourse.prolog-lang.org/user_avatar/discourse.prolog-lang.org/herme/32/27_2.png) [@herme](https://discourse.prolog-lang.org/u/herme)\
**Post date:** [December 17, 2024, 3:14pm UTC](https://discourse.prolog-lang.org/t/some-ideas-on-how-to-present-our-peg-examples/131/1 "2024-12-17T15:14:28Z")

</div>

These are some ideas on several ways in which we can present the Prolog examples developed within PEG, as background material for our discussions:

1. A simple and standard way is to simply save them in a **code repository** (gitlab,  
github, etc.).

2. If we want to _present_ them in a more user-friendly way, these are  
some possible options:

- Other issues:

---

<div class="post-metadata">

**Author:** ![herme](https://discourse.prolog-lang.org/user_avatar/discourse.prolog-lang.org/herme/32/27_2.png) [@herme](https://discourse.prolog-lang.org/u/herme)\
**Post date:** [December 17, 2024, 6:56pm UTC](https://discourse.prolog-lang.org/t/some-ideas-on-how-to-present-our-peg-examples/131/2 "2024-12-17T18:56:22Z")

</div>

This is a **links version** of the example page: contains the **examples** with **links to execution in several Prologs**.

# An example:

Consider the factorial example, using Peano arithmetic, that we saw in the first part of the course:

```prolog
factorial(0,s(0)).
factorial(s(N),F) :-
    factorial(N,F1),
    times(s(N),F1,F).

```

This version is very attractive:

- It is fully reversible!
- But also inefficient…

However, we can also code it using ISO-Prolog arithmetic, i.e., `is/2`:

```prolog
 ... Z is X * Y ... 

```

Note that this type of arithmetic has limitations: it only works in  
one direction, i.e., `X` and `Y` must be bound to  
arithmetic terms.

But it provides a (large!) performance gain. Also, meta-logical tests  
(see later) allow using it in more modes.

The factorial program can be encoded using `is/2` as follows:

⏵ **[SWI](https://swish.swi-prolog.org/?code=factorial(0%2C1).%20%0Afactorial(N%2CF)%20%3A-%0A%20%20%20%20N%20%3E%200%2C%0A%20%20%20%20N1%20is%20N-1%2C%0A%20%20%20%20factorial(N1%2CF1)%2C%0A%20%20%20%20F%20is%20F1*N.%0A%0A%25%20Try%20it%3A%0A%25%20%3F-%20factorial(20%2CF).%0A%25%0A%25%20Now%20it%20works%20even%20for%20very%20large%20numbers%3A%20%0A%25%20%3F-%20factorial(100%2CF).%0A%25%0A%25%20But%20it%20does%20not%20run%20%22backwards%22%3A%0A%25%0A%25%20%3F-%20factorial(N%2C40320).%0A)** ⚙ **[Ciao](https://ciao-lang.org/playground/?code=%3A-%20module(_%2C_).%0A%0Afactorial(0%2C1).%20%0Afactorial(N%2CF)%20%3A-%0A%20%20%20%20N%20%3E%200%2C%0A%20%20%20%20N1%20is%20N-1%2C%0A%20%20%20%20factorial(N1%2CF1)%2C%0A%20%20%20%20F%20is%20F1*N.%0A%0A%25%20Try%20it%3A%0A%25%20%3F-%20factorial(20%2CF).%0A%25%0A%25%20Now%20it%20works%20even%20for%20very%20large%20numbers%3A%20%0A%25%20%3F-%20factorial(100%2CF).%0A%25%0A%25%20But%20it%20does%20not%20run%20%22backwards%22%3A%0A%25%0A%25%20%3F-%20factorial(N%2C40320).%0A&ext=.pl)** ⚙ **XSB** ⚙ … (i.e., here we would put links to run in different Prologs,  
maybe with slightly different code)

```prolog
:- module(_,_). 

factorial(0,1). 
factorial(N,F) :-
    N > 0,
    N1 is N-1,
    factorial(N1,F1),
    F is F1*N.

% Try it:
% ?- factorial(20,F).
%
% Now it works even for very large numbers: 
% ?- factorial(100,F).
%
% But it does not run "backwards":
%
% ?- factorial(N,40320).

```

Note that wrong goal order can raise an error (e.g., moving the last  
call to `is/2` before the call to factorial). We can solve this using constraints:

⏵ **[SWI](https://swish.swi-prolog.org/?code=%3A-%20use_module(library(clpq)).%0A%0Afactorial(0%2C1).%20%0Afactorial(N%2CF)%20%3A-%0A%20%20%20%20%7B%20N%20%3E%200%2C%0A%20%20%20%20%20N1%20%3D%20N-1%0A%20%20%20%20%7D%2C%0A%20%20%20%20factorial(N1%2CF1)%2C%0A%20%20%20%20%7B%20F%20%3D%20F1*N%0A%20%20%20%20%7D.%0A%0A%25%20And%20now%20it%20runs%20in%20both%20directions%2C%20and%20more%20efficiently%20than%20Peano%3A%20%0A%25%20%0A%25%20%3F-%20factorial(8%2CF).%0A%25%20%0A%25%20%3F-%20factorial(N%2C40320).)** ⚙ **[Ciao](https://ciao-lang.org/playground/?code=%3A-%20module(_%2C_).%0A%3A-%20use_package(clpq).%0A%0Afactorial(0%2C1).%20%0Afactorial(N%2CF)%20%3A-%0A%20%20%20%20N%20.%3E.%200%2C%0A%20%20%20%20N1%20.%3D.%20N-1%2C%0A%20%20%20%20factorial(N1%2CF1)%2C%0A%20%20%20%20F%20.%3D.%20F1*N.%0A%0A%25%20And%20now%20it%20runs%20in%20both%20directions%2C%20and%20more%20efficiently%20than%20Peano%3A%20%0A%25%20%0A%25%20%3F-%20factorial(8%2CF).%0A%25%20%0A%25%20%3F-%20factorial(N%2C40320).&ext=.pl&ext=.pl)** ⚙ **XSB** ⚙ …

```prolog
:- module(_,_).
:- use_package(clpq).

factorial(0,1). 
factorial(N,F) :-
    N .>. 0,
    N1 .=. N-1,
    factorial(N1,F1),
    F .=. F1*N.

% And now it runs in both directions, and more efficiently than Peano: 
% 
% ?- factorial(8,F).
% 
% ?- factorial(N,40320).

```

---

<div class="post-metadata">

**Author:** ![herme](https://discourse.prolog-lang.org/user_avatar/discourse.prolog-lang.org/herme/32/27_2.png) [@herme](https://discourse.prolog-lang.org/u/herme)\
**Post date:** [December 17, 2024, 7:00pm UTC](https://discourse.prolog-lang.org/t/some-ideas-on-how-to-present-our-peg-examples/131/3 "2024-12-17T19:00:39Z")

</div>

This is a **plain version** of the example page: contains **just the examples** , with **no links or executable cells**.

## A factorial example:

Consider the factorial example, using Peano arithmetic, that we saw in the first part of the course:

```prolog
factorial(0,s(0)).
factorial(s(N),F) :-
    factorial(N,F1),
    times(s(N),F1,F).

```

This version is very attractive:

- It is fully reversible!
- But also inefficient…

However, we can also code it using ISO-Prolog arithmetic, i.e., `is/2`:

```prolog
 ... Z is X * Y ... 

```

Note that this type of arithmetic has limitations: it only works in  
one direction, i.e., `X` and `Y` must be bound to  
arithmetic terms.

But it provides a (large!) performance gain. Also, meta-logical tests  
(see later) allow using it in more modes.

The factorial program can be encoded using `is/2` as follows:

```prolog
:- module(_,_).

factorial(0,1). 
factorial(N,F) :-
    N > 0,
    N1 is N-1,
    factorial(N1,F1),
    F is F1*N.

```

Try it:

```prolog
?- factorial(20,F).

```

Now it works even for very large numbers:

```prolog
?- factorial(100,F).

```

But it does not run “backwards”:

```prolog
?- factorial(N,40320).

```

Note that wrong goal order can raise an error (e.g., moving the last  
call to `is/2` before the call to factorial). We can solve this using constraints:

```prolog
:- module(_,_).
:- use_package(clpq).

factorial(0,1). 
factorial(N,F) :-
    N .>. 0,
    N1 .=. N-1,
    factorial(N1,F1),
    F .=. F1*N.

```

And now it runs in both directions, and more efficiently than Peano:

```prolog
?- factorial(8,F).

```

```prolog
?- factorial(N,40320).

```

---

<div class="post-metadata">

**Author:** ![JanWielemaker](https://discourse.prolog-lang.org/user_avatar/discourse.prolog-lang.org/janwielemaker/32/24_2.png) [@JanWielemaker](https://discourse.prolog-lang.org/u/JanWielemaker)\
**Post date:** [December 18, 2024, 10:47am UTC](https://discourse.prolog-lang.org/t/some-ideas-on-how-to-present-our-peg-examples/131/4 "2024-12-18T10:47:24Z")

</div>

Possibly one additional data point to consider is the work by Peter Flach and Kacper Sokol for their publishing of “Simply Logical”. Citing [Simply Logical — Simply Logical](https://book.simply-logical.space/src/simply-logical.html)

> The online edition of the book is hosted on [_GitHub Pages_](https://book.simply-logical.space). It is built with [Jupyter Book](https://jupyterbook.org/) and [SWISH](https://swish.swi-prolog.org/), the online version of [SWI-Prolog](https://swi-prolog.org/). It follows the structure of the original print version, with minor corrections and additions as explained in the [Preface to the online edition](https://book.simply-logical.space/src/text/0_preface/_preface.html#part-preface). A brief description of how the online edition came to be is posted on [arXiv](https://arxiv.org/abs/2208.06823).

This looks like a really professional way to create educational content. While it currently uses SWISH as backend, I suspect it should be fairly easy to offer multiple backends. I have only been (very) remotely involved in this work though and I do not know the technical details of the backend integration. Merely ensured it was up 🙂

---

<div class="post-metadata">

**Author:** ![herme](https://discourse.prolog-lang.org/user_avatar/discourse.prolog-lang.org/herme/32/27_2.png) [@herme](https://discourse.prolog-lang.org/u/herme)\
**Post date:** [December 18, 2024, 11:27am UTC](https://discourse.prolog-lang.org/t/some-ideas-on-how-to-present-our-peg-examples/131/5 "2024-12-18T11:27:46Z")

</div>

Hi Jan, yes, indeed Sphinx is a good solution and there are more of course (e.g., the related jupyter notebooks integration with SICStus Prolog, etc.). I think a first objective in our context, as Prolog Education Group, is to simply agree on a means through which anyone in the group can easily provide examples and materials, in a way that can be easily stored and modified, and commented on, and that is as system-agnostic as possible. We are using already this discourse and gitlab/github repos for the web site. The idea would be to use those and, from there, as you mention, it is easy to generate materials in different formats. Regarding books, in the case of the Flach/Sokol book the hard work is already done: the examples are already in Prolog, so it is relatively easy to generate versions using other Prologs. For other books where the material is not already in Prolog or is not in suitable form this has to be done.
