![]() |
![]() |
|

Flexible Output
You have now seen some simple examples which built up from an initial, "Hello World" program, through one which can backtrack through solutions, into one which let you add your own cases dynamically. However, all these programs limited their output to simple substitutions, where a label, such as "{:hello:}", was replaced with a phrase such as, "Bonjour le Monde".

With this next example, you will see that you can go further, displaying whatever you like on your web pages. This example of a classic Prolog program demonstrates the ease of use and flexibility of Weblog output.
John Likes Mary
Well, we all knew that, didn't we! From the earliest days of teaching Prolog, the "X likes Y" example has appeared in some form or another in every Prolog text book. And here is our simple version, ready for exploring and modifying on Weblog.
As you found out on the previous page, your Weblog application can use assert/1 and retract/1 to modify its coding at runtime. This next example does likewise, but with a twist: the program being modified is not just a look-up table of greetings that you can extend; it consists of a mixture of facts and rules.
This time, as well as adding more cases to the facts, you can also selectively delete them, and the best bit of all, is that you are shown the whole "X likes Y" program as a listing, just as you would see on a classic Prolog console if you typed the command, "?- listing.", so that you can keep track of what you've been doing. And without further ado, here is the "John Likes Mary" program in full, complete (at last!) with some comments:
:- dynamic likes/2. % call "likes(X,Y)", and show the results one at a time on a web page weblog :- listing( likes ) ~> List, ( likes( X, Y ), submit( 'likes_1.htm', [(x,X),(y,Y),(list,List)] ), getarg( choice, `done` ) -> submit( 'likes_2.htm', [(say,`You Stopped Me`),(list,List)] ) ; submit( 'likes_2.htm', [(say,`No More Results`),(list,List)] ) ), what_next. % see if the user wants to add or delete a case, and add it if so what_next :-getarg( choice, More ), ( More = `add` -> getarg( x, XS ), getarg( y, YS ), stratm( XS, X ), stratm( YS, Y ), asserta( likes(X,Y) ) ; More = `delete` -> getarg( x, XS ), getarg( y, YS ), stratm( XS, X ), stratm( YS, Y ), retractall( likes(X,Y) ) ; More = `continue` ), weblog. % the classic prolog example: what john and mary like likes( john, mary ). likes( john, food ). likes( mary, wine ). likes( mary, john ). likes( john, Something ) :- likes( mary, Something ).
Shedding Light
As usual, weblog/0 is the application's entry point, and here, the first thing it does is to perform a Prolog "listing" into the variable, "List". Next, it calls the "likes/2" program to generate a solution, and it shows this solution, together with the program listing, using this HTML page, "likes_1.htm":
<html> <head> <title>John Likes Mary Page 1</title> </head> <body> <h2>John Likes Mary Page 1</h2> <p>This is a listing of the "John Likes Mary" program so far:</p> <pre>{:list:}</pre> <p>And here is a solution:</p> <h3>{:x:} likes {:y:}</h3> <form name="likes" method="get" action="/weblog/likes.exe"> <input type="submit" name="choice" value="more"/> <input type="submit" name="choice" value="done"/> </form> </body> </html>
Preformatted Output
By using a "<pre>" element, the program listing is shown, correctly formatted, just as it would be on a Prolog console. Although a very simple illustration, this example shows how easily you can produce any kind of output in Weblog.
The form on this HTML page gives you just two options, "more", which causes backtracking, or "done", which stops generating solutions. Either when you hit "done", or you hit "more", but there are no more solutions, an appropriate message ("You Stopped Me" or "No More Results" respectively) is shown in a second HTML page, "likes_2.htm":
<html> <head> <title>John Likes Mary Page 2</title> </head> <body> <h2>John Likes Mary Page 2</h2> <p>This is a listing of the "John Likes Mary" program so far:</p> <pre>{:list:}</pre> <h3>{:say:}</h3> <p>Now you can add or delete some cases for "X likes Y", or simply continue <form name="likes" method="get" action="/weblog/likes.exe"> <input type="text" name="x" value="" placeholder="type X here"/> <input type="text" name="y" value="" placeholder="type Y here"/> <input type="submit" name="choice" value="add"/> <input type="submit" name="choice" value="delete"/> <input type="submit" name="choice" value="continue"/> </form> </body> </html>
What Next?
After displaying the message as described above, this program calls a new predicate, which has been called "what_next/0". This, in turn, calls "getarg/2" to pick up the "choice" field from the form in likes_2.htm.
If the choice returned was "add", the program then calls getarg/2 twice more, to pick up the "x" and "y" fields, and asserts a new case for likes/2 with a call to "asserta/1". Similarly, if the choice was "delete", the program again calls getarg/2 to collect the "x" and "y" fields, and attempts to retract the given case with a call to "retractall/1". Finally, if the choice was "continue", it does nothing to the likes/2 predicate.
In all three cases, "what_next" starts the whole program over, with whatever modifications have been made, by calling weblog/0.
Flexible Ouptut with Weblog
There we have it: Weblog runs just like regular Prolog, and can be used to display anything you might see on a normal Prolog console; it supports backtracking, dynamic programming, and most anything else you can do in Prolog, with absolutely no special coding tricks required, apart from knowing about "submit/2" and "getarg/2".
In the pages that follow, you will see some more detailed examples, combining the simplicity of Prolog with web pages created with a variety of packages, including DreamWeaver and Photoshop, to give you a better flavour of what is possible with Weblog.
Click here to run the "John Likes Mary" example
Click on the buttons to find out more, or jump directly to any of these links:
![]() |
![]() |
![]() |
Direct Link | Example Name |
---|---|
One Shot Program | "Hello World" |
Input and Backtracking | "Bonjour Le Monde" |
Learning and Storage | "Teach Me" |
Flexible Output | "John Likes Mary" |
Tables and Forms | "Family Tree" |
Photoshop and Images | "Lunar Phase" |
Illustrator and Prolog | "Big Ben Time Check" |
DreamWeaver and VisiRule 2 | "Lawns" |