Skip to content

Commit e612560

Browse files
committed
Polish documentation for options.md
1 parent 2a9f896 commit e612560

File tree

1 file changed

+89
-86
lines changed

1 file changed

+89
-86
lines changed

docs/mkDocs/docs/options.md

Lines changed: 89 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,19 @@ checking.
55

66
To see all options, run `liquid --help`.
77

8-
Each option can be passed in at the command line, or directly
9-
added to the source file via a **pragma**
8+
You can pass options in different ways:
109

11-
```haskell
12-
{-@ LIQUID "option-within-quotes" @-}
13-
```
10+
1. From the **command line**, if you use the **legacy executable**:
1411

15-
for example, to disable termination checking (see below)
12+
liquid --opt1 --opt2 ...
1613

17-
```haskell
18-
{-@ LIQUID "--no-termination" @-}
19-
```
14+
2. As a **plugin option**:
15+
16+
ghc-options: -fplugin-opt=LiquidHaskell:--opt1 -fplugin-opt=LiquidHaskell:--opt2
17+
18+
3. As a **pragma**, directly added to the source file:
19+
20+
{-@ LIQUID "opt1" @-}
2021

2122
You may also put command line options in the environment variable
2223
`LIQUIDHASKELL_OPTS`. For example, if you add the line:
@@ -33,6 +34,10 @@ Below, we list the various options and what they are used for.
3334

3435
## Theorem Proving
3536

37+
**Options:** `reflection`, `ple`, `ple-local`, `extensionality`
38+
39+
**Directives:** `automatic-instances`
40+
3641
To enable theorem proving, e.g. as [described here](https://ucsd-progsys.github.io/liquidhaskell-blog/tags/reflection.html)
3742
use the option
3843

@@ -65,14 +70,17 @@ liquid annotation
6570
{-@ automatic-instances theorem @-}
6671
```
6772

68-
To allow reasoning about function extensionality use the `extensionality flag`. [See](https://github.com/ucsd-progsys/liquidhaskell/blob/880c78f94520d76fa13880eac050f21dacb592fd/tests/pos/T1577.hs)
73+
To allow reasoning about function extensionality use the `--extensionality` flag.
74+
[See test T1577](https://github.com/ucsd-progsys/liquidhaskell/blob/880c78f94520d76fa13880eac050f21dacb592fd/tests/pos/T1577.hs).
6975

7076
```
7177
{-@ LIQUID "--extensionality" @-}
7278
```
7379

7480
## Fast Checking
7581

82+
**Options:** `fast`, `nopolyinfer`
83+
7684
The option `--fast` or `--nopolyinfer` greatly recudes verification time, can also reduces precision of type checking.
7785
It, per module, deactivates inference of refinements during
7886
instantiation of polymorphic type variables.
@@ -81,16 +89,13 @@ functions are trivially refined.
8189

8290
## Incremental Checking
8391

84-
The LiquidHaskell executable supports *incremental* checking where each run only checks
85-
the part of the program that has been modified since the previous run.
92+
**Options:** `diff`
8693

87-
```
88-
$ liquid --diff foo.hs
89-
```
90-
91-
Each run of `liquid` saves the file to a `.bak` file and the *subsequent* run does a `diff` to see what
92-
has changed w.r.t. the `.bak` file only generates constraints for the `[CoreBind]` corresponding to the
93-
changed top-level binders and their transitive dependencies.
94+
The LiquidHaskell executable supports *incremental* checking where each run only checks
95+
the part of the program that has been modified since the previous run. Each run of `liquid` saves the file
96+
to a `.bak` file and the *subsequent* run does a `diff` to see what has changed w.r.t. the `.bak` file only
97+
generates constraints for the `[CoreBind]` corresponding to the changed top-level binders and their
98+
transitive dependencies.
9499

95100
The time savings are quite significant. For example:
96101

@@ -105,7 +110,7 @@ The time savings are quite significant. For example:
105110
Now if you go and tweak the definition of `spanEnd` on line 1192 and re-run:
106111

107112
```
108-
$ time liquid -d --notermination -i . Data/ByteString.hs > log 2>&1
113+
$ time liquid --diff --notermination -i . Data/ByteString.hs > log 2>&1
109114

110115
real 0m11.584s
111116
user 0m6.008s
@@ -129,21 +134,18 @@ the pragma:
129134

130135
## Full Checking (DEFAULT)
131136

132-
To force LiquidHaskell to check the **whole** file (DEFAULT), use:
137+
**Options:** `full`
133138

134-
$ liquid --full foo.hs
135-
136-
to the file. This will override any other `--diff` incantation
137-
elsewhere (e.g. inside the file.)
138-
139-
140-
If you always want to run a given file with full-checking, add
141-
the pragma:
139+
You can force LiquidHaskell to check the **whole** file (which is the _DEFAULT_) using the `--full` option.
140+
This will override any other `--diff` incantation elsewhere (e.g. inside the file). If you always want
141+
to run a given file with full-checking, add the pragma:
142142

143143
{-@ LIQUID "--full" @-}
144144

145145
## Specifying Different SMT Solvers
146146

147+
**Options:** `smtsolver`
148+
147149
By default, LiquidHaskell uses the SMTLIB2 interface for Z3.
148150

149151
To run a different solver (supporting SMTLIB2) do:
@@ -163,26 +165,27 @@ dependencies). If you do so, you can use that interface with:
163165

