Add alternative command input format and IO stub

This commit is contained in:
Leni Aniva 2023-05-20 13:03:12 -07:00
parent 14a6eb1f59
commit 65da39440d
6 changed files with 81 additions and 19 deletions

25
Examples/ExprIO.lean Normal file
View File

@ -0,0 +1,25 @@
import Lean
def strToName (s: String): Lean.Name :=
(s.splitOn ".").foldl Lean.Name.str Lean.Name.anonymous
unsafe def main (args: List String): IO Unit := do
Lean.enableInitializersExecution
Lean.initSearchPath (← Lean.findSysroot)
let imports := ["Init"]
let env: Lean.Environment ← Lean.importModules
(imports := imports.map (λ str => { module := strToName str, runtimeOnly := false }))
(opts := {})
(trustLevel := 1)
let expr := args.head?.getD "a + b"
match Lean.Parser.runParserCategory
(env := env)
(catName := `term)
(input := expr)
(fileName := "<stdin>") with
| Except.error error => IO.println s!"{error}"
| Except.ok (syn: Lean.Syntax) =>
let reprint := Lean.Syntax.reprint syn |>.get!
IO.println reprint

View File

@ -17,9 +17,9 @@ def execute_proof (env: Lean.Environment): IO Unit := do
let tactic := "intro n m" let tactic := "intro n m"
let (state, response) ← execute_tactic state tactic let (state, response) ← execute_tactic state tactic
IO.println s! "Executed {tactic} Errors: {response.errors} Goals: {response.goals}" IO.println s! "Executed {tactic} Errors: {response.errors} Goals: {response.goals}"
--let tactic := "assumption" -- should fail let tactic := "assumption" -- should fail
--let (_, response) ← execute_tactic state tactic let (_, response) ← execute_tactic state tactic
--IO.println s! "Executed {tactic} Errors: {response.errors} Goals: {response.goals}" IO.println s! "Executed {tactic} Errors: {response.errors} Goals: {response.goals}"
let tactic := "rw [Nat.add_comm]" let tactic := "rw [Nat.add_comm]"
let (state, response) ← execute_tactic state tactic let (state, response) ← execute_tactic state tactic
IO.println s! "Executed {tactic} Errors: {response.errors} Goals: {response.goals}" IO.println s! "Executed {tactic} Errors: {response.errors} Goals: {response.goals}"
@ -34,7 +34,3 @@ unsafe def main : IO Unit := do
(opts := {}) (opts := {})
(trustLevel := 1) (trustLevel := 1)
execute_proof env execute_proof env
example : ∀ (n m : Nat), n + m = m + n := by
intros n m
rw [Nat.add_comm]

View File

@ -12,6 +12,27 @@ def option_expect (o: Option α) (error: String): Except String α :=
| .some value => return value | .some value => return value
| .none => throw error | .none => throw error
structure Command where
cmd: String
payload: Lean.Json
deriving Lean.FromJson
/-- Parse a command either in `{ "cmd": ..., "payload": ... }` form or `cmd { ... }` form. -/
def parse_command (s: String): Except String Command := do
let s := s.trim
match s.get? 0 with
| .some '{' => -- Parse in Json mode
Lean.fromJson? (← Lean.Json.parse s)
| .some _ => -- Parse in line mode
let offset := s.posOf ' ' |> s.offsetOfPos
if offset = s.length then
return { cmd := s.take offset, payload := Lean.Json.null }
else
let payload ← s.drop offset |> Lean.Json.parse
return { cmd := s.take offset, payload := payload }
| .none => throw "Command is empty"
structure State where structure State where
environments: Array Lean.Environment environments: Array Lean.Environment
@ -22,16 +43,10 @@ abbrev Subroutine α := ExceptT String (T IO) α
def nextId (s: State): Nat := s.environments.size def nextId (s: State): Nat := s.environments.size
structure Command where
cmd: String
payload: Lean.Json
deriving Lean.FromJson
open Commands open Commands
unsafe def execute (command: String): ExceptT String (T IO) Lean.Json := do unsafe def execute (command: String): ExceptT String (T IO) Lean.Json := do
let obj ← Lean.Json.parse command let command: Command ← parse_command command
let command: Command ← Lean.fromJson? obj
match command.cmd with match command.cmd with
| "create" => | "create" =>
let args: Commands.Create ← Lean.fromJson? command.payload let args: Commands.Create ← Lean.fromJson? command.payload

13
Pantograph/IO.lean Normal file
View File

@ -0,0 +1,13 @@
import Lean
/-
Expression IO
-/
namespace Pantograph.IO
end Pantograph.IO

View File

@ -19,19 +19,26 @@ lake build mathlib
## Usage ## Usage
The binary must be run inside a `lake env` environment. The binary must be run inside a `lake env` environment. i.e. `lake env
build/bin/pantograph`. The REPL loop accepts commands and outputs either an
`Error:` (indicating malformed command) or a json return value indicating the
result of a command execution. The command can be passed in one of two formats
```
command { ... }
{ "cmd": command, "payload": ... }
```
Example: (~5k symbols) Example: (~5k symbols)
``` ```
$ lake env build/bin/Pantograph $ lake env build/bin/Pantograph
{"cmd": "create", "payload": {"imports": ["Init"]}} create {"imports": ["Init"]}
{"cmd": "catalog", "payload": {"id": 0}} catalog {"id": 0}
``` ```
Example with `mathlib` (~90k symbols) Example with `mathlib` (~90k symbols)
``` ```
$ lake env build/bin/Pantograph $ lake env build/bin/Pantograph
{"cmd": "create", "payload": {"imports": ["Mathlib.Analysis.Seminorm"]}} create {"imports": ["Mathlib.Analysis.Seminorm"]}
{"cmd": "catalog", "payload": {"id": 0}} catalog {"id": 0}
``` ```

View File

@ -23,3 +23,9 @@ lean_exe examples_proof {
-- Somehow solves the native symbol not found problem -- Somehow solves the native symbol not found problem
supportInterpreter := true supportInterpreter := true
} }
lean_exe examples_expr_io {
root := `Examples.ExprIO
-- Somehow solves the native symbol not found problem
supportInterpreter := true
}