Error: Unbound module ... in Ocaml - ocaml

I have just installed a library called Apron, the installation seems to be done:
#ubuntu$ find -name "*apron*"
./lib/libapron_debug.so
./lib/libapron.a
./lib/libapron.so
./lib/libapron_debug.a
./local/lib/ocaml/3.11.2/stublibs/dllapron_caml.so.owner
./local/lib/ocaml/3.11.2/stublibs/dllapron_caml.so
./local/lib/ocaml/3.11.2/apron
./local/lib/ocaml/3.11.2/apron/libapron_caml_debug.a
./local/lib/ocaml/3.11.2/apron/apron.cmxa
./local/lib/ocaml/3.11.2/apron/libapron_caml.a
./local/lib/ocaml/3.11.2/apron/apron.cmi
./local/lib/ocaml/3.11.2/apron/apron.cmx
./local/lib/ocaml/3.11.2/apron/apron.a
./local/lib/ocaml/3.11.2/apron/apron.cma
And I tried a first example:
(* with default setting:
apronppltop -I $MLGMPIDL_INSTALL/lib -I $APRON_INSTALL/lib
#load "gmp.cma";;
#load "apron.cma";;
#load "box.cma";;
#load "oct.cma";;
#load "polka.cma";;
#load "ppl.cma";;
#load "polkaGrid.cma";;
#install_printer Apron.Linexpr1.print;;
#install_printer Apron.Texpr1.print;;
#install_printer Apron.Lincons1.print;;
#install_printer Apron.Generator1.print;;
#install_printer Apron.Abstract1.print;;
let environment_print fmt x = Apron.Environment.print fmt x;;
let lincons1_array_print fmt x = Apron.Lincons1.array_print fmt x;;
let generator1_array_print fmt x = Apron.Generator1.array_print fmt x;;
#install_printer Apron.Var.print;;
#install_printer environment_print;;
#install_printer lincons1_array_print;;
#install_printer generator1_array_print;; *)
open Apron;;
...
However ocaml -c file.ml gives me Error: Unbound module Apron which happens on open Apron;;
Does anyone know why I could not load the Apron module? Thank you very much!

I should indicate the path of the Apron library with '-I' options. As it is installed in the standard library of OCaml, you only need to compile with:
ocamlc -I +apron -c file.ml

Related

How to get system page size in OCaml

I have searched in modules Sys, Gc, and Unix, but did not find a means to get the system page size in OCaml. How can we get the system page size?
I have OCaml 4.06 and macOS 10.12.6 (Sierra)
If you just want the answer for MacOS, there is a pagesize command that you can run with Unix.open_process_in:
$ rlwrap ocaml
OCaml version 4.06.0
# #load "unix.cma";;
# Unix.open_process_in "pagesize" |> input_line |> int_of_string;;
- : int = 4096
Update
There is a POSIX command line program getconf that is quite portable, I believe. It works on macOS and all the versions of Linux I tried. You can use that instead:
$ rlwrap ocaml
OCaml version 4.06.0
# #load "unix.cma";;
# Unix.open_process_in "getconf PAGE_SIZE" |> input_line |> int_of_string;;
- : int = 4096
You can call sysconf(SC_PAGESIZE) from ocaml to get that information. You can either do that using a .c file, or using ctypes (although you'll need the value of the SC_PAGESIZE, so it might not be the best solution):
% utop -require ctypes.foreign
# open Foreign;;
# open Ctypes;;
# let sysconf = foreign "sysconf" (int #-> returning long);;
val sysconf : int -> Signed.long = <fun>
# sysconf 30;;
- : Signed.long = <long 4096>

How do I setup ocamlinit so that ppx works?

This is my ocamlinit:
(* Added by OPAM. *)
let () =
try Topdirs.dir_directory (Sys.getenv "OCAML_TOPLEVEL_PATH")
with Not_found -> ()
;;
(* ## added by OPAM user-setup for ocamltop / base ## 3ec62baf6f9c219ae06d9814069da862 ## you can edit, but keep this line *)
#use "topfind";;
(* ## end of OPAM user-setup addition for ocamltop / base ## keep this line *)
#thread;;
(* #ppx "ppx-jane -as-ppx";; *)
#require "ppx_jane";;
#require "core.top";;
#require "async";;
#require "core_extended";;
open Core.Std;;
With this exactly, I get this in utop
utop # type test = char list [##deriving show];;
Error: Cannot locate deriver show
If I use the line beginning with #ppx instead of #require "ppx_jane", I get this error
utop # type test = char list [##deriving show];;
Error: ppx_type_conv: 'show' is not a supported type type-conv generator
How should I set up ocamlinit to use [##deriving show]?
I managed to have it working using #require "ppx_deriving.show";; (with or without #require "ppx_jane";;).
In addition to Pierre's suggestion, I found that I needed the line with ppx_jane.
Also, I used #require "ppx_deriving.std" instead of just ppx_deriving.show to get ord and the rest of the stuff too.
Here's my full ocamlinit
(* Added by OPAM. *)
let () =
try Topdirs.dir_directory (Sys.getenv "OCAML_TOPLEVEL_PATH")
with Not_found -> ()
;;
(* ## added by OPAM user-setup for ocamltop / base ## 3ec62baf6f9c219ae06d9814069da862 ## you can edit, but keep this line *)
#use "topfind";;
(* ## end of OPAM user-setup addition for ocamltop / base ## keep this line *)
#thread;;
#require "ppx_jane";;
#require "core.top";;
#require "async";;
#require "core_extended";;
#require "ppx_deriving.std";;
open Core.Std;;

OCaml refer to module in ml file inside mli

Here I have a file set.ml with a module called IntSet. How do I refer to the module IntSet inside the corresponding interface file set.mli?
module IntSet = struct
type t = int list;;
let empty = [];;
let rec is_member key = function
| [] -> false
| (x::xs) -> (
if x = key then true
else is_member key xs
);;
end;;
let join xs ys = xs # ys;;
Here is set.mli
val join : IntSet.t -> IntSet.t -> IntSet.t
If I try to compile it, I get an error claiming that the module IntSet is unbound.
% corebuild set.native
+ ocamlfind ocamlc -c -w A-4-33-40-41-42-43-34-44 -strict-sequence -g -bin-annot -short-paths -thread -package core -ppx 'ppx-jane -as-ppx' -o set.cmi set.mli
File "set.mli", line 1, characters 11-19:
Error: Unbound module IntSet
Command exited with code 2.
Hint: Recursive traversal of subdirectories was not enabled for this build,
as the working directory does not look like an ocamlbuild project (no
'_tags' or 'myocamlbuild.ml' file). If you have modules in subdirectories,
you should add the option "-r" or create an empty '_tags' file.
To enable recursive traversal for some subdirectories only, you can use the
following '_tags' file:
true: -traverse
<dir1> or <dir2>: traverse
Compilation unsuccessful after building 3 targets (1 cached) in 00:00:00.
How do I expose a module defined in set.ml so I can use it in definitions?
I changed set.mli to this, and the compiler seems happy:
module IntSet : sig type t end
val join : IntSet.t -> IntSet.t -> IntSet.t
There is probably more work to make things usable. There's no way to make a value of type IntSet.t, for example.

Use OUnit module in OCaml - Unbound module OUnit error

I'm trying to use OUnit with OCaml.
The unit code source (unit.ml) is as follows:
open OUnit
let empty_list = []
let list_a = [1;2;3]
let test_list_length _ =
assert_equal 1 (List.length empty_list);
assert_equal 3 (List.length list_a)
(* etc, etc *)
let test_list_append _ =
let list_b = List.append empty_list [1;2;3] in
assert_equal list_b list_a
let suite = "OUnit Example" >::: ["test_list_length" >:: test_list_length;
"test_list_append" >:: test_list_append]
let _ =
run_test_tt_main suite
With ocamlc unit.ml, I got an error message Error: Unbound module OUnit. Why is this? How can I use the OUnit in OCaml. I installed OUnit with opam.
You should use for example:
ocamlfind ocamlc -package oUnit -linkpkg -o unit unit.ml
ocamlfind is an utility that encapsulates lookup of installed libraries. You can also avoid composing compiler-invocation yourself and use a build tool.

Building a haskell interpreter (hint) as dynamic library, useable from C++: Missing Interpreter.dyn_hi

I want to create a haskell interpreter that I can use from C++ on linux.
I have a file FFIInterpreter.hs which implements the interpreter in haskell and exports the functions via FFI to C++.
module FFIInterpreter where
import Language.Haskell.Interpreter
import Data.IORef
import Foreign.StablePtr
import Foreign.C.Types
import Foreign.C.String
import Control.Monad
import Foreign.Marshal.Alloc
type Session = Interpreter ()
type Context = StablePtr (IORef Session)
foreign export ccall createContext :: CString -> IO Context
createContext :: CString -> IO Context
createContext name = join ((liftM doCreateContext) (peekCString name))
where
doCreateContext :: ModuleName -> IO Context
doCreateContext name
= do let session = newModule name
_ <- runInterpreter session
liftIO $ newStablePtr =<< newIORef session
newModule :: ModuleName -> Session
newModule name = loadModules [name] >> setTopLevelModules [name]
foreign export ccall freeContext :: Context -> IO ()
freeContext :: Context -> IO ()
freeContext = freeStablePtr
foreign export ccall runExpr :: Context -> CString -> IO CString
runExpr :: Context -> CString -> IO CString
runExpr env input = join ((liftM newCString) (join (((liftM liftM) doRunExpr) env (peekCString input))))
where
doRunExpr :: Context -> String -> IO String
doRunExpr env input
= do env_value <- deRefStablePtr env
tcs_value <- readIORef env_value
result <- runInterpreter (tcs_value >> eval input)
return $ either show id result
foreign export ccall freeString :: CString -> IO ()
freeString :: CString -> IO ()
freeString = Foreign.Marshal.Alloc.free
When I compile the whole project with ghc, everything works fine. I use the following command:
ghc -no-hs-main FFIInterpreter.hs main.cpp -lstdc++
But the haskell module is only a small piece of the C++ project and I don't want the whole project to depend on ghc.
So I want to build a dynamic library with ghc and then link it to the project using g++.
$ ghc -shared -fPIC FFIInterpreter.hs module_init.c -lstdc++
[1 of 1] Compiling FFIInterpreter ( FFIInterpreter.hs, FFIInterpreter.o )
Linking a.out ...
/usr/bin/ld: /usr/lib/haskell-packages/ghc/lib/hint-0.3.3.2/ghc-7.0.3/libHShint-0.3.3.2.a(Interpreter.o): relocation R_X86_64_32S against `.data' can not be used when making a shared object; recompile with -fPIC
/usr/lib/haskell-packages/ghc/lib/hint-0.3.3.2/ghc-7.0.3/libHShint-0.3.3.2.a: could not read symbols: Bad value
collect2: ld gab 1 als Ende-Status zurück
So I added the -dynamic keyword, but that also doesn't work:
$ ghc -dynamic -shared -fPIC FFIInterpreter.hs librarymain.cpp -lstdc++
FFIInterpreter.hs:3:8:
Could not find module `Language.Haskell.Interpreter':
Perhaps you haven't installed the "dyn" libraries for package `hint-0.3.3.2'?
Use -v to see a list of the files searched for.
I searched my system for Interpreter.dyn_hi but didn't find it. Is there a way to get it?
I also tried to install hint manually, but this also doesn't deliver the Interpreter.dyn_hi file.
You have to install the library (and all it depends on) with the --enable-shared flag (using cabal-install) to get the .dyn_hi and .dyn_o files. You may consider setting that option in your ~/.cabal/config file.
Perhaps the easiest way is to uncomment the shared: XXX line in ~/.cabal/config, set the option to True and
cabal install --reinstall world
For safety, run that with the --dry-run option first to detect problems early. If the --dry-run output looks reasonable, go ahead and reinstall - it will take a while, though.