-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathtest_interpreter.py
85 lines (75 loc) · 2.88 KB
/
test_interpreter.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import pytest
from model import *
from interpreter import *
package = [
# member(E, [H|T]) :- member_(T, E, H).
# member_(_, E, E).
# member_([H|T], E, _) :- member_(T, E, H).
Clause(Struct("member", Var("E"), Struct(".", Var("H"), Var("T"))),
Struct("member_", Var("T"), Var("E"), Var("H"))),
Clause(Struct("member_", Var("_"), Var("E"), Var("E"))),
Clause(Struct("member_", Struct(".", Var("H"), Var("T")), Var("E"), Var("_")),
Struct("member_", Var("T"), Var("E"), Var("H"))),
# length([], 0).
# length([_|T], s(L)) :- length(T, L).
Clause(Struct("length", Atom("[]"), Atom("0"))),
Clause(Struct("length", Struct(".", Var("_"), Var("T")), Struct("s", Var("L"))),
Struct("length", Var("T"), Var("L"))),
# nat(0).
# nat(s(X)) :- nat(X).
Clause(Struct("nat", Atom("0"))),
Clause(Struct("nat", Struct("s", Var("X"))),
Struct("nat", Var("X"))),
]
testdata = [
(
'length(L, s(s(s(0)))), member(a, L)',
[
Struct("length", Var("L"), Struct("s", Struct("s", Struct("s", Atom("0"))))),
Struct("member", Atom("a"), Var("L")),
], [
Solution({Var("L"): to_list([Atom("a"), Var("_"), Var("_")])}),
Solution({Var("L"): to_list([Var("_"), Atom("a"), Var("_")])}),
Solution({Var("L"): to_list([Var("_"), Var("_"), Atom("a")])}),
]),
(
'nat(X)',
[
Struct("nat", Var("X")),
], [
Solution({Var("X"): Atom("0")}),
Solution({Var("X"): Struct("s", Atom("0"))}),
Solution({Var("X"): Struct("s", Struct("s", Atom("0")))}),
Solution({Var("X"): Struct("s", Struct("s", Struct("s", Atom("0"))))}),
]),
(
'member(f(X), [a, f(b), g(c), f(d)])',
[
Struct("member", Struct("f", Var("X")), to_list([
Atom("a"),
Struct("f", Atom("b")),
Struct("g", Atom("c")),
Struct("f", Atom("d")),
])),
], [
Solution({Var("X"): Atom("b")}),
Solution({Var("X"): Atom("d")}),
]),
]
def ignore_vars(term: Term) -> Term:
if isinstance(term, Atom):
return term
if isinstance(term, Var):
return Var("_")
if isinstance(term, Struct):
return Struct(term.name, *(ignore_vars(arg) for arg in term.args))
raise ValueError(f"unexpected term type {type(term)}")
def ignore_vars_in_solution(solution: Solution) -> Solution:
return Solution({x: ignore_vars(term) for x, term in solution.items()})
@pytest.mark.parametrize("testname, query, solutions", testdata)
def test_interpreter(testname, query, solutions):
wam = Machine(package, query)
wam.debug_filename = f'debugtest/{testname}.jsonl'
for got, want in zip(wam.run(), solutions):
got = ignore_vars_in_solution(got)
assert got == want