How to register MMT as Isabelle component on Windows 10 (to call isabelle mmt_build)? - isabelle

I have installed Isabelle2021 in C:\Homes\Isabelle2021\Isabelle2021 and MMT (from https://uniformal.github.io//doc/setup/) in C:\Homes\MMT21 and I have made additional entries in the C:\Homes\Isabelle2021\Isabelle2021\etc\Components file:
/cygdrive/c/Homes/MMT21
/cygdrive/c/Homes/MMT21/systems/MMT/deploy
But my cygwin-terminal.bat command gives the error that the component can not be found:
C:\Homes\Isabelle2021\Isabelle2021>cygwin-terminal
This is the GNU Bash interpreter of Cygwin.
Use command "isabelle" to invoke Isabelle tools.
tomr#DESKTOP /cygdrive/c/Homes/Isabelle2021/Isabelle2021
$ isabelle mmt_build
*** Unknown Isabelle tool: "mmt_build"
tomr#DESKTOP /cygdrive/c/Homes/Isabelle2021/Isabelle2021
I have tried to follow https://drops.dagstuhl.de/opus/volltexte/2020/13065/pdf/LIPIcs-TYPES-2019-1.pdf:
if the Mmt directory is registered to Isabelle as component, it
provides a tool isabelle mmt_build (shell script) to build MMT with
Isabelle support enabled. The resulting mmt.jar will provide further
tools isabelle mmt_import and isabelle mmt_server (in Scala) to
perform the import and view its results. Users merely need to invoke,
e.g., isabelle mmt_import -B ZF.
What is wrong with my efforts? Does the registration of Isabelle component required additional activies? And is mmt.jar really so adapted to Isabelle (one specific tool in opposition of MMT being the very universal system) that mmt.jar really contains such mmt_build command?
I am going to read https://isabelle.in.tum.de/dist/Isabelle2021/doc/system.pdf Chapter 7.2 "Managing Isabelle Components", maybe it will help and maybe it will work on Windows...

This is partial answer. Simple addition of the MMT directory was not possible due to error messages:
tomr# /cygdrive/c/Homes/Isabelle2021/Isabelle2021
$ isabelle components -x /cygdrive/c/Homes/MMT21
*** Bad component directory: "/cygdrive/c/Homes/MMT21"
I found in the Isabelle source code https://isabelle-dev.sketis.net/file/data/ldiwqhsxa4d5zojczqye/PHID-FILE-2yuwbxlojqunqpdcqvqg/file the reason for this:
def update_components(add: Boolean, path0: Path, progress: Progress = new Progress): Unit =
{
val path = path0.expand.absolute
if (!(path + Path.explode("etc/settings")).is_file &&
!(path + Path.explode("etc/components")).is_file) error("Bad component directory: " + path)
So, it is required (for directory to be used as the Isabelle component) that MMT directory contains etc/settings file. MMT didn't have one, so, I grabbed one such file from the existinc Isabelle components and I modified it to be:
# -*- shell-script -*- :mode=shellscript:
classpath "C:/Homes/MMT21/mmt.jar"
isabelle_scala_service "isabelle.FlatLightLaf"
isabelle_scala_service "isabelle.FlatDarkLaf"
After having that file in MMT21 directory I managed to add MMT21 as a component:
tomr#DESKTOP /cygdrive/c/Homes/Isabelle2021/Isabelle2021
$ isabelle components -u /cygdrive/c/Homes/MMT21
Added component "/cygdrive/c/Homes/MMT21"
But, unfortunately, it didn't solve my initial problem, I am still getting an error:
tomr#DESKTOP /cygdrive/c/Homes/Isabelle2021/Isabelle2021
$ isabelle mmt_build
*** Unknown Isabelle tool: "mmt_build"
So, know I am going deep down into Google and into respective project sites to dig this out...
ADDED:
There are good materials https://sketis.net/2019/mmt-as-component-for-isabelle2019 and https://github.com/UniFormal/MMT/tree/master/src/mmt-isabelle about this, so, it appears, that there is special jar, not the main mmt.jar. I am now reading about this. I will see whether it this works with Isabelle2021 or should I use it with my older Isabelle2020.

Related

Frama-C aborted Invalid user input

I am very new to Frama-c and I got an issue when I am trying to open a C source file.
The error shows as
"fatal error: event.h: No such file or directory. Compilation terminated".
[kernel] Parsing FRAMAC_SHARE/libc/__fc_builtin_for_normalization.i (no preprocessing)
[kernel] Parsing WorkSpace/bipbuffer.c (with preprocessing)
[kernel] user error: failed to run: gcc -E -C -I. -dD -D__FRAMAC__ -nostdinc -D__FC_MACHDEP_X86_32 -I/usr/share/frama-c/libc -o '/tmp/bipbuffer.ce6d077.i' '/home/xxx/WorkSpace/bipbuffer.c' you may set the CPP environment variable to select the proper preprocessor command or use the option "-cpp-command".
[kernel] user error: stopping on file "/home/xxx/WorkSpace/bipbuffer.c" that has errors. Add'-kernel-msg-key pp' for preprocessing command.
So bascially I am trying to open a C source file but it returns an error like this. I aslo tried other very simple C files like hello world and other slicing functions, it works well.
I thought it was because I didn't have the dependencies of 'event.h' but it still return these errors after I installed the libevent dependencies. I am not sure if I need to manually set some path of the dependencies for frama-c
Here is part of the C file (Source link: https://memcached.org/) that I would like to open:
#include "stdio.h"
#include <stdlib.h>
/* for memcpy */
#include <string.h>
#include "bipbuffer.h"
static size_t bipbuf_sizeof(const unsigned int size)
{
return sizeof(bipbuf_t) + size;
}
int bipbuf_unused(const bipbuf_t* me)
{
if (1 == me->b_inuse)
/* distance between region B and region A */
return me->a_start - me->b_end;
else
return me->size - me->a_end;
}
......
Thanks,
Compilers and other tools working with C source code need to know where to find header files. There are some standard places where they look automatically, but Frama-C has fewer of those than (and different ones from) a normal compiler.
You need to find out where event.h is installed, then pass something like -cpp-extra-args "-I /path/to/directory/" to Frama-C. Pass the directory name only, not including the name event.h itself.
In addition to Isabelle Newbie's answer, I'd like to point out that the Chlorine version of Frama-C, whose beta has been recently announced, features a new option -json-compilation-database that attempts to read the arguments to be passed to the pre-processor from a compilation database.
Such database can be generated directly by cmake, but there are solutions for make-based project such as the one you refer to, in particular bear, which intercepts the commands launched by make to build the database.
Here's a detailed summary of how you could proceed, using the new -json-compilation-database option from Frama-C 17 Chlorine, plus an extra script list_files.py (which is not in the beta, but will be available in the final 17 release, and can be downloaded here):
Get the source files you want to analyze with Frama-C, run ./configure, and if possible try to disable optional dependencies from external libraries; for instance, some code bases include optional dependencies based on availability of libraries/system features, but have fallback options (resorting to standard C library or POSIX functions). The more you give Frama-C, the better the chances of analyzing it well, so if such external libraries are not essential, excluding them might help get a more "POSIXy" code, which should help. This is typically visible in config.h files, in macros commonly named HAVE_*.
Compile and install Build EAR or some equivalent tool to obtain a compile_commands.json file.
Run bear make (or cmake with flag CMAKE_EXPORT_COMPILE_COMMANDS) to get the compile_commands.json file.
Run the aforementioned list_files.py in the directory containing compile_commands.json to obtain the list of C sources used during compilation.
Run Frama-C (17 Chlorine or newer), giving it the list of sources found in the previous step, plus option -json-compilation-database . to parse the compile_commands.json and, hopefully, get the appropriate preprocessing flags.
Ideally, this should suffice, but in practice, this is rarely enough. In particular due to the presence of external libraries and non-C99, non-POSIX functions, the following steps are always needed.
6. Inclusion of external libraries
At this step, Frama-C will complain about the lack of event.h. You'll have to include the headers of this library yourself. Note: copying headers directly from your /usr/include is not likely to work, due to several architecture-specific definitions, especially files such as bits/*.h..
Instead, consider downloading the external libraries and preparing them (e.g. running ./configure at least). Then manually add the extra include directory via -cpp-extra-args="-I <path/to/your/sources/for/libevent.h>/include".
7. Inclusion of missing non-POSIX headers
Some other headers may be missing, in particular GNU- or BSD-specific sources (e.g. sysexits.h). Get these headers and add them when necessary. The error message in this case comes from the preprocessor (gcc) and is similar to this:
memcached.c:51:10: fatal error: sysexits.h: No such file or directory
#include <sysexits.h>
^~~~~~~~~~~~
compilation terminated.
8. Definition of missing non-POSIX types and constants
At this point, all necessary headers should be available, but parsing with Frama-C may still fail. This is due to usage of non-POSIX type definitions (e.g. caddr_t, struct ling), non-POSIX constants (e.g. MAXPATHLEN, SOCK_NONBLOCK, NI_MAXSERV). Error messages typically resemble the following:
[kernel] memcached.c:3261: Failure: Cannot resolve variable MAXPATHLEN
Constants are often easy to provide manually, by grepping what's available in your /usr/include.
Type definitions, on the other hand, may require some copy-pasting at the right places, especially if they depend on other types which are also missing. This step is hardly automatizable, but relatively straightforward once you get used to some specific error messages.
For instance, the following error message is related to a missing type definition (caddr_t):
[kernel] Parsing memcached.c (with preprocessing)
[kernel] memcached.c:1074:
syntax error:
Location: line 1074, between columns 38 and 47, before or at token: c
1072 *hdr++ = 0;
1073 *hdr++ = 0;
1074 assert((void *) hdr == (caddr_t)c->msglist[i].msg_iov[0].iov_base + UDP_HEADER_SIZE);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1075 }
1076
Note that the token just before c is (caddr_t), which has never been defined (it is often defined as either void * or char *).
The following error message is related to an incomplete type, i.e., a struct used somewhere but never defined:
[kernel] memcached.c:5811: User Error:
variable `ling' has initializer but incomplete type
It means that variable ling's type, which is struct linger (non-POSIX), has never been defined. In this case, we can copy it from our /usr/include/bits/socket.h:
struct linger
{
int l_onoff; /* Nonzero to linger on close. */
int l_linger; /* Time to linger. */
};
Note: if there are POSIX constants/definitions missing from Frama-C's libc, consider notifying its developers, or proposing pull requests in Frama-C's Github.
9. Fixing incompatible and missing function prototypes
Parsing is likely to succeed after the previous step, but it may still fail due to incompatible function prototypes. For instance, you may get:
[kernel] User Error: Incompatible declaration for usleep:
different integer types int and unsigned int
First declaration was at assoc.c:238
Current declaration is at items.c:1573
This is the consequence of a warning emitted earlier:
[kernel:typing:implicit-function-declaration] slabs.c:1150: Warning:
Calling undeclared function usleep. Old style K&R code?
It means that function usleep is called, but it does not have a prototype, therefore Frama-C uses the pre-C99 convention of "implicit int": it generates such a prototype, but later in the code, an actual declaration of usleep is found, and its type is not int. Hence the error.
To prevent this, you need to ensure usleep's prototype is properly included. Since it is not POSIX.1-2008, you need to either define/undefine the appropriate macros (see unistd.h), or add your own prototype.
At the end, this should allow Frama-C to parse the files and build an AST.
However, there are several missing prototypes yet; we were just lucky that none conflicted with actual declarations. Ideally, you'll consider the parsing stage done when there are no more messages such as implicit-function-declaration and similar warnings.
Some of the missing prototypes in memcached, such as getsubopt, are POSIX and should be integrated into Frama-C's standard library. Others might make part of a small library of non-standard stubs, to be reused for other software.
Contributing with results for future reuse
Successful conclusion of the parsing stage for such open source libraries is enough to consider them for integration into this repository of open source case studies, so that future users can start their analyses without having to redo all of these steps. (The repository is oriented towards Eva, but not exclusively: parsing is useful for all of Frama-C plug-ins.)

Default sequence of debhelper

I am trying to get a better understanding of debhelper's dh tool. As I understand it, dh is a frontend for various dh_* helper tools. These helper tools can both be called standalone or automatically from the dh tool. Usually a debian/rules file is created which somehow invokes dh and possibly overrides certain dh_* invocations. dh then seems to know which of the dh_* tools it needs to invoke and in which sequence.
The example under /usr/share/doc/debhelper/examples/rules.tiny contains the following as an example for a debian/rules file:
#!/usr/bin/make -f
%:
dh $#
What is the sequence of dh_* helper tools that gets executed by dh as result of this rules file? And more importantly, how does dh determine this sequence and where is this documented.
The sequence of helper tools that will get executed depends on a few things:
what build target is being passed. these include: build-arch, build-indep, build, clean, install-indep, install-arch, install, binary-arch, binary-indep, and binary. The meanings of (most of) these are discussed in Debian Policy §4.9.
the Debhelper compat level (as found in the debian/compat file)
your version of Debhelper (although an effort is made to make different versions work the same given the same compat level)
what helper commands have already been run since the last clean (in debhelper compat levels 9 and lower)
what addons are being used (the --with and --without options)
what override targets exist in the makefile (e.g. override_dh_auto_test)
As you can see, it could be confusing to document which commands are run, in which order, for all the possible build targets and configuration arrangements (or even just for the most common ones). The way to know, therefore, is to use the --no-act argument to dh, with your build directory set up the way you want it.
Here is an example run with the binary target in a dummy build directory I've just made using dh_make, put into compat level 10. The exact commands or the exact ordering you will see will likely be slightly different:
~/dh-demo$ dh binary --no-act
dh_testdir
dh_update_autotools_config
dh_autoreconf
dh_auto_configure
dh_auto_build
dh_auto_test
dh_testroot
dh_prep
dh_installdirs
dh_auto_install
dh_install
dh_installdocs
dh_installchangelogs
dh_installexamples
dh_installman
dh_installcatalogs
dh_installcron
dh_installdebconf
dh_installemacsen
dh_installifupdown
dh_installinfo
dh_systemd_enable
dh_installinit
dh_systemd_start
dh_installmenu
dh_installmime
dh_installmodules
dh_installlogcheck
dh_installlogrotate
dh_installpam
dh_installppp
dh_installudev
dh_installgsettings
dh_bugfiles
dh_ucf
dh_lintian
dh_gconf
dh_icons
dh_perl
dh_usrlocal
dh_link
dh_installwm
dh_installxfonts
dh_strip_nondeterminism
dh_compress
dh_fixperms
dh_strip
dh_makeshlibs
dh_shlibdeps
dh_installdeb
dh_gencontrol
dh_md5sums
dh_builddeb

Call Rmath via Ctypes from Ocaml on OS X

I want to use R's mathematical functions as provided in libRmath from Ocaml. I successfully installed the library via brew tap homebrew science && brew install --with-librmath-only r. I end up with a .dylib in /usr/local/lib and a .h in /usr/local/include. Following the Ocaml ctypes tutorial, i do this in utop
#require "ctypes.foreign";;
open Ctypes;;
open Foreign;;
let test_pow = foreign "pow_di" (float #-> int #-> returning float);;
this complains that it can't find the symbol. What am I doing wrong? Do I need to open the dynamic library first? Set some environment variables? After googling, I also did this:
nm -gU /usr/local/lib/libRmath.dylib
which gives a bunch of symbols all with a leading underscore including 00000000000013ff T _R_pow_di. In the header file, pow_di is defined via some #define directive from _R_pow_di. I did try variations of the name like "R_pow_di" etc.
Edit: I tried compiling a simple C program using Rmath using Xcode. After setting the include path manually to include /usr/local/include, Xcode can find the header file Rmath.h. However, inside the header file, there is an include of R_ext/Boolean.h which does not seem to exist. This error is flagged by Xcode and compilation stops.
Noob alert: this may be totally obvious to a C programmer...
In order to use external library you still need to link. There're at least two different ways, either link using compiler, or link even more dynamically using dlopen.
For the first method use the following command (as an initial approximation):
ocamlbuild -pkg ctypes.foreign -lflags -cclib,-lRmath yourapp.native
under premise that your code is put into yourapp.ml file.
The second method is to use ctypes interface to dlopen to open the library. Using the correct types and name for the C function call, this goes like this:
let library = Dl.dlopen ~filename:"libRmath.dylib" ~flags:[]
let test_pow = foreign ~from:library "R_pow_di" (double #-> int #-> returning double)

Does sbt have something like gradle's processResources task with ReplaceTokens support?

We are moving into Scala/SBT from a Java/Gradle stack. Our gradle builds were leveraging a task called processResources and some Ant filter thing named ReplaceTokens to dynamically replace tokens in a checked-in .properties file without actually changing the .properties file (just changing the output). The gradle task looks like:
processResources {
def whoami = System.getProperty( 'user.name' );
def hostname = InetAddress.getLocalHost().getHostName()
def buildTimestamp = new Date().format('yyyy-MM-dd HH:mm:ss z')
filter ReplaceTokens, tokens: [
"buildsig.version" : project.version,
"buildsig.classifier" : project.classifier,
"buildsig.timestamp" : buildTimestamp,
"buildsig.user" : whoami,
"buildsig.system" : hostname,
"buildsig.tag" : buildTag
]
}
This task locates all the template files in the src/main/resources directory, performs the requisite substitutions and outputs the results at build/resources/main. In other words it transforms src/main/resources/buildsig.properties from...
buildsig.version=#buildsig.version#
buildsig.classifier=#buildsig.classifier#
buildsig.timestamp=#buildsig.timestamp#
buildsig.user=#buildsig.user#
buildsig.system=#buildsig.system#
buildsig.tag=#buildsig.tag#
...to build/resources/main/buildsig.properties...
buildsig.version=1.6.5
buildsig.classifier=RELEASE
buildsig.timestamp=2013-05-06 09:46:52 PDT
buildsig.user=jenkins
buildsig.system=bobk-mbp.local
buildsig.tag=dev
Which, ultimately, finds its way into the WAR file at WEB-INF/classes/buildsig.properties. This works like a champ to record build specific information in a Properties file which gets loaded from the classpath at runtime.
What do I do in SBT to get something like this done? I'm new to Scala / SBT so please forgive me if this seems a stupid question. At the end of the day what I need is a means of pulling some information from the environment on which I build and placing that information into a properties file that is classpath loadable at runtime. Any insights you can give to help me get this done are greatly appreciated.
The sbt-buildinfo is a good option. The README shows an example of how to define custom mappings and mappings that should run on each compile. In addition to the straightforward addition of normal settings like version shown there, you want a section like this:
buildInfoKeys ++= Seq[BuildInfoKey](
"hostname" -> java.net.InetAddress.getLocalHost().getHostName(),
"whoami" -> System.getProperty("user.name"),
BuildInfoKey.action("buildTimestamp") {
java.text.DateFormat.getDateTimeInstance.format(new java.util.Date())
}
)
Would the following be what you're looking for:
sbt-editsource: An SBT plugin for editing files
sbt-editsource is a text substitution plugin for SBT 0.11.x and
greater. In a way, it’s a poor man’s sed(1), for SBT. It provides the
ability to apply line-by-line substitutions to a source text file,
producing an edited output file. It supports two kinds of edits:
Variable substitution, where ${var} is replaced by a value. sed-like
regular expression substitution.
This is from Community Plugins.

AFP Dijkstra's Shortest Path Algorithm

For the AFP entry Dijkstra's Shortest Path Algorithm, both the proof outline and proof document were nonexistent *. Unfortunately, I did not find an IsaMakefile either to build those documents locally. What is the best way to get those documents?
Another question, as the Dijkstra.thy depends on a lot of other theories, is there a way to load everything faster?
*) It is fixed now.
(There seems to be something broken at AFP right now, please tell the editors about it.)
In general, you can download the sources of AFP entries and produce the documents yourself like this:
Get and unpack all AFP sources -- downloading separate entries is offered as well, but then you have to disentangle dependencies manually.
Invoke isabelle build like this:
isabelle build -d afp-2013-03-02 -o document=pdf -v Dijkstra_Shortest_Path
Here afp-2013-03-02 is the directory that was obtained by unpacking the current AFP sources.
See also the Isabelle System manual about "Isabelle sessions and build management", which is all new in Isabelle2013.
See isabelle build -b there to make things load faster, by producing persistent heap images from sessions.
The links in the AFP entry were indeed broken and should now be fixed again, sorry about that.
As Makarius writes, the AFP new uses Isabelle's new build system, i.e. has a ROOT file for each entry that can be used to check the associated theories and build the document.
Makarius' answer is pretty much the official way to do it, although I would additionally recommend setting up the AFP as a component. This gives you the following steps:
Download the AFP to e.g. ~/afp
Set it up as component e.g. by adding ~/afp to ~/.isabelle/Isabelle2013/components (see also AFP as a component)
build the entry with
isabelle afp_build Dijkstra_Shortest_Path
You can also have jEdit build the heap image for you. If the AFP is setup as a component (see the other answers for that), just start jEdit with
isabelle jedit -d '$AFP' -l Dijkstra_Shortest_Path
and jEdit will select Dijkstra_Shortest_Path as base logic and (re)build it if necessary.
If you make regular use of the AFP, it might be useful to add the AFP path by default. For this, create a file ROOTS in $ISABELLE_HOME_USER with the line $AFP in it (or add this line, if the file already exists).

Resources