Lichen

Change of docs/wiki/Inspection

861:f745d151a441
docs/wiki/Inspection
     1.1 --- a/docs/wiki/Inspection	Sat Jul 21 23:19:26 2018 +0200
     1.2 +++ b/docs/wiki/Inspection	Fri Aug 17 11:41:28 2018 +0200
     1.3 @@ -1,6 +1,12 @@
     1.4  = Inspecting Programs =
     1.5  
     1.6 -A program's source code is inspected module by module. As [[../Imports|imports]] of modules are encountered, other modules are added to the program. The inspection process for each module involves top-to-bottom traversal of the code using depth-first processing of the abstract syntax tree, with a stack of namespaces being employed to record definitions and names within namespaces are they are visited. Inspection continues until all modules in the program have been imported and inspected.
     1.7 +A program's source code is inspected module by module. As
     1.8 +[[../Imports|imports]] of modules are encountered, other modules are added to
     1.9 +the program. The inspection process for each module involves top-to-bottom
    1.10 +traversal of the code using depth-first processing of the abstract syntax
    1.11 +tree, with a stack of namespaces being employed to record definitions and
    1.12 +names within namespaces are they are visited. Inspection continues until all
    1.13 +modules in the program have been imported and inspected.
    1.14  
    1.15  <<TableOfContents(2,3)>>
    1.16  
    1.17 @@ -12,14 +18,20 @@
    1.18     * Identifying the names defined by each namespace
    1.19     * Recording relationships between namespaces
    1.20   * Describing the operations in each namespace
    1.21 -   * Identifying the names in each namespace and the attributes used by those names
    1.22 +   * Identifying the names in each namespace and the attributes used by those
    1.23 +     names
    1.24     * Recording details of assignments and invocations
    1.25  
    1.26 -The results of inspection are written out to [[../Cache|cache]] files, one for each module in the program.
    1.27 +The results of inspection are written out to [[../Cache|cache]] files, one for
    1.28 +each module in the program.
    1.29  
    1.30  === Program Units for Inspection ===
    1.31  
    1.32 -The `inspector` module performs much of the inspection work, relying on the `common` module for certain tasks, with the `modules` module providing the relevant module abstractions including those writing to and reading from cache files, and the `resolving` module completing each module's inspection. The `importer` module coordinates inspection across the whole program.
    1.33 +The `inspector` module performs much of the inspection work, relying on the
    1.34 +`common` module for certain tasks, with the `modules` module providing the
    1.35 +relevant module abstractions including those writing to and reading from cache
    1.36 +files, and the `resolving` module completing each module's inspection. The
    1.37 +`importer` module coordinates inspection across the whole program.
    1.38  
    1.39  === Name Identification ===
    1.40  
    1.41 @@ -31,15 +43,31 @@
    1.42   * Importing of modules
    1.43   * Importing of names from modules
    1.44  
    1.45 -The origins of names are discovered by considering local, global and built-in namespaces. Where a name is '''local''', it is defined in the same namespace. Where a name is '''global''', it is defined in the same module at the module level. Where a name is '''built-in''', it is defined in a module in the `__builtins__` package and exposed via the `__builtins__` namespace.
    1.46 +The origins of names are discovered by considering local, global and built-in
    1.47 +namespaces. Where a name is '''local''', it is defined in the same namespace.
    1.48 +Where a name is '''global''', it is defined in the same module at the module
    1.49 +level. Where a name is '''built-in''', it is defined in a module in the
    1.50 +`__builtins__` package and exposed via the `__builtins__` namespace.
    1.51  
    1.52 -Initial tentative identification of names will sort names into two categories: locals and external names. Global variables employed in function (or method) namespaces may not be defined when a function body is inspected, either within a module or being imported from another module, and so it is not initially possible to more specifically determine the nature of a name.
    1.53 +Initial tentative identification of names will sort names into two categories:
    1.54 +locals and external names. Global variables employed in function (or method)
    1.55 +namespaces may not be defined when a function body is inspected, either within
    1.56 +a module or being imported from another module, and so it is not initially
    1.57 +possible to more specifically determine the nature of a name.
    1.58  
    1.59 -These categories are later refined to distinguish between globals and built-in names as external names. The built-in origin of a name is only suggested when no locals or globals can provide the name, and the final identification of such names, plus other external names introduced as locals or globals via imports, will occur at the end of the inspection activity. Names that are unrecognised by then may be treated like unrecognised built-ins.
    1.60 +These categories are later refined to distinguish between globals and built-in
    1.61 +names as external names. The built-in origin of a name is only suggested when
    1.62 +no locals or globals can provide the name, and the final identification of
    1.63 +such names, plus other external names introduced as locals or globals via
    1.64 +imports, will occur at the end of the inspection activity. Names that are
    1.65 +unrecognised by then may be treated like unrecognised built-ins.
    1.66  
    1.67  === Name Restrictions and Resolution ===
    1.68  
    1.69 -'''Static''' objects, forming the fundamental [[../Structure|structure]] of the program, expose their names through the general structure hierarchy. Classes, which are defined as part of this structure, depend on well-defined names for any base classes they employ. For example:
    1.70 +'''Static''' objects, forming the fundamental [[../Structure|structure]] of
    1.71 +the program, expose their names through the general structure hierarchy.
    1.72 +Classes, which are defined as part of this structure, depend on well-defined
    1.73 +names for any base classes they employ. For example:
    1.74  
    1.75  {{{#!python numbers=disable
    1.76  class C(A): # depends on A being a name that can be resolved (and being a class)
    1.77 @@ -49,50 +77,83 @@
    1.78      ...
    1.79  }}}
    1.80  
    1.81 -Base classes must be identifiable and unambiguous. Since base classes may be imported, their identification may not necessarily occur immediately, but it must be possible once all information about a program is known and when all such dependencies are resolved.
    1.82 +Base classes must be identifiable and unambiguous. Since base classes may be
    1.83 +imported, their identification may not necessarily occur immediately, but it
    1.84 +must be possible once all information about a program is known and when all
    1.85 +such dependencies are resolved.
    1.86  
    1.87  === Attribute Identification ===
    1.88  
    1.89  Attributes are introduced to namespaces as follows:
    1.90  
    1.91 - * For classes and modules, the definition of names defines attributes in those namespaces
    1.92 - * Functions do not generally support attributes, although [[../Representations#Special_Members|representation-specific attributes]] do exist on functions
    1.93 - * For instances, assignments to attributes of the special `self` name, performed in methods, define attributes in all instances of the method's class
    1.94 + * For classes and modules, the definition of names defines attributes in
    1.95 +   those namespaces
    1.96 + * Functions do not generally support attributes, although
    1.97 +   [[../Representations#Special_Members|representation-specific attributes]]
    1.98 +   do exist on functions
    1.99 + * For instances, assignments to attributes of the special `self` name,
   1.100 +   performed in methods, define attributes in all instances of the method's
   1.101 +   class
   1.102  
   1.103 -Attributes are only supported on program objects if they have been defined or '''bound''' as described above. Any attempt to access or set an attribute on an object using a name that was not determined through the above process is considered an invalid operation. Thus, augmenting the attributes available on an object (so-called "monkeypatching") is not possible.
   1.104 +Attributes are only supported on program objects if they have been defined or
   1.105 +'''bound''' as described above. Any attempt to access or set an attribute on
   1.106 +an object using a name that was not determined through the above process is
   1.107 +considered an invalid operation. Thus, augmenting the attributes available on
   1.108 +an object (so-called "monkeypatching") is not possible.
   1.109  
   1.110 -When an attribute is accessed, the location of its use is recorded and ultimately associated with assignments of the name involved, just as is done for accesses of the plain name itself, but the attribute details are subsequently collected together for each assignment or '''version''' of the name. This is discussed below.
   1.111 +When an attribute is accessed, the location of its use is recorded and
   1.112 +ultimately associated with assignments of the name involved, just as is done
   1.113 +for accesses of the plain name itself, but the attribute details are
   1.114 +subsequently collected together for each assignment or '''version''' of the
   1.115 +name. This is discussed below.
   1.116  
   1.117  === Inherited Attributes ===
   1.118  
   1.119 -In order to support inheritance, a process of propagation makes class and instance attributes available to any given class from its ancestor classes according to a depth-first traversal of a class's base class hierarchy. Thus, for each class, given the definition of its base classes, a complete collection of class and instance attribute names can be determined. The actual mechanism of propagation occurs during the consolidation phase of inspection, principally because class bases are not generally immediately identifiable upon completing the inspection of any given class.
   1.120 +In order to support inheritance, a process of propagation makes class and
   1.121 +instance attributes available to any given class from its ancestor classes
   1.122 +according to a depth-first traversal of a class's base class hierarchy. Thus,
   1.123 +for each class, given the definition of its base classes, a complete
   1.124 +collection of class and instance attribute names can be determined. The actual
   1.125 +mechanism of propagation occurs during the consolidation phase of inspection,
   1.126 +principally because class bases are not generally immediately identifiable
   1.127 +upon completing the inspection of any given class.
   1.128  
   1.129  === Name Assignments and Accesses ===
   1.130  
   1.131 -Each assignment of a name defines a '''version''' of the name within a namespace. The location of this definition consists of the following:
   1.132 +Each assignment of a name defines a '''version''' of the name within a
   1.133 +namespace. The location of this definition consists of the following:
   1.134  
   1.135   * The namespace in which the assignment appears
   1.136   * The name itself
   1.137   * The version or assignment instance number
   1.138  
   1.139 -When a name is used, the location of its use is recorded and is ultimately associated with the assignments that may be providing the name at that location. This permits information about the type of the name to become available for each usage location. The location of each name usage consists of the following:
   1.140 +When a name is used, the location of its use is recorded and is ultimately
   1.141 +associated with the assignments that may be providing the name at that
   1.142 +location. This permits information about the type of the name to become
   1.143 +available for each usage location. The location of each name usage consists of
   1.144 +the following:
   1.145  
   1.146   * The namespace in which the name appears
   1.147   * The name itself
   1.148   * The access instance number
   1.149  
   1.150 -Name accesses are described as special cases of attribute accesses: where attributes would be indicated, none are specified.
   1.151 +Name accesses are described as special cases of attribute accesses: where
   1.152 +attributes would be indicated, none are specified.
   1.153  
   1.154  === Attribute Accesses ===
   1.155  
   1.156 -Attribute '''accesses''' are operations involving attributes where those attributes are obtained or set in conjunction with an '''accessor''' expression. They are recorded in terms of location tuples, each describing an access as follows:
   1.157 +Attribute '''accesses''' are operations involving attributes where those
   1.158 +attributes are obtained or set in conjunction with an '''accessor'''
   1.159 +expression. They are recorded in terms of location tuples, each describing an
   1.160 +access as follows:
   1.161  
   1.162   * The namespace in which the access occurs
   1.163   * Any named accessor or an anonymous accessor
   1.164   * The attribute (or chain of attributes) involved (omitted for name accesses)
   1.165   * The access instance number
   1.166  
   1.167 -As with name accesses, the access instance number distinguishes between different accesses employing the same details.
   1.168 +As with name accesses, the access instance number distinguishes between
   1.169 +different accesses employing the same details.
   1.170  
   1.171  Consider the following example:
   1.172  
   1.173 @@ -197,7 +258,11 @@
   1.174  }}}
   1.175  }}}}
   1.176  
   1.177 -Since the names involved may be provided by different name versions, accesses are counted independently. Meanwhile, a non-name or '''anonymous''' accessor may be involved in an access. Such anonymous accessors are independent and do not accumulate attribute usage because they potentially involve completely different objects.
   1.178 +Since the names involved may be provided by different name versions, accesses
   1.179 +are counted independently. Meanwhile, a non-name or '''anonymous''' accessor
   1.180 +may be involved in an access. Such anonymous accessors are independent and do
   1.181 +not accumulate attribute usage because they potentially involve completely
   1.182 +different objects.
   1.183  
   1.184  || '''Namespace''' || '''Name''' || '''Attribute''' || '''Access number''' ||
   1.185  || `module.f`      || `p`        || `a`             || 0 ||
   1.186 @@ -215,11 +280,19 @@
   1.187  || `module.f`      || `q`        || `{}`            || 0 ||
   1.188  || `module.f`      || `q`        || `{}`            || 1 ||
   1.189  
   1.190 -Here, the attribute field is left empty and indicates that name definitions are being described. Although the data is superficially similar to name accesses, it should be remembered that accesses employ an access number whereas accessors employ a name version, with such identifiers being different things.
   1.191 +Here, the attribute field is left empty and indicates that name definitions
   1.192 +are being described. Although the data is superficially similar to name
   1.193 +accesses, it should be remembered that accesses employ an access number
   1.194 +whereas accessors employ a name version, with such identifiers being different
   1.195 +things.
   1.196  
   1.197  === Names and Attribute Usage ===
   1.198  
   1.199 -Within each scope, the names employed by the program and the attributes used with those names are tracked. As the path of execution diverges and converges again through control-flow constructs, the tracking attempts to maintain the '''attribute usage''' associated with each name, or specifically each '''version''' of each name.
   1.200 +Within each scope, the names employed by the program and the attributes used
   1.201 +with those names are tracked. As the path of execution diverges and converges
   1.202 +again through control-flow constructs, the tracking attempts to maintain the
   1.203 +'''attribute usage''' associated with each name, or specifically each
   1.204 +'''version''' of each name.
   1.205  
   1.206  {{{{#!table
   1.207  <style="vertical-align: top">
   1.208 @@ -285,21 +358,45 @@
   1.209  }}}
   1.210  }}}}
   1.211  
   1.212 -The outcome of such tracking should be an indication of the attribute usage with each name based on the shortest routes that names can take through the control-flow structure. Such shortest-route usage defines the minimal selection of attributes that can be considered used with a name, and thus such usage defines the broadest selection of object types that can be identified as supporting such attributes. In the above example, the following minimal selections of attributes apply:
   1.213 +The outcome of such tracking should be an indication of the attribute usage
   1.214 +with each name based on the shortest routes that names can take through the
   1.215 +control-flow structure. Such shortest-route usage defines the minimal
   1.216 +selection of attributes that can be considered used with a name, and thus such
   1.217 +usage defines the broadest selection of object types that can be identified as
   1.218 +supporting such attributes. In the above example, the following minimal
   1.219 +selections of attributes apply:
   1.220  
   1.221  || '''Name Version''' || '''Minimal Set of Attributes''' || '''Types''' ||
   1.222  || `y` (version 0) || ''empty set'' || ''any object'' ||
   1.223  || `y` (version 1) || `a2` ||  ''only objects providing the single attribute'' ||
   1.224  
   1.225 -The assumption is made that any attribute used with a name is always provided by the object referenced by that name and that the correct execution of the code does not rely on an attribute being absent (and thus raising an exception). By defining usage for each name, the toolchain can determine whether any type can provide the attributes used with a name, producing a compile-time error if no type supports such usage.
   1.226 +The assumption is made that any attribute used with a name is always provided
   1.227 +by the object referenced by that name and that the correct execution of the
   1.228 +code does not rely on an attribute being absent (and thus raising an
   1.229 +exception). By defining usage for each name, the toolchain can determine
   1.230 +whether any type can provide the attributes used with a name, producing a
   1.231 +compile-time error if no type supports such usage.
   1.232  
   1.233 -It is possible that certain routes taken by names might define attribute usage that cannot be supported by types that do support the shortest-route usage, yet it might not be appropriate to forbid usage of such types with such names: the program logic may intend that such types do not visit the regions of the code that employ the attributes that such types cannot support. However, as a consequence, run-time tests will be required to prevent attribute accesses that are inappropriate for such types from taking place. In the above example, the following maximal selections apply:
   1.234 +It is possible that certain routes taken by names might define attribute usage
   1.235 +that cannot be supported by types that do support the shortest-route usage,
   1.236 +yet it might not be appropriate to forbid usage of such types with such names:
   1.237 +the program logic may intend that such types do not visit the regions of the
   1.238 +code that employ the attributes that such types cannot support. However, as a
   1.239 +consequence, run-time tests will be required to prevent attribute accesses
   1.240 +that are inappropriate for such types from taking place. In the above example,
   1.241 +the following maximal selections apply:
   1.242  
   1.243  || '''Name Version''' || '''Maximal Set of Attributes''' || '''Types''' ||
   1.244  || `y` (version 0) || `a1`, `a3` || ''only objects providing both attributes'' ||
   1.245  || `y` (version 1) || `a1`, `a2`, `a3` ||  ''only objects providing all three attributes'' ||
   1.246  
   1.247 -Tracking occurs separately in function or method namespaces and at a level combining the static namespaces in a module. This latter combination of namespaces permits the flow of global name details through class namespaces. Tracking employs special '''tracking names''' with which usage is associated, with globals and class attributes employing complete object paths to describe their names, whereas locals merely employ the plain names defined and used in local namespaces. Some examples follow:
   1.248 +Tracking occurs separately in function or method namespaces and at a level
   1.249 +combining the static namespaces in a module. This latter combination of
   1.250 +namespaces permits the flow of global name details through class namespaces.
   1.251 +Tracking employs special '''tracking names''' with which usage is associated,
   1.252 +with globals and class attributes employing complete object paths to describe
   1.253 +their names, whereas locals merely employ the plain names defined and used in
   1.254 +local namespaces. Some examples follow:
   1.255  
   1.256  || '''Namespace''' || '''Name''' || '''Name Scope''' || '''Tracking Name''' ||
   1.257  || `__main__` (module) || `x` || global || `__main__.x` ||
   1.258 @@ -309,14 +406,21 @@
   1.259  
   1.260  === Name Initialisation and Aliases ===
   1.261  
   1.262 -Each name version may be associated with a value upon assignment provided by an expression known as an '''initialiser'''. Such values may be used to inform the interpretation of operations on names, restricting the types involved to the initialised values. Some examples are as follows:
   1.263 +Each name version may be associated with a value upon assignment provided by
   1.264 +an expression known as an '''initialiser'''. Such values may be used to inform
   1.265 +the interpretation of operations on names, restricting the types involved to
   1.266 +the initialised values. Some examples are as follows:
   1.267  
   1.268  {{{#!python numbers=disable
   1.269  x = 123         # initialiser is a constant, indicating a known type
   1.270  x = classname() # initialiser refers to a class, indicating instantiation
   1.271  }}}
   1.272  
   1.273 -Names may also be assigned the values of other names, and such a name becomes an '''alias''' for such other names. Aliases can therefore be used to combine attribute usage observations across names. Other forms of aliases involve assigning attributes accessed via other names to any given name. Some examples are as follows:
   1.274 +Names may also be assigned the values of other names, and such a name becomes
   1.275 +an '''alias''' for such other names. Aliases can therefore be used to combine
   1.276 +attribute usage observations across names. Other forms of aliases involve
   1.277 +assigning attributes accessed via other names to any given name. Some examples
   1.278 +are as follows:
   1.279  
   1.280  {{{#!python numbers=disable
   1.281  y = x   # y 
   1.282 @@ -324,95 +428,180 @@
   1.283  z = x.q # z can be restricted to the types deduced for x.q
   1.284  }}}
   1.285  
   1.286 -Initialising values are retained for later resolution because their identities are not generally known until certain name resolution activities have taken place.
   1.287 +Initialising values are retained for later resolution because their identities
   1.288 +are not generally known until certain name resolution activities have taken
   1.289 +place.
   1.290  
   1.291  === Invocations ===
   1.292  
   1.293 -During inspection only limited information is available about the nature of invocations. However, some information will already be available about global names and these may be defined by classes. Thus, invocations that cause the instantiation of classes may be determined even during the inspection phase.
   1.294 +During inspection only limited information is available about the nature of
   1.295 +invocations. However, some information will already be available about global
   1.296 +names and these may be defined by classes. Thus, invocations that cause the
   1.297 +instantiation of classes may be determined even during the inspection phase.
   1.298  
   1.299 -Information about class instantiation is most useful in combination with the initialisation of names. When an assignment occurs, any initialising expression that provides enough information can be evaluated to see if it describes instantiation. If so, the nature of the instantiation can be associated with the name and used in the deduction process to constrain any usage of that name and its attributes. Such restrictions on the types associated with names are applied in the deduction phase.
   1.300 +Information about class instantiation is most useful in combination with the
   1.301 +initialisation of names. When an assignment occurs, any initialising
   1.302 +expression that provides enough information can be evaluated to see if it
   1.303 +describes instantiation. If so, the nature of the instantiation can be
   1.304 +associated with the name and used in the deduction process to constrain any
   1.305 +usage of that name and its attributes. Such restrictions on the types
   1.306 +associated with names are applied in the deduction phase.
   1.307  
   1.308  === Literals and Constants ===
   1.309  
   1.310 -Literal values or '''literals''' are specific values that appear in the program, typically representing numbers, character strings, mappings or collections. Literal numbers and strings are effectively '''constants''', meaning that their values are unambiguously defined and can eventually be referenced using a unique identifier that applies throughout the program and which can refer to an initialised object in any generated program. Initially, they are recorded for the namespace in which they appear. For example:
   1.311 +Literal values or '''literals''' are specific values that appear in the
   1.312 +program, typically representing numbers, character strings, mappings or
   1.313 +collections. Literal numbers and strings are effectively '''constants''',
   1.314 +meaning that their values are unambiguously defined and can eventually be
   1.315 +referenced using a unique identifier that applies throughout the program and
   1.316 +which can refer to an initialised object in any generated program. Initially,
   1.317 +they are recorded for the namespace in which they appear. For example:
   1.318  
   1.319  || '''Namespace''' || '''Identifier''' || '''Type''' || '''Encoding''' || '''Value''' ||
   1.320  || `__main__` || `__main__.$c0` || `__builtins__.str.string` || `iso-8859-15` || `'\xc6\xd8\xc5'` ||
   1.321  || `__main__` || `__main__.$c1` || `__builtins__.int.int` || || `123` ||
   1.322  
   1.323 -Since values may appear again in other namespaces, a mapping is generated from such local identifiers to common global identifiers for constants. Where such an identifier is derived from the value content, this can potentially occur immediately, although in practice (and in general) such a mapping will be generated after all modules have been inspected.
   1.324 +Since values may appear again in other namespaces, a mapping is generated from
   1.325 +such local identifiers to common global identifiers for constants. Where such
   1.326 +an identifier is derived from the value content, this can potentially occur
   1.327 +immediately, although in practice (and in general) such a mapping will be
   1.328 +generated after all modules have been inspected.
   1.329  
   1.330 -Collections and mappings may also be initialised using literal syntax but may contain non-constant information such as names or expressions whose values are unknown before the program is run. Such values can be represented as instantiation operations of the appropriate type in any generated program, and the instances of the type concerned can be associated with any names to which such literals are assigned. Special names are used to refer to literal types for collections and mappings. For example:
   1.331 +Collections and mappings may also be initialised using literal syntax but may
   1.332 +contain non-constant information such as names or expressions whose values are
   1.333 +unknown before the program is run. Such values can be represented as
   1.334 +instantiation operations of the appropriate type in any generated program, and
   1.335 +the instances of the type concerned can be associated with any names to which
   1.336 +such literals are assigned. Special names are used to refer to literal types
   1.337 +for collections and mappings. For example:
   1.338  
   1.339  || '''Identifier''' || '''Type''' ||
   1.340  || `$Ldict` || `__builtins__.dict.dict` ||
   1.341  || `$Llist` || `__builtins__.list.list` ||
   1.342  || `$Ltuple` || `__builtins__.tuple.tuple` ||
   1.343  
   1.344 -Such special names merely serve as convenient placeholders for the types of any literals mentioned in a module.
   1.345 +Such special names merely serve as convenient placeholders for the types of
   1.346 +any literals mentioned in a module.
   1.347  
   1.348  == Consolidating Inspection Details ==
   1.349  
   1.350 -As briefly discussed above, certain activities occur after information has been collected from an input program. Within each module, names that are external to namespaces are recorded in a '''name reference''' collection. These references identify unrecognised names but do not generally define their origins. Examples of name references are as follows:
   1.351 +As briefly discussed above, certain activities occur after information has
   1.352 +been collected from an input program. Within each module, names that are
   1.353 +external to namespaces are recorded in a '''name reference''' collection.
   1.354 +These references identify unrecognised names but do not generally define their
   1.355 +origins. Examples of name references are as follows:
   1.356  
   1.357  || '''Name''' || '''Identity''' ||
   1.358  || `__main__.repr` || `<deferred>:__builtins__.repr` ||
   1.359  || `__main__.sys` || `<module>:sys` ||
   1.360  
   1.361 -In order to obtain the final identities, deferred references may need to be resolved, yielding concrete references:
   1.362 +In order to obtain the final identities, deferred references may need to be
   1.363 +resolved, yielding concrete references:
   1.364  
   1.365  || '''Name''' || '''Identity''' ||
   1.366  || `__main__.repr` || `<function>:__builtins__.identity.repr` ||
   1.367  || `__main__.sys` || `<module>:sys` ||
   1.368  
   1.369 -This process of resolution cannot be performed immediately with only the knowledge available in a single module. Only with all program modules loaded can such resolution occur.
   1.370 +This process of resolution cannot be performed immediately with only the
   1.371 +knowledge available in a single module. Only with all program modules loaded
   1.372 +can such resolution occur.
   1.373  
   1.374  === Identifying Deferred References ===
   1.375  
   1.376 -After all modules are loaded, and with all objects present in the program at this point, each deferred reference defined within a module should ultimately yield an identity. Any failure to do so indicates usage of a name not defined in the program. The process of identifying them by resolving what each of them points to, is illustrated by the following example:
   1.377 +After all modules are loaded, and with all objects present in the program at
   1.378 +this point, each deferred reference defined within a module should ultimately
   1.379 +yield an identity. Any failure to do so indicates usage of a name not defined
   1.380 +in the program. The process of identifying them by resolving what each of them
   1.381 +points to, is illustrated by the following example:
   1.382  
   1.383  || '''Reference''' || '''Object Path to Search''' ||
   1.384  || `<depends>:__builtins__.repr` || `__builtins__.repr` ||
   1.385  || `<depends>:__builtins__.identity.repr` || `__builtins__.identity.repr` ||
   1.386  || `<function>:__builtins__.identity.repr` || ''identification has occurred'' ||
   1.387  
   1.388 -Initially, the origin information from the reference is used to find the details of the referenced object. However, in this case, the details yield another deferred reference that has not yet been resolved. Consequently, the origin information must be used to find the details of the object referenced in this case, finally yielding a reference with concrete object information. Deferred references are mutated to concrete references, thus changing the nature of such references throughout the accumulated data.
   1.389 +Initially, the origin information from the reference is used to find the
   1.390 +details of the referenced object. However, in this case, the details yield
   1.391 +another deferred reference that has not yet been resolved. Consequently, the
   1.392 +origin information must be used to find the details of the object referenced
   1.393 +in this case, finally yielding a reference with concrete object information.
   1.394 +Deferred references are mutated to concrete references, thus changing the
   1.395 +nature of such references throughout the accumulated data.
   1.396  
   1.397  === Identifying Module Dependencies ===
   1.398  
   1.399 -During deferred reference resolution, relationships are catalogued between modules in which deferred references are found and those providing the corresponding referenced objects. In addition, module ordering dependencies are established on the basis that some kinds of objects must be initialised before being used in other parts of the program. As a result, the modules providing such objects must themselves be initialised before the modules referencing such objects. More information on this topic can be found in the [[../Imports#Import_Sequencing|import sequencing]] documentation.
   1.400 +During deferred reference resolution, relationships are catalogued between
   1.401 +modules in which deferred references are found and those providing the
   1.402 +corresponding referenced objects. In addition, module ordering dependencies
   1.403 +are established on the basis that some kinds of objects must be initialised
   1.404 +before being used in other parts of the program. As a result, the modules
   1.405 +providing such objects must themselves be initialised before the modules
   1.406 +referencing such objects. More information on this topic can be found in the
   1.407 +[[../Imports#Import_Sequencing|import sequencing]] documentation.
   1.408  
   1.409  === Resolving Module Details ===
   1.410  
   1.411 -With all dependencies resolved, further work can be done with the details within each module. The `resolving` module provides the functionality to each module instance to perform such work.
   1.412 +With all dependencies resolved, further work can be done with the details
   1.413 +within each module. The `resolving` module provides the functionality to each
   1.414 +module instance to perform such work.
   1.415  
   1.416   1. Class bases can be identified.
   1.417 - 1. Special names (referring to built-in objects employed by certain operations) are resolved.
   1.418 - 1. Each access involving an external name is investigated to see if it provides an effectively constant object (as described below).
   1.419 - 1. Invocation references are converted to provide instantiation information, if appropriate.
   1.420 - 1. Initialisers are investigated to see if they provide concrete object details and can thus indicate the nature of a name.
   1.421 + 1. Special names (referring to built-in objects employed by certain
   1.422 +    operations) are resolved.
   1.423 + 1. Each access involving an external name is investigated to see if it
   1.424 +    provides an effectively constant object (as described below).
   1.425 + 1. Invocation references are converted to provide instantiation information,
   1.426 +    if appropriate.
   1.427 + 1. Initialisers are investigated to see if they provide concrete object
   1.428 +    details and can thus indicate the nature of a name.
   1.429   1. Constant value literals are associated with the appropriate types.
   1.430  
   1.431 -Thus, attribute details for each module and its classes are finalised. Meanwhile, modules that are still hidden are removed from the program.
   1.432 +Thus, attribute details for each module and its classes are finalised.
   1.433 +Meanwhile, modules that are still hidden are removed from the program.
   1.434  
   1.435  ==== Investigating Accesses ====
   1.436  
   1.437 -External names will not have been resolved during the inspection process, but with information about the whole program, it becomes possible to identify names and to determine whether attribute accesses involving those names can also be identified. Thus, name references from each namespace are investigated in turn as follows.
   1.438 +External names will not have been resolved during the inspection process, but
   1.439 +with information about the whole program, it becomes possible to identify
   1.440 +names and to determine whether attribute accesses involving those names can
   1.441 +also be identified. Thus, name references from each namespace are investigated
   1.442 +in turn as follows.
   1.443  
   1.444 -Each name referencing a static object is considered a constant access of that object. However, given a number of accompanying attributes describing an access, each attribute is added in turn, and the resulting object path identified. If the path identifies a constant object, the next attribute in the access chain is added and the resulting object path identified, and so on. The maximal collection of attributes identifying a constant object is then recorded as a constant access, with any remaining attributes in the access chain retained for traversal in a later phase.
   1.445 +Each name referencing a static object is considered a constant access of that
   1.446 +object. However, given a number of accompanying attributes describing an
   1.447 +access, each attribute is added in turn, and the resulting object path
   1.448 +identified. If the path identifies a constant object, the next attribute in
   1.449 +the access chain is added and the resulting object path identified, and so on.
   1.450 +The maximal collection of attributes identifying a constant object is then
   1.451 +recorded as a constant access, with any remaining attributes in the access
   1.452 +chain retained for traversal in a later phase.
   1.453  
   1.454 -Names yielding constant accesses do not need to have their identity deduced through the application of attribute usage.
   1.455 +Names yielding constant accesses do not need to have their identity deduced
   1.456 +through the application of attribute usage.
   1.457  
   1.458  ==== Investigating Initialisers ====
   1.459  
   1.460 -During inspection, initialisers will have been recorded in terms of expression results such as names, invocations, readily-identifiable instances, and attribute accesses. With details of the whole program plus constant accesses having been made available, such results may be definitively identified and associated with initialised names.
   1.461 +During inspection, initialisers will have been recorded in terms of expression
   1.462 +results such as names, invocations, readily-identifiable instances, and
   1.463 +attribute accesses. With details of the whole program plus constant accesses
   1.464 +having been made available, such results may be definitively identified and
   1.465 +associated with initialised names.
   1.466  
   1.467 -Alias information may also be refined at this point by identifying attribute accesses that are used to initialise names.
   1.468 +Alias information may also be refined at this point by identifying attribute
   1.469 +accesses that are used to initialise names.
   1.470  
   1.471  === Finalising Program Details ===
   1.472  
   1.473 -With class contents and relationships identified, class attribute inheritance and instance attribute availability can be defined. Some classes may depend on external state for their initialisation, and so additional module dependencies may be defined at this stage. The `importer` module contains the functionality to conduct these whole-program activities.
   1.474 +With class contents and relationships identified, class attribute inheritance
   1.475 +and instance attribute availability can be defined. Some classes may depend on
   1.476 +external state for their initialisation, and so additional module dependencies
   1.477 +may be defined at this stage. The `importer` module contains the functionality
   1.478 +to conduct these whole-program activities.
   1.479  
   1.480  == Inspection Outcome ==
   1.481  
   1.482 -Once inspection is complete, the available knowledge concerns the whole program and not merely individual modules or parts of the program. However, only limited efforts have been made until this point, notably in the acquisition of statically-defined object details when referencing names or attributes, to integrate the different modules. The [[../Deduction|deduction]] process is concerned with such integration.
   1.483 +Once inspection is complete, the available knowledge concerns the whole
   1.484 +program and not merely individual modules or parts of the program. However,
   1.485 +only limited efforts have been made until this point, notably in the
   1.486 +acquisition of statically-defined object details when referencing names or
   1.487 +attributes, to integrate the different modules. The [[../Deduction|deduction]]
   1.488 +process is concerned with such integration.