Overview

A web-based ontology editor uses HTML pages to support browsing and editing a knowledge base. Several are mentioned here and here.

In these exercises, we start with a Lisp image containing a knowledge base, i.e., a set of defined MOPs. The exercises begin the simplest possible way to display a single given MOP, then improve on that interface to be more readable, then to allow easy one-click browsing, and finally to allow MOPs to be defined or redefined by changing fields on a web page.

These exercises require:

The Exercises

When submitting these exercises, use the heading as the Subject line, e.g., the first exercise should be submitted with the Subject line "MopEd #1: show-frame browser."


MopEd #1: show-frame browser

Use AServe to publish the Mop Browser with the URL /cs325/mop_browser. The Mop Browser lets a user browse a MOP memory.

Use an interface similar to the Lisp Evaluator example in test-aserve.lisp. The input area should be a simple 1-line text field, and the button should say Show. If you type the name of a MOP in the input field and click Show, the MOP's content should be displayed below. Use show-frame to display the MOP.

Test with the memory examples in mop-examples.lisp.

Submit: The function(s) you defined that create the HTML form and show the MOP.

MopEd #2: mop-html browser

Change the Mop Browser to display MOP's using an HTML table. Design a simple readable tabular format that shows the name of the MOP, the immediate ancestors of the MOP, and the non-inherited slots (roles and fillers) of the MOP. Do this by defining a function (not a macro) (mop-html mop-name) that uses the AServe html macro to print HTML.

Nesting printing calls inside printing calls requires careful thought about which things get evaluated and printed when in html forms.

Test with the memory examples in mop-examples.lisp. You can test your code at the Listener level using (html-stream *standard-output* ...). html-stream is described in the AServe documentation.

Submit: The function mop-html and any helper functions you defined that it uses. Do not send the code that makes the form.

MopEd #3: Clickable mop-html browser

Upgrade mop-html so that the HTML it generates for a MOP has links:

Note that some fillers are not MOP's, e.g., the filler for :AGE is a number, not a MOP. An ancestor is not a MOP if no MOP has been defined for the ancestor. If a filler or ancestor is not a MOP, there should not be a clickable link.

Test with the memory examples in mop-examples.lisp.

Submit: The function mop-html and any helper functions you defined that it uses.

MopEd #4: MOP menu

Replace the text input field with a drop-down list of all MOP's in memory. These lists are generated in HTML with SELECT and OPTION.

Submit: The function(s) you defined to that create the HTML form.

MopEd #5: MOP Editor Display

Now define a MOP editing interface based on this sample page. This page has some simple Javascript that lets you edit fields and copy MOP names into fields. To do the latter, select one of the "Existing MOPs" and then click the Use MOP in any row to put the MOP there. If you click Cancel Changes, the fields will go back to their original values.

If you click on Use MOP in the "MOP Name" row, the page is reloaded, but look at the URL. It should end with "?source=mop-name" where the MOP name is the one you selected. This is called a "search URL." In AllegroServe, this causes the MOP name to be stored in the request variable source.

Publish a new URL, /cs325/mop_editor. It should call the function edit-mop.

Define edit-mop to generate a page like the sample page, including the Javascript. edit-mop should show the name, abstractions and slots for the MOP given by the source request variable. If source is not specified, the page should show the first MOP in memory. Make sure to add an empty abstraction row and slot row, as the sample page shows.

Don't worry about Store Changes. Just write the code so that the right MOP data is displayed in the MOP editor interface.

Send edit-mop and any functions you defined that it calls. Don't send any functions reused from the MOP browser.

MopEd #6: MOP Editor Update

Now fix it so that clicking Store Changes does the following defines a MOP with the name, abstractions, and slots specified by the current values of the fields in the form. A slot with an empty role or filler should be ignored.

NOTE: Store MOPs with add-frame. Don't make an DEFMOP and call eval. That would require calling the compiler to create a MOP or instance. It would also require any deployed application would have to include the Lisp compiler..

There's one other tricky bit of logic. There's three ways this form might get called:

You'll need to change the opening <FORM> tag to read:

<form name="mainForm" method="post" 
action="/cs325/mopedit">

MopEd #7: MOP Editor Persistence

The last big thing you need to add to your editor is the ability to make your changes persistent. Currently, all your changed MOPs only exist in the current Lisp server image. You need to save those MOPs to a file that will be reloaded when your server restarts.

Add code to write all MOPs that have been changed to a file. Every time the user clicks Store Changes, the file of changed MOPs should be re-written. This is to save changes in case the server or browser crashes. Because there might be mistakes, and because you don't want to write every single MOP to a file when only a few have changed, this file should be separate from your master file of MOPs, i.e., it should not be mop-examples.lisp.

Commonly in situations like this, an administrator will go through the changed MOPs, check for errors, and, if there are no problems, move the changed MOPs to the master file.

Whatever file of code builds your server should load the master files then the file of changes. You'll need to keep a list or table of what MOPs have changed, and it should always include everything in the file of changed MOPs.


Comments? Send mail to Chris Riesbeck.