[ConstraintSystem] new argument matching algorithm #32082
Closed
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
I created new algorithm of argument matching that produces expected result in all difficult situation we discussed at #32037 #30444.
EDIT at 2020/05/30 07:32:30 JST: add document.
EDIT at 2020/05/30 23:59:30 JST: add result section.
@xedin Could you review this?
I am going to write full explanation soon.The new 3 stage argument matching algorithm
I propose a new 3 stage argument matching algorihm in this patch.
Introduction
The current
matchCallArgument
has a problem with argument matching.This is that diagnostic message about label errors doesn't match the result of argument matching
where input source code has a compilation error.
It is difficult to build argument matching that matches desired diagnostic message.
I tried it once with patch here #32307 , but it wasn't perfect.
This patch completely overhauls existing
matchCallArgument
implementation and changes it new algorithm.In this document, I describe this algorithm.
Expression form of bindings
I had
parameter => argument
form in past at #32307, but I actually useargument => parameter
form because it's still easier to understand.Requirements
I enumerate an nature of expected bindings.
R-1 Unlabeled arguments are aligned with labeled arguments
Unlabeled arguments should be aligned from where the preceding labeled arguments match.
For following example:
2
should match_ dd:
since it followscc:
and4
should match_ bb:
since it followsaa:
.R-2 Unlabeled arguments must be bound to same number of unlabeled parameters
When there are same number of unlabeled arguments and parameters, they must be bound with higher priority.
For following example:
Since there are two unlabeled arguments in
1
and3
andtwo unlabeled parameters in
_ bb:
and_ cc:
,they must be bound.
xx:
should not match_ bb:
or_ cc:
.R-3 Unlabeled arguments(parameters) should be bound to labeled parameters(arguments) if possible
When there are more unlabeled arguments than unlabled parameters,
extra unlabeled arguments should be bound as much as labeled parameters.
For following example:
There are two arguments in
1
and3
,more than one parameter in
_ bb:
.So, the extra
1
should be matchedaa:
.In this case, crossed binding such as the following are undesirable.
Also, it is undesirable to build the following extra and missing arguments.
As shown below,
even if unlabeled arguments has an unrelated labeled arguments near it,
unlabeled arguments should take precedence over labeled arguments and match labeled parameter.
Contrary to what I have said,
when there are more unlabeled parameters than unlabeled arguments,
extra unlabeled parameters should be matched labeled arguments.
For example:
R-4 Even different labels bind each other.
Even if it's a different label,
they should be matched if that's the only option.
For example:
It is undesirable to build the following extra and missing arguments.
Discussion
Based on the requirements, consider the necessary rules.
D-1 4 levels of priority
From requirements,
we can see that there are four levels of strength in binding of arguments.
In order of strength are the following
labeled arguments and unlabeled parameters
D-2 Binding of unlabeled arguments
Consider the following situations.
Now, we suppose to decide binding of
_ cc:
.Since
aa:
andcc:
are not claimed,we would like to match unlabeled arguments to them if possible.
Now there are two unlabeled parameters and three unlabeled arguments,
so there is one unlabeled argument left over.
So, save
1
for binding labeled arguments later, and bind2
to_ cc:
.Next, we suppose to decide binding of
_ dd:
.Since
aa:
andcc:
are not claimed,we would like to match unlabeled arguments to them if possible.
Since we've already bind
2
to_ cc:
,there are one unlabeled parameter in
_ dd:
and two unlabeled arguments in1
and3
, so there is one unlabeled argument left over.So, save
1
again for binding labeled argumets later, and bind3
to_ dd:
.After binding of unlabeled arguments is finished,
unlabeled argument in
1
and unlabeled parameters inaa:
,bb:
are left.So, if we match them positionally, finally get the following bindings.
In this way,
by examining the number of unlabeled parameters,
the number of labeled parameters at left,
and the number of unlabeled arguments,
bindings satisfying
R-2
andR-3
can be made.If unlabeled parameters are more than unlabeled arguments,
the same process can be done with the opposite view.
Proposal
Based on the above, I propose argument matching algorithm with three levels of grouping.
This method divides the steps into the following three stages.
In the first label match,
look for a match between all parameters and arguments.
Once matching is complete,
split remaining arguments by bound pairs into groups.
For example:
In stage 1,
cc:
andff:
are matched.By splitting arguments with these matchings, we group them as follows.
Next, in stage 2, do unlabeled matching among groups created in stage 1.
Use the procedure described in D-2 for matching.
Then we will get following bindings.
Now we have complete bindings.
In this way, we can get the desired bindings.
Next, consider following example:
In this case, group will not be split in stage 1.
Unlabeled matching as following in stage 2.
In stage 2, as in stage 1,
split arguments by bound pairs into groups.
Next, in stage 3,
do posional matching ignoring labels among among groups created in stage 2.
Then we will get following bindings.
Now we have complete bindings.
In this way, we can get the desired bindings.
Implementation
The implementation is as follows.
claim
: claims arguments same as current.bindParameter
: After bind givenparamIdx
andargIdx
,bind variadic tails if necessary.
claimNextNamed
: deleted.bindNextParameter
: deleted.In the part with
Step 1
in comment,label matching in stage 1 is done.
In the part with
Step 2
in comment,label matching with typo correction in stage 1 is done.
bindUnlabeledParameters
:Unlabeled matching in first half of stage 2.
Save extra unlabeled arguments.
bindParameterPositionally
:Match unlabeled and labeled in second half of stage 2.
By argument
ignoreLabel
,it is used for label agnostic matching in stage 3.
iterateGroups
: Higher function that iterate each group which is split by existing bindings. It is used for stage 2 and 3.In the part with
Step 3
in comment,stage 2 is done.
In the part with
Step 4
in comment,stage 3 is done.
In the part with
Step 5
in comment,it reports extra arguments.
In the part with
Step 6
in comment,it reports missing arguments.
In the part with
Step 7
in comment,it reports label errors.
Result
Inconsistent bindings with diagnostics and undesired bindings are built currently in some cases.
This patch improve these cases.
I show some good results below.