Z3 bindings on ocaml - ocaml

I am currently using ocaml 4.06.0 and I am trying to use the Z3 sat solver. I am using opam's oasis to compile the files (which is building everything successfully). However, when I run the native code produced I am getting the following error: error while loading shared libraries: libz3.so. I tried reinstalling the z3 package but the error still persists. Can anyone help me solve this please because I have no idea what else to try?

Here is what I did just now to install z3 under Ubuntu 18.04.1:
$ opam depext conf-gmp.1
$ opam depext conf-m4.1
These installed gmp and m4 outside of opam. Pretty impressive.
$ opam install z3
Now the z3 library is installed so you can use it from OCaml code. But there are no executables installed (that I can find).
$ export LD_LIBRARY_PATH=~/.opam/4.06.0/lib/z3
$ ocaml -I ~/.opam/4.06.0/lib/z3
OCaml version 4.06.0
# #load "nums.cma";;
# #load "z3ml.cma";;
# let ctx = Z3.mk_context [];;
val ctx : Z3.context = <abstr>
The setting of LD_LIBRARY_PATH is what makes it possible to find libz3.so.
This is as far as I got for now. Maybe this will be helpful.
Update
Here is how I compiled and linked a test program.
$ export LD_LIBRARY_PATH=~/.opam/4.06.0/lib/z3
$ cat tz3.ml
let context = Z3.mk_context []
let solver = Z3.Solver.mk_solver context None
let xsy = Z3.Symbol.mk_string context "x"
let x = Z3.Boolean.mk_const context xsy
let () = Z3.Solver.add solver [x]
let main () =
match Z3.Solver.check solver [] with
| UNSATISFIABLE -> Printf.printf "unsat\n"
| UNKNOWN -> Printf.printf "unknown"
| SATISFIABLE ->
match Z3.Solver.get_model solver with
| None -> ()
| Some model ->
Printf.printf "%s\n"
(Z3.Model.to_string model)
let () = main ()
$ ocamlopt -I ~/.opam/4.06.0/lib/z3 -o tz3 \
nums.cmxa z3ml.cmxa tz3.ml
$ ./tz3
(define-fun x () Bool
true)
$ unset LD_LIBRARY_PATH
$ ./tz3
./tz3: error while loading shared libraries: libz3.so:
cannot open shared object file: No such file or directory
It works--i.e., it says that the trivial formula x can be satisfied by making x be true.
Note: initially I thought the setting of LD_LIBRARY_PATH wasn't necessary here. But in later testing I've found that it is necessary. So that is probably the key to your problem.
It's a little cumbersome and error prone to set LD_LIBRARY_PATH for running your programs. It's good enough for personal testing, but probably not for any kind of wider deployment. There are ways to set the search path for shared libraries at link time.
I hope this helps.

Related

How to force ppx to use an OCaml version?

