Optimal Set of Includes Directives

From wiki.visual-prolog.com

Revision as of 18:15, 28 April 2016 by Thomas Linder Puls (talk | contribs) (category)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

The current #include support has two major problems:

  • There is no way to detect whether #include directives are superfluous. Superfluous includes can result in longer and more frequent compilations and thus waste of programmer time.
  • There is no way to detect whether the includes in a .ph file are sufficient. Because .ph files are always included from a .pack file and that .pack file can provide includes lacked by the .ph file. Consequently, bugs may rise when the .ph file is included from a new context.

To overcome these two problems we introduce the Optimal Set of Include Directives(called OSID in the sequel). Intuitively the OSID for a certain file (.ph or .pack) is:

enough must be included to ensure that the file compiles.
If A is needed, then the file must itself #include A. It is not sufficient to #include B even though B includes A. Especially, it is necessary to ensure that .ph files are self-contained, so that the file compiles no matter which .pack file it is included from.
There should not be includes other than those needed to fulfill the two other requirements.

It was the plan that the compiler should be able to issue warnings (or messages to the IDE), such that an optimal set of #include directives could be calculated for each pack and ph file.

But it seems better to move te calculation to the IDE, as described here.


In brief we ensure that we can obtain the following information:

  • The file name in which each scope is defined/declared (already in browse info today).
  • The scopes directly used by another scope (new info).
  • The #include structure (available to the IDE, but should rather be put in browse info).

Based on this the IDE (rather than the compiler) can calculate and maintain the optimal set of #include directives for each .ph and .pack file.

Notice that it is necessary for the IDE not only to insert include statements, but also to remove them. It might be a good idea mark both the start and the end of the #include directives.

Optimal Set of Include Directives

Since this calculation of the OSID is made by the IDE, it seems reasonable to assume the package concept that the IDE maintains.

The IDE should "think" of things in the following way (during calculation of OSID's the IDE should report the mentioned anomalies):

Code files
Files containing actual code (i.e. one or more scopes or a goal) are called code files. Normally code files are .i, .cl and .pro files, but in this context we will not look at the extensions.
Structure files
Files containing #include directives are called structure files. Normally structure files are .pack and .ph files, but in this context we will not look at the extensions.
It is an anomaly if a file is both a code file and a structure file.
Owned files
A structure file owns the code files it directly includes.
It is an anomaly if a code file is owned by two or more structure files.
Owned scopes
A structure file owns the scopes in the files it owns.
Exposed scopes
If a structure file only owns interface definitions and class declarations (but no implementations or the goal). Then the file exposes the scopes it owns. Otherwise it exposes nothing.
Exposing file
The file that expose a cetain scope, is the exposing file of that scope. (Since code files only have one owner, scopes only have at most one exposing file). An exposing file can be included in other files (think of .ph files).
Used scopes
A structure file uses the scopes that are used directly by its owned scopes.
The Optimal Set of Include Directives for a structure file is the sum of the exposing files of the used scopes (excluding the file itself).

Notice that if a scope does not have an exposing file then it can only be referenced from the owning file (or in normal terms the owning file is a .pack file and the scope is therefore private).


If aaa.pack includes aaa.pro directly, and aaa.pro contains the implementation of aaa. Furthermore, aaa directly uses bbb:

  • aaa.pro is a code file
  • aaa.pack is a structure file
  • aaa.pack owns aaa.pro
  • aaa.pack owns the implementation aaa
  • aaa.pack owns an implementation therefore nothing is exposed
  • aaa.pack uses bbb, so the exposer of bbb is in aaa.packs OSID.

If aaa.ph includes aaa.cl directly, and aaa.cl contains the declaration of aaa:

  • aaa.cl is a code file
  • aaa.ph is a structure file
  • aaa.ph owns aaa.cl
  • aaa.ph owns the declaration of aaa
  • aaa.ph exposes the declaration of aaa
  • The exposer of aaa is aaa.ph

If bbb.ph is the exposer of bbb then bbb.ph is in the OSID of aaa.pack.


With the descriptions above the .pack file can contain #include directives that are also in the corresponding .ph file. We could choose the exclude such #include directives. But I think it is simpler to consider each structure file as a completely independent file.