forked from leanprover/lean3
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(library/vm/process): add basic process support
- Loading branch information
1 parent
1ffc01f
commit dc4086d
Showing
25 changed files
with
1,006 additions
and
141 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
|
||
BreakBeforeBraces: 'Attach' | ||
|
||
IndentWidth: 4 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import init.data.list.basic | ||
|
||
inductive process.stdio | ||
| piped | ||
| inherit | ||
| null | ||
|
||
structure process := | ||
(cmd : string) | ||
/- Add an argument to pass to the process. -/ | ||
(args : list string) | ||
/- Configuration for the process's stdin handle. -/ | ||
(stdin := stdio.inherit) | ||
/- Configuration for the process's stdout handle. -/ | ||
(stdout := stdio.inherit) | ||
/- Configuration for the process's stderr handle. -/ | ||
(stderr := stdio.inherit) | ||
|
||
structure process.child (handle : Type) := | ||
(stdin : handle) | ||
(stdout : handle) | ||
(stderr : handle) | ||
|
||
structure io.process (err : Type) (handle : Type) (m : Type → Type → Type) := | ||
(spawn : process → m err (process.child handle)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import .syntax | ||
|
||
@[reducible] def smt2.builder (α : Type) := state (list smt2.cmd) α | ||
|
||
meta def smt2.builder.to_format {α : Type} (build : smt2.builder α) : format := | ||
format.join $ list.map to_fmt $ (build [])^.snd | ||
|
||
meta instance (α : Type) : has_to_format (smt2.builder α) := | ||
⟨ smt2.builder.to_format ⟩ | ||
|
||
namespace smt2 | ||
|
||
namespace builder | ||
|
||
def add_command (c : cmd) : builder unit := do | ||
cs ← state.read, | ||
state.write (c :: cs) | ||
|
||
def echo (msg : string) : builder unit := | ||
add_command (cmd.echo msg) | ||
|
||
def check_sat : builder unit := | ||
add_command cmd.check_sat | ||
|
||
def pop (n : nat) : builder unit := | ||
add_command $ cmd.pop n | ||
|
||
def push (n : nat) : builder unit := | ||
add_command $ cmd.push n | ||
|
||
def scope {α} (level : nat) (action : builder α) : builder α := | ||
do push level, | ||
res ← action, | ||
pop level, | ||
return res | ||
|
||
def reset : builder unit := | ||
add_command cmd.reset | ||
|
||
def exit' : builder unit := | ||
add_command cmd.exit_cmd | ||
|
||
def declare_const (sym : string) (s : sort) : builder unit := | ||
add_command $ cmd.declare_const sym s | ||
|
||
end builder | ||
|
||
end smt2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import system.io | ||
import system.process | ||
import .solvers.z3 | ||
import .syntax | ||
import .builder | ||
|
||
meta def smt2 [io.interface] (build : smt2.builder unit) : io string := | ||
do z3 ← z3_instance.start, | ||
io.put_str (to_string $ to_fmt build), | ||
res ← z3^.raw (to_string $ to_fmt build), | ||
io.put_str res, | ||
return res | ||
|
||
open tactic | ||
open smt2 | ||
open smt2.builder | ||
|
||
meta def reflect_prop (e : expr) : tactic (builder unit) := | ||
do p ← is_prop e, | ||
if p | ||
then do | ||
trace e, | ||
n ← mk_fresh_name, | ||
return $ declare_const (to_string n) "Bool" | ||
else return (return ()) | ||
|
||
meta def reflect_context : tactic (builder unit) := | ||
do ls ← local_context, | ||
bs ← monad.mapm reflect_prop ls, | ||
return $ list.foldl (λ (a b : builder unit), a >> b) (return ()) bs | ||
|
||
meta def reflect : tactic unit := | ||
do tgt ← target, | ||
b ← reflect_context, | ||
str ← run_io (λ ioi, @smt2 ioi b), | ||
tactic.trace str, | ||
return () |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import system.io | ||
import system.process | ||
import data.buffer | ||
|
||
open process | ||
|
||
structure z3_instance [io.interface] : Type := | ||
(process : child io.handle) | ||
|
||
def spawn [ioi : io.interface] : process → io (child io.handle) := | ||
io.interface.process^.spawn | ||
|
||
def z3_instance.start [io.interface] : io z3_instance := | ||
do let proc : process := { | ||
cmd := "z3", | ||
args := ["-smt2", "-in"], | ||
stdin := stdio.piped, | ||
stdout := stdio.piped | ||
}, | ||
z3_instance.mk <$> spawn proc | ||
|
||
def z3_instance.raw [io.interface] (z3 : z3_instance) (cmd : string) : io string := | ||
do let z3_stdin := z3^.process^.stdin, | ||
let z3_stdout := z3^.process^.stdout, | ||
let cs := cmd^.reverse^.to_buffer, | ||
io.fs.write z3_stdin cs, | ||
io.fs.close z3_stdin, | ||
-- need read all | ||
res ← io.fs.read z3_stdout 1024, | ||
return res^.to_string |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
namespace smt2 | ||
|
||
@[reducible] def symbol : Type := string | ||
@[reducible] def identifier : Type := string | ||
|
||
inductive special_constant : Type | ||
| number : int → special_constant | ||
| string : string → special_constant | ||
|
||
inductive sort : Type | ||
| id : identifier → sort | ||
| apply : identifier → list sort → sort | ||
|
||
instance : has_coe string sort := | ||
⟨ fun str, sort.id str ⟩ | ||
|
||
meta def sort.to_format : sort → format | ||
| (sort.id i) := to_fmt i | ||
| (sort.apply _ _) := "NYI" | ||
|
||
meta instance sort_has_to_fmt : has_to_format sort := | ||
⟨ sort.to_format ⟩ | ||
|
||
inductive attr : Type | ||
|
||
inductive qualified_name : Type | ||
| id : identifier → qualified_name | ||
| qual_id : identifier → sort → qualified_name | ||
|
||
inductive term : Type | ||
| qual_id : qualified_name → term | ||
| const : special_constant → term | ||
| apply : qualified_name → list term → term | ||
| letb : list (name × term) → term → term | ||
| forallq : list (symbol × sort) → term → term | ||
| existsq : list (symbol × sort) → term → term | ||
| annotate : term → list attr → term | ||
|
||
inductive fun_def : Type | ||
inductive info_flag : Type | ||
inductive keyword : Type | ||
inductive option : Type | ||
|
||
inductive cmd : Type | ||
| assert_cmd : term → cmd | ||
| check_sat : cmd | ||
| check_sat_assuming : term → cmd -- not complete | ||
| declare_const : symbol → sort → cmd | ||
| declare_fun : symbol → list sort → cmd | ||
| declare_sort : symbol → nat → cmd | ||
| define_fun : fun_def → cmd | ||
| define_fun_rec : fun_def → cmd | ||
| define_funs_rec : cmd -- not complete | ||
| define_sort : symbol → list symbol → sort → cmd | ||
| echo : string → cmd | ||
| exit_cmd : cmd | ||
| get_assertions : cmd | ||
| get_assignment : cmd | ||
| get_info : info_flag → cmd | ||
| get_model : cmd | ||
| get_option : keyword → cmd | ||
| get_proof : cmd | ||
| get_unsat_assumtpions : cmd | ||
| get_unsat_core : cmd | ||
| get_value : cmd -- not complete | ||
| pop : nat → cmd | ||
| push : nat → cmd | ||
| reset : cmd | ||
| reset_assertions : cmd | ||
| set_info : attr → cmd | ||
| set_logic : symbol → cmd | ||
| set_opt : option → cmd | ||
|
||
open cmd | ||
|
||
meta def string_lit (s : string) : format := | ||
format.bracket "\"" "\"" (to_fmt s) | ||
|
||
meta def cmd.to_format : cmd → format | ||
| (echo msg) := "(echo " ++ string_lit msg ++ ")\n" | ||
| (declare_const sym srt) := "(declare-const " ++ sym ++ " " ++ to_fmt srt ++ ")" | ||
| _ := "NYI" | ||
|
||
meta instance : has_to_format cmd := | ||
⟨ cmd.to_format ⟩ | ||
|
||
end smt2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
/* | ||
Copyright (c) 2017 Microsoft Corporation. All rights reserved. | ||
Released under Apache 2.0 license as described in the file LICENSE. | ||
Author: Leonardo de Moura & Jared Roesch | ||
*/ | ||
#include <string> | ||
#include <fstream> | ||
#include <iostream> | ||
#include <iomanip> | ||
#include <utility> | ||
#include <stdio.h> | ||
|
||
#if defined(LEAN_WINDOWS) && !defined(LEAN_CYGWIN) | ||
#include <windows.h> | ||
#include <tchar.h> | ||
#include <strsafe.h> | ||
#else | ||
#include <sys/wait.h> | ||
#include <unistd.h> | ||
#endif | ||
|
||
#include "library/process.h" | ||
#include "library/handle.h" | ||
#include "util/buffer.h" | ||
#include "library/pipe.h" | ||
|
||
|
||
namespace lean { | ||
|
||
void handle::write(buffer<char> & buf) { | ||
auto sz = buf.size(); | ||
if (fwrite(buf.data(), 1, sz, m_file) != sz) { | ||
std::cout << "write_error: " << errno << std::endl; | ||
clearerr(m_file); | ||
throw handle_exception("write failed"); | ||
} | ||
} | ||
|
||
void handle::flush() { | ||
if (fflush(m_file) != 0) { | ||
clearerr(m_file); | ||
throw handle_exception("flush failed"); | ||
} | ||
} | ||
|
||
handle::~handle() { | ||
if (m_file && m_file != stdin && | ||
m_file != stderr && m_file != stdout) { | ||
fclose(m_file); | ||
} | ||
} | ||
|
||
bool handle::is_stdin() { | ||
return m_file == stdin; | ||
} | ||
|
||
bool handle::is_stdout() { | ||
return m_file == stdout; | ||
} | ||
|
||
bool handle::is_stderr() { | ||
return m_file == stderr; | ||
} | ||
|
||
void handle::close() { | ||
if (fclose(m_file) == 0) { | ||
m_file = nullptr; | ||
} else { | ||
clearerr(m_file); | ||
throw handle_exception("close failed"); | ||
} | ||
} | ||
|
||
bool handle::is_closed() { return !m_file; } | ||
|
||
} |
Oops, something went wrong.