I have the below OCaml file which compiles correctly without ppx and fails with this dune file
(library
(name so_proj)
(preprocess
(pps
ppx_inline_test
ppx_deriving.show
ppx_deriving.ord
ppx_deriving.map
ppx_deriving.eq
ppx_deriving.fold
ppx_deriving.iter)))
and works with
(library
(name so_proj))
the error being
File "SO_naming_existential.ml", line 23, characters 16-18:
23 | fun (Mod (type xr) (m : xr)) ->
^^
Error: migration error: existentials in pattern-matching is not supported before OCaml 4.13
here's the OCaml file in question which uses a new syntax (and provides an equivalent - I believe - version when it's not available)
type existentiel = Mod : 'x -> existentiel
module type existentiel_m = sig
type x
val value : x
end
let to_Module : existentiel -> (module existentiel_m) =
fun (Mod m) ->
let namedxr : type xr. xr -> (module existentiel_m) =
fun v ->
(module struct
type x = xr
let value = v
end)
in
namedxr m
(* Since 4.13 https://github.com/ocaml/ocaml/pull/9584 *)
let to_Module2 : existentiel -> (module existentiel_m) =
fun (Mod (type xr) (m : xr)) ->
(module struct
type x = xr
let value = m
end)
To confirm the origin of the error (and to run first for avoiding to waste time..) the command
dune build --verbose points indeed at an error happening in ppx
Running[2]: (cd _build/default && .ppx/0789030747a4993265eb655c993f5cab/ppx.exe --cookie 'inline_tests="enabled"' --cookie 'library-name="so_proj"' -o SO_naming_existential.pp.ml --impl SO_naming_existential.ml -corrected-suffix .ppx-corrected -diff-cmd - -dump-ast)
Command [2] exited with code 1:
$ (cd _build/default && .ppx/0789030747a4993265eb655c993f5cab/ppx.exe --cookie 'inline_tests="enabled"' --cookie 'library-name="so_proj"' -o SO_naming_existential.pp.ml --impl SO_naming_existential.ml -corrected-suffix .ppx-corrected -diff-cmd - -dump-ast)
File "SO_naming_existential.ml", line 23, characters 16-18:
23 | fun (Mod (type xr) (m : xr)) ->
^^
Error: migration error: existentials in pattern-matching is not supported before OCaml 4.13
Can one force ppx to use 4.13, or get a warning when a ppx is not compatible with a given version ? (or is it a bug ?)
An executable or a library could only be composed of compilation units that are compiled by the same compiler. In other words, you can't build some parts of your project with one compiler and the other parts with another.
When you compile an OCaml project using dune the compiler is searched in the in the directories specified in your PATH variable (in Linux). You can see which compiler is selected using the shell command which ocaml. And ocaml -version will tell you its version.
If you're using opam (most likely you are), then you can install the required version of the compiler using the following shell command,
opam switch create 4.13.1
once it is finished, activate the created switch with
eval $(opam env)
This will ensure that the newly installed version of OCaml is available in your path. Double-check that using which ocaml and ocaml -version.
Finally, install the dependencies required by your project with opam install and rebuild the project.

When are OCaml expressions at the top level of a file evaluated?

It seems that OCaml runs some expressions at compile-time; e.g., if I write
let (_ : int) = 1 / 0
at the top level of a file, the compiler will fail with an "Uncaught exception: Division_by_zero" error.
Does this mean that these values are computed at compile time in the binary? e.g., if I was using Core, and I wrote
open! Core
let date = Date.today ~zone:(force Time.Zone.local)
would this refer to the date at the time of compilation, or something else, like the date when the program is executed?
I can't reproduce the behavior you describe. Here's what I see:
$ cat dz.ml
let (_ : int) = 1 / 0
$ ocamlc -c dz.ml
$ ocamlopt -c dz.ml
The two OCaml compilers are ocamlc and ocamlopt, and neither of them shows this behavior on my system.
It would help if you give a specific sequence of commands to reproduce what you observe.

Frama-C Aluminum "Unbound module GMenu"

On Fedora 21, I compiled the Frama-C Aluminum distribution from source after installing all its prerequisites. My version of OCaml is 4.02.3. Frama-C and the Frama-C GUI work fine. I am trying to follow section 2.3, "The ViewCfg plug-in" of the Frama-C Plug-In Development Guide. However, in section 2.3.4, "Extending the Frama-C GUI", after I add the GUI extension code and run it using the "-load-script" option, I get the following message:
File "cfg_print.ml", line 87, characters 19-43:
Error: Unbound module GMenu
[kernel] user error: compilation of 'cfg_print.ml' failed
Lines 86-87 read:
let cfg_selector
(popup_factory:GMenu.menu GMenu.factory) main_ui ~button:_ localizable =
I googled "unbound module gmenu" but didn't find anything useful. I also never ran into this error while using the Neon and Sodium versions of Frama-C. Interestingly, if I skip that section and follow section 2.3.5, "Splitting files and writing a Makefile", I no longer get the "Unbound module GMenu" message, and the example works fine.
If I had to guess, when I use the "-load-script" option, Frama-C (or my version of OCaml, whatever the case may be) apparently cannot find the Gtk libraries for some reason. But if I use make, OCaml can find the Gtk libraries. Is there something possibly wrong with the way I installed Frama-C and/or the Gtk libraries? How can I check this, or more importantly, how can I fix this?
Your Frama-C installation is probably ok. What you observe is a bug that was introduced when we transitioned to OCamlfind. We will fix it for Frama-C Silicium.
In case you really want to use a script, here is the patch that you need to apply to the sources of Frama-C:
--- a/src/kernel_services/plugin_entry_points/dynamic.ml
+++ b/src/kernel_services/plugin_entry_points/dynamic.ml
## -236,7 +236,7 ## let load_script base =
else
Format.fprintf fmt "%s -c" Config.ocamlc ;
Format.fprintf fmt " -w Ly -warn-error A -I %s" Config.libdir ;
- if !Config.is_gui then Format.pp_print_string fmt " -I +lablgtk" ;
+ if !Config.is_gui then Format.pp_print_string fmt " -package lablgtk2" ;
List.iter (fun p -> Format.fprintf fmt " -I %s" p) !load_path ;
Format.fprintf fmt " %s.ml" base ;
Format.pp_print_flush fmt () ;

OCaml - compiling a program as a library

I have an OCaml program(with a main method - it generates an executable) and I want to use it as a library.
I was compiling my program like this: ocamlc -I someDir -g -unsafe lotsOfCmoFiles -o outputFile and the program works fine.
Now I'm removing the line that makes it an executable(something like let _ = ...) and adding -a parameter to compile command: ocamlc -a -I someDir -g -unsafe lotsOfCmoFiles -o outputFile.cma
But somehow I can't load generated .cma file with ocamltop and ocamlbrowser shows an empty list. When I try to load from ocamltop:
# #load "outputFile.cma";;
Error: Reference to undefined global `Xyz'
And I'm 100% sure that xyz.cmo is included in lotsOfCmoFiles.
Am I giving some parameter wrong while compiling? Or else, what should I do to load my program in ocamltop ? (I'll use this library in another program, I'm giving ocamltop outputs as an example)
Any helps will be appreciated.
EDIT: So I can finally managed to compile and load it thanks to #cago, now I can load my library, and when I don't remove the main let _ = ... line it's automatically run when I load the .cma.
But I still can't open any modules. Strangely, this doesn't raise an exception
open Main
but then when I call a function from module Main:
# someFun;;
Error: Reference to undefined global `Main'
and ocamlbrowse still shows an empty list. now why is that?
EDIT2: I realized open Main doesn't fail because I have a Main module in the same folder(even though I didn't explicitly load it). If I move my .cma file somewhere else and load it, it works(ie. main function runs automatically), but now I can't open any modules even though ocamlobjinfo shows the modules.
EDIT3: -I doesn't help:
$ ocaml
OCaml version 4.00.1
# #load "lib.cma";;
ok
# open Lib;;
Error: Unbound module Lib
#
$ ocaml -I libFolder
OCaml version 4.00.1
# #load "toylib.cma";;
ok
# open Lib;;
# fun;;
Error: Reference to undefined global `Lib'
Some of the cmo in your lotsOfCmoFiles need to know the module Xyz. You need to take care of the dependency between your cmo files.
For example:
toto.ml:
let x = "toto"
titi.ml:
let y = Toto.x ^ " titi"
ocamlc -c toto.ml
ocamlc -c titi.ml
ocamlc -a titi.cmo toto.cmo -o lib.cma (* here is the probleme *)
# #load "lib.cma"
Error: Reference to undefined global `Toto'
Because titi depends on toto so you need to change the order of cmos:
ocamlc -a toto.cmo titi.cmo -o lib.cma
# #load "lib.cma"
# Titi.y;;
- : string = "toto titi"
EDIT:
If your cma is in a subdirectory for example, when you call ocaml you need to specify the path:
ocaml -I subdir/ (* subdir which contains lib.cma *)
# #load "lib.cma"
# Toto.x;;
- : string = "toto"
TL;DR: Make sure you don't have any top-level side-effects in the
I was running into this same kind of trouble. My project would build fine, most modules were available, but there was one module that kept triggering Reference to undefined global. But it was clear that the module was visible to the system: it was showing up in utop's autocomplete list, along with all of it's values, and I could reference it and import it into other modules.
The problem turned out to be an uncaught exception that was being thrown when that module was loaded. The exception was due to an attempt to load a non-existing file. It wouldn't cause problems during complication, but when the module was actually loaded it was breaking and the exception was being swallowed somewhere before I ever saw it.

