Chapter 4: Ingres domain function / mediator example.
-
4.1 -- Introduction: This chapter serves to explain
the Hermes language syntax and function while examining some features
implemented in, and tracing a sample query execution for, the Ingres
relational database domain.
-
4.1.1 -- The Hermes language started as a simple subset of Prolog.
To this we added function calls which allow access to external software
packages and data.
-
4.1.2 -- Hermes annotates mediator predicates with terms ranging
over truth values to indicate relative expression confidence or certainty.
Hermes represents these truth values as real numbers ranging typically
between 0 (no certainty) and 1 (total certainty).
-
4.1.3 -- Hermes uses a standard data format for exchanging information
between its search engine(s) and defined domains. This standard data exchange
format provides a rich set of data structures which include constants,
records, arrays and sets. The data types are both very flexible and precise.
Moreover, Hermes language constructs provide easy access to data
structure elements; Unstructured or binary data can be exchanged through
files.
-
4.1.4 -- All Hermes mediator return types are explicitly declared;
As such the engine checks return types during parsing, as the system loads,
rather than when a given query executes.
-
4.1.5 -- A Hermes domain declaration, listed in a catalog file,
defines an interface used by Hermes mediators to access 3rd
party software packages, or data sources, via supported interface calls
supplied by the software, or data, vendor.
NOTE: For all defined domains there exists a data communications
and conversion layer, written currently in Ansi C by the domain integrator,
which spans the gap between Hermes search engine(s) and the target data
application. Programmers who integrate new domains into Hermes must become
well versed in the data representation of both Hermes and the target 3rd
party application / data source; This is perhaps best accomplished by examining
one or more of the provided domain implementations.
-
4.2
-- Domain implementation, the Ingres example: Relational database
systems, such as Ingres or Oracle,
typically provide a function call interface for database operations which
include field projection and record selection. Fig. 4-1, an excerpt of
the Ingres domain declaration, shows Hermes exploiting the
ingres:select function. Domain declarations specify both the function
arguments and return types as variable-name/data-type pairs. Using the
ingres:select function, Hermes mediators can select records
from any ingres database by specifying the database Relation
file path, the target Field name, the Comparison
operator, and a Value with which to compare the target
field. Note that the comparison value may be of any type; However it must
match the target field type (This condition gets checked by the domain
interface). The function output type, in this case a relational database
table, is computed by the built-in data function, which takes the file
and field name inputs and assigns the output from the matching mediator
data declaration. (Additional forms of the data declaration are described
in section 7.2.3.)
Implementing similar high-level function interfaces
for other relational database systems, such as Oracle, Dbase,
and Paradox, provides Hermes uniform database functionality
which spans a variety of systems and platforms. While relational databases
are probably the most common domain class, the general domain function
framework applies to many other types of software as well. In this respect,
Hermes can form the glue by which to cement greatly varied data
sources and types into an easily referenced, homogeneous knowledge pool.
-
4.3
-- Mediator implementation: Once integrated, domain functions can be
used in mediator text files to define queries into domain data. Mediator
files typically consist of data sources, rules employing domain functions,
and facts. The mediator listed in Fig. 4-2 defines a rule, supplier_part,
which answers the query "Who supplies a given part ?" using information
stored in the Ingres inventory/supplier_part relational
database table.
Hermes provides several mediator declarations
for declaring data types and locations. Within the mediator, the predicate
declaration defines a data query into one or more domains. Predicate
arguments include the predicate name, description (both strings), and its
term names and types. The data
declaration defines the target database relation record structure.
Observing Hermes type notation in the example mediator data declaration
(brackets '[]' surround arrays, angle brackets '<>'
surround record structures, and braces '{}' surround data sets),
we note that the 'parts' Ingres relation table consists of a set
of records. Each record, contains a suppler field (of string type), a part
name field (also a string), and an integer supply quantity field.
Of key importance to the Hermes language
is that the domain catalog data function and the mediator data declaration
work together, but within different parts of the search engine(s) --
This allows integration separation for new domains (software) and associated
data. That is to say that the user need only integrate software package
X once, during the initial X domain integration phase. After
domain X exists within Hermes, then additional X domain
data files can be integrated simply by writing the appropriate mediator
data declarations which describe the underlying data structures (and is
used ultimately to define the domain data function output type) of the
new X files.
-
4.4 -- Mediator query execution -- the "Proof":
The simple rule in Fig. 4-2 states that a supplier provides a part if the
Ingres 'inventory/supplier_part' relation shows that it
does. (The symbols beginning with an upper-case letter (Supplier, Part
and R) are variables.). In order to answer, or prove, a query, the Hermes
engine effectively compiles the applicable rules into a stack of operations
which include the following:
-
Resolution between predicates (such as supplier_part).
-
Comparison operation evaluation ( "<", "<=", "=",
"<>", ">=", ">").
-
Variable and token instantiation.
-
Domain function evaluation (such as calls to ingres:select).
-
Built-in type conversion execution (such as string).
Suppose a user wishes to find all listed suppliers of "part3". They may
query this through Hermes by using the supplier_part predicate
and instantiating the Part variable to a constant, "part3"
(as shown in Fig. 4-3).

