NuSMV is a symbolic model checker, which I use as part of my PhD thesis. However, NuSMV is written in C and I could not found any Java API to use the model checker from Java. Luckily, creating Java libraries out from C-headers becomes very easy by using
JNA and
JNAerator:
JNA stands for Java Native Access and is a alternative to
JNI, the official way to access shared native libraries. The advantage of JNA is the dynamic binding to shared libraries, whithout writing anything but Java code. Principally, you write a Java Interface with methods machting the corresponding C-header of the library and provide that Java Interface to JNA. More info‘s and examples can be found on the
project‘s website.
While JNA provides the dynamic bridging between calls to the java interface, you still have to write the Java Interface and therefore you also need the knowledge about the conversion conventions from C to Java. Here comes JNAerator into the game. JNAerator is a tool to parse C headers and generate the corresponding JNA Java Interfaces. It comes with a Graphical User Interface, but can also be used on the command-line.
To create a Java API for NuSMV, first a dynamic library has to be created out of the sources. Unfortunately, this library is not created by the make files. I host some
scripts for the current NuSMV 2.5.2 to help you out with
windows,
linux, and
osx.
Having the shared library for NuSMV (nusmv.dll, libnusmv.so, libnusmv.jnilib), we can go an create the Java API using JNAerator (I also host the
script for that). What we get is a java interface which now gives us access to NuSMV.
Accessing NuSMV becomes now as easy as:
import static org.eclipselabs.nusmvtools.nusmv4j.NusmvLibraryUtil.toByteBuffer;
import java.io.File;
import java.io.PrintStream;
import org.eclipselabs.nusmvtools.nusmv4j.NuSMV4J;
import org.eclipselabs.nusmvtools.nusmv4j.NusmvLibrary;
public class Main {
public static void main(final String[] args) throws Exception {
final File file = new File("testModel.nusmv");
final PrintStream ps = new PrintStream(file);
ps.println("MODULE main");
ps.println(" VAR");
ps.println(" x : boolean;");
ps.flush();
ps.close();
final NusmvLibrary nusmvLibrary = NuSMV4J.getNusmvLibrary();
nusmvLibrary.Cmd_CommandExecute(toByteBuffer("reset"));
nusmvLibrary.Cmd_CommandExecute(toByteBuffer("set default_trace_plugin 4"));
nusmvLibrary.Cmd_CommandExecute(toByteBuffer("read_model -i testModel.nusmv"));
nusmvLibrary.Cmd_CommandExecute(toByteBuffer("go"));
nusmvLibrary.Cmd_CommandExecute(toByteBuffer("check_ctlspec -p \"!x\""));
nusmvLibrary.Cmd_CommandExecute(toByteBuffer("show_traces"));
file.delete();
}
}
When you run the above class, you get the following line on the console:
-- specification !x is false
-- as demonstrated by the following execution sequence
<?xml version="1.0" encoding="UTF-8"?>
<counter-example type="0" desc="CTL Counterexample" >
<node>
<state id="1">
<value variable="x">TRUE</value>
</state>
</node>
<loops> </loops>
</counter-example>
If you don't want to take the above steps on your own, you should take a look at my project
nusmv-tools, which contains some Eclipse based tools like an Eclipse editor for NuSMV files (see blow), an API to read the NuSMV counterexamples in java, a model advisor, and the libraries for accessing NuSMV from java, which I presented in this post.
Happy model checking!