If your application demands functional expressions beyond the set of predefined-functions, you can extend the capabilities of your ConceptBase installation by adding more functions. There are two ways: first, you can extend the capabilities of a certain ConceptBase database (also called ConceptBase application for historical reasons), or secondly, you can add the new functionality to your ConceptBase system files. We will discuss the first option in more details using the function ISQUARE as an example, and then give some hints on how to achieve the second option.
A function (like any builtin query class) has two aspects. First, the ConceptBase server requires a regular Telos definition of the function declaring its name and parameters. This can look like:
ISQUARE in Function isA Integer with
parameter
x : Integer
comment
c : "computes x * x"
end
The super-class Integer is the domain of the function. i.e. any result is declared to be an instance of Integer. The parameters are listed like for any regular generic query class. The comment is optional. We recommend to use short names to simplify the constructions of functional expressions. The above Telos frame must be permanently stored in any ConceptBase database that is supposed to use the new function.
The second aspect of a function is its implementation. The implementation can be in principal in any programming language but we only support PROLOG because it can be incrementally addded to a ConceptBase database. An implementation in another programming language would require a re-compilation of the ConceptBase server source code. The syntax of the PROLOG code must be conformant to the Prolog compiler with which ConceptBase was compiled. This is in all cases SWI-Prolog (www.swi-prolog.org) except for the Solaris-Sparc variant where an older PROLOG system is employed. Since it will be discontinued, we only discuss the SWI-Prolog variant. For our ISQUARE example, the PROLOG code would look like:
compute_ISQUARE(_res,_r1expr,_c1) :-
'Literals':evalFunctionArg(_r1expr,_r1id),
ground(_r1id),
'GeneralUtilities':id2name(_r1id,_r1atom),
term_to_atom(_r1,_r1atom),
_rres is _r1 * _r1,
term_to_atom(_rres,_resatom),
'FragmentToPropositions':create_if_builtin_object(_resatom),
'GeneralUtilities':name2id(_resatom,_res).
The first argument _res is reserved for the result. then, for each parameter of the function there are two arguments. The first is for the parameter itself (_r1expr), the second holds the identifier of the class of the parameter (here: _c1). The class argument can in most cased be neglected.
There are a few ConceptBase procedures in the body of the PROLOG code that are of importance here. The procedure evalFunctionArg will make sure that a parameter passed to the function is first evaluated. This is important for functions used in complex expressions like in PercentageOfQueryClasses. The procedure ground checks whether the parameters are actually bound to a value. The procedure id2name transforms an object identifier to a name. This is necessary because any object including any number or string is internal referred to by an identifier. The procedure term_to_atom converts the value to the required PROLOG type (here: integer). The subsequent expression computed the fuinction result which then has to be converted to a name by term_to_atom. Then, the procedure create_if_builtin_object will declare the result value as a Telos object and name2id will return the object identifier of the result.
The above code should be stored in a file like ISQUARE.lpi. This file has to be copied into the ConceptBase database which holds the Telos definition of ISQUARE. You will have to restart the ConceptBase server after you have copied the LPI file into the directory of the ConceptBase database.
If you want the new function to be available for all the databases you construct, then you need to update replace some system files of your ConceptBase installation. You can do it as follows. Execute the steps as shown above for a new database, say MySystemDb. Switch to the subdirectory lib/system of your ConceptBase installation. Replace the files as follows:
Make backups of the original files to be on the safe side. Note that your extensions might be incompatible with future ConceptBase releases. If you think that your extensions are of general interest, you can share them with other ConceptBase users at the CB-Forum (see www.conceptbase.cc).
The above example of ISQUARE was just to illustrate the capabilities to include external functions. Of course, the simple ISQUARE can also be defined directly as
ISQUARE in Function isA Integer with
parameter
x : Integer
constraint
squareforumula: $ (~this in IMULT[~x/i1,~x/i2]) $
end