Error: Unbound value Ppl.manager_alloc_strict

I just installed a package called Ppl, here is the result of find -name "*ppl.*" under /usr/:
./lib/libppl.so.7.1.0
./lib/libppl.so.7
./lib/libcloog-ppl.so.0
./local/share/man/man3/libppl.3
./local/share/aclocal/ppl.m4
./local/include/ppl.hh
./local/lib/libppl.so
./local/lib/libppl.la
./local/lib/libppl.a
./local/lib/libppl.so.9
./local/lib/libppl.so.9.0.0
But when I run the following code by ocamlc -I /usr/local/lib/ocaml/3.11.2/apron -I /usr/local/lib/ocaml/3.11.2/gmp/ -I /usr/local/lib/ -c file.ml, I got an error Unbound value Ppl.manager_alloc_strict.
open Apron;;
open Mpqf;;
open Format;;
let print_array = Abstract0.print_array;;
let lincons1_array_print fmt x =
Lincons1.array_print fmt x
;;
let generator1_array_print fmt x =
Generator1.array_print fmt x
;;
let manpk = Polka.manager_alloc_strict();;
let manbox = Box.manager_alloc ();;
let manoct = Oct.manager_alloc ();;
let manppl = Ppl.manager_alloc_strict();;
...
Does anyone know what happened? Thank you very much!
You've showed us the library, but not anything regarding the OCaml interface to the library -- cmx or cmxa for native compilation. Just as the comment I left prior, do the same thing with where Ppl package for OCaml is. OCaml is not interfacing with the C library directly (.a, .so), but through a compiled interface (cmxa or cmi files).
You might also consider using the ocamlbuild system. You can tag modules with external dependencies, and have the build system find the package (via ocamlfind, or hard-coded).