cgpic – Calling GProlog in C

Prolog is a straight-forward way to implement simple logic rules and do the query of the system. GProlog(gprolog) is the GNU version of Prolog implementation. To leverage the power of gprolog into our system code (C/C++), there are usually 2 ways – using IPC or C interface. (GProlog dev usually call C/C++ in the GProlog). This post is focusing on calling GProlog in C using GProlog C interfaces. Thanks Sean and Michal from GNU Prolog User forum for answering my questions. Have fun~

0. Reference

http://gprolog.univ-paris1.fr/manual/gprolog.html#sec371
http://gnu-prolog.996310.n3.nabble.com/How-to-get-the-return-value-from-gprolog-in-C-td1166.html
http://gnu-prolog.996310.n3.nabble.com/Is-that-possible-to-call-dynamic-function-in-the-C-interface-td1177.html

1. IPC

The reason we would not like to do IPC with GProlog is the performance. Even though IPC with pipes is not that slow, the performance bottle neck may be the IPC if all other (C/C++) stuffs in the code run fast.

2. Calling the GProlog in C using GProlog C/C++ interface

Recalling the common patterns used in the interactive gprolog interpreter, we need to handle 3 calling/passing styles in the C code. All the code/examples are based on the pl file below:

% Dynamic function definition
:- dynamic(parent/2).

parent(bob,mary).
parent(jane,mary).
parent(mary,peter).
parent(paul,peter).
parent(peter,john).

anc(X, Y) :-
parent(X, Y).

anc(X, Z) :-
parent(X, Y),
anc(Y, Z).

a. solution query – anc(X, john).

func = Pl_Find_Atom(“anc”);
Pl_Query_Begin(PL_TRUE);
arg[0] = Pl_Mk_Variable();
arg[1] = Pl_Mk_String(n2);
nb_sol = 0;
res = Pl_Query_Call(func, 2, arg);
while (res)
{
sol[nb_sol++] = Pl_Rd_String(arg[0]);
res = Pl_Query_Next_Solution();
}
Pl_Query_End(PL_RECOVER);

b. judgement query – anc(john, bob).

func = Pl_Find_Atom(“anc”);
Pl_Query_Begin(PL_TRUE);
arg[0] = Pl_Mk_String(n1);
arg[1] = Pl_Mk_String(n2);
res = Pl_Query_Call(func, 2, arg);
Pl_Query_End(PL_RECOVER);

c. dynamic function – asserta(parent(dave, john)).

func = Pl_Find_Atom(“parent”);
Pl_Query_Begin(PL_TRUE);
arg[0] = Pl_Mk_String(n1);
arg[1] = Pl_Mk_String(n2);
arg2[0] = Pl_Mk_Callable(func, 2, arg);
func = Pl_Find_Atom(“asserta”);
res = Pl_Query_Call(func, 1, arg2);

3. The power of gplc

gplc is eventually a wrapper for gcc, which allows you to compile pl and C file the same time to generate the binary containing all the logic functionalities you need in GProlog. More over, all the gcc parameters could be passed from gplc. For details, please refer to the code repo down there.

4. R.t.D.C. – Read the Damn Code

https://github.com/daveti/cgpic

About daveti

Interested in kernel hacking, compilers, machine learning and guitars.
This entry was posted in AI/ML, Programming and tagged , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.