users-prolog
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Prolog not fully initialized


From: cschick
Subject: Re: Prolog not fully initialized
Date: Sat, 8 Jun 2013 07:33:09 -0700 (PDT)

The post is more than 2 years old, but I've had the same problem and wanted
to share what I've found out.

The main point seems to be to ask gcc to call the constructors. I've
succeded by creating a dynamic library where gcc seems to initialize them
correctly. I needed a little C snippet to interface some of the funtions to
get GProlog to work. The main task is done by the shell script
"makefile.sh".

Remarks:
1) I needed libgcc.a to be present in the directory where I compiled the
program. Maybe someone could find out how this can be omitted.
2) I needed to append LD_LIBRARY_PATH so as to point to the directory where
the dynamic library is. I hope this can be omitted, too.
3) The directories pointing to gprolog-1.4.0 need to be changed to suit your
needs.
4) The post is rather long, I'm not too used to mailing lists.

The following files did the trick for me:
--makefile.sh----
#!/bin/sh
gplc -c -v new_main.pl my_c_snippet.c
i686-pc-linux-gnu-gcc -march=pentiumpro -m32 -fno-strict-aliasing -shared
-Wl,-O1 -Wl,--as-needed -Wl,-soname,libmy_prolog_library.so -o
my_prolog_library.so ./new_main.o ./my_c_snippet.o
/usr/lib/gprolog-1.4.0/lib/all_pl_bips.o
/usr/lib/gprolog-1.4.0/lib/all_fd_bips.o
/usr/lib/gprolog-1.4.0/lib/top_level.o /usr/lib/gprolog-1.4.0/lib/debugger.o
/usr/lib/gprolog-1.4.0/lib/libbips_fd.a
/usr/lib/gprolog-1.4.0/lib/libengine_fd.a
/usr/lib/gprolog-1.4.0/lib/libbips_pl.a
/usr/lib/gprolog-1.4.0/lib/libengine_pl.a
/usr/lib/gprolog-1.4.0/lib/liblinedit.a -lm
fpc pas_pl.pas
--------------------------------------

--my_c_snippet.c----
#include <gprolog.h>
#include <stdio.h>
                                                                                
                                                             
void Query_Begin(PlBool recoverable)
{
  return Pl_Query_Begin(recoverable);
}                                                                               
                                                               

int Query_Call(int func, int arity, PlTerm *arg_adr)
{
  return Pl_Query_Call(func, arity, arg_adr);
}
                                                                                
                                                              
#define Pl_Query_Start(func, arity, arg_adr, recoverable) \
  (Pl_Query_Begin(recoverable), Pl_Query_Call(func, arity, arg_adr))
                                                                                
                                                              
void Query_End(int op)
{
  Pl_Query_End(op);
}
--------------------------------------

--new_main.pl----
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). 
--------------------------------------

--pas_pl.pas----
program pas_pl;
{ Program interfaces Free Pascal with GNU Prolog }
{ Unfortunately it does not work fully. }
{It does now a bit better... May 1st, 2013...except for hello, which
(obviously) was not specified}

{$linklib my_prolog_library.so}
{$linklib c}
{$linklib gcc.a}

function Pl_Start_Prolog(argc : LongWord; argv : array of PChar) : LongInt;
cdecl; external;
procedure Pl_Stop_Prolog; cdecl; external;

function Pl_Find_Atom(name : PChar) : LongInt; cdecl; external;

procedure Query_Begin(recoverable : SmallInt); cdecl; external;
function Query_Call(func : LongInt; arity : LongInt; arg_adr : PLongWord) :
LongInt; cdecl; external;
procedure Query_End(op : LongInt); cdecl; external;

procedure do_stuff;
var somevar: LongWord;
    reply: SmallInt;