164166
$ liquid --smtsolver=z3mem foo.hs
165167

166-
167168
## Short Error Messages
168169

170+
**Options:** `short-errors`
171+
169172
By default, subtyping error messages will contain the inferred type, the
170173
expected type -- which is **not** a super-type, hence the error -- and a
171174
context containing relevant variables and their type to help you understand
172175
the error. If you don't want the above and instead, want only the
173-
**source position** of the error use:
174-
175-
--short-errors
176+
**source position** of the error use `--short-errors`.
176177

177178
## Short (Unqualified) Module Names
178179

179-
By default, the inferred types will have fully qualified module names.
180-
To use unqualified names, much easier to read, use:
180+
**Options:** `short-names`
181181

182-
--short-names
182+
By default, the inferred types will have fully qualified module names.
183+
To use unqualified names, much easier to read, use `--short-names`.
183184

184185
## Disabling Checks on Functions
185186

187+
**Directives:** `ignore`
188+
186189
You can _disable_ checking of a particular function (e.g. because it is unsafe,
187190
or somehow not currently outside the scope of LH) by using the `ignore` directive.
188191

@@ -199,44 +202,44 @@ See `tests/pos/Ignores.hs` for an example.
199202

200203
## Totality Check
201204

205+
**Options:** `no-totality`
206+
202207
LiquidHaskell proves the absence of pattern match failures.
203208

204209
For example, the definition
205210

206-
fromJust :: Maybe a -> a
207-
fromJust (Just a) = a
211+
```haskell
212+
fromJust :: Maybe a -> a
213+
fromJust (Just a) = a
214+
```
208215

209216
is not total and it will create an error message.
210217
If we exclude `Nothing` from its domain, for example using the following specification
211218

212-
{-@ fromJust :: {v:Maybe a | (isJust v)} -> a @-}
219+
```haskell
220+
{-@ fromJust :: {v:Maybe a | (isJust v)} -> a @-}
221+
```
213222

214223
`fromJust` will be safe.
215224

216225
Use the `no-totality` flag to disable totality checking.
217226

218-
liquid --no-totality test.hs
219-
220227
## Termination Check
221228

222-
By **default** a termination check is performed on all recursive functions.
223-
224-
Use the `--no-termination` option to disable the check
225-
226-
{-@ LIQUID "--no-termination" @-}
229+
**Options:** `no-termination`
227230

228-
See the [specifications section](specifications.md) for how to write termination
229-
specifications.
231+
By **default** a termination check is performed on all recursive functions, but you can disable the check
232+
with the `--no-termination` option.
230233

234+
See the [specifications section](specifications.md) for how to write termination specifications.
231235

232236
## Total Haskell
233237

238+
**Options:** `total-Haskell`
239+
234240
LiquidHaskell provides a total Haskell flag that checks both totallity and termination of the program,
235241
overriding a potential no-termination flag.
236242

237-
liquid --total-Haskell test.hs
238-
239-
240243
## Lazy Variables
241244

242245
A variable can be specified as `LAZYVAR`
@@ -246,111 +249,111 @@ A variable can be specified as `LAZYVAR`
246249
With this annotation the definition of `z` will be checked at the points where
247250
it is used. For example, with the above annotation the following code is SAFE:
248251

249-
foo = if x > 0 then z else x
250-
where
251-
z = 42 `safeDiv` x
252-
x = choose 0
252+
```haskell
253+
foo = if x > 0 then z else x
254+
where
255+
z = 42 `safeDiv` x
256+
x = choose 0
257+
```
253258

254259
By default, all the variables starting with `fail` are marked as LAZY, to defer
255260
failing checks at the point where these variables are used.
256261

257262
## No measure fields
258263

