Is the Prolog runtime re-entrantable in Prolog --> C --> Prolog procedure?

Shuai Wang <[email protected]>
Newsgroups gmane.comp.gnu.prolog.general
Message-ID <CAEQMQokryMVMYvxxm9ax=wgF3mX5Hh18NtSjvaNxkE47kfgsuQ@mail.gmail.com>
Hello prolog users,


I just asked a question in this email list about
"why failed in process of Prolog call C call Prolog"

Now after several test, I have a more general question which confused
me...

I myself have some experience about using C call Prolog and
using Prolog to call C in GNU-Prolog, however, I have several
strange problems in recent test of procedure below:

     C -- call -- > Prolog -- call --> C -- call --> Prolog
     -- return --> C -- return --> Prolog (fail..)

*So basically, is the Prolog runtime reentrantable in Prolog --> C -->
Prolog*
*procedure..?*


I attached my test code in the email, in this code, the weird thing is that
return value of *TMP  *in  Prolog function *foo * can not be binded.

BTW:  Is it something related to the arguments of
Pl_Query_Begin; Pl_Query_End ?


Best,
Shuai

_______________________________________________
Users-prolog mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/users-prolog
simple.cil.c (text/x-csrc, 3.1 KB)
/* Generated by CIL v. 1.5.1 */
/* print_CIL_Input is true */

#include <gprolog.h>

   int  babel_wrapper_foo1(int  n)                           // function name insert
      {
        // wrapper for function foo1        // function name insert
         int  return_value; //  return value type (how about array type)

        //rountine code
        int func;
        PlTerm arg[2];    //  function variable + return value insert
        PlBool res;

        func = Pl_Find_Atom("foo1"); // function name insert

      //routine code
        Pl_Query_Begin(PL_TRUE);

      //prepare parameters
      //partial routine code, pass in parameter  // we need to init arguments and return value
      //  arg[0] = Pl_Mk_Integer(n);
      arg[0] = Pl_Mk_Integer(n);

      //routine code, reserve a place for return value
      arg[1] = Pl_Mk_Variable();

      //partial routine code, 2 is not routine. (number of arguments) + 1
        res = Pl_Query_Call(func, 2, arg);          // insert (variable+return value)

      //get return value, partial routine code, 1 is not routine
        return_value = Pl_Rd_Integer(arg[1]);        // insert ()

      //routine code
        //Pl_Query_End(PL_KEEP_FOR_PROLOG);
        Pl_Query_End(PL_RECOVER);

      //routine code
        return return_value;
        }
      
   int  babel_wrapper_foo()                           // function name insert
      {
        // wrapper for function foo        // function name insert
         int  return_value; //  return value type (how about array type)

        //rountine code
        int func;
        PlTerm arg[1];    //  function variable + return value insert
        PlBool res;

        func = Pl_Find_Atom("foo"); // function name insert

      //routine code
        Pl_Query_Begin(PL_TRUE);

      //prepare parameters
      //partial routine code, pass in parameter  // we need to init arguments and return value
      //  arg[0] = Pl_Mk_Integer(n);
      
      //routine code, reserve a place for return value
      arg[0] = Pl_Mk_Variable();

      //partial routine code, 2 is not routine. (number of arguments) + 1
        res = Pl_Query_Call(func, 1, arg);          // insert (variable+return value)

      //get return value, partial routine code, 1 is not routine
        return_value = Pl_Rd_Integer(arg[0]);        // insert ()

      //routine code
        //Pl_Query_End(PL_KEEP_FOR_PROLOG);
        Pl_Query_End(PL_RECOVER);

      //routine code
        return return_value;
        }
      
