matchpy.expressions.substitution module

Contains the Substitution class which is a specialized dictionary.

A substitution maps a variable to a replacement value. The variable is represented by its string name. The replacement can either be a plain expression, a sequence of expressions, or a Multiset of expressions:

>>> subst = Substitution({'x': a, 'y': (a, b), 'z': Multiset([a, b])})
>>> print(subst)
{x ↦ a, y ↦ (a, b), z ↦ {a, b}}

In addition, the Substitution class has some helper methods to unify multiple substitutions and nicer string formatting.

class Substitution

Bases: dict

Special dict for substitutions with nicer formatting.

The key is a variable’s name and the value the replacement for it.

extract_substitution(subject: matchpy.expressions.expressions.Expression, pattern: matchpy.expressions.expressions.Expression) → bool

Extract the variable substitution for the given pattern and subject.

This assumes that subject and pattern already match when being considered as linear. Also, they both must be syntactic, as sequence variables cannot be handled here. All that this method does is checking whether all the substitutions for the variables can be unified. So, in case it returns False, the substitution is invalid for the match.

..warning:

This method mutates the substitution and will even do so in case the extraction fails.

Create a copy before using this method if you need to preserve the original substitution.

Example

With an empty initial substitution and a linear pattern, the extraction will always succeed:

>>> subst = Substitution()
>>> subst.extract_substitution(f(a, b), f(x_, y_))
True
>>> print(subst)
{x ↦ a, y ↦ b}

Clashing values for existing variables will fail:

>>> subst.extract_substitution(b, x_)
False

For non-linear patterns, the extraction can also fail with an empty substitution:

>>> subst = Substitution()
>>> subst.extract_substitution(f(a, b), f(x_, x_))
False
>>> print(subst)
{x ↦ a}

Note that the initial substitution got mutated even though the extraction failed!

Parameters:
  • subject – A syntactic subject that matches the pattern.
  • pattern – A syntactic pattern that matches the subject.
Returns:

True iff the substitution could be extracted successfully.

rename(renaming: Dict[str, str]) → matchpy.expressions.substitution.Substitution

Return a copy of the substitution with renamed variables.

Example

Rename the variable x to y:

>>> subst = Substitution({'x': a})
>>> subst.rename({'x': 'y'})
{'y': Symbol('a')}
Parameters:renaming – A dictionary mapping old variable names to new ones.
Returns:A copy of the substitution where variable names have been replaced according to the given renaming dictionary. Names that are not contained in the dictionary are left unchanged.
try_add_variable(variable_name: str, replacement: Union[Tuple[expressions.Expression, ...], multiset.Multiset, expressions.Expression]) → None

Try to add the variable with its replacement to the substitution.

This considers an existing replacement and will only succeed if the new replacement can be merged with the old replacement. Merging can occur if either the two replacements are equivalent. Replacements can also be merged if the old replacement for the variable_name was unordered (i.e. a Multiset) and the new one is an equivalent ordered version of it:

>>> subst = Substitution({'x': Multiset(['a', 'b'])})
>>> subst.try_add_variable('x', ('a', 'b'))
>>> print(subst)
{x ↦ (a, b)}
Parameters:
  • variable – The name of the variable to add.
  • replacement – The replacement for the variable.
Raises:

ValueError – if the variable cannot be merged because it conflicts with the existing substitution for the variable_name.

union(*others) → matchpy.expressions.substitution.Substitution

Try to merge the substitutions.

If a variable occurs in multiple substitutions, try to merge the replacements. See union_with_variable() to see how replacements are merged.

Does not modify any of the original substitutions.

Example:

>>> subst1 = Substitution({'x': Multiset(['a', 'b']), 'z': a})
>>> subst2 = Substitution({'x': ('a', 'b'), 'y': ('c', )})
>>> print(subst1.union(subst2))
{x ↦ (a, b), y ↦ (c), z ↦ a}
Parameters:others – The other substitutions to merge with this one.
Returns:The new substitution with the other substitutions merged.
Raises:ValueError – if a variable occurs in multiple substitutions but cannot be merged because the substitutions conflict.
union_with_variable(variable: str, replacement: Union[Tuple[expressions.Expression, ...], multiset.Multiset, expressions.Expression]) → matchpy.expressions.substitution.Substitution

Try to create a new substitution with the given variable added.

See try_add_variable() for a version of this method that modifies the substitution in place.

Parameters:
  • variable_name – The name of the variable to add.
  • replacement – The substitution for the variable.
Returns:

The new substitution with the variable_name added or merged.

Raises:

ValueError – if the variable cannot be merged because it conflicts with the existing substitution for the variable.