Skip to content

Commit f07d9f7

Browse files
authored
Dev (#2)
* add pytest dependency * add test code for minif2f * update minif2f from purewhite * add github action * migrate tests from server.py * add three error tests * fix minif2f statements * add pytest marks * minif2f: fix & check * update tests * ignore poetry.lock * fix json dumps in server.py * add pylock
1 parent 5adbbca commit f07d9f7

File tree

16 files changed

+2364
-1996
lines changed

16 files changed

+2364
-1996
lines changed

.github/workflows/test.yaml

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
name: Python Package
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
branches:
9+
- main
10+
11+
jobs:
12+
build:
13+
runs-on: ${{ matrix.os }}
14+
strategy:
15+
matrix:
16+
python-version: ["3.10"]
17+
os: [ubuntu-latest]
18+
19+
steps:
20+
- name: Install elan
21+
run: |
22+
set -o pipefail
23+
curl -sSfL https://github.com/leanprover/elan/releases/download/v3.1.1/elan-x86_64-unknown-linux-gnu.tar.gz | tar xz
24+
./elan-init -y --default-toolchain none
25+
echo "$HOME/.elan/bin" >> $GITHUB_PATH
26+
27+
- uses: actions/checkout@v3
28+
with:
29+
submodules: recursive
30+
- name: Install Dependencies
31+
run: |
32+
pushd experiments/minif2f/MiniF2F/
33+
lake exe cache get && lake build
34+
popd
35+
- name: Cache dependencies
36+
uses: actions/cache@v3
37+
with:
38+
path: |
39+
~/.cache/pip
40+
~/.cache/pypoetry
41+
key: ${{ runner.os }}-poetry-${{ hashFiles('**/poetry.lock') }}
42+
restore-keys: |
43+
${{ runner.os }}-poetry-
44+
45+
- name: Install Poetry
46+
run: |
47+
curl -sSL https://install.python-poetry.org | python3 -
48+
echo "export PATH=$HOME/.local/bin:$PATH" >> $GITHUB_ENV
49+
- name: Set up Python ${{ matrix.python-version }}
50+
uses: actions/setup-python@v2
51+
with:
52+
python-version: ${{ matrix.python-version }}
53+
- name: Install dependencies
54+
run: |
55+
poetry build
56+
poetry install
57+
- name: Test with pytest
58+
run: |
59+
poetry run pytest -s tests/

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@
88

99
# Output
1010
/dist
11-
/venv
11+
/venv
File renamed without changes.

experiments/minif2f/test.jsonl

Lines changed: 244 additions & 244 deletions
Large diffs are not rendered by default.

experiments/minif2f/valid.jsonl

Lines changed: 244 additions & 244 deletions
Large diffs are not rendered by default.

pantograph/server.py

Lines changed: 1 addition & 199 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ def run(self, cmd, payload):
125125
:meta private:
126126
"""
127127
assert self.proc
128-
s = json.dumps(payload)
128+
s = json.dumps(payload, ensure_ascii=False)
129129
self.proc.sendline(f"{cmd} {s}")
130130
try:
131131
line = self.proc.readline()
@@ -339,201 +339,3 @@ def get_version():
339339
stdout=subprocess.PIPE,
340340
cwd=_get_proc_cwd()) as p:
341341
return p.communicate()[0].decode('utf-8').strip()
342-
343-
344-
class TestServer(unittest.TestCase):
345-
346-
def test_version(self):
347-
self.assertEqual(get_version(), "0.2.24")
348-
349-
def test_expr_type(self):
350-
server = Server()
351-
t = server.expr_type("forall (n m: Nat), n + m = m + n")
352-
self.assertEqual(t, "Prop")
353-
354-
def test_goal_start(self):
355-
server = Server()
356-
state0 = server.goal_start("forall (p q: Prop), Or p q -> Or q p")
357-
self.assertEqual(len(server.to_remove_goal_states), 0)
358-
self.assertEqual(state0.state_id, 0)
359-
state1 = server.goal_tactic(state0, goal_id=0, tactic="intro a")
360-
self.assertEqual(state1.state_id, 1)
361-
self.assertEqual(state1.goals, [Goal(
362-
variables=[Variable(name="a", t="Prop")],
363-
target="∀ (q : Prop), a ∨ q → q ∨ a",
364-
name=None,
365-
)])
366-
self.assertEqual(str(state1.goals[0]),"a : Prop\n⊢ ∀ (q : Prop), a ∨ q → q ∨ a")
367-
368-
del state0
369-
self.assertEqual(len(server.to_remove_goal_states), 1)
370-
server.gc()
371-
self.assertEqual(len(server.to_remove_goal_states), 0)
372-
373-
state0b = server.goal_start("forall (p: Prop), p -> p")
374-
del state0b
375-
self.assertEqual(len(server.to_remove_goal_states), 1)
376-
server.gc()
377-
self.assertEqual(len(server.to_remove_goal_states), 0)
378-
379-
def test_automatic_mode(self):
380-
server = Server()
381-
state0 = server.goal_start("forall (p q: Prop), Or p q -> Or q p")
382-
self.assertEqual(len(server.to_remove_goal_states), 0)
383-
self.assertEqual(state0.state_id, 0)
384-
state1 = server.goal_tactic(state0, goal_id=0, tactic="intro a b h")
385-
self.assertEqual(state1.state_id, 1)
386-
self.assertEqual(state1.goals, [Goal(
387-
variables=[
388-
Variable(name="a", t="Prop"),
389-
Variable(name="b", t="Prop"),
390-
Variable(name="h", t="a ∨ b"),
391-
],
392-
target="b ∨ a",
393-
name=None,
394-
)])
395-
state2 = server.goal_tactic(state1, goal_id=0, tactic="cases h")
396-
self.assertEqual(state2.goals, [
397-
Goal(
398-
variables=[
399-
Variable(name="a", t="Prop"),
400-
Variable(name="b", t="Prop"),
401-
Variable(name="h✝", t="a"),
402-
],
403-
target="b ∨ a",
404-
name="inl",
405-
),
406-
Goal(
407-
variables=[
408-
Variable(name="a", t="Prop"),
409-
Variable(name="b", t="Prop"),
410-
Variable(name="h✝", t="b"),
411-
],
412-
target="b ∨ a",
413-
name="inr",
414-
),
415-
])
416-
state3 = server.goal_tactic(state2, goal_id=1, tactic="apply Or.inl")
417-
state4 = server.goal_tactic(state3, goal_id=0, tactic="assumption")
418-
self.assertEqual(state4.goals, [
419-
Goal(
420-
variables=[
421-
Variable(name="a", t="Prop"),
422-
Variable(name="b", t="Prop"),
423-
Variable(name="h✝", t="a"),
424-
],
425-
target="b ∨ a",
426-
name="inl",
427-
)
428-
])
429-
430-
def test_have(self):
431-
server = Server()
432-
state0 = server.goal_start("1 + 1 = 2")
433-
state1 = server.goal_tactic(state0, goal_id=0, tactic=TacticHave(branch="2 = 1 + 1", binder_name="h"))
434-
self.assertEqual(state1.goals, [
435-
Goal(
436-
variables=[],
437-
target="2 = 1 + 1",
438-
),
439-
Goal(
440-
variables=[Variable(name="h", t="2 = 1 + 1")],
441-
target="1 + 1 = 2",
442-
),
443-
])
444-
def test_let(self):
445-
server = Server()
446-
state0 = server.goal_start("1 + 1 = 2")
447-
state1 = server.goal_tactic(
448-
state0, goal_id=0,
449-
tactic=TacticLet(branch="2 = 1 + 1", binder_name="h"))
450-
self.assertEqual(state1.goals, [
451-
Goal(
452-
variables=[],
453-
name="h",
454-
target="2 = 1 + 1",
455-
),
456-
Goal(
457-
variables=[Variable(name="h", t="2 = 1 + 1", v="?h")],
458-
target="1 + 1 = 2",
459-
),
460-
])
461-
462-
def test_conv_calc(self):
463-
server = Server(options={"automaticMode": False})
464-
state0 = server.goal_start("∀ (a b: Nat), (b = 2) -> 1 + a + 1 = a + b")
465-
466-
variables = [
467-
Variable(name="a", t="Nat"),
468-
Variable(name="b", t="Nat"),
469-
Variable(name="h", t="b = 2"),
470-
]
471-
state1 = server.goal_tactic(state0, goal_id=0, tactic="intro a b h")
472-
state2 = server.goal_tactic(state1, goal_id=0, tactic=TacticCalc("1 + a + 1 = a + 1 + 1"))
473-
self.assertEqual(state2.goals, [
474-
Goal(
475-
variables,
476-
target="1 + a + 1 = a + 1 + 1",
477-
name='calc',
478-
),
479-
Goal(
480-
variables,
481-
target="a + 1 + 1 = a + b",
482-
),
483-
])
484-
state_c1 = server.goal_conv_begin(state2, goal_id=0)
485-
state_c2 = server.goal_tactic(state_c1, goal_id=0, tactic="rhs")
486-
state_c3 = server.goal_tactic(state_c2, goal_id=0, tactic="rw [Nat.add_comm]")
487-
state_c4 = server.goal_conv_end(state_c3)
488-
state_c5 = server.goal_tactic(state_c4, goal_id=0, tactic="rfl")
489-
self.assertTrue(state_c5.is_solved)
490-
491-
state3 = server.goal_tactic(state2, goal_id=1, tactic=TacticCalc("_ = a + 2"))
492-
state4 = server.goal_tactic(state3, goal_id=0, tactic="rw [Nat.add_assoc]")
493-
self.assertTrue(state4.is_solved)
494-
495-
def test_load_sorry(self):
496-
server = Server()
497-
unit, = server.load_sorry("example (p: Prop): p → p := sorry")
498-
self.assertIsNotNone(unit.goal_state, f"{unit.messages}")
499-
state0 = unit.goal_state
500-
self.assertEqual(state0.goals, [
501-
Goal(
502-
[Variable(name="p", t="Prop")],
503-
target="p → p",
504-
),
505-
])
506-
state1 = server.goal_tactic(state0, goal_id=0, tactic="intro h")
507-
state2 = server.goal_tactic(state1, goal_id=0, tactic="exact h")
508-
self.assertTrue(state2.is_solved)
509-
510-
def test_env_add_inspect(self):
511-
server = Server()
512-
server.env_add(
513-
name="mystery",
514-
t="forall (n: Nat), Nat",
515-
v="fun (n: Nat) => n + 1",
516-
is_theorem=False,
517-
)
518-
inspect_result = server.env_inspect(name="mystery")
519-
self.assertEqual(inspect_result['type'], {'pp': 'Nat → Nat', 'dependentMVars': []})
520-
521-
def test_goal_state_pickling(self):
522-
import tempfile
523-
server = Server()
524-
state0 = server.goal_start("forall (p q: Prop), Or p q -> Or q p")
525-
with tempfile.TemporaryDirectory() as td:
526-
path = td + "/goal-state.pickle"
527-
server.goal_save(state0, path)
528-
state0b = server.goal_load(path)
529-
self.assertEqual(state0b.goals, [
530-
Goal(
531-
variables=[
532-
],
533-
target="∀ (p q : Prop), p ∨ q → q ∨ p",
534-
)
535-
])
536-
537-
538-
if __name__ == '__main__':
539-
unittest.main()

0 commit comments

Comments
 (0)