Error: Reference to undefined global `Num'
Asked Answered
L

3

11

I'm trying to use the Num module in OCaml (bignums and big fractions). Some things seem to be working, while others seem not to, and I'm not able to generate a single, complete example. For instance:

# Num.Int(234);;
- : Num.num = Num.Int 234
# Num.mult_num;;
Characters -1--1:
  Num.mult_num;;
Error: Reference to undefined global `Num'

May I ask for a simple example of multiplying two bignums?

The reference for Num is here.

Lapoint answered 14/6, 2015 at 13:52 Comment(0)
U
13

If the toplevel is already launched, you can dynamically load the library:

# #load "nums.cma";;
# Num.mult_num;;
- : Num.num -> Num.num -> Num.num = <fun>

Another possibility (which will work for all third party libraries and will manage paths and dependencies for you) is to use ocamlfind. For this, issue

#use "topfind";;

(or better put it in your ~/.ocamlinit file). To load a library, just do

# #require "num";;
/usr/lib/ocaml/nums.cma: loaded
/home/user/.opam/system/lib/num-top: added to search path
/home/user/.opam/system/lib/num-top/num_top.cma: loaded
/home/user/.opam/system/lib/num: added to search path

(If ocamlfind — hence topfind — is not available, install it using opam.)

Here is an example of multiplication:

# Num.(num_of_int 30 */ num_of_int 1234);;
- : Num.num = Num.Int 37020

The construction Num.(e) is a shorthand for let open Num in e and makes possible to use the Num functions without prefix in e. Here is a definition of the factorial:

# let rec fac n =
    let open Num in
    if n =/ Int 0 then Int 1 else n */ fac (n -/  Int 1);;
val fac : Num.num -> Num.num = <fun>

You can try it with

# fac Num.(Int 100);;
- : Num.num = Num.Big_int <abstr>

If you used #require, it installs a pretty printer for Num values so the previous interaction looks like:

# fac Num.(Int 100);;
- : Num.num =
<num 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000>

which is much easier to read!

Urfa answered 15/6, 2015 at 6:22 Comment(1)
You taught me tons of ocaml in a single reply! Thanks!Lapoint
R
6

The Num module is provided by a library which is not linked by default. You need to pass the library on the linker or toplevel command line. You can use types (e.g. Num.num) and constructors (e.g. Num.Int) from the module, because they only require static (compile-time) information, but using variables (including functions, e.g. Num.mult_num) require dynamic information (code), which must be linked in explicitly.

For toplevel use:

$ ocaml nums.cma
        OCaml version 4.01.0

# Num.mult_num;;
- : Num.num -> Num.num -> Num.num = <fun>
# 

To compile and link a program:

ocamlc -o myprogram.byte myfile.ml nums.cma
ocamlopt -o myprogram.native myfile.ml nums.cmxa

The name of the library containing the module is provided at the beginning of the chapter about the library in the Ocaml reference manual. For many of these, the name of the library is the same as the name of the sole module it contains, but that's a convention, not an obligation. For libraries like nums that contain multiple modules, you need to look up the name of the library.

Reins answered 14/6, 2015 at 14:11 Comment(0)
B
0

Num is an independent library (not part of the standard library), that must be required before it is used in the toplevel.

$ ocaml nums.cma

# Num.mult_num;;
- : Num.num -> Num.num -> Num.num = <fun>
Brier answered 14/6, 2015 at 14:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.