File size: 8,518 Bytes
0115dcf | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 | # REPL
This documentation is about interacting with the REPL.
## Examples
After building the `repl`, it will be available in `.lake/build/bin/repl`.
Execute it by either directly referring to its name, or `lake exe repl`.
``` sh
repl MODULES|LEAN_OPTIONS
```
The `repl` executable must be given with a list of modules to import. By default
it will import nothing, not even `Init`. It can also accept lean options of the
form `--key=value` e.g. `--pp.raw=true`.
Running repl with `--version` shows the version and then exits.
After it emits the `ready.` signal, `repl` accepts commands as single-line JSON
inputs and outputs either an `Error:` (indicating malformed command) or a JSON
return value indicating the result of a command execution. The command must be
given in one of two formats
```
command { ... }
{ "cmd": command, "payload": ... }
```
The list of available commands can be found below. An empty command aborts the
REPL.
Example: (~5k symbols)
```
$ repl Init
env.catalog {}
env.inspect {"name": "Nat.le_add_left"}
```
Example with `mathlib4` (~90k symbols, may stack overflow, see troubleshooting)
```
$ repl Mathlib.Analysis.Seminorm
env.catalog {}
```
Example proving a theorem: (alternatively use `goal.start {"copyFrom": "Nat.add_comm"}`)
to prime the proof
```
$ repl Init
goal.start {"expr": "∀ (n m : Nat), n + m = m + n"}
goal.tactic {"stateId": 0, "tactic": "intro n m"}
goal.tactic {"stateId": 1, "tactic": "assumption"}
goal.delete {"stateIds": [0]}
stat {}
goal.tactic {"stateId": 1, "tactic": "rw [Nat.add_comm]"}
stat
```
where the application of `assumption` should lead to a failure.
### Project Environment
To use Pantograph in a project environment, setup the `LEAN_PATH` environment
variable so it contains the library path of lean libraries. The libraries must
be built in advance. For example, if `mathlib4` is stored at `../lib/mathlib4`,
the environment might be setup like this:
``` sh
LIB="../lib"
LIB_MATHLIB="$LIB/mathlib4/.lake"
export LEAN_PATH="$LIB_MATHLIB:$LIB_MATHLIB/aesop/build/lib:$LIB_MATHLIB/Qq/build/lib:$LIB_MATHLIB/std/build/lib"
LEAN_PATH=$LEAN_PATH repl $@
```
The `$LEAN_PATH` executable of any project can be extracted by
``` sh
lake env printenv LEAN_PATH
```
Additional modules cannot be imported after the perennial process starts, either
via `env.load` or the frontend functions. The technical reason for this is when
Lean cannot determine whether an imported module's initializer has run.
## Commands
See `Pantograph/Protocol.lean` for a description of the parameters and return values in JSON.
* `reset`: Delete all cached expressions and proof trees
* `stat`: Display resource usage
* `options.set { key: value, ... }`: Set one or more options. These are not Lean
`CoreM` options; those have to be set via command line arguments.), for
options see below.
* `options.print`: Display the current set of options
* `expr.echo {"expr": <expr>, "type": <optional expected type>, ["levels": [<levels>]]}`: Determine the
type of an expression and format it.
* `env.catalog`: Display a list of all safe Lean symbols in the current environment
* `env.inspect {"name": <name>, "value": <bool>}`: Show the type and package of a
given symbol; If value flag is set, the value is printed or hidden. By default
only the values of definitions are printed.
* `env.save { "path": <fileName> }`, `env.load { "path": <fileName> }`: Save/Load the
current environment to/from a file
* `env.module_read { "module": <name> }`: Reads a list of symbols from a module
* `env.describe {}`: Describes the imports and modules in the current environment
* `env.parse { "input": <input>, "category": <parser-category> }`: Parse a bit
of syntax and returns the parser's terminal position.
* `goal.start {["name": <name>], ["expr": <expr>], ["levels": [<levels>]], ["copyFrom": <symbol>]}`:
Start a new proof from a given expression or symbol
* `goal.tactic {"stateId": <id>, ["goalId": <id>], ["autoResume": <bool>], ...}`:
Execute a tactic string on a given goal site. The tactic is supplied as additional
key-value pairs in one of the following formats:
- `{ "tactic": <tactic> }`: Executes a tactic or a sequence of tactics in the
current mode.
- `{ "mode": <mode> }`: Enter a different tactic mode. The permitted values
are `tactic` (default), `conv`, `calc`. In case of `calc`, each step must
be of the form `lhs op rhs`. An `lhs` of `_` indicates that it should be set
to the previous `rhs`.
- `{ "expr": <expr> }`: Assign the given proof term to the current goal
- `{ "have": <expr>, "binderName": <name> }`: Execute `have` and creates a branch goal
- `{ "let": <expr>, "binderName": <name> }`: Execute `let` and creates a branch goal
- `{ "draft": <expr> }`: Draft an expression with `sorry`s, turning them into
goals. Coupling is not allowed.
If the `goals` field does not exist, the tactic execution has failed. Read
`messages` to find the reason.
* `goal.continue {"stateId": <id>, ["branch": <id>], ["goals": <names>]}`:
Execute continuation/resumption
- `{ "branch": <id> }`: Continue on branch state. The current state must have no goals.
- `{ "goals": <names> }`: Resume the given goals
* `goal.subsume {"stateId": <id>, "goal": <name>, "candidates":
<names>, ["srcStateId": <id>]}`: determine if any goal in `candidates` (coming
from either the provided state id or `srcStateId`) subsumes `goal`. It returns
the *subsumptor* (goal providing the solution) and a new state id if the
subsumption is not a cycle, in which case the *subsumend* `goal` is erased.
* `goal.remove {"stateIds": [<id>]}"`: Drop the goal states specified in the list
* `goal.print {"stateId": <id>}"`: Print a goal state
* `goal.save { "id": <id>, "path": <fileName> }`, `goal.load { "path": <fileName> }`:
Save/Load a goal state to/from a file. The environment is not carried with the
state. The user is responsible to ensure the sender/receiver instances share
the same environment.
* `frontend.process { ["fileName": <fileName>,] ["file": <str>], readHeader:
<bool>, inheritEnv: <bool>, invocations: <string>, newConstants: <bool> }`:
Executes the Lean frontend on a file, collecting the tactic invocations
(`"invocations": output-path`), or new constants (`newConstants`)
* `frontend.distil { "file": <str>, ["binderName": <str>], "ignoreValues": bool
}`: Extract condensed search targets from a file, where coupled search targets
will be condensed into one. Set `binderName` to override the binder name to
e.g. `f`. Set `ignoreValues` to false to incorporate existing solutions.
Note that `example`s are not search targets!
* `frontend.track { "src": <str>, "dst": <str> }`: Check if one file conforms to
another. The declarations in `src` could have `sorry`s and the declarations in
`dst` would fill them.
* [Experimental] `frontend.refactor { "file": <str>, "coreOptions":
[["<key>=<val>"]] }`: Group dependent `sorry`s into one single `sorry`.
Currently only flat dependencies are supported (i.e. an object with a list of
properties).
## Options
The full list of options can be found in `Pantograph/Protocol.lean`. Particularly:
- `automaticMode` (default on): Goals will not become dormant when this is
turned on. By default it is turned on, with all goals automatically resuming.
This makes Pantograph act like a gym, with no resumption necessary to manage
your goals.
- `timeout` (default 0): Set `timeout` to a non-zero number to specify timeout
(milliseconds) for all `CoreM` and frontend operations.
## Errors
When an error pertaining to the execution of a command happens, the returning JSON structure is
``` json
{ "error": "type", "desc": "description" }
```
Common error forms:
* `command`: Indicates malformed command structure which results from either
invalid command or a malformed JSON structure that cannot be fed to an
individual command.
* `index`: Indicates an invariant maintained by the output of one command and
input of another is broken. For example, attempting to query a symbol not
existing in the library or indexing into a non-existent proof state.
* `parse`: Indicates parsing errors
* `elab`: Indicates elaboration errors
* `frontend`: Indicates whole-file parsing and elaboration errors
* `io`: Generic IO error
* `command`: The command's argument is malformed
## Troubleshooting
If lean encounters stack overflow problems when printing catalog, execute this before running lean:
```sh
ulimit -s unlimited
```
|