Quantcast
Channel: How to generally match, unify and merge patterns? - Mathematica Stack Exchange
Viewing all articles
Browse latest Browse all 2

How to generally match, unify and merge patterns?

$
0
0

This question was split from this one. While that question is now about how to match two particular patterns (mostly using Verbatim or HoldPattern), this question is about how to match any pattern with another one, in other words: "How can I test if a given pattern intersects with, or is a subset of another pattern?" (borrowed from Mr.Wizard). Consider the following examples where one can see that the left pattern should "match" the right one, but which all return False:

MatchQ[a|b, b|a]MatchQ[{a..}, {a..}]MatchQ[{a..}, {a...}]

Of course one trivial way to deal with Alternatives would be to simply Sort its arguments:

MatchQ[a | b | c, Verbatim[Sort[b | c | a]]]  --->  True

but things get complicated if the pattern involves more than Alternatives.

Problem specification:


Therefore I am looking for a predicate function that compares any pattern with another pattern and decides whether the first one matches the second one. For this, one needs a general way of matching two expressions that may contain any of these operators: {|, .., ..., _, __, ___} and possibly anything else that is specific for patterns. The predicate should have the following behaviour:

PatternMatchQ::usage="PatternMatchQ[e1, e2] returns Trueif the set of expressions matched by pattern e1 is the sameor is a subset of the expressions matched by pattern e2, False otherwise."

i.e. the first pattern should cover the same (or smaller) domain as the second does. Now of course if any of the arguments is a non-pattern, PatternMatchQ can fall back to MatchQ.

Examples:


  • a|b agrees with b|a
  • a|b agrees with c|b|a (as a|b covers adomain that is covered by a|b|c as well)
  • a|b|c does not agreewith b|a (as a|b|c covers a domain that is larger than the domaincovered by b|aunlessc == a or c == b, in which case thepattern simplifies to a|b)
  • {a..} agrees with {a..}
  • {a..} agrees with {a...}
  • {a...} does not agree with {a..}


Extension:


Now the concept of matching can be extended in the following way. So far we were only concerned about whether it is true that $domain(e_1) \subseteq domain(e_2)$, and if not, return False. But even if the test gives false, it is possible to define the smallest (most simple) domain that both patterns cover. Also, a full pattern-set-algebra emerges, if one thinks it further. Accordingly, for example PatternUnion could work on any number of arguments, and should return the most general unifier of all the argument patterns. The union of patterns would be equivalent to the merging of patterns.

Now, of course, "The thing that hath been, it is that which shall be; and that which is done is that which shall be done: and there is no new thing under the sun"... in certain fields (e.g. in logic or in linguistics and especially in construction grammar), this method is called unification:

Two expressions $e_1$ and $e_2$ are said to unify iff there exists a substitution $s$ such that $s(e_1) = s(e_2)$

where a substitution is a binding of variables (i.e. implicit, hidden variables introduced by Mathematica to deal with e.g. _, __) in patterns $e_1$ and $e_2$ with actual fitting values. Note that the substituted value of a pattern-variable can be any atom, even symbols, it does not matter. Thus what the code should look for is the equality of variables (i.e. implicit pattern variables). If such an $s$ exists, it is called a unifier.It is known that if two expressions $e_1$ and $e_2$ unify, then there always is only one most general unifier (up to a renaming of variables). Now this general unifier of two pattern expressions can be called (or used to describe) the intersection of $e_1$ and $e_2$.


Viewing all articles
Browse latest Browse all 2

Trending Articles