C++ ODBC Genealogical Sample
The DBGene sample application uses a classic Prolog application idea to
illustrate how the Amzi! Logic Server can be used to provide the services
of Prolog in conventional application environments. Given a genealogical
database of information about people, the application lets you pose queries
about various relationships, such as sister, uncle, grandparent, and ancestor.
To run it you need:
-
ODBC 2.0 installed
-
AODBC.LSX somewhere in your path (it is in amzi\bin).
-
An amzi.cfg file containing the line 'lsxload=aodbc'.
-
A data source named 'gene' defined in your 32-bit ODBC administrator (in
the control panel) that uses the gene.mdb database included with this demo.
This implementation was built with three tools:
-
Visual C++ was used for the GUI interface (other GUI tools such
as Delphi or VB could have been used instead),
-
Amzi! Prolog was used to define the rules for family relationships,
and
-
Access was used for the database of people (any database with an
ODBC driver could be used).
The glue for the application is the Amzi! Logic Server. The application:
-
Uses the Logic Server API to get easy access from Visual C++ to
the Prolog logic base, and
-
Uses the Logic Server ODBC extension to lets the Prolog rules reason
directly over the database tables.
To learn more see:
Using DBGene - How to use the sample, and
how to put in your own family database.
Application Architecture
- Details on the implementation, including annotated source code.
www.amzi.com - Additional demos, articles,
freeware, evaluation copies and information about Amzi! Prolog + Logic
Server.
We welcome any and all comments about this demo. Contact us at info@amzi.com
Using DBGene
To use DBGene, you must have ODBC installed and the Microsoft Access driver.
Use the ODBC control panel to add a data source named ‘gene’ that accesses
the gene.mdb.
DBGene automatically loads the ODBC database, ‘gene’ and the logic base,
‘dbgene’. The middle listbox contains the names of the people in the gene
database. The left hand listbox contains a list of the relations the dbgene
logic base knows about. If you select a relation and an individual and
push the ‘Query’ button, the names of the people who satisfy that relation
appear in the right hand box.
If you have the tools to modify the database, which was created using
Microsoft Access, you can fill it with individuals from your own family
tree. Or you can replace the gene database with an ODBC database of your
own choosing.
DBGENE Application Architecture
The DBGene application is composed of three components
-
the Visual C++ user interface,
-
the Amzi! Prolog logic base, and
-
the Access database of people.
The database contains two tables, one defining
people, with information such as a unique ID number, name, date-of-birth,
and parents, and the other defining marriages, with the ID numbers of the
individuals in each marriage.
The logic base contains rules that define
relationships based on the database. These are rules that express what
it means to be a sibling, uncle, ancestor, etc. At the base of each of
these rules are Prolog predicates that map directly to the database, using
the Logic Server ODBC extension.
The user interface contains list boxes
that present the pertinent information from the logic base. That information
is obtained from a C++ class that encapsulates the logic base services.
Database
The database used in this example is an Access database. If you have Access,
you can edit it directly to reflect your own family tree. If you have a
different database with an ODBC driver, you can create tables like these
for your own family and assign the ODBC database name ‘gene’ to your database.
There are two tables in the database defined as follows.
Person
*pid number (key)
*surname text[40] (indexed)
*midname....text[40]
*name text[40]
*gender text[1] m/f
*mother number (indexed) (a pid)
*father number (indexed) (a pid)
dob text[10] (date yyyy-mm-dd)
dod text[10] (date yyyy-mm-dd)
birthplace text[50]
nation text[40]
note text[255]
Marriage
*husband number (indexed) (a pid)
*wife number (indexed) (a pid)
married text[10] (date yyyy-mm-dd)
divorced text[10] (date yyyy-mm-dd)
note text[255]
* - Fields that are used in this demonstration. Other fields are ignored.
The Sample People
The people in the sample database have decided to propagate maternal family
names through the middle name, just as paternal family names are often
propagated by the last name. That is, the children of a marriage take the
middle name of the mother and the last name of the father. That way the
daughters carry on the maternal family name and the sons carry on the paternal
family names, and you can get a better sense by looking at the names who
might be related to whom.
Individuals with no middle name are at the top of the tree, also indicated
by parents with PID numbers of 0.
Logic Base
This is the Prolog code used to define the genealogical logic base. To
use it the host language must first open the ODBC connection by calling
the db_open/1 predicate.
The code consists of these primary sections:
-
A list of relations, used by the host language to display the choices to
the user.
-
Database definitions used to build SQL queries from Prolog queries.
-
The rules defining the primitive relationships that are based directly
on the representation of people in the database. These rules make heavy
use of the ODBC query predicate.
-
The higher-level rules for more complex relationships, all defined using
the primitive rules described above, so they are not affected by changes
to the representation of a person.
The query interface designed for use from a host language program. Other
versions of the program have different interfaces.
User Interface
The Visual C++ interface consists of a simple dialog box and a class that
encapsulates the Prolog services portion of the application, used to populate
the list boxes of the dialog.
Some of the files in the application are pure boiler plate generated
by the application wizard of Visual C++. That code is not included here.
The code listed is:
progene.h - the header file for the class that
encapsulates the Prolog services, based on the Logic Server C++ wrapper
class.
progene.cpp - the implementation file for
the ProGene class. Its primary function is to take one of the three list
boxes of the application as input and fill it with the appropriate information
derived from the Logic Base. API calls that loop through lists and queries
are used to generate all the information required for each list box.
dbgendlg.cpp - the main dialog implementation
that use the ProGene services. The OnInitDialog function calls ProGene
to fill up the relations and individuals list boxes, and the OnQuery function
passes the selected name and relation to ProGene, which then fills in the
answers list box.
Copyright ©1996-98 Amzi! inc. All Rights Reserved.