Skip to content

Commit a91efa0

Browse files
committed
fixing bug in transform operations by grounding patterns
1 parent abf558b commit a91efa0

1 file changed

Lines changed: 34 additions & 2 deletions

File tree

src/hyperbase/transforms.py

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,7 @@ def _instantiate_with_preserve(
449449
original: Hyperedge,
450450
bindings: dict[str, Hyperedge],
451451
) -> Hyperedge:
452-
consumed = _consumed_arg_indices(original, origin)
452+
consumed = _consumed_arg_indices(original, origin, bindings)
453453
edge_argroles = original.argroles()
454454
if edge_argroles.startswith("{"):
455455
edge_argroles = edge_argroles[1:-1]
@@ -477,6 +477,7 @@ def _instantiate_with_preserve(
477477
def _consumed_arg_indices(
478478
original_edge: Hyperedge,
479479
origin_pattern: Hyperedge,
480+
bindings: dict[str, Hyperedge],
480481
) -> set[int]:
481482
from hyperbase.patterns import match_pattern
482483

@@ -486,15 +487,46 @@ def _consumed_arg_indices(
486487

487488
args = list(original_edge[1:])
488489
for arg_pattern in origin_pattern[1:]:
490+
grounded = _ground_pattern(arg_pattern, bindings)
489491
for i, arg in enumerate(args):
490492
if i in consumed:
491493
continue
492-
if match_pattern(arg, arg_pattern):
494+
if grounded is not None:
495+
if arg == grounded:
496+
consumed.add(i)
497+
break
498+
elif match_pattern(arg, arg_pattern):
493499
consumed.add(i)
494500
break
495501
return consumed
496502

497503

504+
def _ground_pattern(
505+
pattern: Hyperedge, bindings: dict[str, Hyperedge]
506+
) -> Hyperedge | None:
507+
"""Substitute every variable in ``pattern`` with its binding.
508+
509+
Returns the grounded edge, or ``None`` if any variable is unbound (in which
510+
case the caller should fall back to a structural match).
511+
"""
512+
from hyperbase.patterns.checks import is_variable, variable_name
513+
514+
if pattern.atom:
515+
if is_variable(pattern):
516+
name = variable_name(pattern)
517+
if name not in bindings:
518+
return None
519+
return bindings[name]
520+
return pattern
521+
children: list[Hyperedge] = []
522+
for child in pattern:
523+
sub = _ground_pattern(child, bindings)
524+
if sub is None:
525+
return None
526+
children.append(sub)
527+
return Hyperedge(tuple(children))
528+
529+
498530
def _propagate_root_text(original: Hyperedge, result: Hyperedge) -> Hyperedge:
499531
"""Carry the original root's source-text fingerprint onto a transform's
500532
result.

0 commit comments

Comments
 (0)