Access ELF Documentation Access ELF Tutorials Access ELF On-Line Help Access ELF Downloadable Help File Access ELF FAQ VB ELF Documentation VB ELF Tutorials VB ELF On-Line Help VB ELF Downloadable Help File VB ELF FAQ
Configuration & Licensing Options
Critical Opinions
Our Users Talk Back






Analysis Script (Settings/Views tab)


Analysis scripts are triggered immediately after the completion of an analysis for the associated View. The purpose of an Analysis script is to automate the customizations which would otherwise have to be performed manually. These might include adding Verbs to relate tables, ususally done with the Verb Mapper, or adding/removing word definitions, usually done via the Lexicon Lookup window.

This feature is meant to be used after trial-and-error demonstrates that a given View perennially requires the same hand-customizations. Note that it's impossible to run an Analysis script the first time a View is created, because scripts are stored in the directory created along with the View. The normal sequence of events runs as follows: A View is created for a given database. Testing determines that some hand-customizations need to be made. These customizations prove their value through repeated re-runnings of the analysis. Finally, they are placed into an Analysis script which runs immediately after each re-running of the View's analysis. This saves the developer/administrator the steps involved in making the customizations manually.

Here is an example Analysis script which applies to the Northwind database.

function Prep
Dim result
   AddAttribute "price","regular", "CNoun"
   AddAttribute "price","syn (UnitPrice)", "CNoun"
   AddAttribute "place","action (OrderID)", "Verb"
   AddAttribute "write","regular\root\display", "Verb"
   AddAttribute "let","DELETE", "PNoun"         ' remove "Let" from "Let's Stop N Shop"
   AddAttribute "product","DELETE", "PNoun" ' remove "Product" from "Dairy Products"
   AddAttribute "sale","syn (order)", "CNoun"
   
   AddVerbMapping "Northwind", "Employees", "EmployeeID", "Employees", "ReportsTo", "govern"
   AddVerbMapping "Northwind", "Suppliers", "ProductID", "Products", "ProductID", "sell"
end function

The first block demonstrates the use of the AddAttribute subroutine, which automates the actions performed by the Add button on the Lexicon Lookup window. The second block shows how to automate Verb Mapper additions.

Let's step through the above code. The first two lines are used to define "price" as a Common Noun (CNoun). It is a REGULAR noun, meaning that it can be pluralized normally, by adding an "s". Once "price" is defined, it is then given an additional attribute, defining it as a synonym for "UnitPrice". The attribute string "syn (UnitPrice)" demonstrates how to set a synonym attribute.

Formally, the syntax of the AddAttribute call is Word, Attributes, Part-of-Speech. The possible parts-of-speech are shown by the labels on the Lexicon Lookup window. (The one exception is the "Data" label, which actually stands for the PNoun part-of-speech.) The Attributes parameter corresponds to the word properties which are displayed in the Lexicon Lookup information panel, for each part-of-speech listed. Multiple attributes can be added in a single call by separating them with a backslash, as in the example of "write" (Verb) above.

Attributes can be extinguished by using the Attribute parameter "KILL xyz" where xyz is the attribute. The lexicon listing of the word as a given part-of-speech can be removed entirely by using the attribute parameter "DELETE".

Note that the definition of "price" takes place in two steps because synonyms -- and other attributes requiring a secondary parameter (enclosed in parens) -- can only operate on words which already have a lexicon entry. The same isn't required for "place" and "sale" because coincidentally these terms happen to already appear in the database, so they have predefined lexicon entries: "24, place Kléber" (customer address), "Sales Representative" (contact title). It probably wouldn't hurt to follow the two-step method for all such cases.

Note that the "mystery" script methods AppendFunction() and SetGrammarLayer() are provided because the atomic actions taken by SetVerbMapping include adding entries into the lexicon -- ie, AddAttribute() -- and adding function definitions. Providing a way to reach AppendFunction() directly from a script is a backup mechanism in case we find we've failed to prepackage some needed functionality into the SetVerbMapping code. (SetGrammarLayer() allows us to specify on which of the three possible layers of the interface this insertion should be performed.)

