2

I get this error message when trying to use a Python library in Promela and spin (error message screenshot):

spin: /usr/include/unistd.h:778, Error: inline text too long near '/usr/include/unistd.h'

My Promela code is

c_code{
  #include "demo1.c" /* the c code written above */
}

bool badstate = false;

active proctype driver()
{
  do
    :: (1) ->
       c_code{
         demo_fun();
       } 
       if
        :: c_expr{ x == 5 } ->
           badstate = true;
        :: else ->
           skip;
       fi;
  od;
}

Here is my demo1.c file, which I am including in my Promela code:

#include "python2.7/Python.h"

void demo_fun(void)
{
    Py_Initialize(); 
    PyRun_SimpleString("import sys; sys.path.insert(0, '/home/zeeshan/Documents/Promela')");
    PyObject* pModule = NULL; 
    PyObject* pFunc   = NULL; 
    pModule = PyImport_ImportModule("hello");
    if (pModule == NULL) {
        printf("Error importing module.");
        exit(-1);
    }
    pFunc = PyObject_GetAttrString(pModule, "Hello"); 
    PyEval_CallObject(pFunc, NULL); 
    Py_Finalize();
}

int main() 
{ 
    demo_fun();
    return 0; 
}

The Python code in hello.py is:

def Hello():
    a = 5
    b = 2
    print("hello world " + str(a + b))

From what I understand, Promela takes the code from all included files and inlines it. The size of this code becomes larger than spin's big number after the inline and causes it to crash.

Am I correct in thinking this? How can I fix my issue, and successfully call the Python code from my Promela specification?

Billy Brown
  • 2,272
  • 23
  • 25

2 Answers2

2

An alternative solution, which is recommended by Spin documentation, is to replace

c_code{
  #include "demo1.c" /* the c code written above */
}

with

c_code{
  \#include "demo1.c" /* the c code written above */
}

This prevents the c code from being inserted into the text of the model before it is passed to the Spin parser.

From the docs:

The Spin parser will now simply copy the include directive itself into the generated C code, without expanding it first.

The backslash can only be used in this way inside c_decl and c_code statements, and it is the recommended way to handle included files in these cases.


Sample output:

~$ spin t.pml
spin: warning: c_code fragments remain uninterpreted
      in random simulations with spin; use ./pan -r instead
c_code2:    { 
         demo_fun();
        }
c_code3:     x == 5 
c_code2:    { 
         demo_fun();
        }
c_code3:     x == 5 
c_code2:    { 
         demo_fun();
        }
c_code3:     x == 5 
c_code2:    { 
         demo_fun();
        }
...
Patrick Trentin
  • 7,126
  • 3
  • 23
  • 40
1

According to the spinroot website:

The maximum length of an inline is 64K (65536 characters).

and

the limit is per inline definition

"python2.7/Python.h" and some of its own includes are more than 64K, which is why you are getting this error. You cannot simply include the whole Python library into your Promela specification (at lease with spin as it is currently implemented).

As the C code must link to the Python libraries anyway, you could provide extern definitions, or even a custom header file, for the elements that your C code needs in order to call your Python code.

So in your case, in minimal_python.h (I am assuming void return types when unused):

#ifndef MINIMAL_PYTHON_H
#define MINIMAL_PYTHON_H

void Py_Initialize(void); 
void Py_Finalize(void);

void PyRun_SimpleString(const char *);

PyObject * PyImport_ImportModule(const char *);

void PyEval_CallObject(PyObject *, void *); 
PyObject * PyObject_GetAttrString(PyObject *, const char *); 

#endif

And then demo1.c includes minimal_python.h instead of python2.7/Python.h.

In your code's case, you would also need a definition for printf and any other standard library or Python functions, as those includes are beyond the 64K limit.

Billy Brown
  • 2,272
  • 23
  • 25