-
4.4.1 -- Following the supplier_part predicate, Hermes
resolves this query via the supplier_part rule, noted in Fig.
4-4, from the mediator file.
-
4.4.2 -- Since the "part3" constant (highlighted in Fig.
4-3) matches the Part variable in the clause header (highlighted
in Fig. 4-4), Hermes replaces all Part variable instances
with the constant value throughout the rest of the rule (see Fig. 4-5 highlights).
NOTE: All of the variables are standardized apart to unique
numbered names such as S1 within the compiler stack when the rules and
query are parsed, and when the predicates are resolved, but the English
variable names are shown here for clarity.
-
4.4.3 -- The
built-in constant literal
(see Fig. 4-5) appears in this rule to ensure instantiation of all domain
function inputs; Calling a domain function with variable arguments would
cause a system error. "part3" is a constant, however, so the literal
succeeds and thus gets eliminated from the rule (see Fig. 4-6).
-
4.4.4 --
Hermes evaluates functions embedded in a literal before processing
the literal further. Fig. 4-7 shows that the in
literal now contains two functions: the ingres:select domain
function and the built-in string type conversion. Hermes evaluates
functions from innermost to outermost, so the string function is evaluated
first. The string function evaluates its terms, if necessary, and concatenates
the results.

-
4.4.5 -- Next Hermes evaluates the ingres:select
domain function noted in Fig. 4-8 and writes the solution, the set of all
suppliers and available "part3" quantities, in standard Hermes data
format to a numbered temporary file located in the system work directory
(see Fig. 4-9).
Successful
domain function execution then prompts Hermes to replace the original
ingres:select function call rule entry (see Fig. 4-7) with the
newly created solution file name as highlighted in Fig. 4-10.

Note that all solution files (Fig. 4-9) contain a type declaration
to reveal the underlying Hermes data structure.
-
4.4.6 -- Hermes Domain functions, such as ingres:select,
typically render a set, or array, of data elements. The search engines
then can use the in function to iterate through individual
set, or array, elements as necessary, applying further substitutions required
to resolve the query rule.
The first in function execution on the 1.hrm solution
file (Fig. 4-9) prompts Hermes to substitute the rules' R
variable with the resulting record constant <"supplier5" 29>.
Next, Hermes replaces rule variables R.Supplier, and R.Quantity,
with data field constants "supplier5", and 29, respectively
(see Fig. 4-11), and refines the rule to solve for the first in
function iteration as listed in Fig. 4-12.
NOTE:
Subsequent executions of the in function over the 1.hrm
solution file would result in similar data substitutions drawing from remaining
record elements <"supplier23" 34> and <"supplier17"
8>.
-
4.4.7 --
Hermes next instantiates the rule's Supplier variable with
constant value "supplier5" and updates the query rule to read
as listed in Fig. 4-13.

-
4.4.8 -- Final resolution of the Quantity variable to constant
29 leaves the query rule empty (Fig. 4-14) and the proof complete
(for this iteration). Hermes now displays the answer using the saved
substitutions (Fig. 4-15).
As the user requests more answers, Hermes would continue the in
function iteration / data instantiation process using the 1.hrm
solution file and render additional answers such as those listed in Fig.
4-16.
NOTE: Had there been no suppliers of "part3" listed,
the domain function would have returned an empty set, the in function,
and thus the query, would have failed, returning no for an answer.

Now suppose the user wished to determine whether
a particular supplier provides "part3". Hermes can answer this query
using a slightly different instantiation of the same supplier_part
predicate (Fig. 4-17). Execution of the predicate rule for this new query
would proceed similar to the previous Fig. as the domain function call
would again return a solution file and the in function would iterate through
individual records. Since the user supplied the supplier value on query
execution, however, Hermes propagated the value down thru the rule
prior to processing (see Fig. 4-18). Following the in function
iteration, we now find a slightly different situation for processing the
equal '=' literal. Where previously the equal literal addressed
a variable token and constant value (Fig. 4-12 above), here it applies
to two constant values and thus must perform an equality test (Fig. 4-19).
Walking through the 1.hrm solution set, this test would fail for
the first element <"supplier5" 29>, succeed for the second
element <"supplier23" 34>, and fail for the third element <"supplier17"
8>. Thus Hermes would return only one answer (Fig. 4-20), listing
also the available part quantity.
Web Accessibility