Instructor's Guide
intro,
components,
case study,
crossing boundaries,
styles,
platform,
summary,
Q/A,
literature
Knowledge is a substantial ingredient in many applications.
By knowledge we mean information and rules
operating on that information, to obtain derived information.
As in any (software) engineering effort, maintenance,
that is knowledge maintenance, is of crucial importance.
When we do not avoid the dispersion of knowledge and information
in the actual code of the system, maintenance will
be difficult.
Put differently, for reasons of flexibility and maintenance
we need to factor out the (volatile) knowledge and information
components.
Traditionally, the information components are often
taken care of by a database that allows
for the formulation of views to obtain (possibly aggregate)
information.
Logic or logic programming is a strictly more powerful
mechanism to deal with information and knowledge.
In our group, we have been studying the use of logic programming
in knowledge-intensive software engineering applications.
<query kit=pl src=local.pl cmd=X:email_address(X)>
<param format=" \%s">
<param result="">
<param display="<h4>The query</h4>">
<param header="<h4>The adresses</h4> <ul>">
<param footer="</ul>">
email_address(E) :-
person(X),
property(X,name:N),
property(X,familyname:F),
email(X,E),
cout(['', N,' ',F,' has email adress ']),
cout([ '<a href=mailto:', E, '>', E, '</a>',nl]).
</query>
As an example, consider the query above,
which is expressed in an SGML/XML like syntax.
The query command X:email_address(X) asks
for all X for which the predicate email_address(X)
holds. The predicate email_address is defined between
the query begin and end tags.
The query tag is an element of one of the
text processing filters to provide
hypermedia
support for software engineering described
in [HypermediaSE].
Processing the fragment above results in an HTML list
of names and email addresses.
The collection of filters itself is written in
lex, yacc and C++.
To process the query, an embedded logic programming interpreter
is invoked.
To merge the output from the query, a handler is installed
for the cout command.
The query example was motivated by the need to maintain
Web pages for the administration of a colloquium
within our group.
The actual knowledge base consists of a list of people
and some rules to determine their affiliations
and email addresses.
The knowledge base is made available by
consulting the file local.pl.
As concerns the implementation,
the Java fragment below indicates how to access the logic
programming interpreter from a (Java) program.
query pl = new query("kit=pl src=remote.pl");
pl.eval("X:assistant(X)");
String res = null;
while ( (res = pl.result()) != null ) {
System.out.println(" " + res);
}
After creating a query object,
the goal X:assistant(X) is invoked,
which can be taken to mean, give me every X for
which the predicate assistant(X) holds.
The final output is obtained by iterating over the results
of the evaluation of that goal.
As a comment, multiple results may be obtained
in Prolog by backtracking over the possible choice points.
Distributed knowledge servers
Maintaining knowledge is difficult.
As a rule of thumb, avoid the replication of knowledge
as much as possible.
However, this means that we may need to access
knowledge from remote sources.
One (obvious) solution that presents itself is to allow
for url-enabled consults,
as illustrated in the fragment below.
:- source('www.cs.vu.nl/~eliens/db/se/people.pl').
:- source('www.cs.vu.nl/~eliens/db/se/institute.pl').
:- source('www.cs.vu.nl/~eliens/db/se/property.pl').
:- source('www.cs.vu.nl/~eliens/db/se/query.pl').
This solution has (indeed) be implemented in our filters,
since the url addressing scheme is straightforward
and easy to implement.
However, processing the information accessed by url
is still done locally.
So, the next step that may be suggested is to
distribute the knowledge processing itself,
for example by using CORBA.
interface query {
void source(in string file);
long eval(in string cmd);
string result(in long id);
oneway void halt();
};
Exploiting the integration of CORBA and hush,
we have defined an interface for query
in IDL and implemented query client and query server objects.
These objects may be created by giving appropriate
parameters to the query constructor invocation.
This approach allows for embedding remote knowledge processing
transparently in our collection of filters.
Nevertheless, although we showed that this approach is feasible,
we have not addressed the problems that may occur
due to the unavailability or faults of the server.