[{"data":1,"prerenderedAt":4},["ShallowReactive",2],{"SP6gtVlShW":3},"# A read-eval-print-loop for Lean 4\n\nRun using `lake exe repl`.\nCommunicates via JSON on stdin and stdout.\nCommands should be separated by blank lines.\n\nThe REPL works both in \"command\" mode and \"tactic\" mode.\n\n## Command mode\n\nIn command mode, you send complete commands (e.g. declarations) to the REPL.\n\nCommands may be of the form\n\n```json\n{ \"cmd\" : \"def f := 2\" }\n```\n\n```json\n{ \"cmd\" : \"example : f = 2 := rfl\", \"env\" : 1 }\n```\n\nThe `env` field, if present,\nmust contain a number received in the `env` field of a previous response,\nand causes the command to be run in the existing environment.\n\nIf there is no `env` field, a new environment is created.\n\nYou can only use `import` commands when you do not specify the `env` field.\n\nYou can backtrack simply by using earlier values for `env`.\n\nThe response includes:\n* A numeric label for the `Environment` after your command,\n  which you can use as the starting point for subsequent commands.\n* Any messages generated while processing your command.\n* A list of the `sorry`s in your command, including\n  * their expected type, and\n  * a numeric label for the proof state at the `sorry`, which you can then use in tactic mode.\n\nExample output:\n\n```json\n{\"sorries\":\n [{\"pos\": {\"line\": 1, \"column\": 18},\n   \"endPos\": {\"line\": 1, \"column\": 23},\n   \"goal\": \"⊢ Nat\",\n   \"proofState\": 0}],\n \"messages\":\n [{\"severity\": \"error\",\n   \"pos\": {\"line\": 1, \"column\": 23},\n   \"endPos\": {\"line\": 1, \"column\": 26},\n   \"data\":\n   \"type mismatch\\n  rfl\\nhas type\\n  f = f : Prop\\nbut is expected to have type\\n  f = 2 : Prop\"}],\n \"env\": 6}\n```\n\nshowing any messages generated, and sorries with their goal states.\n\n## File mode\n\nThere is a simple wrapper around command mode that allows reading in an entire file.\n\nIf `test/file.lean` contains\n```lean\ndef f : Nat := 37\n\ndef g := 2\n\ntheorem h : f + g = 39 := by exact rfl\n```\n\nthen\n```\necho '{\"path\": \"test/file.lean\", \"allTactics\": true}' | lake exe repl\n```\nresults in output\n```json\n{\"tactics\":\n [{\"tactic\": \"exact rfl\",\n   \"proofState\": 0,\n   \"pos\": {\"line\": 5, \"column\": 29},\n   \"goals\": \"⊢ f + g = 39\",\n   \"endPos\": {\"line\": 5, \"column\": 38}}],\n \"env\": 0}\n ```\n\n## Tactic mode (experimental)\n\nTo enter tactic mode issue a command containing a `sorry`,\nand then use the `proofState` index returned for each `sorry`.\n\nExample usage:\n```json\n{\"cmd\" : \"def f (x : Unit) : Nat := by sorry\"}\n\n{\"sorries\":\n [{\"proofState\": 0,\n   \"pos\": {\"line\": 1, \"column\": 29},\n   \"goal\": \"x : Unit\\n⊢ Nat\",\n   \"endPos\": {\"line\": 1, \"column\": 34}}],\n \"messages\":\n [{\"severity\": \"warning\",\n   \"pos\": {\"line\": 1, \"column\": 4},\n   \"endPos\": {\"line\": 1, \"column\": 5},\n   \"data\": \"declaration uses 'sorry'\"}],\n \"env\": 0}\n\n{\"tactic\": \"apply Int.natAbs\", \"proofState\": 0}\n\n{\"proofState\": 1, \"goals\": [\"x : Unit\\n⊢ Int\"]}\n\n{\"tactic\": \"exact -37\", \"proofState\": 1}\n\n{\"proofState\": 2, \"goals\": []}\n```\n\nYou can use `sorry` in tactic mode.\nThe result will contain additional `proofState` identifiers for the goal at each sorry.\n\nAt present there is nothing you can do with a completed proof state:\nwe would like to extend this so that you can replace the original `sorry` with your tactic script,\nand obtain the resulting `Environment`\n\n## Pickling\n\nThe REPL supports pickling environments and proof states to disk as `.olean` files.\nAs long as the same imports are available, it should be possible to move such an `.olean` file\nto another machine and unpickle into a new REPL session.\n\nThe commands are\n\n```json\n{\"pickleTo\": \"path/to/file.olean\", \"env\": 7}\n\n{\"pickleTo\": \"path/to/file.olean\", \"proofState\": 17}\n\n{\"unpickleEnvFrom\": \"path/to/file.olean\"}\n\n{\"unpickleProofStateFrom\": \"path/to/file.olean\"}\n```\n\nThe unpickling commands will report the new \"env\" or \"proofState\" identifier that\nyou can use in subsequent commands.\n\nPickling is quite efficient:\n* we don't record full `Environment`s, only the changes relative to imports\n* unpickling uses memory mapping\n* file sizes are generally small, but see https://github.com/digama0/leangz if compression is\n  desirable\n\n## Using the REPL from another project\n\nSet up your project as usual using `lake new` or `lake init`\n(or the interactive setup GUI available via the VSCode extension under the `∀` menu).\n\nIn that project, add `require` statements in the `lakefile.lean` for any dependencies you need\n(e.g. Mathlib). (You probably should verify that `lake build` works as expected in that project.)\n\nNow you can run the REPL as:\n```shell\nlake env ../path/to/repl/.lake/build/bin/repl \u003C commands.in\n```\n(Here `../path/to/repl/` represents the path to your checkout of this repository,\nin which you've already run `lake build`.)\n\nThe `lake env` prefix sets up the environment associated to your local project, so that the REPL\ncan find needed imports.\n\n## Future work\n\n* Replay tactic scripts from tactic mode back into the original `sorry`.\n* Currently if you create scoped environment extensions (e.g. scoped notations) in a session\n  these are not correctly pickled and unpickled in later sessions.\n\n## Running Tests\n\nTo run the test suite (which wraps `test.sh` and checks the REPL against expected outputs), use:\n\n```sh\nlake exe test\n```\n\nThis will execute all tests in the `test/` directory and propagate the exit code, making it suitable for CI and scripting.\n",1780846754707]