Now let's look at the logic behind these customizations. What is the purpose of the "price" definition, for instance. If you run an Express analysis for Northwind, then check the Lexicon, you'll see that "price" is already automatically defined as a synonym for "UnitPrice". Why go to the extra trouble?

The answer becomes clear if you run an analysis of Northwind which includes the [Order Details Extended] query. This query includes a calculated field called "ExtendedPrice". When both Products, which has the UnitPrice field, and [Order Details Extended] are included together in a View, Access ELF cannot resolve the meaning of "price" -- it could mean either UnitPrice or ExtendedPrice. Manual (or as shown here, programmatic) intervention is required to tip the balance. Here, we're saying that when "price" is used by itself, it really means UnitPrice.

Of course, we could override this new default behavior contextually, for instance by adding a Phrase rule that states that "price" should be replaced by "ExtendedPrice" whenever "order" appears in the question (unless "extended" already appears also):
When I Type: [price]     I Really Mean: [ ExtendedPrice | price ] * order * extended

But that's another topic; see Phrases.

The purpose of the entry for "place" is to replace a mistaken association which Access ELF makes between the verb "place" and the HomePhone field of the Employees table. This comes about because "place" has thesaurus entires which include "house;home;dwelling" etc. (It has nothing to do with the fact that people "place" calls.) When "place" is used in the context of Northwind, it usually refers to placing an order. This line changes the ACTION (HomePhone) association of "place" to ACTION (OrderID).

This case is another illustration of why the manual changes required won't be known until after extended use of the system. The association between "place" and HomePhone is not actually present in the interface definition after the analysis. It is not until the first time someone uses the word "place" in a question that Access ELF looks up the thesaurus entries for the verb "to place", and tries to associate this verb with a known database field. This is when the mistake occurs, and it's obviously impossible to know in advance which of the many thousands of words in our English language will trigger such associations. Only once such an error is detected by a sharp-eyed user or administrator is it then possible to short-circuit the improper association, either by deleting it from the word's entry (eg, select Verb, enter KILL ACTION) or by the programmed method shown above.

To see which associations have been made over the course of time via the ACTION attribute, you can also use the Browse feature of the Lexicon Lookup window. With the Attribs radio button selected, type ACTION into the "Browse for this attribute:" box and press Return or Tab (or click the Browse results panel).

We're not exactly sure what the point was of adding the "write" (Verb:DISPLAY) definition above, which illustrates how important it is to document your code! Nevertheless, here's a somewhat contrived example showing the difference between how "write" might behave with and without the DISPLAY attribute. Let's assume we notice that Access ELF handles "graph the prices", but ignores the "graph" instruction in "show a graph of prices". (How this simple case got missed is another question.) We might add the following line:
When I Type: [{DISPLAY} a graph]     I Really Mean: graph

What this accomplishes is to change the sequence: <verb> "a graph" into just-plain "graph" whenever the Verb in question has the DISPLAY attribute. You can browse for the DISPLAY attribute in Lexicon Lookup to see that verbs such as give, present, display, generate etc. have this attribute. This rule would change "display a graph of prices" into the more explicit "graph of the prices" (note that the original is a command, the modification a description of the desired response).

How does this relate to "write"? Well, without the programmed definition, "write a graph of prices" would generate a list, not a graph. Giving "write" the DISPLAY attribute qualifies it for application to the Phrase rule above.

The entry for "let" illustrates a common situation, where a word contained within the database is unlikely to be used as an indicator for the record, but much more likely to be used in a generic sense. For instance, no one would ask "Show the Let customers." expecting to see customers with names like "Let's Stop N Shop." But someone might reasonably ask "Let me see the customers." (not, of course, intending to restrict the records to "Let's Stop N Shop"). While Access ELF is very adept at resolving usage ambiguities, sometimes it errs. Here we want to completely remove the association between "let" and the data entry "Let's Stop N Shop". Actually, it might have been adviable to do the same for "N". As noted above, "assigning" the DELETE attribute has the effect of removing the specified word/part-of-speech combination from the lexicon.

