What is matching?
It is very common in mathematics to say that one mathematical expression
"is of the form" of another. For example, we might say that
For us to be able to speak this way requires no special treatment of the
first expression (in this case, the expression
Given two mathematical expressions, pattern matching (or just matching)
is the act of determining the substitution (like
Terminology
When performing pattern matching, one of the two expressions is the one intended for substitution, and the other expression is the goal to be built by doing the substitution. The one into which substitution happens is called the pattern and the other is simply the expression.
The symbols that will be replaced by substitution (
In mathematics, one usually figures out what is a metavariable from context and common sense, but in software, it will be important to mark out metavariables explicitly. To that end, this module imports all the tools defined in the metavariables module and exposes them to clients. For more information about determining metavariables from context, see the Formula namespace.
Thus the problem of matching can be stated like so: Given a pattern
Expression functions
In mathematics, we often want to perform matching while paying attention to
certain key parameters. For example, we could express the general rule for
mathematical induction as
We call such a
Providing support for expression functions makes the job of matching more
difficult. For example, consider performing matching with
is the expression function is the expression function is the expression function is the expression function
The answer is that all are correct, and thus there is more than one correct answer to the question, and thus there must be more than one output from the matching algorithm.
Thus the matching algorithm takes as input a pattern-expression pair
Matching, fully stated
We will often want to match multiple pattern-expression pairs at the same
time. For example, a user might claim that a conclusion
Thus we come to the following final statement of the problem: The matching
algorithm takes as input a set of pairs
We call a set of inputs
We call each
Technical details
A substitution that would cause variable capture does not count as a solution to a matching problem. This is for two reasons: First, the very definition of substitution does not permit variable capture. Second, the mathematical uses to which we will put the algorithm do not want such solutions anyway. Consider the following example.
A standard rule of predicate logic is universal instantiation, which says
that from
To ensure that our matching algorithm does not introduce variable capture, we use de Bruijn indices to represent patterns and expressions internally during the matching process.
Recall the example above, in which an expression function
Source
Methods
allInstantiations(patterns, expressionLists, soFaropt, debugopt) → {Array.<Object>}
Matching problems are of the form
This function generalizes that capability as follows.
It supports problems of the form
In addition to producing solutions
Parameters
-
patterns
Array.<LogicConcept>
JavaScript array of LogicConcept instances, each of which may contain metavariables, and each will be used as a pattern. The elements
patterns[i]
in this array are the patterns documented as above. -
expressionLists
Array.<Array.<LogicConcept>>
array of arrays of LogicConcept instances, none of which should contain metavariables; the outer array must be the same length as
patterns
, because each array within it corresponds to an entry inpatterns
, as discussed above. That is, the elementsexpressionLists[i]
in this array are the "sets" documented as above. -
soFar
Solution
<optional>
used in recursion, defaults to an empty Solution; clients typically do not provide this value
-
debug
boolean
<optional>
whether to print debugging information to the console while it does its job, defaults to false
Returns
-
Array.<Object>
an array of objects, each of which has two entries: one under the key "solution" maps to a solution as described above, and the entry under the key "expressionIndices" is an array of integers that indicates which entry in each of the
expressionLists
is matched by each of thepatterns
Source
allOptionalInstantiations(patterns, expressionLists, firstOptional, soFar, debug) → {Array.<Object>}
There will be situations in which we want to seek instantiations of patterns but not require absolutely every pattern to be instantiated.
The simplest example is probably the following: Imagine we have a formula
for the introduction of a conditional, such as :{ :{ :A B } (=> A B) }
if
we're using putdown notation. We're
checking to see if it justifies conclusion (=> P Q)
, so we need to find a
premise of the form { :P Q }
. But actually, we would accept a premise
that's just of the form Q
even if there is no P
in sight, because that
could be strictly stronger than { :P Q }
, so we would want to run it
through validation to see if it works. Thus we do not need to match both
P
and Q
when searching; we must match Q
and can optionally also match
P
.
That's not an excellent example, because of course just matching the final
conclusion (=> A B)
to (=> P Q)
provides us with the full instantiation,
but there are many example of rules with environment premises, and not all
are so simple.
We therefore create this function, which behaves exactly like
allInstantiations(), except that
you can provide an index that indicates how to separate the constraints into
the required ones and the optional ones. We call that index
firstOptional
, and it has the meaning that it is the index of the first
optional constraint, in the sense that all previous ones are required, and
any constraint from that point onward is optional.
The return values will be exactly like those for
allInstantiations(), except that
some of the expression indices may be
Parameters
-
patterns
Array.<LogicConcept>
this parameter has the same meaning as it has in allInstantiations(); see the documentation there
-
expressionLists
Array.<Array.<LogicConcept>>
this parameter has the same meaning as it has in allInstantiations(); see the documentation there
-
firstOptional
integer
the index of the first optional constraint. To indicate that all constraints are required, set this value to be less than 0 or larger than the last valid index into
patterns
. -
soFar
Solution
this parameter has the same meaning as it has in allInstantiations(); see the documentation there
-
debug
boolean
this parameter has the same meaning as it has in allInstantiations(); see the documentation there
Returns
-
Array.<Object>
the return value has the same format as it has in allInstantiations(); see the documentation there, plus the comments above about
expression indices for unmatched and optional constraints