Skip to content

Commit 0bcdbb7

Browse files
authored
Merge pull request #50 from Upabjojr/codegen_skip_conditions
Fixing the code generator
2 parents 1a74da2 + 8cdfa44 commit 0bcdbb7

File tree

3 files changed

+58
-27
lines changed

3 files changed

+58
-27
lines changed

matchpy/matching/code_generation.py

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class CodeGenerator:
2020
def __init__(self, matcher):
2121
self._matcher = matcher
2222
self._var_number = 0
23-
self._indentation = '\t'
23+
self._indentation = ' '
2424
self._level = 0
2525
self._code = ''
2626
self._subjects = ['subjects']
@@ -82,28 +82,28 @@ def generate_state_code(self, state):
8282
self._global_code.append(
8383
'''
8484
class CommutativeMatcher{0}(CommutativeMatcher):
85-
\t_instance = None
86-
\tpatterns = {1}
87-
\tsubjects = {2}
88-
\tsubjects_by_id = {7}
89-
\tbipartite = BipartiteGraph()
90-
\tassociative = {3}
91-
\tmax_optional_count = {4}
92-
\tanonymous_patterns = {5}
93-
94-
\tdef __init__(self):
95-
\t\tself.add_subject(None)
96-
97-
\t@staticmethod
98-
\tdef get():
99-
\t\tif CommutativeMatcher{0}._instance is None:
100-
\t\t\tCommutativeMatcher{0}._instance = CommutativeMatcher{0}()
101-
\t\treturn CommutativeMatcher{0}._instance
102-
103-
\t@staticmethod
85+
{8}_instance = None
86+
{8}patterns = {1}
87+
{8}subjects = {2}
88+
{8}subjects_by_id = {7}
89+
{8}bipartite = BipartiteGraph()
90+
{8}associative = {3}
91+
{8}max_optional_count = {4}
92+
{8}anonymous_patterns = {5}
93+
94+
{8}def __init__(self):
95+
{8}{8}self.add_subject(None)
96+
97+
{8}@staticmethod
98+
{8}def get():
99+
{8}{8}if CommutativeMatcher{0}._instance is None:
100+
{8}{8}{8}CommutativeMatcher{0}._instance = CommutativeMatcher{0}()
101+
{8}{8}return CommutativeMatcher{0}._instance
102+
103+
{8}@staticmethod
104104
{6}'''.strip().format(
105105
state.number, patterns, subjects, associative, max_optional_count, anonymous_patterns, code,
106-
subjects_by_id
106+
subjects_by_id, self._indentation
107107
)
108108
)
109109
self.add_line('matcher = CommutativeMatcher{}.get()'.format(state.number))
@@ -451,9 +451,9 @@ def generate_constraints(self, constraints, transitions):
451451
checked_patterns = self._patterns & patterns
452452
checked_transitions = [t for t in transitions if t.patterns & checked_patterns]
453453
if checked_patterns and checked_transitions:
454-
cvars = ' and '.join('{!r} in subst{}'.format(v, self._substs) for v in constraint.variables)
454+
cvars = ' or '.join('{!r} not in subst{}'.format(v, self._substs) for v in constraint.variables)
455455
if cvars:
456-
cvars += ' and '
456+
cvars += ' or '
457457
cexpr, call = self.constraint_repr(constraint)
458458
if call:
459459
self.add_line('if {}{}(subst{}):'.format(cvars, cexpr, self._substs))

tests/conftest.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,13 @@ def pytest_generate_tests(metafunc):
1717
metafunc.parametrize('match', ['one-to-one', 'many-to-one', 'generated'], indirect=True)
1818
if 'match_syntactic' in metafunc.fixturenames:
1919
metafunc.parametrize('match_syntactic', ['one-to-one', 'many-to-one', 'syntactic', 'generated'], indirect=True)
20+
if 'match_many' in metafunc.fixturenames:
21+
metafunc.parametrize('match_many', ['many-to-one', 'generated'], indirect=True)
2022

2123

22-
def match_many_to_one(expression, pattern):
24+
def match_many_to_one(expression, *patterns):
2325
try:
26+
pattern = patterns[0]
2427
commutative = next(
2528
p for p in preorder_iter(pattern.expression) if isinstance(p, CommutativeOperation)
2629
)
@@ -29,7 +32,7 @@ def match_many_to_one(expression, pattern):
2932
pass
3033
else:
3134
pytest.xfail('Matcher does not support fixed wildcards with length != 1 in commutative operations')
32-
matcher = ManyToOneMatcher(pattern)
35+
matcher = ManyToOneMatcher(*patterns)
3336
for _, substitution in matcher.match(expression):
3437
yield substitution
3538

@@ -46,8 +49,8 @@ def match_many_to_one(expression, pattern):
4649
'''.strip()
4750

4851

49-
def match_generated(expression, pattern):
50-
matcher = ManyToOneMatcher(pattern)
52+
def match_generated(expression, *patterns):
53+
matcher = ManyToOneMatcher(*patterns)
5154
generator = CodeGenerator(matcher)
5255
gc, code = generator.generate_code()
5356
code = GENERATED_TEMPLATE.format(gc, code)
@@ -93,3 +96,14 @@ def match_syntactic(request):
9396
return match_generated
9497
else:
9598
raise ValueError("Invalid internal test config")
99+
100+
101+
@pytest.fixture
102+
def match_many(request):
103+
pytest.matcher = request.param
104+
if request.param == 'many-to-one':
105+
return match_many_to_one
106+
elif request.param == 'generated':
107+
return match_generated
108+
else:
109+
raise ValueError("Invalid internal test config")

tests/test_matching.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -815,6 +815,23 @@ def test_selective_constraint(self, match):
815815
assert {'x': Symbol('aa')} in result
816816
assert {'x': Symbol('bb')} in result
817817

818+
def test_double_custom_constraint(self, match_many):
819+
constraint1 = CustomConstraint(lambda x, y: (x > 0) and (y > 0))
820+
constraint2 = CustomConstraint(lambda x, y: (x > 0) or (y > 0))
821+
822+
pattern1 = Pattern(f(x_, a, y_), constraint1)
823+
pattern2 = Pattern(f(x_, b, y_), constraint2)
824+
825+
subject1 = f(3, a, 4)
826+
result = list(match_many(subject1, pattern1, pattern2))
827+
assert len(result) == 1
828+
assert {'x': 3, 'y': 4} in result
829+
830+
subject2 = f(3, b, 4)
831+
result = list(match_many(subject2, pattern1, pattern2))
832+
assert len(result) == 1
833+
assert {'x': 3, 'y': 4} in result
834+
818835

819836
def func_wrap_strategy(args, func):
820837
min_size = func.arity[0]

0 commit comments

Comments
 (0)