Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Why3
why3
Commits
6b662f87
Commit
6b662f87
authored
Sep 21, 2012
by
Guillaume Melquiond
Browse files
Add syntactic coloring for OCaml code too.
parent
2bf65706
Changes
2
Hide whitespace changes
Inline
Side-by-side
doc/api.tex
View file @
6b662f87
...
...
@@ -19,7 +19,7 @@ the source distribution as \url{examples/use_api.ml}.
The first step is to know how to build propositional formulas. The
module
\texttt
{
Term
}
gives a few functions for building these. Here is
a piece of OCaml code for building the formula
$
true
\lor
false
$
.
\begin{
verbatim
}
\begin{
ocamlcode
}
(* opening the Why3 library *)
open Why3
...
...
@@ -27,7 +27,7 @@ open Why3
let fmla
_
true : Term.term = Term.t
_
true
let fmla
_
false : Term.term = Term.t
_
false
let fmla1 : Term.term = Term.t
_
or fmla
_
true fmla
_
false
\end{
verbatim
}
\end{
ocamlcode
}
The library uses the common type
\texttt
{
term
}
both for terms
(i.e.~expressions that produce a value of some particular type)
and formulas (i.e.~boolean-valued expressions).
...
...
@@ -38,11 +38,11 @@ and formulas (i.e.~boolean-valued expressions).
Such a formula can be printed using the module
\texttt
{
Pretty
}
providing pretty-printers.
\begin{
verbatim
}
\begin{
ocamlcode
}
(* printing it *)
open Format
let () = printf "@[formula 1 is:@
%a@]@." Pretty.print_term fmla1
\end{
verbatim
}
\end{
ocamlcode
}
Assuming the lines above are written in a file
\texttt
{
f.ml
}
, it can
be compiled using
...
...
@@ -58,23 +58,23 @@ formula 1 is: true \/ false
Let's now build a formula with propositional variables:
$
A
\land
B
\rightarrow
A
$
. Propositional variables must be declared first before
using them in formulas. This is done as follows.
\begin{
verbatim
}
\begin{
ocamlcode
}
let prop
_
var
_
A : Term.lsymbol =
Term.create
_
psymbol (Ident.id
_
fresh "A") []
let prop
_
var
_
B : Term.lsymbol =
Term.create
_
psymbol (Ident.id
_
fresh "B") []
\end{
verbatim
}
\end{
ocamlcode
}
The type
\texttt
{
lsymbol
}
is the type of function and predicate symbols (which
we call logic symbols for brevity). Then the atoms
$
A
$
and
$
B
$
must be built
by the general function for applying a predicate symbol to a list of terms.
Here we just need the empty list of arguments.
\begin{
verbatim
}
\begin{
ocamlcode
}
let atom
_
A : Term.term = Term.ps
_
app prop
_
var
_
A []
let atom
_
B : Term.term = Term.ps
_
app prop
_
var
_
B []
let fmla2 : Term.term =
Term.t
_
implies (Term.t
_
and atom
_
A atom
_
B) atom
_
A
let () = printf "@[formula 2 is:@
%a@]@." Pretty.print_term fmla2
\end{
verbatim
}
\end{
ocamlcode
}
As expected, the output is as follows.
\begin{verbatim}
...
...
@@ -93,13 +93,13 @@ tasks from our formulas. Task can be build incrementally from an empty
task by adding declaration to it, using the functions
\texttt
{
add
\_*\_
decl
}
of module
\texttt
{
Task
}
. For the formula
$
true
\lor
false
$
above, this is done as follows.
\begin{
verbatim
}
\begin{
ocamlcode
}
let task1 : Task.task = None (* empty task *)
let goal
_
id1 : Decl.prsymbol =
Decl.create
_
prsymbol (Ident.id
_
fresh "goal1")
let task1 : Task.task =
Task.add
_
prop
_
decl task1 Decl.Pgoal goal
_
id1 fmla1
\end{
verbatim
}
\end{
ocamlcode
}
To make the formula a goal, we must give a name to it, here "goal1". A
goal name has type
\texttt
{
prsymbol
}
, for identifiers denoting
propositions in a theory or a task. Notice again that the concrete
...
...
@@ -112,15 +112,15 @@ and can only be used in theories).
Once a task is built, it can be printed.
\begin{
verbatim
}
\begin{
ocamlcode
}
(* printing the task *)
let () = printf "@[task 1 is:@
\n
%a@]@." Pretty.print_task task1
\end{
verbatim
}
\end{
ocamlcode
}
The task for our second formula is a bit more complex to build, because
the variables A and B must be added as abstract (i.e.~not defined)
propositional symbols in the task.
\begin{
verbatim
}
\begin{
ocamlcode
}
(* task for formula 2 *)
let task2 = None
let task2 = Task.add
_
param
_
decl task2 prop
_
var
_
A
...
...
@@ -128,7 +128,7 @@ let task2 = Task.add_param_decl task2 prop_var_B
let goal
_
id2 = Decl.create
_
prsymbol (Ident.id
_
fresh "goal2")
let task2 = Task.add
_
prop
_
decl task2 Decl.Pgoal goal
_
id2 fmla2
let () = printf "@[task 2 is:@
\n
%a@]@." Pretty.print_task task2
\end{
verbatim
}
\end{
ocamlcode
}
Execution of our OCaml program now outputs:
\begin{verbatim}
...
...
@@ -154,7 +154,7 @@ file \texttt{why3.conf}, as it was built using the \texttt{why3config}
command line tool or the
\textsf
{
Detect Provers
}
menu of the graphical
IDE. The following API calls allow to access the content of this
configuration file.
\begin{
verbatim
}
\begin{
ocamlcode
}
(* reads the config file *)
let config : Whyconf.config = Whyconf.read
_
config None
(* the [main] section of the config file *)
...
...
@@ -162,24 +162,24 @@ let main : Whyconf.main = Whyconf.get_main config
(* all the provers detected, from the config file *)
let provers : Whyconf.config
_
prover Whyconf.Mprover.t =
Whyconf.get
_
provers config
\end{
verbatim
}
\end{
ocamlcode
}
The type
\texttt
{
'a Whyconf.Mprover.t
}
is a map indexed by provers. A
provers is a record with a name, a version and an alternative description
(if someone want to compare different command line options of the same
provers for example). It's definition is in the module
\texttt
{
Whyconf
}
:
\begin{
verbatim
}
\begin{
ocamlcode
}
type prover =
{
prover
_
name : string; (* "Alt-Ergo" *)
prover
_
version : string; (* "2.95" *)
prover
_
altern : string; (* "special" *)
}
\end{
verbatim
}
\end{
ocamlcode
}
The map
\texttt
{
provers
}
provides the set of existing provers.
In the following, we directly
attempt to access the prover Alt-Ergo, which is known to be identified
with id
\texttt
{
"alt-ergo"
}
.
\begin{
verbatim
}
\begin{
ocamlcode
}
(* the [prover alt-ergo] section of the config file *)
let alt
_
ergo : Whyconf.config
_
prover =
try
...
...
@@ -187,9 +187,9 @@ let alt_ergo : Whyconf.config_prover =
with Whyconf.ProverNotFound
_
->
eprintf "Prover alt-ergo not installed or not configured@.";
exit 0
\end{
verbatim
}
\end{
ocamlcode
}
We could also get a specific version with :
\begin{
verbatim
}
\begin{
ocamlcode
}
let alt
_
ergo : Whyconf.config
_
prover =
try
let prover =
{
Whyconf.prover
_
name = "Alt-Ergo";
...
...
@@ -199,12 +199,12 @@ let alt_ergo : Whyconf.config_prover =
with Not
_
found ->
eprintf "Prover alt-ergo not installed or not configured@.";
exit 0
\end{
verbatim
}
\end{
ocamlcode
}
The next step is to obtain the driver associated to this prover. A
driver typically depends on the standard theories so these should be
loaded first.
\begin{
verbatim
}
\begin{
ocamlcode
}
(* builds the environment from the [loadpath] *)
let env : Env.env =
Env.create
_
env (Whyconf.loadpath main)
...
...
@@ -216,12 +216,12 @@ let alt_ergo_driver : Driver.driver =
eprintf "Failed to load driver for alt-ergo:
%a@."
Exn
_
printer.exn
_
printer e;
exit 1
\end{
verbatim
}
\end{
ocamlcode
}
We are now ready to call the prover on the tasks. This is done by a
function call that launches the external executable and waits for its
termination. Here is a simple way to proceed:
\begin{
verbatim
}
\begin{
ocamlcode
}
(* calls Alt-Ergo *)
let result1 : Call
_
provers.prover
_
result =
Call
_
provers.wait
_
on
_
call
...
...
@@ -230,7 +230,7 @@ let result1 : Call_provers.prover_result =
(* prints Alt-Ergo answer *)
let () = printf "@[On task 1, alt-ergo answers
%a@]@."
Call
_
provers.print
_
prover
_
result result1
\end{
verbatim
}
\end{
ocamlcode
}
This way to call a prover is in general too naive, since it may never
return if the prover runs without time limit. The function
\texttt
{
prove
\_
task
}
has two optional parameters:
\texttt
{
timelimit
}
...
...
@@ -261,7 +261,7 @@ A \texttt{pr\_answer} is a sum of several kind of answers:
\end{itemize}
Here is thus another way of calling the Alt-Ergo prover, on our second
task.
\begin{
verbatim
}
\begin{
ocamlcode
}
let result2 : Call
_
provers.prover
_
result =
Call
_
provers.wait
_
on
_
call
(Driver.prove
_
task ~command:alt
_
ergo.Whyconf.command
...
...
@@ -273,7 +273,7 @@ let () =
Call
_
provers.print
_
prover
_
answer
result1.Call
_
provers.pr
_
answer
result1.Call
_
provers.pr
_
time
\end{
verbatim
}
\end{
ocamlcode
}
The output of our program is now as follows.
\begin{verbatim}
On task 1, alt-ergo answers Valid (0.01s)
...
...
@@ -290,7 +290,7 @@ Here is the way we build the formula $2+2=4$. The main difficulty is to
access the internal identifier for addition: it must be retrieved from
the standard theory
\texttt
{
Int
}
of the file
\texttt
{
int.why
}
(see
Chap~
\ref
{
chap:library
}
).
\begin{
verbatim
}
\begin{
ocamlcode
}
let two : Term.term = Term.t
_
const (Term.ConstInt (Term.IConstDecimal "2"))
let four : Term.term = Term.t
_
const (Term.ConstInt (Term.IConstDecimal "4"))
let int
_
theory : Theory.theory =
...
...
@@ -300,52 +300,52 @@ let plus_symbol : Term.lsymbol =
let two
_
plus
_
two : Term.term =
Term.t
_
app
_
infer plus
_
symbol [two;two]
let fmla3 : Term.term = Term.t
_
equ two
_
plus
_
two four
\end{
verbatim
}
\end{
ocamlcode
}
An important point to notice as that when building the application of
$
+
$
to the arguments, it is checked that the types are correct. Indeed
the constructor
\texttt
{
t
\_
app
\_
infer
}
infers the type of the resulting
term. One could also provide the expected type as follows.
\begin{
verbatim
}
\begin{
ocamlcode
}
let two
_
plus
_
two : Term.term =
Term.fs
_
app plus
_
symbol [two;two] Ty.ty
_
int
\end{
verbatim
}
\end{
ocamlcode
}
When building a task with this formula, we need to declare that we use
theory
\texttt
{
Int
}
:
\begin{
verbatim
}
\begin{
ocamlcode
}
let task3 = None
let task3 = Task.use
_
export task3 int
_
theory
let goal
_
id3 = Decl.create
_
prsymbol (Ident.id
_
fresh "goal3")
let task3 = Task.add
_
prop
_
decl task3 Decl.Pgoal goal
_
id3 fmla3
\end{
verbatim
}
\end{
ocamlcode
}
\section
{
Building Quantified Formulas
}
To illustrate how to build quantified formulas, let us consider
the formula
$
\forall
x:int. x
*
x
\geq
0
$
. The first step is to
obtain the symbols from
\texttt
{
Int
}
.
\begin{
verbatim
}
\begin{
ocamlcode
}
let zero : Term.term = Term.t
_
const (Term.ConstInt "0")
let mult
_
symbol : Term.lsymbol =
Theory.ns
_
find
_
ls int
_
theory.Theory.th
_
export ["infix *"]
let ge
_
symbol : Term.lsymbol =
Theory.ns
_
find
_
ls int
_
theory.Theory.th
_
export ["infix >="]
\end{
verbatim
}
\end{
ocamlcode
}
The next step is to introduce the variable
$
x
$
with the type int.
\begin{
verbatim
}
\begin{
ocamlcode
}
let var
_
x : Term.vsymbol =
Term.create
_
vsymbol (Ident.id
_
fresh "x") Ty.ty
_
int
\end{
verbatim
}
\end{
ocamlcode
}
The formula
$
x
*
x
\geq
0
$
is obtained as in the previous example.
\begin{
verbatim
}
\begin{
ocamlcode
}
let x : Term.term = Term.t
_
var var
_
x
let x
_
times
_
x : Term.term = Term.t
_
app
_
infer mult
_
symbol [x;x]
let fmla4
_
aux : Term.term = Term.ps
_
app ge
_
symbol [x
_
times
_
x;zero]
\end{
verbatim
}
\end{
ocamlcode
}
To quantify on
$
x
$
, we use the appropriate smart constructor as follows.
\begin{
verbatim
}
\begin{
ocamlcode
}
let fmla4 : Term.term = Term.t
_
forall
_
close [var
_
x] [] fmla4
_
aux
\end{
verbatim
}
\end{
ocamlcode
}
\section
{
Building Theories
}
...
...
doc/macros.tex
View file @
6b662f87
...
...
@@ -39,7 +39,16 @@
\RequirePackage
{
listings
}
\RequirePackage
{
amssymb
}
\lstset
{
basicstyle=
{
\ttfamily
}
,framesep=2pt,frame=single
}
\lstset
{
basicstyle=
{
\ttfamily
}
,
framesep=2pt,
frame=single,
keywordstyle=
{
\color
{
blue
}}
,
stringstyle=
\itshape
,
commentstyle=
\itshape
,
columns=[l]fullflexible,
showstringspaces=false,
}
\lstdefinelanguage
{
why3
}
{
...
...
@@ -48,13 +57,7 @@ import,export,theory,module,end,in,with,%
let,rec,for,to,do,done,match,if,then,else,while,try,invariant,variant,
%
absurd,raise,assert,exception,
%
goal,axiom,lemma,forall
}
,
%
keywordstyle=
{
\color
{
blue
}}
,
%
otherkeywords=
{}
,
%
string=[b]",
%
showstringspaces=false,
%
stringstyle=
\itshape
,
%
commentstyle=
\itshape
,
%
columns=[l]fullflexible,
%
sensitive=true,
%
morecomment=[s]
{
(*
}{
*)
}
,
%
keepspaces=true,
...
...
@@ -82,6 +85,7 @@ literate=%
}
\lstnewenvironment
{
whycode
}{
\lstset
{
language=why3
}}{}
\lstnewenvironment
{
ocamlcode
}{
\lstset
{
language=
{
[Objective]Caml
}}}{}
%%% Local Variables:
%%% mode: latex
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment