---------------------- | | | C O G E N T | | | | | | the programmer's | | | | P R O L O G | | | ---------------------- Prolog is a non-proprietary, rule-based language, based on logic, that is ideally suited for implementing rule-based application components such as problem diagnosis & resolution, configuration & tuning, intelligent advice & help, language parsing & understanding, and planning & evaluation. While Cogent Prolog is a powerful stand-alone Prolog for implementing these types of applications, today's increasingly complex applications have a greater need for embedded components that provide these services. For this reason, Cogent Prolog 3.0 is designed to be easily integrated with Windows and DOS applications, offering plug-in, rule-based services for C, C++, Visual Basic, PowerBuilder, Access and many other development tools. (Other platforms are available as well.) The integration is achieved through the Logic Server API that lets you access a LogicBase of rules as easily as you access a database today. The result is a manageable, well-behaved and predictable interface that makes it possible to utilize rule-based programming everywhere it is needed. The Logic Server API also lets you mold Cogent Prolog to your applications--accessing your data, calling your code and linking to other libraries and interfaces. Prolog components are written, tested and debugged using the Windows- based Interactive Development Environment (IDE). The Windows IDE and Logic Server API make Cogent Prolog a powerful addition to any programmer's tool kit. Embedding Prolog Services ------------------------- The Logic Server API is implemented like a database API. It gives you the ability to load, query and update a Prolog LogicBase of rules and data from C or C++ on any supported platform, and, under Windows, from any tool that can call a DLL, such as Visual Basic, Access, and PowerBuilder. The boxes below illustrate a simple rule-based system that asks the user for a sound, from which it identifies a pet. While a trivial example, this same idea can be used to identify problems based on symptoms, tuning parameters based on system configuration, help based on user needs, and so on. The API has 50+ functions that provide both high-level and detailed access to Prolog rules, terms and data. The high-level functions use intuitive string-mapping functions that simulate a Prolog listener (see code boxes). The detailed functions let you construct and/or decompose arbitrarily complex Prolog terms and lists. For example, this C code pops all of the elements from a Prolog list and prints them: while (cpPopList(Eng,&tList,cSTR,s)==OK) printf("Popped %s\n", s); ----------------------------------------- | | | PETS.PRO | | | | % Three Prolog rules for identifying | | % pets based on their sound | | | | pet(dog) :- sound(woof). | | pet(cat) :- sound(meow). | | pet(duck) :- sound(quack). | | | ----------------------------------------- ----------------------------------- | | | Using the Pets example from a | | Prolog Listener | | | | ?- consult(pets). | | yes | | | | ?- assert(sound(woof)). | | yes | | | | ?- pet(X). | | X = dog | | yes | | | ----------------------------------- ----------------------------------------------------------------------- | | | Calling the Logic Server from C | | | | ... | | /* initialize the Prolog engine */ | | cpInit(&Eng, ""); | | | | /* load the pet rules */ | | cpLoad(Eng, "pets"); | | | | puts("What sound does the pet make? "); | | gets(sSound); | | | | /* assert a Prolog fact with user sound */ | | cpvAssertaStr(Eng, "sound(%s)", sSound); | | | | /* query the Prolog logic database */ | | cpvCallStr(Eng, &term, "pet(X)"); | | | | /* map Prolog answer back to C */ | | cpvScanTerm(Eng, term, "pet(%s)", sPet); | | printf("The pet is a %s\n", sPet); | | | | /* close Prolog engine, freeing all memory and resources used */ | | cpClose(Eng); | | | ----------------------------------------------------------------------- ----------------------------------------------------------------------- | | | Calling the Logic Server from Visual Basic | | | | ... | | % initialize the Prolog engine | | rc = cpInit(Eng, Chr$(0)) | | % load the pet rules | | rc = cpLoad(Eng, "pets" + Chr$(0)) | | | | sSound = InputBox$("What sound does the pet make?") | | | | % assert sound fact | | rc = cpAssertaStr(Eng, "sound("+sSound+")"+Chr$(0)) | | | | % query the Prolog logic database | | tf = cpCallStr(Eng, Term, "pet(X)"+Chr$(0)) | | | | % make room for the returned string | | sPet = Space$(80) | | | | % map Prolog answer back to VB | | rc = cpGetArg(Eng, Term, 1, bSTR, byval sPet) | | MsgBox "The pet is a " + sPet | | | | % close Prolog engine, freeing all memory and resources used | | rc = cpClose(Eng) | | | ----------------------------------------------------------------------- Prolog to C/C++ --------------- The API also makes it easy to build links from Prolog back to C/C++, giving the Prolog code access to any library, GUI or API that can be accessed from C/C++. For example, a Windows tuning application might have its user interface implemented in Visual C++, which loads and calls tuning rules written in Prolog. Those rules make their decisions based on the state of the machine which is determined by C functions that are called directly by the Prolog program. Or, you might want your Prolog code to access an SQL database, or graphics functions, or any other specialized library. You can use the Logic Server API to let Prolog directly access the particular API. Object Oriented Programming --------------------------- The C++ wrapper lets the C++ programmer encapsulate a Prolog program as an object in a larger application, thus shielding its implementation from the rest of the code. For example, the pet identification code could be encapsulated as a class whose interface is defined by member functions that call Prolog as shown in the box below. The class is derived from the C++ class definition for the Logic Server. ----------------------------------------------------------------------- | | | Encapsulating a Prolog LogicBase as a C++ Object | | | | // derive a class from the Prolog engine | | // that can be used to identify pets based on | | // input sound | | class CPets: public CPEngine | | { | | public: | | CPets(); | | ~CPets(); | | void id(char *, char *); | | }; | | | | // constructor initializes engine and loads rules | | CPets::CPets | | { | | Init(""); | | Load("pets"); | | } | | | | // destructor frees Prolog resources | | CPets::~CPets | | { | | Close(); | | } | | | | // member function asserts input sSound, and | | // then, queries Prolog and retrieve sPet | | void CPets::id(char* sSound, char* sPet) | | { | | char sBuf[40]; | | TERM term; | | | | sprintf(sBuf, "sound(%s)", sSound); | | AssertaStr(sBuf); | | CallStr(&term, "pet(X)"); | | GetArg(term, 1, cStr, sPet); | | } | | | | // sample code to use CPets object | | ... | | CPets aPetAdvisor; | | cout<<"what sound does the pet make?"; | | cin >> sSound; | | aPetAdvisor.id(sSound, sPet); | | cout<<"The pet is a "<