The ConceptBase.cc server (CBserver) offers its services via a TCP/IP port to client programs. The main services are to TELL or UNTELL O-Telos objects and to ASK queries to the database. The operations are called by clients (for example, the user interfaces described in section 8). An arbitrary number of clients can connect to a CBserver.
The CBserver is started1 by a command line
cbserver <params>
assuming that the installation directory of ConceptBase.cc is added to the search path of executable programs. If it is not on the search path, then simply change the current directory to the installation directory of ConceptBase.cc or use its absolute path of the cbserver script.
The following parameters are available for the ’cbserver’ command:
If a CBserver is started without any parameter, then the update mode shall be set to nonpersistent, the trace mode to no, multi-user mode is disabled, and the server mode to slave. The other parameters are set to their defaults. Such a CBserver is useful as companion of tools that need it only while they are running.
cbserver
A ConceptBase client running on the same computer will then connect to this CBserver, when it uses ’localhost’ as host and 4001 as port number. Since the CBserver runs un slave mode, it will shut down when its client disconnects.
The CBserver is only compiled for Linux architectures. This means that user of other platforms must rely on a Linux system to utilize ConceptBase. The traditional way is to start the CBserver on such a Linux system and then connect to it, possibly using a so-called public CBserver (see section 6.6). Since April 2017, this detour is no longer required for users of Windows 10 (64bit, Creators Update). This version of Windows is capable to let Linux programs run under the ’bash’ utility, which is basically a whole Linux system under Windows that realizes calls to the Linux API by hooks to the Windows API. Hence, it is not a virtual machine, it lets you run the Linux (64bit) variant of the CBserver natively on Windows 10.
To enable the Linux capability on Windows 10, follow the instructions at link. Note that you must have installed Java (64bit) on your Windows machine, not Java (32bit) to take full advantage of this feature. You can check whether your Java is 64bit by calling the following command in a Windows command window.
java -d64 -version
Users of older Windows versions and of other operating systems can continue to use the public CBserver (see section 6.6) to take advantage of ConceptBase.
A ConceptBase database is a directory that contains at least the following files:
The database files may only be updated via the ConceptBase server. Their initial state is bootstrapped from textual Telos frames that define the pre-defined objects of O-Telos. Since the pre-defined objects can change from version to version, we cannot guarantee binary compatibility of ConceptBase databases. You can easily export the textual definitions from a databases via the -save option. Those definitions can then be imported to the new ConceptBase version. The database directory may contain further text files with filetype ’lpi’. These are Prolog plugins loaded at startup time, see also section F.
A new database is created from the database lib/SystemDB in your ConceptBase installation directory. The System database contains exactly the objects of the root module System. They include for example the definitions of the objects Proposition, Individual, Attribute, InstanceOf, and IsA. Further the objects Class, QueryClass, Function, ECArule, Module and many more are defined that are needed to formulate queries and to use the capabilities of the system.
Whenever a new database is created, the files from this System database are copied into the new database directory. This allows experienced ConceptBase users to adapt the System database to their needs. Just start a ConceptBase server with
cbserver -d $CB_HOME/lib/SystemDB -s 0
Replace $CB_HOME by the path to your ConceptBase installation directory. Then start a CBIva user interface, connect to the CBserver and switch to the module System. Assume you want to predefine the class Container and declare a Model as subclass of Container:
Container with attribute contains: Proposition end Model isA Container end
You can also add rules and constraints about containers, e.g. that containers may not contain themselves. A more significant extension would be to add active rules to the system database. For example, the active rules in CB-Forum at link changes the semantics of the UNTELL operation. Such definitions are subsequently included in any new database that you create. Be careful with deleting system objects. The code of the CBserver relies on the existence of certain system objects.
The trace of the CBserver can be saved by redirecting its
output, e.g.
cbserver -r 10 -port 4444 -t high -d MYDB >> mylogfile.log
The CBserver can also be started directly from the ConceptBase.cc User Interface (see section 8) and most parameters can be specified interactively. The command line version is recommended when one CBserver serves multiple users or when user interface and server shall run on different machines. The parameter -r 10 instructs the CBserver to restart after 10 seconds if a crash has occurred.
A special error message during the startup of the CBserver is the following:
### FATAL ERROR: Application is locked by hostname, PID 1234 ### CBserver aborted
This messsage is printed if there is still a file with the name OB.lock in the database directory (option -d). The OB.lock file should avoid that two servers are using the same database directory. The file may be left over of a previous CBserver if the server was not stopped correctly (e.g. aborted by Ctrl-C or it crashed). If you get this error message, make sure that there is no other server running that uses this directory and then delete the file OB.lock. Then, the CBserver should start correctly.
A public CBserver is a ConceptBase server that is accessible from the whole network. As such this is a property that any CBserver has, except when the multi-user capability is disabled, or when your firewall prevents external access.
If you work with an existing database, you may want to specify some access rights rules like suggested in section 5.7. We neglect them in this simple example. Now, start the public CBserver with suitable parameters under Linux/Unix:
cbserver -r 2 -a jonny -g public -ia 0.5 -u nonpersistent -d MDB &> log.txt &
The option -g public enables the slave mode implicitely and tells oHome as an instance of AutoHomeModule. The combination of the slave mode and the option -r instructs CBserver to stop and restart when the last client exits. The update mode is nonpersistent. As a consequence, the restarted CBserver will use the unchanged state of MDB. This is useful, if you want to provide the service of CBserver to a larger group of (anonymous) users. They can log in with a client, operate on the database in nonpersistent mode and eventually leave the CBserver. When the last active client3 leaves the CBserver, then CBserver will freshly start up after 2 seconds. Due to the option -u nonpersistent user-defined objects are only stored at the public CBserver while there are still active clients enrolled to the public CBserver.
The parameter -a sets the administrator user of the public CBserver. This user is allowed to shutdown the CBserver from a client. The auto home feature will assign different users to individual workspaces. Unless you introduce access rights (and enable them via the CBserver option -s 2) the users can also manipulate the modules of other users. However, the CBserver is restarted whenever the last client logs off. Hence, the definitions of different users are not permanently stored on the CBserver. The parameter -ia used here instructs the CBserver to regard a client as active of it had its last interaction within 0.5 hours. Clients that were inactive for a longer time will not prevent the CBserver from restarting when another (active) client logs off the CBserver.
Consider the following alternative command to start a public CBserver:
cbserver -t no -r 2 -a jonny -g public -ia -1 -d ALLDB &> /dev/null &
Here, the updates are stored persistently in the database ALLDB. Changes to modules are not lost when the last active client leaves the CBserver. There is no log file created as well. The option ’-ia -1’ used here instructs the CBserver to regard any client as active, regardless of how long ago its last interaction occurred.
Configure the CBIva interface to use the public CBserver via the variable PublicCBserver. It can be set by the menu item "Options/Edit Options Manually" of CBIva, see section 8.4. A value different from none enables the use of the public CBserver by CBGraph. You can optionally append a port number like "cbserver.acme.com/4002". The default value for the port number is 4001. Installations of ConceptBase on platforms, for which no binaries of the CBserver exist, may use a default public CBserver. This is the case OS-X and older versions of Windows4.
Don’t forget to save the options after changing the variable.
The best way to interact with a public CBserver is to use graph files, see section 8.2.3. Assume that a public CBserver is running on host cbserver.acme.com. and that cbserver.acme.com was configured as the public CBserver to be used. Then, calling
cbgraph graph1.gel
will connect to the public CBserver instead of ’localhost’. The port number for the connection is taken from the graph file. Do not forget to save the graph file before exiting CBGraph if the public CBserver was started in non-persistent mode. If you subsequently open the graph file, it will attempt to connect to the same host. You can force it to attempt the connection to localhost instead by
cbgraph -host localhost graph1.gel
Since version V5.2.4 ConceptBase.cc features a new query evaluation method, which uses a so-called tabling cache to store intermediate results of predicates that are called during the top-down (SLDNF) query evaluation. Assume, for example, that an employee ’bill’ has two projects ’p1’ and ’p2’. Then, the result of a predicate ’(bill hasProject x)’ with variable x would be the set {(bill hasProject p1),(bill hasProject p2)} consisting of facts. We call this fact set also the extension of the predicate.
After a completed predicate evaluation, the tabling cache of the predicate holds its extension. Tabling speeds up query evaluation and prevents infinite loops when ConceptBase.cc evaluates recursive queries and deductive rules. Essentially, the tabled evaluation allows to compute dynamically stratified semantics of the Datalog database underlying ConceptBase.cc. Plenty of examples for recursive rules and queries are provided in the online ConceptBase Forum.
The CBserver provides three tabling cache modes to control the behavior during query evaluation:
ConceptBase will only call tabled evaluation for deductive predicates. Other predicates are evaluated by the regular SLDNF engine of the underlying Prolog engine. By default, the tabling cache mode is activated in mode keep. Some statistics on cache usage are written to the terminal window of the ConceptBase server when the tracemode has been set to veryhigh.
Acknowledgements: The techniques for the tabled query evaluator of ConceptBase.cc are inspired by the ’tabled evaluation’ [SSW94, CW96]. We do however not delay the evaluation of negated predicates but rather re-order them at compile time to guarantee that all variables are bound at call time. Tabled evaluation is also implemented in XSB [link] and DES [link].
The default update mode is ’persistent’. In persistent mode, all changes
to the database are written to the file system at the directory specified in
the parameter ’-d’. Persistent mode is suitable when a CBserver
runs for a longer period of time and is directly updated by
application programs.
If ConceptBase.cc is used for testing and modeling
purposes, the update mode ’nonpersistent’ is an interesting alternative.
We discuss two scenarios for the nonpersistent mode and one for the
persistent mode.
Scenario 1: Single-user modeling. When a user needs to model a certain application domain with classes and meta classes, he usually works with external Telos files (aka source models, file extension ’.sml’). These files can include comments like usual with program source code. The recommended mode here is ’-u nonpersistent’ without specifying a database. The user can load the source models into such a non-persistent server and make corrections to the source files in case of errors or design changes. Here, ConceptBase is mostly used to check and analyze the models. Recommended options:
cbserver -u nonpersistent -mu disabled
Scenario 2: Lab assignments. Assume that a teacher wants students to exercise a certain modelling task using ConceptBase.cc. Then, he would prepare some Telos files with necessary definitions (e.g. some meta classes) and load them into a persistent ConceptBase server. After that, he can restart the ConceptBase server in non-persistent mode on the same database created before. Student can then work on their extensions while the state of the database can easily be set back to the original state defined by the teacher. The module system of ConceptBase.cc can be used to support multiple students to work on the same server without interfering with each other, see section 5. Recommended options:
cbserver -d MYDB -s 2 -mu enabled -u nonpersistent
The second scenario might also be useful in modeling. If there are some
parts that are regarded as stable, the modeller can decide to make
them persistent and only add/modify those Telos models that are still
subject to change. In particular for large Telos models, this strategy
saves time.
Note that the updates by the users are lost when the non-persistent
CBserver is stopped. This might be useful, if you want to re-use the same
initial database MYDB several times, e.g. for different user groups.
Scenario 3: Project work. Here the students work for several days on a given task. Changes shall not be lost. The use of the -db option will not only store the database in binary form but also store the source code of all modules as text files in directory MYDB. Recommended options:
cbserver -db MYDB -s 2 -mu enabled
If ConceptBase.cc is used in a multi-user setting, then one can combine the update mode with the module feature (see section 5). In this scenario, multiple users access the same CBserver. A common super module (e.g. the module oHome) carries the common objects of the users. Each user can be assigned to her own hown module (a sub module of the common super module) and create and update objects in this workspace without interfering with other users. If several groups of users shall share their definitions, then they would be assigned to the same home module. The home module may have sub modules for testing and releasing definitions. By employing access rights to modules, one can also design which user has which read/write permissions. The builtin query listModule allows to save the contents of a module to a Telos source file (see section 5.8).
ConceptBase.cc realizes the concept of a historical database. The TELL operation submits O-Telos frames to the CBserver. The CBserver extracts the ’novelty’ of the submitted frames and translates it into a set of P-facts to be stored in the object store. Any P-fact has a so-called belief time associated to it (see section 2.1). The belief time is an interval (t1,t2) whose left boundary t1 is the time point when the P-fact was inserted to the object store, i.e. the time when the transaction was executed that led to the insertion of the P-fact. The right boundary t2 specifies the time point after which the CBserver assumes the P-fact to be not true anymore. It is initialized with ’Now’ when the P-fact is created. This symbolic value is interpreted as the current time. You may also interpret such a time interval to be right open.
The UNTELL operation terminates the belief time of P-facts specified in an O-Telos frame. The value ’Now’ is replaced by the time5 when the UNTELL operation is executed.
From the user’s perspective, a TELL operation is about creating some objects and the UNTELL operation is about deleting them6. Many users expect the UNTELL operation to be symmetric to the TELL operation, i.e. untelling a frame that has been told before should remove the frame completely. This is however not the case for the following reasons:
The last reason is most significant in preventing symmetry. As an example consider the O-Telos frame (referred to as frame 1).
bill in Employee with name bname: "William" end
ConceptBase.cc will recognize that bill is an individual and that bill!bname is an attribute. This information is attached internally to the P-facts, more precisely, it is derivable from the structure of the corresponding P-facts. Assume that you started a CBserver with untell model verbatim (see below). When you ASK the CBserver for the frame of bill after the TELL operation on frame 1, you will get frame 2:
Individual bill in Employee with attribute,name bname: "William" end
Hence, the instantiation to the builtin classes Individual and Attribute is added to the frame. If we submit the original frame 1 to an UNTELL operation, ConceptBase.cc assumes by default that only two facts should be untold:
As a consequence, the object bill and its attribute continue to exist after the UNTELL on frame 1. It would look like (frame 3):
Individual bill with attribute bname: "William" end
Only by untelling this frame 3 as a second operation or by untelling the completed frame 2, the object bill and its attribute bill!bname shall be made historical.
This assymmetry of TELL and UNTELL is regarded by some ConceptBase.cc users as unnatural behavior. They expect that an UNTELL is also supposed to affect the objects themselves, not just their instantiation to classes. To support those users, we provide a so-called untell mode (see parameter -U in the list of CBserver command line parameters). The untell mode verbatim will cause ConceptBase.cc to behave as explained above. The mode cleanup (default) will take care to remove the objects themselves provided that they have no other instantiations to classes except instantiation to the four builtin classes Individual, Attribute, InstanceOf, and IsA. Furthermore, no other object may be linked to the object subject to be untold.
You can use ECArules to realize a cascading UNTELL, i.e. if an object is deleted then all its links to other objects are deleted as well, leading to potential follow-up deletions. The required ECArules are provided in link. You only need to add the ECArules to your database to enact the cascading UNTELL. You should be careful with using the cascading UNTELL. For example, untelling a system class will also untell all instantiations to it. Use the CBserver option -s 1 to prevent such undesired deletions.
ConceptBase.cc stores objects in a dedicated object store maintained in main memory. A P-fact P(o,x,n,y) consumes about 800 bytes of main memory. That means that one can store roughly 1 million P-facts in 1 GB of main memory. A typical Telos frame is stored with roughly 10 P-facts. Hence, 1 GB of main memory allows you to store around 100.000 Telos frames. On 32 bit CPUs, this results in a maximum of roughly 400.000 frames that can fit into 4 GB of addressable main memory. This restriction virtually vanishes with 64 bit CPUs.
A single TELL/UNTELL operation submitted to the CBserver should not contain more than about 2000 frames (at about 5 attributes per frame). Otherwise, the compiler can run out of stack memory.
The raw performance of the object store, i.e. the time needed to reconstruct a frame for a given object identifier, is virtually independent from the number of P-facts that it stores. However, if you have defined many rules or integrity constraints, the performance may well degrade significantly with the number of stored P-facts. The same holds for queries. We tested the response times for standard queries such as computing the transitive closure in relation to varying database sizes. Results indicate that ConceptBase apparently approximates in many cases the theoretic optimum.
The performance of the active rule evaluator (section 4) is currently rather limited. We measured around 100 rule firings per second. This can be a performance bottleneck when many active rules are being processed.
The application programming interface (API) to the ConceptBase server (CBserver) is realized by the Java class LocalCBclient. Most (Java) application programmers presumably only need the simple String-based part of LocalCBclient to interact with a CBserver. LocalCBclient uses socket-based data streams to realize the communication. We define here the methods of this String-based API. If the argument starts with an "s", then the data type is String. If it starts with an "i", then the data type is int.
LocalCBclient cbClient = new LocalCBclient();
sAnswer = cbClient.cbserver();
sAnswer = cbClient.connect(sHost, iPort, sTool, sUser);
sAnswer = cbClient.connect();
sAnswer = cbClient.disconnect();
sAnswer = cbClient.pwd();
sAnswer = cbClient.mkdir(sModule);
sAnswer = cbClient.cd(sModule);
sAnswer = cbClient.tells(sFrames);
sAnswer = cbClient.untells(sFrames);
sAnswer = cbClient.asks(sQuery,sFormat);
sAnswer = cbClient.asks(sQuery);
sAnswer = cbClient.clientid();
sAnswer = cbClient.clearall();
Below is the listing of the Java program TinyClient.java that uses the
String-valued API:
import i5.cb.api.*;
public class TinyClient {
private static LocalCBclient cbClient = null;
public static void main(String argv[]) {
String sAnswer;
cbClient=new LocalCBclient();
sAnswer = cbClient.connect("cbserver.acme.org",4001,"TinyClient",null);
sAnswer = cbClient.tells("Employee in Class end");
sAnswer = cbClient.asks("get_object[Employee/objname]");
System.out.println(sAnswer);
sAnswer = cbClient.disconnect();
}
}
You need to compile the Java program with the cb.jar library. This is available from the ConceptBase installation directory (referred here as CB_HOME). To compile the Java program call
javac -classpath $CB_HOME/lib/classes/cb.jar TinyClient.java
Before running the client, make sure that the CBserver runs on the specified Linux computer (here "cbserver.acme.org") under the specified port number (here 4001), and that this port number is accessible from your client computer. You may want to configure that CBserver as a public CBserver (see section 6.6) to have a save way to connect your Java program to it.
The Java program can then be started under Linux as follows:
java -classpath $CB_HOME/lib/classes/cb.jar:. TinyClient
Under Windows, you should use:
java -classpath c:\conceptbase\lib\classes\cb.jar;. TinyClient
The Java source code for TinyClient.java, TinyClient2.java (uses the cbserver method), TinyClient3.java (uses the connect method), and a more elaborate example SimpleClient.java is included in the directory examples/Clients/JavaClient of your ConceptBase installation directory.