Quickstart#

This page gives simple examples of using Camltac. You can also follow the tour, follow our tutorials, or have a look at examples for more examples of projects using Camltac.

To try these examples, you’ll need to have Camltac installed on your machine. See Installation.

Initializing a project#

To add Camltac to an existing project, you simply need to declare a dependency on the Camltac theory (in your rocq.theory stanza, if you’re using Dune), and add the following line to your file:

[Loading ML file rocq-runtime.plugins.ltac2 (implicit dependency) ... done]
[Loading ML file ppx_rocq.runtime (implicit dependency) ... done]
[Loading ML file rocq-mltac2 (implicit dependency) ... done]
[Loading ML file rocq-camltac.plugin.api (implicit dependency) ... done]
[Loading ML file rocq-camltac.plugin.runtime (implicit dependency) ... done]
[Loading ML file rocq-camltac.plugin ... done]

“Hello, world!”#

In Camltac, the most primitive command is Camltac Run, which runs OCaml code in the current context:

Hello, world!

Defining a module#

Camltac lets you define modules to reuse definitions across OCaml snippets:

Camltac Module M := ocaml:{{
  let one = 1
}}.

1

Modules in Camltac follow Rocq’s locality attributes, so the following works as well:

Module M.
  (* This module is not visible outside of M. *)
  #[local]
  Camltac Module Local := ocaml:{{
    let foo = "foo"
  }}.

  (* This module is: *)
  #[export]
  Camltac Module Export := ocaml:{{
    let bar = Local.foo
  }}.
End M.

Import M.

foo
Unbound module Local

Writing a tactic#

A tactic is a value of type a tactic for some a. To evaluate a tactic, use Camltac Eval:

- : int = 0
- : constr = (forall x : nat, x = x)
- : constr = (1 + 1)