264+
**Options:** `no-measure-fields`
265+
259266
When a data type is refined, Liquid Haskell automatically turns the data constructor fields into measures.
260267
For example,
261268

262-
{-@ data L a = N | C {hd :: a, tl :: L a} @-}
263-
264-
will automatically create two measures `hd` and `td`.
265-
To deactivate this automatic measure definition, and speed up verification, you can use the `no-measure-fields` flag.
266-
267-
liquid --no-measure-fields test.hs
268-
269+
```haskell
270+
{-@ data L a = N | C {hd :: a, tl :: L a} @-}
271+
```
269272

273+
will automatically create two measures `hd` and `td`. To deactivate this automatic measure definition,
274+
and speed up verification, you can use the `--no-measure-fields` flag.
270275

271276
## Prune Unsorted Predicates
272277

278+
**Options:** `prune-unsorted`
279+
273280
The `--prune-unsorted` flag is needed when using *measures over specialized instances* of ADTs.
274281

275282
For example, consider a measure over lists of integers
276283

277284
```haskell
278-
sum :: [Int] -> Int
279-
sum [] = 0
280-
sum (x:xs) = 1 + sum xs
285+
sum :: [Int] -> Int
286+
sum [] = 0
287+
sum (x:xs) = 1 + sum xs
281288
```
282289

283290
This measure will translate into strengthening the types of list constructors
284291

285292
```
286-
[] :: {v:[Int] | sum v = 0 }
287-
(:) :: x:Int -> xs:[Int] -> {v:[Int] | sum v = x + sum xs}
293+
[] :: {v:[Int] | sum v = 0 }
294+
(:) :: x:Int -> xs:[Int] -> {v:[Int] | sum v = x + sum xs}
288295
```
289296

290297
But what if our list is polymorphic `[a]` and later instantiate to list of ints?
291298
The workaround we have right now is to strengthen the polymorphic list with the
292299
`sum` information
293300

294301
```
295-
[] :: {v:[a] | sum v = 0 }
296-
(:) :: x:a -> xs:[a] -> {v:[a] | sum v = x + sum xs}
302+
[] :: {v:[a] | sum v = 0 }
303+
(:) :: x:a -> xs:[a] -> {v:[a] | sum v = x + sum xs}
297304
```
298305

299306
But for non numeric `a`s, refinements like `x + sum xs` are ill-sorted!
300307

301308
We use the flag `--prune-unsorted` to prune away unsorted expressions
302309
(like `x + sum xs`) inside refinements.
303310

304-
305-
```
306-
liquid --prune-unsorted test.hs
307-
```
308-
309-
310311
## Case Expansion
311312

313+
**Options:** `no-case-expand`
314+
312315
By default LiquidHaskell expands all data constructors to the case statements.
313316
For example, given the definition
314317

315318
```haskell
316-
data F = A1 | A2 | .. | A10
319+
data F = A1 | A2 | .. | A10
317320
```
318321

319322
LiquidHaskell will expand the code
320323

321324
```haskell
322-
case f of {A1 -> True; _ -> False}
325+
case f of {A1 -> True; _ -> False}
323326
```
324327

325328
to
326329

327330
```haskell
328-
case f of {A1 -> True; A2 -> False; ...; A10 -> False}
331+
case f of {A1 -> True; A2 -> False; ...; A10 -> False}
329332
```
330333

331334
This expansion can lead to more precise code analysis
332335
but it can get really expensive due to code explosion.
333-
The `no-case-expand` flag prevents this expansion and keeps the user
336+
The `--no-case-expand` flag prevents this expansion and keeps the user
334337
provided cases for the case expression.
335338

336-
liquid --no-case-expand test.hs
337-
338-
339339
## Higher order logic
340340

341-
The flag `--higherorder` allows reasoning about higher order functions.
341+
**Options:** `higherorder`
342342

343+
The flag `--higherorder` allows reasoning about higher order functions.
343344

344345
## Restriction to Linear Arithmetic
345346

347+
**Options:** `linear`
348+
346349
When using `z3` as the solver, LiquidHaskell allows for non-linear arithmetic:
347350
division and multiplication on integers are interpreted by `z3`. To treat division
348-
and multiplication as uninterpreted functions use the `linear` flag
349-
350-
liquid --linear test.hs
351+
and multiplication as uninterpreted functions use the `--linear` flag.
351352

352353
## Counter examples
353354

355+
**Options:** `counter-examples`
356+
354357
**Status:** `experimental`
355358

356359
When given the `--counter-examples` flag, LiquidHaskell will attempt to produce

0 commit comments

Comments
 (0)