Merge pull request #11 from lenianiva/dev
feat: Automatic mode (for the gym experience)
This commit is contained in:
commit
889aa79c18
|
@ -8,6 +8,3 @@
|
||||||
# Output
|
# Output
|
||||||
/dist
|
/dist
|
||||||
/venv
|
/venv
|
||||||
|
|
||||||
pantograph/pantograph
|
|
||||||
pantograph/lean-toolchain
|
|
||||||
|
|
6
build.py
6
build.py
|
@ -6,10 +6,10 @@ from pathlib import Path
|
||||||
PATH_PANTOGRAPH = Path("./src")
|
PATH_PANTOGRAPH = Path("./src")
|
||||||
PATH_PY = Path("./pantograph")
|
PATH_PY = Path("./pantograph")
|
||||||
|
|
||||||
with subprocess.Popen(["make"], cwd=PATH_PANTOGRAPH) as p:
|
with subprocess.Popen(["lake", "build", "repl"], cwd=PATH_PANTOGRAPH) as p:
|
||||||
p.wait()
|
p.wait()
|
||||||
|
|
||||||
path_executable = PATH_PY / "pantograph"
|
path_executable = PATH_PY / "pantograph-repl"
|
||||||
shutil.copyfile(PATH_PANTOGRAPH / ".lake/build/bin/pantograph", path_executable)
|
shutil.copyfile(PATH_PANTOGRAPH / ".lake/build/bin/repl", path_executable)
|
||||||
os.chmod(path_executable, os.stat(path_executable).st_mode | stat.S_IEXEC)
|
os.chmod(path_executable, os.stat(path_executable).st_mode | stat.S_IEXEC)
|
||||||
shutil.copyfile(PATH_PANTOGRAPH / "lean-toolchain", PATH_PY / "lean-toolchain")
|
shutil.copyfile(PATH_PANTOGRAPH / "lean-toolchain", PATH_PY / "lean-toolchain")
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
pantograph-repl
|
||||||
|
lean-toolchain
|
|
@ -10,7 +10,7 @@ from pantograph.compiler import TacticInvocation
|
||||||
def _get_proc_cwd():
|
def _get_proc_cwd():
|
||||||
return pathlib.Path(__file__).parent
|
return pathlib.Path(__file__).parent
|
||||||
def _get_proc_path():
|
def _get_proc_path():
|
||||||
return _get_proc_cwd() / "pantograph"
|
return _get_proc_cwd() / "pantograph-repl"
|
||||||
|
|
||||||
class ServerError(Exception):
|
class ServerError(Exception):
|
||||||
pass
|
pass
|
||||||
|
@ -21,7 +21,10 @@ class Server:
|
||||||
imports=["Init"],
|
imports=["Init"],
|
||||||
project_path=None,
|
project_path=None,
|
||||||
lean_path=None,
|
lean_path=None,
|
||||||
options=[],
|
# Options for executing the REPL.
|
||||||
|
# Set `{ "automaticMode" : True }` to get a gym-like experience
|
||||||
|
options={},
|
||||||
|
core_options=[],
|
||||||
timeout=20,
|
timeout=20,
|
||||||
maxread=1000000):
|
maxread=1000000):
|
||||||
"""
|
"""
|
||||||
|
@ -36,7 +39,8 @@ class Server:
|
||||||
self.proc_path = _get_proc_path()
|
self.proc_path = _get_proc_path()
|
||||||
|
|
||||||
self.options = options
|
self.options = options
|
||||||
self.args = " ".join(imports + [f'--{opt}' for opt in options])
|
self.core_options = core_options
|
||||||
|
self.args = " ".join(imports + [f'--{opt}' for opt in core_options])
|
||||||
self.proc = None
|
self.proc = None
|
||||||
self.restart()
|
self.restart()
|
||||||
|
|
||||||
|
@ -54,10 +58,16 @@ class Server:
|
||||||
f"{self.proc_path} {self.args}",
|
f"{self.proc_path} {self.args}",
|
||||||
encoding="utf-8",
|
encoding="utf-8",
|
||||||
maxread=self.maxread,
|
maxread=self.maxread,
|
||||||
|
timeout=self.timeout,
|
||||||
cwd=self.project_path,
|
cwd=self.project_path,
|
||||||
env=env,
|
env=env,
|
||||||
)
|
)
|
||||||
self.proc.setecho(False)
|
self.proc.setecho(False) # Do not send any command before this.
|
||||||
|
ready = self.proc.readline() # Reads the "ready."
|
||||||
|
assert ready == "ready.\r\n"
|
||||||
|
|
||||||
|
if self.options:
|
||||||
|
self.run("options.set", self.options)
|
||||||
|
|
||||||
def run(self, cmd, payload):
|
def run(self, cmd, payload):
|
||||||
"""
|
"""
|
||||||
|
@ -66,9 +76,8 @@ class Server:
|
||||||
s = json.dumps(payload)
|
s = json.dumps(payload)
|
||||||
self.proc.sendline(f"{cmd} {s}")
|
self.proc.sendline(f"{cmd} {s}")
|
||||||
try:
|
try:
|
||||||
self.proc.expect("{.*}\r\n", timeout=self.timeout)
|
line = self.proc.readline()
|
||||||
output = self.proc.match.group()
|
return json.loads(line)
|
||||||
return json.loads(output)
|
|
||||||
except pexpect.exceptions.TIMEOUT as exc:
|
except pexpect.exceptions.TIMEOUT as exc:
|
||||||
raise exc
|
raise exc
|
||||||
|
|
||||||
|
@ -167,7 +176,7 @@ def get_version():
|
||||||
class TestServer(unittest.TestCase):
|
class TestServer(unittest.TestCase):
|
||||||
|
|
||||||
def test_version(self):
|
def test_version(self):
|
||||||
self.assertEqual(get_version(), "0.2.16")
|
self.assertEqual(get_version(), "0.2.17")
|
||||||
|
|
||||||
def test_expr_type(self):
|
def test_expr_type(self):
|
||||||
server = Server()
|
server = Server()
|
||||||
|
@ -199,6 +208,58 @@ class TestServer(unittest.TestCase):
|
||||||
server.gc()
|
server.gc()
|
||||||
self.assertEqual(len(server.to_remove_goal_states), 0)
|
self.assertEqual(len(server.to_remove_goal_states), 0)
|
||||||
|
|
||||||
|
def test_automatic_mode(self):
|
||||||
|
server = Server(options={"automaticMode": True})
|
||||||
|
state0 = server.goal_start("forall (p q: Prop), Or p q -> Or q p")
|
||||||
|
self.assertEqual(len(server.to_remove_goal_states), 0)
|
||||||
|
self.assertEqual(state0.state_id, 0)
|
||||||
|
state1 = server.goal_tactic(state0, goal_id=0, tactic="intro a b h")
|
||||||
|
self.assertEqual(state1.state_id, 1)
|
||||||
|
self.assertEqual(state1.goals, [Goal(
|
||||||
|
variables=[
|
||||||
|
Variable(name="a", t="Prop"),
|
||||||
|
Variable(name="b", t="Prop"),
|
||||||
|
Variable(name="h", t="a ∨ b"),
|
||||||
|
],
|
||||||
|
target="b ∨ a",
|
||||||
|
name=None,
|
||||||
|
)])
|
||||||
|
state2 = server.goal_tactic(state1, goal_id=0, tactic="cases h")
|
||||||
|
self.assertEqual(state2.goals, [
|
||||||
|
Goal(
|
||||||
|
variables=[
|
||||||
|
Variable(name="a", t="Prop"),
|
||||||
|
Variable(name="b", t="Prop"),
|
||||||
|
Variable(name="h✝", t="a"),
|
||||||
|
],
|
||||||
|
target="b ∨ a",
|
||||||
|
name="inl",
|
||||||
|
),
|
||||||
|
Goal(
|
||||||
|
variables=[
|
||||||
|
Variable(name="a", t="Prop"),
|
||||||
|
Variable(name="b", t="Prop"),
|
||||||
|
Variable(name="h✝", t="b"),
|
||||||
|
],
|
||||||
|
target="b ∨ a",
|
||||||
|
name="inr",
|
||||||
|
),
|
||||||
|
])
|
||||||
|
state3 = server.goal_tactic(state2, goal_id=1, tactic="apply Or.inl")
|
||||||
|
state4 = server.goal_tactic(state3, goal_id=0, tactic="assumption")
|
||||||
|
self.assertEqual(state4.goals, [
|
||||||
|
Goal(
|
||||||
|
variables=[
|
||||||
|
Variable(name="a", t="Prop"),
|
||||||
|
Variable(name="b", t="Prop"),
|
||||||
|
Variable(name="h✝", t="a"),
|
||||||
|
],
|
||||||
|
target="b ∨ a",
|
||||||
|
name="inl",
|
||||||
|
)
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
def test_conv_calc(self):
|
def test_conv_calc(self):
|
||||||
server = Server()
|
server = Server()
|
||||||
state0 = server.goal_start("∀ (a b: Nat), (b = 2) -> 1 + a + 1 = a + b")
|
state0 = server.goal_start("∀ (a b: Nat), (b = 2) -> 1 + a + 1 = a + b")
|
||||||
|
|
2
src
2
src
|
@ -1 +1 @@
|
||||||
Subproject commit 67e7f22b0a1eb280af5eca078bcb383731b76f37
|
Subproject commit 9b3eef35ec40a09bba7140ecfc04dafddbd92c27
|
Loading…
Reference in New Issue