begin
pl_start_prolog(0, ['program']);
{ following atoms are found }
writeln('t=',pl_find_atom('t'));
writeln('f=',pl_find_atom('f'));
writeln('+=',pl_find_atom('+'));
writeln('\+=',pl_find_atom('\+'));
writeln('=:==',pl_find_atom('=:='));
writeln('is=',pl_find_atom('is'));
writeln('read=',pl_find_atom('read'));
writeln('write=',pl_find_atom('write'));
writeln('append=',pl_find_atom('append'));
{ atoms below are now found }
writeln('random=',pl_find_atom('random'));
writeln('consult=',pl_find_atom('consult'));
writeln('abolish=',pl_find_atom('abolish'));
writeln('abort=',pl_find_atom('abort'));
writeln('var=',pl_find_atom('var'));
writeln('exec=',pl_find_atom('exec'));
writeln('put=',pl_find_atom('put'));
writeln('atomic=',pl_find_atom('atomic'));
writeln('fail=',pl_find_atom('fail'));
writeln('nl=',pl_find_atom('nl'));
writeln('trace=',pl_find_atom('trace'));
writeln('anc=',pl_find_atom('anc'));
writeln('parent=',pl_find_atom('parent'));
writeln('hello=',pl_find_atom('hello'));

//halt(0); { pl_query_call with -1 as first arg will crash the program }

Query_Begin(1);
reply := Query_Call(pl_find_atom('nl'), 0, @somevar);
writeln('reply: ',reply);
Query_End(0);
Pl_Stop_Prolog;
end;

begin
do_stuff
end.
--------------------------------------

Best regards
c-schick



&quot;Michał Bieliński&quot; wrote:
> 
> Dnia 29 Września 2010, 00:54, Śr, Daniel Diaz napisał:
>>   Le 28/09/2010 22:42, "Michał Bieliński" a écrit :
>>> Greetings!
>>>
>>> I recently managed to interface GNU Prolog with Free Pascal albeit not
>>> fully. Both Prolog and Pascal units compile and link.
>>>
>>> Pl_Start_Prolog executes and returns. Manual states this function will
>>> collect all objects and initialize them. Probably this somehow fails
>>> because many standard atoms are not found by Pl_Find_Atom function. It
>>> seems linking through gcc allows Prolog to find all objects but using
>>> another compiler does not.
> [snip]
> 
>> Hello,
>>
>> gprolog uses the underlying gcc mechanism to collect and initialize
>> linked objects : constructors functions. Each Prolog source give rise to
>> a constructor function to register it (and later to initialize it). The
>> asm code is similar to what is generated by gcc when compiling a
>> function declared as follows (see also src/EnginePl/obj_chain.h and .c) :
> 
> Ah, I see now. Object files need to modify a static table with pointers to
> their initialization functions before Pl_Start_Prolog is called.
> 
>> /* file x.c */
>> static void __attribute__((constructor)) foo(void) {
>>     ...
>> }
>>
>> use gcc -S -O2 x.c
>> to see x.s
> 
> In assembly file I located "Object_Initializer" symbol. By making it
> global (static modifier in C code ensures it is not visible by default) I
> could call it from Pascal file and suddenly there are atoms from Prolog
> example available! Doing the same with gprolog libs is not an option
> though.
> 
>> I suppose you have to succeed in doing the same as gcc to initialize
>> correctly the objects.
> 
> Indeed. Addresses of initializers are stored in .ctors section. gcc walks
> through this table and calls these pointers. Question is how exactly is it
> done. Probably code for this task is not generated but linked with some
> standard gcc library. I need to get my hands on this routine.
> 
> -- 
> Michal Bielinski
> 
> 
> _______________________________________________
> Users-prolog mailing list
> address@hidden
> http://lists.gnu.org/mailman/listinfo/users-prolog
> 
> 

-- 
View this message in context: 
http://old.nabble.com/Prolog-not-fully-initialized-tp29832732p35603225.html
Sent from the Gnu - Prolog - Users mailing list archive at Nabble.com.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]