As a footnote, note that even if the association between a word and a data item is broken, this doesn't automatically remove the entries where it forms part of a compound word. And in fact, this is exactly what you'd want. Because of this, if we remove the association between "N" and the Customers CompanyName, we can still ask about Stop N Shop. StopˇNˇShop is a distinct lexical entry. (The "ˇ" symbol is used by ELF as a compound-word-space indicator.) Unfortunately, the apostrophe in "Let's" prevents this nice effect in "Let's Stop", so "Show me the Let's Stop companies." fails somewhat (it includes QUICK-Stop).

A similar deletion is performed for the word "Product", which appears in the data entry "Dairy Products" (CategoryName). This is actually something of an error on the part of Microsoft when they designed the Northwind sample database. Since the seafood category is named "Seafood" not "Seafood Products" and the produce category is named "Produce" not "Produce Products", one would expect the dairy category to be named "Dairy" and not "Dairy Products". Giving it the name "Dairy Products" implies some special link between the word "products" (or product) and the dairy category, which is not the case.

Entering "sale" as a synonym of "order" enables simple questions like "Show Davolio's sales." to be interpreted as "Show Davolio's orders." This is another case where additional overrides might be useful in the form of context-sensitive Phrase definitions. For instance:
When I Type: [{LastName}'s sales]     I Really Mean: sum Subtotal for {1}

Assuming that [Order Subtotals] is included in the View, this would redefine "sales" to mean the accumulated (summed) sales when used in an expression like "Davolio's sales".

The final block of code in the Analysis script example shows how to automate the insertion of Verbs into pre-existing Verb Map records, as well as creating new Verb Map records from scratch. In Northwind, the Suppliers-to-Products relationship is defined by the Access Relationship Diagrammer (Tools / Relationships). This link is reflected in the Suppliers-to-Products record shown by the Verb Mapper. The purpose of adding the verb "sell" to this record is to ensure that "who" in questions like "Who sells seafood?" is correctly interpreted as a reference to the Supplier.

The second example is a case where the Verb Mapper is being used for one of the three special purposes it also serves. (See the drop-down box for use of the IMPLY, GOVERN and DRILL verbs.) In this case we want to use the GOVERN verb to define a hierarchical relationship between records of the Employees table. By relating the Employees table to itself, via a link from EmployeeID to ReportsTo, we establish the chain-of-command in the Northwind organization. This simple association lets us perform computations of almost unbelievable complexity with simple point-and-click ease. In the simplest case, we can click on the Organizational Chart link in the Worksheet window, to turn the results of "Show the employees." into a tree displaying the hierarchy.

To take a more complex example, let's say we wanted to find the first employee hired in each department. First ask "Show the hire date of each employee." and display the results in Worksheet mode. Click "Organizational Chart" and check the "Apply aggregate operator" box. Now select HireDate as the aggregate field and Min as the aggregate operator. Clicking OK displays a view of the hierarchy in which each employee is listed along with the earliest date that either he or one of his subordinates was employed. Please note carefully that this display is not showing the hire date of each employee. It shows the hire dates of the lowest-level employees, with the earliest dates credited upwards to their supervisor. This is a hugely powerful accessory. For another example, let's include [Order Subtotals] in the View and then ask "Show the summed subtotals of employees." Selecting "sum of subtotal" as the aggregate field and Sum as the aggregate operator yields a tree showing the total sales along each branch of the organization; that is, crediting Buchanan not only with his own sales but with those of his subordinates as well.

Notice that if you're interested in the simpler case, where each employee is listed alongside his own hire date or sales figures, you'd need to select First as the aggregate operator. With the First operator, no values are carried upward along the tree.

Note that there should be no need to remove Verb Mapper entries programatically, because only custom mappings (ie those added by the user, either manually or programatically) are deletable. Mappings which are implied by the Relationship map or Master Query cannot be deleted.


Last Updated: March, 2002