Equations
Equations
Equations
- io.iterate a f = monad_io.iterate e α a f
Equations
- io.forever a = io.iterate () (λ (_x : unit), a >> return (option.some ()))
Equations
- io.fail s = monad_io.fail io.error α (io.error.other s)
Equations
- io.put_str_ln s = io.put_str s >> io.put_str "\n"
Equations
Equations
- io.print s = (io.put_str ∘ to_string) s
Equations
- io.print_ln s = io.print s >> io.put_str "\n"
Equations
- io.mk_file_handle s m bin = monad_io_file_system.mk_file_handle s m bin
Equations
- io.env.get env_var = monad_io_environment.get_env env_var
get the current working directory
Equations
set the current working directory
Equations
Equations
Equations
Equations
Equations
Equations
Equations
Equations
Equations
Equations
Equations
- io.fs.get_char h = io.fs.read h 1 >>= λ (b : char_buffer), dite (buffer.size b = 1) (λ (h : buffer.size b = 1), return (buffer.read b ⟨0, _⟩)) (λ (h : ¬buffer.size b = 1), io.fail "get_char failed")
Equations
Equations
- io.fs.put_char h c = io.fs.write h (mk_buffer.push_back c)
Equations
- io.fs.put_str h s = io.fs.write h (mk_buffer.append_string s)
Equations
- io.fs.put_str_ln h s = io.fs.put_str h s >> io.fs.put_str h "\n"
Equations
- io.fs.read_to_end h = io.iterate mk_buffer (λ (r : char_buffer), io.fs.is_eof h >>= λ (done : bool), ite ↥done (return option.none) (io.fs.read h 1024 >>= λ (c : char_buffer), return (option.some (r ++ c))))
Equations
- io.fs.read_file s bin = io.mk_file_handle s io.mode.read bin >>= λ (h : io.handle), io.fs.read_to_end h
Equations
Equations
Equations
- io.fs.mkdir path recursive = monad_io_file_system.mkdir path recursive
Equations
Equations
Equations
Equations
Equations
Run the external process specified by args
.
The process will run to completion with its output captured by a pipe, and
read into string
which is then returned.
Equations
- io.cmd args = io.proc.spawn {cmd := args.cmd, args := args.args, stdin := args.stdin, stdout := io.process.stdio.piped, stderr := args.stderr, cwd := args.cwd, env := args.env} >>= λ (child : io.proc.child), io.fs.read_to_end child.stdout >>= λ (buf : char_buffer), io.fs.close child.stdout >>= λ (_x : unit), io.proc.wait child >>= λ (exitv : ℕ), when (exitv ≠ 0) (io.fail ("process exited with status " ++ repr exitv)) >>= λ (_x : unit), return (buffer.to_string buf)
This is the "back door" into the io
monad, allowing IO computation to be performed during tactic execution.
For this to be safe, the IO computation should be ideally free of side effects and independent of its environment.
This primitive is used to invoke external tools (e.g., SAT and SMT solvers) from a tactic.
IMPORTANT: this primitive can be used to implement unsafe_perform_io {α : Type} : io α → option α
or unsafe_perform_io {α : Type} [inhabited α] : io α → α
. This can be accomplished by executing
the resulting tactic using an empty tactic_state
(we have tactic_state.mk_empty
).
If unsafe_perform_io
is defined, and used to perform side-effects, users need to take the following
precautions:
Use
@[noinline]
attribute in any function to invokestactic.unsafe_perform_io
. Reason: if the call is inlined, the IO may be performed more than once.Set
set_option compiler.cse false
before any function that invokestactic.unsafe_perform_io
. This option disables common subexpression elimination. Common subexpression elimination might combine two side effects that were meant to be separate.
TODO[Leo]: add [noinline]
attribute and option compiler.cse
.
Execute the given tactic with a tactic_state object that contains:
- The current environment in the virtual machine.
- The current set of options in the virtual machine.
- Empty metavariable and local contexts.
- One single goal of the form
⊢ true
. This action is mainly useful for writing tactics that inspect the environment.