3.5 TypeFocus-based analysis of type derivation trees
3.5.1 Algorithm for analyzing type inference decisions a fragment
The complete algorithm, represented by theSLICESfunction, analyzes the decisions of type derivation trees by considering the last type inference rule used in the judgment given as an input. The algorithm is realized by the rule-specialized partial functions, denoted as
SLICESrule, where the rule subscript refers to a particular type inference rule of the Colored Local Type Inference formalization. In Figure 3.11 we provide a fragment of the complete algorithm that analyzes decisions of the three representative rules of the Colored Local Type Inference algorithm.
For clarity, each case of theSLICESfunction provides parameters of the analyzed type infer- ence rule, i.e., the prototype, the environment, the term, and the inferred type. We use a∗w notation that is equivalent to the analyzed inference judgment, to avoid unnecessary dupli- cation of the inference rule elements.
For example, in theSLICES(abs)functionw∗ stands for the inference judgment of shape 64
3.5. TypeFocus-based analysis of type derivation trees
(∀a.T → P, Γ w fun(x)E :∀a.T → S), and for the SLICES(var) functionw∗ stands for the inference judgment of shape (P,Γ wx :Γ(x) P).
The arguments of the slices function, the inference judgment (P, Γ w E : T ) and the Type- FocusΘ, must satisfy only one requirement - the provided TypeFocus value has to be well- formed with respect to the inferred type, i.e., (Θ,fv(T )WFT ). The condition is necessary to perform a guided navigation of the type derivation tree.
Analyzing the inferred type of the abstraction
We first describe theSLICES(abs)algorithm for analyzing typing judgments where the last used type inference rule is(abs). The definition of the algorithm is provided in Figure 3.11.
Given the definition of the type inference rule (in Figure 2.4), the function has to determine if the target type has been inherited from the prototype or whether it has been synthesized in its only premise (no other typing decision could affect any of the possible target types at this point).
The first step of the algorithm determines if the target type has been fully inherited from the expected type of the context. Using the well-formedness pre-condition and Lemma 3.4, we can apply the provided TypeFocus to the prototype to identify the part corresponding to the target type (line 1), PΘ.
If PΘ= ?, then the target type information has already been enforced by the context of the
inference judgment. In consequence, further analysis of the premises of the(abs)rule is fruitless. To represent such type inference decision, theSLICES(abs)function returns immedi- ately with the Prototype Typing Slice,νPT, ∗w,Θ
, in line 3.
If PΘ= ?, then the target type has been synthesized as part of the typing decisions of the inference judgment. We use theheadof the input TypeFocus to decide on the direction of the analysis. By the (Θ,a WF∀a.T → S) precondition and the Canonical Forms lemma (Lemma 3.5), the only allowed values forhead(Θ) are: [ ], [φfun-param], and [φfun-res].
Both, [ ](∀a.T → P) =inl∀a.T → P and [φfun-param](∀a.T → P) =inlT , extract a non- wildcard prototype when applied to the prototype, and by contradiction, are impossible. Ifhead(Θ) = [φfun-res] and PΘ= ?, then the prototype carries no partial type information on the target type and the latter is synthesized in the premise of the rule. ThereforeSLICES(abs) analyzes the only premise of the type inference rule, (P, Γ,a,x : T wE : S), in a recursive call to theSLICESalgorithm (line 2), if and only ifhead(Θ) = [φfun-res].
The TypeFocus provided as the argument in the recursive invocation of theSLICESfunction
differs from the initial one. Knowing that theheadofΘ selects the result type of the function type, we must exclude this type selection when analyzing the premise of the rule. By defi- nition oftailand the decomposition property (Definition 8), (tail(Θ),fv(S)WFS), which
Chapter 3. Guided-analysis for type derivation trees
satisfies theSLICESfunction precondition in its recursive invocation and correctly represents
the target type information when analyzing the premise of the inference judgment.
FUNCTION SLICES(abs)
(∀a.T → P, Γ wfun(x)E :∀a.T → S), Θ= 1
2 3
Θ(∀a.T → P)tpe= PΘ
IF(is-hole(PΘ)) sl i ces((P,Γ,a,x : T wE : S),tail(Θ))
ELSE νPT, w∗,Θ FUNCTION SLICES(var)( (P,Γ wx :Γ(x) P), Θ ) =
1 2 3 4 5 6 7 Θ(P)tpe= PΘ IF(is-hole(PΘ)) IF(shape-match(Γ(x), P, Θ)) νTSIG, w∗,Θ ELSE normalize(Θ, Γ(x),fv(Γ(x))) = Θ νADAPT, w∗,Θ ,νTSIG,w∗,Θ ELSE νPT, ∗w,Θ FUNCTION SLICES(app)
(P,Γ wF (E ) :σC1∪C2,TT P), Θ = 1 2 3 4 5 6 7 8 9 10 11 12 13 Θ(P)tpe= PΘ IF(is-hole(PΘ)) IF(shape-match(σC1∪C2,TT, P,Θ)) Θ(T )tpe= TΘ
IF(is-tvar(TΘ, a)) νTVAR, ∗w,Θ
ELSE sl i ces( (?,Γ,wF :∀a.S → T ), φfun-res::Θ) ELSE normalize(Θ, σC1∪C2,TT,) = Θ Θ(T )tpe= TΘ νADAPT, w∗,Θ ∪
IF(is-tvar(TΘ, a)) νTVAR, w∗,Θ
ELSE sl i ces( (?,Γ wF :∀a.S → T ), φfun-res::Θ) )
ELSE νPT, w∗,Θ
Figure 3.11: A representative fragment of theSLICESalgorithm that analyzes type infer-
ence rules of Colored Local Type Inference. A complete algorithm is provided in Section 3.5.3.
Analyzing the inferred type of the variable
TheSLICES(var)function in Figure 3.11 analyzes typing decisions of the type derivation tree, if the last type inference rule used in it, was(var)(defined in Figure 2.4).
The analysis of the inference judgment proceeds by checking if the target type has been fully 66
3.5. TypeFocus-based analysis of type derivation trees
inherited, identically as in the previous case. The algorithm will return a Prototype Typing Slice if the extracted prototype, PΘ, is not a wildcard constant type. Otherwise we have to search for a different source of the target type.
This time we have to take into account also the consequences of the adaptation between the synthesized type of the variable and the inherited prototype. We use theshape-match function for that purpose. The function returnsfalse if and only if the synthesized type, Γ(x), does not match structurally the prototype, P, within the type selection of TypeFocus, meaning that the operation synthesized the target type.
Ifshape-match(Γ(x), P, Θ) = false, the algorithm returns the Adaptation Typing Slice to re- flect the discovery of the source of the target type. The Adaptation Typing Slice (line 6) implies that the source of the target type is both inherited from the context, P , and synthesized from the term, x. Since the type(var)type inference does not involve any further type inference in its premises, the source of the synthesized type can be immediately represented with the Type Signature Typing Slice (line 6).
We note that the result of theshape-matchapplication also implies that the well-formedness of the provided TypeFocus value with respect to the synthesized term is not guaranteed, i.e., (Θ, WFP ) by Lemma 3.4 but (Θ,fv(Γ(x)) WFΓ(x)) is not necessarily satisfied. In order to return a well-formed type selection in the Type Signature Typing Slice, the former is always normalized with respect to theΓ(x) type (line 5).
Ifshape-match(Γ(x), P, Θ) = true, then the analysis of the type inference rule is much sim- pler - the target type is fully synthesized from the type of the variable and (Θ,fv(Γ(x)) WF Γ(x)). The algorithm returns immediately with the Type Signature Typing Slice since the tar- get type is introduced in the type derivation tree directly from the environmentΓ.
Analyzing the inferred type of the function application
TheSLICES(app)function in Figure 3.11 analyzes typing decisions of the inference judgment where the last used type inference rule is(app).
From the definition of the type inference rule we identify four typing decisions that may be the source of the part of the inferred type:
1. The inherited prototype information, P .
2. The type synthesized from the adaptation in (σC1∪C2,TT ) P.
3. The instantiation of a single type variable in the polymorphic function type resulting from theσC1∪C2,Ttype substitution.
Chapter 3. Guided-analysis for type derivation trees
Similarly as in the previous cases, theSLICES(app)function first checks if the target type has been fully inherited from the context and returns immediately with the Prototype Typing Slice if PΘ= ? in line 13.
If PΘ= ?, the target type was not inherited from the context and we have to consider the other possible options.
Similarly as in the case of the(var)rule, theshape-matchfunction is used to understand the consequences of the adaptation. We notice, however, that further analysis, which analyzes how the target type has been synthesized from the term, follows exactly the same steps, irre- spective of whether the adaptation affected the target type or not, modulo the value of the used type selection. For clarity, we can summarize the relation between the adaptation and the used type selection (here denoted asΘapp) as follows:
• Ifshape-match(σC1∪C2,TT, P,Θ) =truethen (Θ,
WFσ
C1∪C2,TT ) andΘ
app= Θ, from the precondition of theSLICESfunction.
• Ifshape-match(σC1∪C2,TT, P, Θ) =falseand normalize(Θ, σC1∪C2,TT, ) = Θthen
(Θ, WFσC1∪C2,TT ) andΘ
app= Θ,
from the precondition of theSLICESfunction and the definition of thenormalizefunc- tion.
In both cases, the resulting TypeFocus,Θapp, is well-formed with respect to the synthesized type of the function application. This in turn allows us to decide between the two remaining typing decisions that could have synthesized the target type: the instantiation of a single type variable or the inferred type of the function.
In order to decide between the two, equally valid, possibilities, we apply the TypeFocus to the result type of the polymorphic function type which can potentially involve some uninstan- tiated type variables. The intuition, formally stated in the substitution lemma (Lemma 3.8), uses the fact that the synthesized type of the function application is exactly the same as the result type of inferred type of the function (modulo type substitution). The immediate conse- quence of the substitution lemma is that a TypeFocus that is well-formed with respect to the type with instantiated type variables is also well-formed with respect to the same type but with type variables not being instantiated.
Lemma 3.8 Well-formedness of TypeFocus over type substitution.
For any TypeFocusΘ, and a type T , such that (Θ, WFT ), if T results from a type sub- stitution,σ, on some type S, such that T = σS and dom(σ) = a, then (Θ,a WFS).
Proof.
Proof by induction on the structure of T . A complete proof is available in Appendix D.3
3.5. TypeFocus-based analysis of type derivation trees
We now turn our attention to the consequences of the application of theΘappTypeFocus to the inferred result type of the∀a.S → T function type.
IfΘapp(T )=inlTorΘapp(T )=inrT,Θ, for allΘ, such that T∈ a, then by definition of the(app)inference rule
1. The type variable extracted from the inferred polymorphic function type,∀a.S → T , is indirectly the source of the target type.
2. The type variable is only instantiated with the inferred type substitution,σC1∪C2,T, in
the analyzed function application judgment.
3. The target type is first introduced as a result of the inferred type substitution and the type substitution itself is the source of the target type.
Our algorithm does not attempt to immediately analyze the source of the extracted type vari- able instantiation due to our policy of reporting intermediate Typing Slices. Instead the al- gorithm returns a Type Variable Typing Slice that identifies the inference judgment for the function application, and its inferred type substitution, as the source of the target type. The result can be further analyzed using the type variable-specific analysis methods (Section 3.7). IfΘapp(T )=inlTsuch that T∈ a, then the source of the target type is in the type derivation tree that inferred the type of the function. The algorithm analyzes the subtree using the re- cursive call to theSLICESfunction with the updated TypeFocus,φfun-res::Θapp, representing a well-formed type selection from the inferred type of the premise.