Item Type Data Structure

Although being focused on content generation, item types in GIGL is not just for encoding generators, more importantly, it stores the structures the generator goes through according to the underlying grammar, as well as some other information that are potentially needed after the item is fully generated (or in some cases even during the generation process). An example illustration of data structures (as C++ objects) stored in generated items is shown in the figure below. This uses a similar setting to the Quiz demo with some small modification (the "Translate" function renamed to "Print", the functional attribute "Evaluate" become a variable attribute "val", and a boolean variable attribute "solved" added at the item level).

An illustration of the data structure of items generated by GIGL. Blue (big boxes) indicates nonterminal nodes labeled with rule names, red indicates nonterminal pointers, green indicates terminal nodes, purple indicates attributes (functional attributes content omitted).

    • Each item generated in GIGL contains two major parts, the wrapper part and the item tree part. The wrapper is an object that acts as an interface to the item and it represent the item at the very top level. The justification to have a wrapper is further discussed at [Here]. The item tree part is an instance of grammatical representation of the item, in other words, a syntax tree from the grammar, which makes it the main structural part of the item.

    • The wrapper parts contains wrapper attributes, which are declared in the wrapper block (or sometimes implicitly copied from the node block). A small but very important part of the wrapper is a pointer named "root", which is always implicitly declared, and it points to the root of the item tree part.

    • The item tree part contains a collection of nodes connected as a tree structure. Each node in the tree is a nonterminal node (we do not have GIGL specific model for terminal nodes as those represent concrete content and is supposed to be very problem specific and C++ features already handles well on custom type definition), labeled with the rule through which it is expanded, and attached with the node attributes. Nodes attributes are declared in the node block and they appears in all different nodes as different instances (future updates may allow specifying which type of nodes gets which set of attributes).

    • The item tree part can be different cross different item from the same item type, not just in the value of variable attributes, but more importantly the structure of the tree. This is the main point of grammatical representations, i.e. having a compact representation of structurally variant content.

    • Generators are not shown in the figure. In implementation, they are part of the data structure, or, more precisely, they are all member functions in the wrapper class. However, this information should be transparent to users. The semantically correct understanding of generators is that, the item level generator is associated to the wrapper, and the node level generators are associated to each of node types (nonterminal types) and sub-types (rules), and that all generators are only used for generation and therefore not part of the accessible attributes of the generated items. Therefore, the item generator is defined in the wrapper block (see [Here] for syntax) and the node generator is defined in the rule block along with the corresponding rule (see [Here] for syntax), if they are not implicit.

    • Some special pointers, besides the "root" are implicitly declared (not attributes) for convenience of referencing.

      • The "item" pointer in anywhere in the item refer to the wrapper object. While it is the same as "this" inside the wrapper object, it can be very useful in the item tree part when it needs to access wrapper attributes.

      • The "node" pointer in anywhere in the item tree, including when generating item tree, refer to the current node or the node currently being generated. It is mostly same as the "this" pointer semantic-wise. Accessing members of this pointer is not always the same as omitting the "node" or "this" part, because of the possible name collisions with local variables.