Loading files and libraries¶
Imandra comes with several different directives for loading files or including external modules.
It can be a bit daunting initially to undertstand which directive to use in the appropriate context, let's look at each in detail:
use¶
Syntax: #use "filename.iml";;
or [@@@use "filename.iml"]
The behavior of use
is that of reading the content of "filename.iml"
and evaluating it into the current environment, as if each definition had been directly entered into the toplevel.
The use
directive is meant to used in interactive sessions rather than in library/production code, and is not recursive.
There exist a functional equivalent of the directive, called System.use
that can be used to (recursively) load files at runtime, this is often useful to implement the common pattern of having a top.iml
file responsible for loading the entire model one is working on, or more generally for programmatic loading of imandra files.
If filename.iml
is a relative path, it is resolved to an absolute path by searching for it in Imandra's load path.
The current directory is always implicitly part of the load path, and additional directories can be added dynamically via the directory
directive, or at startup using the -dir
argument.
mod_use¶
Syntax: #mod_use "filename.iml";;
or [@@@mod_use "filename.iml"]
mod_use
behaves exactly like use
, with the only exception that the contents of the file will be evaluated in the toplevel as if they were wrapped in a module called Filename
The functional equivalent of the directive is System.mod_use
use_gist¶
Syntax: #use_gist "my-user/gist-hash";;
or [@@@use_gist "my-user/gist-hash"]
use_gist
behaves exactly like use
, except instead of loading a local path it will download the gist content and load that in the current environment.
import¶
Syntax: #import "filename.iml";;
or [@@@import "filename.iml"]
The behavior of import
is similar to that of mod_use
, with a number of significant differences:
- toplevel directives are disabled in the file being imported
import
is idempotent, as it caches on first import- Imandra resolves the import at compile time, so the imported module is available when typechecking the remainder of the file
As such, import
can be considered a version of mod_use
to be used in IML libraries as opposed to during interactive development.
Like use
and mod_use
, import
uses Imandra's load path to search for files, when importing an IML library, the current directory will be temporary set to that of the library itself.
require¶
Syntax: #require "some-lib";;
or [@@@require "some-lib"]
or as an argument to imandra: -require somelib
The behavior of require
is to search for some-lib
in the list of installed libraries (using topfind) and load it in the current environment.
If some-lib
comes packaged with a some-lib.iml
file, it will be automatically loaded by Imandra using #import
after the library has been required.
require_use¶
Syntax: #require_use "some-lib";;
or [@@@require_use "some-lib"]
or as an argument to imandra: -require-use somelib
Similar to #require "some-lib";;
except it loads the file some-lib.iml
with #use
instead of #import
,
so no module is created, and it's not idempotent.
require_mod_use¶
Syntax: #require_mod_use "some-lib";;
or [@@@require_mod_use "some-lib"]
or as an argument to imandra: -require-mod-use somelib
Similar to #require "some-lib";;
except it loads the file some-lib.iml
with #mod_use
instead of #import
,
so it's not idempotent.