#line 3 "simple.c"
int foo1(int n ) ;
#line 4
extern int ( /* missing proto */  printf)() ;
#line 1 "simple.c"
int foo(void) 
{ 
  int a ;
  int tmp ;
  int __retres3 ;

  {

#line 3
  return babel_wrapper_foo();
#line 3
  tmp = foo1(23);
#line 3
  a = tmp;
#line 4
  printf("%d\n", a);
#line 5
  __retres3 = 0;
#line 1
  return (__retres3);
}
}
#line 8 "simple.c"
int foo1(int n ) 
{ 
  int t ;

  {

#line 10
  return babel_wrapper_foo1(n);
#line 10
  t = n + 1;
#line 11
  return (t);
}
}
#line 14 "simple.c"
int main(int argc , char **argv ) 
{ 
  int __retres3 ;

  {
  Pl_Start_Prolog(argc, argv);
#line 16
  foo();
#line 18
  __retres3 = 0;
  {
  Pl_Stop_Prolog();
#line 14
  return (__retres3);
  }
}
}
babel.c (text/x-csrc, 1.2 KB)
#include <gprolog.h>
#include <stdio.h>
#include <stdlib.h>

PlBool babel_ptrR(PlLong* p,  PlLong* star_p, PlLong len)
{

	if (star_p == NULL)
	    return PL_FALSE;
	else
	{
		switch(len)
		{
		    case 1:
		    	*p = *(char*)star_p;
		    	break;
		    case 2:
		    	*p = *(short*)star_p;
		    	break;
		    case 4:
		    	*p = *(int*)star_p;
		    	break;
		    case 8:
		    	*p = *(long long*)star_p;
		    	break;
		    default :
		    	printf("undefined exp length in babel_ptrR\n");
		}
	}

		*p = 0x7fffffffffff&*p;
		return PL_TRUE;
}

PlBool babel_ptrE(PlLong* p,  PlLong e, PlLong len)
{
	if (p == NULL)
	    return PL_FALSE;

	switch(len)
		{
		    case 1:
		    	*(char*)p = (char)e;
		    	break;
		    case 2:
		    	*(short*) p = (short)e;
		    	break;
		    case 4:
		    	*(int*)p = (int)e;
		    	break;
		    case 8:
		    	*(long long*)p = (long long)e;
		    	break;
		    default :
		    	printf("undefined exp length in babel_ptrL\n");
		}

        return PL_TRUE;
}
PlBool babel_c_0(int arg_0,  int * babel_ret) 
{
*babel_ret = foo1(arg_0);
printf("%d\n", *babel_ret);
return PL_TRUE;
}
PlBool babel_c_1(char* arg_0, int  arg_1) 
{
printf(arg_0, arg_1);
return PL_TRUE;
}
babel.pl (text/x-perl-script, 1 KB)
babelJcc(OP, L, R) :-
    (  OP =:= 12 -> L =:= R
    ;  OP =:= 13 -> L \= R
    ;  OP =:= 14 -> L > R
    ;  OP =:= 15 -> L =< R
    ;  OP =:= 16 -> L < R
    ;  OP =:= 17 -> L >= R
    ).

:-foreign(babel_ptrR(-integer, +integer, +integer)).
:-foreign(babel_ptrE(+integer, +integer, +integer)).

babelPtrR(E, P, L) :- babel_ptrR(T, P, L), E is T.
babelPtrL(P, E, L) :- babel_ptrE(P, E, L).

babelAssign(Var, Val) :- Var is Val.
babelAssignStr(Var, Val) :- Var = Val.
babelAssignBool(Var, Val) :- Var = Val.

babelArrayL([_|T], 0, X, [X|T]).
babelArrayL([H|T], I, X, [H|R]):- I > -1, NI is I-1, babelArrayL(T, NI, X, R), !.
babelArrayL(L, _, _, L).

babelArrayR(X, [X|_], 0).
babelArrayR(X, [_|T], I):- I > 0, NI is I-1, babelArrayR(X, T, NI), !.
:- foreign(babel_c_0(+integer,  -integer)).
:- foreign(babel_c_1(+string, +integer)).

foo(__RETRES3) :- 

babel_c_0(23 , TMP),
write(TMP),nl,
babelAssign(A, TMP),
babel_c_1('%d\n', A),babelAssign(__RETRES3, 0). 
 
foo1(N, T) :- 

BabelExp_0 is N + 1,
babelAssign(T, BabelExp_0).
Makefile (application/octet-stream, 986 B) - not displayed
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.