# AIML 2.0 Working Draft ![](https://lh4.googleusercontent.com/2DKqtTnSPq1ezJcXFaW5DcbBlYUGtfylZ4KR3aumLn4Dx0_oAPgdZXzLhl3t4L1zuBNywXTN9Ix0gmyvHGrfxUqm-4lsv4UUXQKhZHqQNLh1OyDWopD4lpyibvyc8PNW) Revision 1.0.2.22
March 9, 2014
Richard S. Wallace
ALICE A.I. Foundation
Contact: info@alicebot.org ## 1. Introduction This document is a draft specification for a new AIML (Artificial Intelligence Markup Language) standard, version 2.0 of the language.   AIML is an XML language for specifying the contents of a chat robot character.   An AIML Interpreter is a program capable of loading and running the bot, and providing the bot’s responses in a chat session with a human user, called the client.  This document explains in detail both the syntax and semantics of AIML, as well as key features that should be supported by an AIML interpreter. The primary design goal of the original AIML language was simplicity.   AIML is motivated by two observations: **1.** Creating an original, believable chatbot character requires writing a significant amount of content, in the form of conversational replies(*) > (*) - This proposition may not be true for chatbots based on other technologies.  AIML implements a form of supervised learning, where a person, the botmaster, plays a crucial role in training the bot.   Unsupervised learning systems, on the other hand, attempt to teach a bot through conversations, in effect crowdsourcing the bot content.   The unsupervised model has its own drawbacks however.  Specifically, the bot database becomes filled with nonsense, which then an editor must later delete.  The tradeoff between supervised and unsupervised methods might be summarized as “Creative writing vs. deleting garbage." **2.** The people who are most suited to writing the bot content are not, by in large, computer programmers.   Those with literary backgrounds are more skilled at developing content for original characters(*). > (*) The caveat to this observation is that there are of course, some talented people who have mastered both computer programming and the literary skill to write quality chatbot content. When AIML was first designed in the late 1990’s, the World Wide Web had burst upon the stage and a rush of creative energy was poured into building websites.  This tsunami of activity has in fact continued to this day.  What has changed however is that the web lost its original simplicity.  Perhaps it was inevitable as users demanded more and more sophisticated services through the web, that layers of complexity would be added.   In 1994 however it was possible to author a web site with only rudimentary knowledge of a few HTML tags.   Because at that time, a number of creative people had mastered the then-simple HTML, I made a decision to create an equally simple AIML.   I was fond of saying, “anyone who knows enough HTML to make a website, can learn enough AIML to write a chatbot."   A parallel development beginning in the 1990’s was the development of XML, including specifications, standards, documents, tools, and applications for XML.  Perhaps the world has not gone the way that the XML evangelists hoped in the 1990’s, as its many competing formats remain viable today.  But XML has not gone away either.  It remains true that XML is a broadly supported standard, and its tag-based representation is easy to grasp without sophisticated knowledge of computer science.  AIML authors have found the many XML tools, such as DTDs, syntax checkers, and editors, to be useful when creating bots.   For these reasons AIML 2.0 remains hitched to the XML wagon. At some level however, AIML does not depend on XML syntax.   There is a deeper representation of the data we represent in XML files.   As long as the representation can capture the basic structure of a pattern path (the input pattern, that pattern and topic pattern), and a hierarchical response template, then AIML could be written in a number of different formats, including Lisp S-expressions, JSON, or a structured text format.  The AIML 2.0 draft even includes an alternative representation: a hybrid of flat files and XML called AIML Intermediate Format (described in a section below). Modifying AIML inevitably reduces some of its original simplicity.   Adding more tags and more features make the language more difficult for people to understand.   The urge to keep it as simple as possible is tempered by our experience over the past decade, in which AIML botmasters learned that the language had some serious limitations.   AIML 2.0 is an attempt to address the shortcomings, while balancing the original goal of keeping the language as simple as possible.   This AIML 2.0 draft specification is, for the most part, designed to be backwards-compatible with the AIML 1.0 and earlier standards, in that way preserving the simplicity of the original language.   What’s new are some new features that build on top of the original language in such a way that the concepts can be pedagogically organized so that AIML can be taught in beginner, intermediate and advanced levels. ### What’s new in AIML 2.0? * Zero+ wildcards: new wildcards that match 0 or more words. * Highest priority matching: select certain words to have top matching priority * Migrating from attributes to tags: more dynamic control of attribute values * AIML Sets: match inputs with sets of words and phrases * AIML Maps: map set elements to members of other sets * Loops: Iterations * Local variables: variables with scope limited to one category. * Sraix: access external web services and other Pandorabots * Denormalization: the (approximate) inverse of normalization. * Pandorabots extensions * date: formatted date and time * request: access previous input request history. * response: access previous bot response history * unbound predicates: check if a predicate has been set or not * learn: learn new AIML categories * learnf: learn new AIML categories and save in a file * explode: split words and phrases into individual character * OOB (Out of Band) Tags: AIML extension for mobile device control ### What’s gone from AIML 1.0? * Gossip - never well defined anyway * Javascript - The interpreter does not have to support a scripting language (to be restored in AIML 2.1). ## 2. AIML System overview AIML defines a relationship between three entities: a human chatter called the client, a human chat bot author called the botmaster, and the robot or bot itself.  In general a botmaster can author multiple bots, and each bot can have multiple clients.   A system like Pandorabots provides for multiple botmasters, multiple bots, and multiple clients.   An AIML system embedded in a consumer device might have only one bot and one client.   The AIML standard does not specify the number of bots, botmasters or clients (except that defining AIML means we have to talk about at least one of each).  The details of handling multiple bots, botmasters and clients is left up to the implementation.   Care should be taken however to manage the state of each bot and each client session. **A. Bot configuration and state:** **AIML Files** -- Each bot is assumed to have its own set of AIML files.  This collection of AIML files uniquely defines the personality of the bot character.   A bot may be a clone of another bot, or may connect to another bot through (defined below) but for the purpose of defining the AIML language, the simple assumption is that each bot has its own AIML files. **Learnf file** -- one AIML file with special meaning is the file created by the tag (defined below).  When an AIML template activates a tag, the bot remembers or “learns" the new category, specially, by saving it in a file given a specific name by the interpreter (for example, learnf.aiml).   The new categories learned with are global to all clients chatting with the bot, so the learnf file should be part of the bot’s AIML file collection. **Bot properties** -- global values for a bot, such as or .  A multiple bot system should take care to maintain bot properties individually and separately for each bot. **Substitutions** -- normalizing substitutions, person substitutions, gender substitutions and sentence splitters are unique to each bot.   Many bots may use copies of the same substitutions, but a multiple-bot system should ensure that each bot can have its own custom substitutions. **Predicate defaults** - Predicate values in AIML are like local variables specific to one client.  Typically one thinks of client profile information like name, age and gender predicates, but predicates can be used to store any string.  AIML predicates are set with the tag and retrieved with the tag.  Predicates are specific to an individual client, but the predicates may have default values that are defined for a specific bot.  There should also be a global predicate default for any predicate whose default value is not specified for a bot. **Sets and Maps** - AIML 2.0 includes a feature that implements sets (collections) and maps.  The sets members are strings and the maps define a mapping from string to string.    Unique collections of Sets and Maps may be defined for each bot. The AIML standard does not specify where or how the properties, sets, maps, substitutions and predicates are defined.  This is an implementation detail left up to the interpreter designer.   The values could be entered through a user interface, saved in text files or a database, or in any other format including XML and JSON, as long as the interpreter can read them when the bot is launched. **B. Client session and state** **Initialization** -- when a client connects to a bot, before they begin chatting, the bot must initialize a client session.   The client session is assigned a unique ID so that the AIML interpreter can track the state of the conversation.   This is important when a single bot is chatting with multiple clients, for example a web based bot. **Predicate defaults** -- Initialization step also includes setting predicates to the default values specified for the bot. **Predicate state** -- The chat session must keep track of the state of predicate values.   Whenever a client activates an AIML category, potentially the tag is some predicate values may change.   The interpreter must remember the predicate values through the course of the conversation. **Topic** - The AIML topic is a unique predicate value, because it becomes part of the pattern matching process.   The topic can be set with **Conversation log** -- Generally an interpreter keeps a conversation log of the interactions between a bot and a client.   The AIML 2.0 draft does not specify how or in what format these logs are stored. **History** -- The AIML 2.0 draft does however specify that the bot maintain, within a chat session, a history of interactions for the purpose of evaluating the tags , , and .   The size of the history (the number of elements saved or remembered) is left up to the interpreter designer.   **Learned categories** -- Categories learned with are saved globally for the bot (see Learnf file above), but categories learned with the tag are specific to each client.   The chat session should maintain any categories learned with .   **C. Counting interactions and sentence splitting** The basic step of AIML pattern matching is to match one input sentence against the bot’s set of AIML categories.   Because inputs and responses may contain more than one sentence, AIML has adopted a particular system for counting and indexing inputs and outputs.   When the bot receives a multiple-sentence input In general one input sentence may result in 1 or more output sentences. ```xml - the current input sentence - the previous input sentence - the Nth previous input sentence. =  - the client’s last input request, consisting of one or more input sentences. - the client’s 2nd to last input request. - the client’s Nth to last input request. = - the bot’s last response, consisting of one or more sentences. - the bot’s second to last response.  - the bot’s Nth to last response. = - the last sentence the bot uttered. - the 2nd to last sentence in , provided it exists.  - The last sentence of . ``` **Human**: Hello
**Robot**: Hi nice to see you!
**Human**: How are you?  My name is Jeff.
**Robot**: I’m very well.  How are you doing? What's up, Jeff?
**Human**: I’m talking to a robot
**Robot**: Would you like to say more about that?
**Human**: Sure At this point, the bot finds a category with a response to the input “Sure". The following table summarizes the current state of input/that and request/ response history at the time when that category’s template is evaluated, Entity | Normalized Sentence | input/that | request/response --- | --- | --- | --- Human | Hello | `````` | `````` Robot | Hi nice to see you | `````` | `````` Human | How are you | `````` | `````` Human | My name is Jeff | `````` | `````` Robot | How are you doing | `````` | Robot | What is up Jeff | `````` Human | I'm talking to a robot | `````` | `````` Robot | Would you like to say more about | `````` | `````` Human | Sure | `````` ## 3. Migrating from attributes to tags in AIML 2.0 One odd feature of XML is the distinction between tags and attributes.   Consider the HTML img tag in an expression like ```html ``` Why was this tag developed to use an attribute, rather than a subtag like: ```html http://alicebot.org/logo.jpg ? ``` HTML is interpreted in a static way, but an XML language can be defined to interpret tags dynamically.  For XML languages like AIML, the problem with attributes is that they are not easy to rewrite dynamically.   Suppose we want the value of the src attribute to vary depending on another XML expression: ```html ``` The problem in XML is that you can’t put an XML expression inside an attribute: ```html is forbidden in XML syntax.   ``` Of course, this problem is not hard to solve with a little computer programming.  The XML attribute values can be rewritten by another process writing the XML.  But at least for AIML and XML languages like it, we would like to specify attribute values dynamically, and allow the botmaster to write the expressions for those values in XML.   Fortunately the problem has a simple solution: don’t use attributes.  Any value in an attribute can just as well be represent with a subtag as in our example ```html http://alicebot.org/logo.jpg ``` AIML 2.0 modifies the definition of every AIML tag that takes an attribute so that the attribute value can be specified with a subtag having the same name.  For example: ```xml  may be written as age Hi, boss!  ``` may be written as ```xml jobmanagerHi, Boss!  may be written as %D %H ``` Even more generally, the contents inside the attribute tags may be any template expression, as these examples show: ```xml PREDICATE NAME jobprofessionHi, Boss! ``` Care should be taken to ensure that whatever these template expressions return is a valid expression for the attribute.  For example in, ```xml GET INDEX ``` The ```GET INDEX``` should return a valid index number > 0. To retain backwards compatibility, either the attribute form or the subtag form may be used in AIML 2.0.  In the definitions of XML tags that follow, with a couple of exceptions noted, the attribute values may also be written in the subtag form. ## 4. AIML Syntax Edit: This section should be rewritten using RELAX NG notation. http://en.wikipedia.org/wiki/RELAX_NG This section makes use a variant of BNF notation to describe the syntax of AIML in detail.  An XML language syntax may also be specified by a DTD or XML Schema.  The BNF variant here is slightly more convenient for someone writing an AIML interpreter, and also it captures one feature of AIML that goes beyond standard XML syntax, namely the AIML pattern language. In this BNF variant: * Literal tag names and attribute expression are written in Consolas Bold font. * Expressions and clauses are written in CONSOLAS UPPERCASE. * The following notation is used to define an expression: ``` (EXPRESSION) - The expression EXPRESSION is optional. (EXPRESSION)* - The expression EXPRESSION  may be repeated 0 or more times. (EXPRESSION)+ - The expression EXPRESSION may be repeated 1 or more times. EXPRESSION3 ::== EXPRESSION1 | EXPRESSION2 - Expression EXPRESSION3 may consist of either EXPRESSION1 or EXPRESSION2.  This is equivalent to the two statements EXPRESSION3 ::== EXPRESSION1 EXPRESSION3 ::== EXPRESSION2 ``` The full description of AIML syntax follows: ``` AIML_FILE ::== AIML  AIML_VERSION ::== 0.9 | 1.0 | 1.1 | 2.0 AIML ::== (CATEGORY_EXPRESSION | TOPIC_EXPRESSION)* TOPIC_EXPRESSION ::== (CATEGORY_EXPRESSION)+ CATEGORY_EXPRESSION ::== PATTERN_EXPRESSION( PATTERN_EXPRESSION)(PATTERN_EXPRESSION) PATTERN_EXPRESSION ::== WORD | PRIORITY_WORD | WILDCARD | SET_STATEMENT | PATTERN_SIDE_BOT_PROPERTY_EXPRESSION PATTERN_EXPRESSION ::== PATTERN_EXPRESSION PATTERN_EXPRESSION ``` with exactly one space “ “ between pattern expressions. The definition of WORD is language dependent.   For English, we generally acknowledge any combination from the regular expression [a-zA-Z0-9]* as an AIML word.   The AIML preprocessor step called normalization (described in detail below) converts an input sentence to a normalized form where punctuation has been removed, and each word consists of an element of [a-zA-Z0-9]*. ``` WILDCARD ::== * | _ SET_STATEMENT ::== SET_NAME SET_NAME ::== WORD PRIORITY_WORD ::== $WORD PATTERN_SIDE_BOT_PROPERTY_EXPRESSION ::==  | PROPERTY_NAME PROPERTY_NAME ::== WORD ``` Now we turn to the AIML template, which has a hierarchical structure: ``` TEMPLATE_EXPRESSION ::== TEXT | TAG_EXPRESSION | (TEMPLATE_EXPRESSION)* ``` TEXT is any ordinary English text consisting of any character except “<" and “> ", which must be specified as < and > respectively. NORAMLIZED_TEXT is any TEXT that has been normalized by the AIML preprocessor.  The exact normalization substitutions are left up to the botmaster.   ``` TAG_EXPRESSION ::== RANDOM_EXPRESSION | CONDITION_EXPRESSION | SRAI_EXPRESSION | SRAIX_EXPRESSION | SET_PREDICATE_EXPRESSION | GET_PREDICATE_EXPRESSION | MAP_EXPRESSION | BOT_PROPERTY_EXPRESSION | DATE_EXPRESSION | THINK_EXPRESSION | EXPLODE_EXPRESSION | NORMALIZE_EXPRESSION | DENORMALIZE_EXPRESSION | FORMAL_EXPRESSION | UPPERCASE_EXPRESSION | LOWERCASE_EXPRESSION | SENTENCE_EXPRESSION | PERSON_EXPRESSION | PERSON2_EXPRESSION | GENDER_EXPRESSION | SYSTEM_EXPRESSION | STAR_EXPRESSION | THATSTAR_EXPRESSION | TOPICSTAR_EXPRESSION | THAT_EXPRESSION | REQUEST_EXPRESSION | RESPONSE_EXPRESSION | LEARN_EXPRESSION | INTERVAL_EXPRESSION |  |  |  | RANDOM_EXPRESSION ::== (
  • TEMPLATE_EXPRESSION
  • )+
    CONDITION_ITEM_COMPONENT ::== TEMPLATE_EXPRESSION | TEMPLATE_EXPRESSION |  | TEMPLATE_EXPRESSION CONDITION_ITEM_EXPRESSION ::== (CONDITION_ITEM_COMPONENT)*  CONDITION_ATTRIBUTES ::== (name="NAME") | (value="NORMALIZED_TEXT") CONDITION_EXPRESSION ::== (CONDITION_ITEM_EXPRESSION)* SRAI_EXPRESSION ::== TEMPLATE_EXPRESSION SRAIX_EXPRESSION ::== TEMPLATE_EXPRESSION
     | (SRAIX_ATTRIBUTE_TAGS)*TEMPLATE_EXPRESSION SRAIX_ATTRIBUTES ::= host="HOSTNAME" | botid="BOTID" | hint="TEXT" | apikey=" APIKEY" | service="SERVICE" SRAIX_ATTRIBUTE_TAGS ::= TEMPLATE_EXPRESSION | TEMPLATE_EXPRESSION | TEMPLATE_EXPRESSION | TEMPLATE_EXPRESSION | TEMPLATE_EXPRESSION GET_PREDICATE_EXPRESSION ::==  | TEMPLATE_EXPRESSION | | WORD SET_PREDICATE_EXPRESSION ::== TEMPLATE_EXPRESSION | TEMPLATE_EXPRESSIONTEMPLATE_EXPRESSION |  TEMPLATE_EXPRESSION | TEMPLATE_EXPRESSION TEMPLATE_EXPRESSION MAP_EXPRESSION ::= TEMPLATE_EXPRESSION | TEMPLATE_EXPRESSIONTEMPLATE_EXPRESSION BOT_PROPERTY_EXPRESSION ::==  | TEMPLATE_EXPRESSION DATE_EXPRESSION ::==  | (DATE_ATTRIBUTE_TAG) DATE_ATTRIBUTES ::== (format="LISP_DATE_FORMAT") | (jformat="JAVA DATE FORMAT") DATE_ATTRIBUTE_TAG ::== TEMPLATE_EXPRESSION | TEMPLATE_EXPRESSION INTERVAL_EXPRESSION ::== (DATE_ATTRIBUTE_TAGS)(TEMPLATE_EXPRESSION) (TEMPLATE_EXPRESSION) THINK_EXPRESSION ::== TEMPLATE_EXPRESSION EXPLODE_EXPRESSION ::== TEMPLATE_EXPRESSION NORMALIZE_EXPRESSION ::== TEMPLATE_EXPRESSION DENORMALIZE_EXPRESSION ::== TEMPLATE_EXPRESSION PERSON_EXPRESSION ::== TEMPLATE_EXPRESSION PERSON2_EXPRESSION ::== TEMPLATE_EXPRESSION GENDER_EXPRESSION ::== TEMPLATE_EXPRESSION SYSTEM_EXPRESSION ::==   TEMPLATE_EXPRESSION |   TEMPLATE_EXPRESSION TIMEOUT_ATTRIBUTE :== timeout=”NUMBER” STAR_EXPRESSION ::==  | TEMPLATE_EXPRESSION INDEX_ATTRIBUTE ::== index="NUMBER" THATSTAR_EXPRESSION ::==  | TEMPLATE_EXPRESSION TOPICSTAR_EXPRESSION ::==  | TEMPLATE_EXPRESSION THAT_EXPRESSION ::==  | TEMPLATE_EXPRESSION THAT_INDEX ::= index="NUMBER,NUMBER" REQUEST_EXPRESSION ::==  | TEMPLATE_EXPRESSION RESPONSE_EXPRESSION ::==  | TEMPLATE_EXPRESSION LEARN_EXPRESSION ::== LEARN_CATEGORY_EXPRESSION | LEARN_CATEGORY_EXPRESSION LEARN_CATEGORY_EXPRESSION ::== LEARN_PATTERN_EXPRESSION(LEARN_P ATTERN_EXPRESSION)(LEARN_PATTERN_EXPRESSION) EVAL_EXPRESSION ::== TEMPLATE_EXPRESSION LEARN_PATTERN_EXPRESSION ::== PATTERN_EXPRESSION | EVAL_EXPRESSION LEARN_PATTERN_EXPRESSION ::== (LEARN_PATTERN_EXPRESSION)+ LEARN_TEMPLATE_EXPRESSION ::== TEXT | TAG_EXPRESSION | EVAL_EXPRESSION LEARN_TEMPLATE_EXPRESSION ::== (LEARN_TEMPLATE_EXPRESSION)* ``` ## 5. AIML Pattern Language AIML patterns are made up of words, wildcards, AIML set expressions, and bot properties. A word is any sequence of characters output by the normalization pre-processor that does not contain a space.   The space character is reserved to indicate a space between words, as it does in many human languages including English.  Exactly which characters are allowed in normalization depends on the botmaster’s choice of normalization substitutions and the input language, but generally the idea with normalization is: * Remove punctuation * Expand contractions * Correct a few common spelling mistakes * Ensure one space between words So “Hello”, “123”, “HaveFun” are normalized words but “can’t”, “1.23”, and “Have-Fun” are not.  Some AIML applications that require the bot to have knowledge of the original punctuation include normalization substitutions so that for example  “,” becomes “comma”, “-” becomes “dash” and “.” becomes “point”. One way to process inputs from languages like Japanese and Chinese that do no separate words with spaces is to place an implicit space between each character and treat each one as a “word”. Pre proprocess the input ``` 日本の伝統 ``` into ``` 日本の伝統 ``` and use patterns like ```xml * の伝統 ``` AIML 2.0 includes some new wildcards and pattern-side expressions.   A. Zero or more words wildcards The AIML 1.0 wildcards * and _ are defined so that they match one or more words.   AIML 2.0 introductes two new wildcards, ^ and #, defined to match zero or more words.  As a shorthand description, we refer to these as “zero+ wildcards”. Both ^ and # are defined to match 0 or more words.   The difference between them is the same as the difference between * and _.   The # matching operator has highest priority in matching, followed by _, followed by an exact word match, followed by ^, and finally * has the lowest matching priority. When defining a zero+ wildcard it is necessary to consider what the value of (as well as and ) should be when the wildcard match has zero length.   In AIML 2.0 we leave this up to the botmaster.  Each bot can have a global property named nullstar which the botmaster can set to “”, “unknown”, or any other value. Examples: ```xml SHARPTEST # SHARPTEST # TEST # KEYWORD # ^ CARETTEST ``` Sample dialog: **Human**: sharptest
    **Robot**: #star = unknown
    **Human**: keyword
    **Robot**: Found KEYWORD
    **Human**: sharptest foo
    **Robot**: #star = foo
    **Human**: sharptest foo bar test
    **Robot**: #star = foo bar
    **Human**: xyz abc carettest
    **Robot**: ^star = xyz abc
    **Human**: carettest
    **Robot**: ^star = unknown
    **Human**: keyword
    **Robot**: Found KEYWORD
    **Human**: abc def keyword ghi jkl
    **Robot**: Found KEYWORD
    **Human**: abc keyword
    **Robot**: Found KEYWORD
    **Human**: keyword def
    **Robot**: Found KEYWORD B. $ operator In some cases it is desirable to make an exact word match have higher priority than _.   For example, The category ```xml _ ALICE ``` is useful for removing the bot’s name, Alice, from many queries such as “Tell me the time, Alice” and “What is your favorite color, Alice?”.  The simplifies these inputs to “Tell me the time” and “What is your favorite color” respectively.  But the category breaks down for other inputs like “Who is Alice?”  which we wouldn’t want to reduce to just “Who is”. Using the $ operator we can add the category ```xml $WHO IS ALICE ``` so that the input “Who is Alice?” matches this category and not the one with ```_ ALICE```. The $ indicates that the word has higher matching priority than _. ### AIML Sets A pattern in AIML 2.0 may contain an expression referring to an AIML set.   If the botmaster has defined a set named “color” of color names, then the expression color can match any member of this set. ### Examples of valid AIML patterns The following are examples of valid AIML patterns ```xml * HOW ARE YOU How are you HoW aRe YoU -- AIML patterns are case invariant color COLOR I LIKE color _ THANK YOU _ MUSIC * # MUSIC # I LIKE # MUSIC _ * _ * _ -- may not be useful but it is valid ``` Examples of invalid patterns: The following are not valid AIML patterns ```xml  -- no concept of a blank pattern How are you? -- no punctuation in AIML patterns I LIKE* -- wildcard should have a space separating it from word * -- no wildcard in set name _*_*_ -- wildcards should have spaces separating them ``` ## 6. AIML Semantics This section explains the semantics of each AIML tag. a. tag The tag wraps the contents of an AIML file.   Example: ```xml COLOR ``` The AIML file is an XML file and so may also have an optional header like however the definition of the XML header is outside the scope of AIML 2.0.  The tag wraps the AIML contents. b. tag The tag wraps a collection of categories that share the same topic pattern. Example: ```xml YESWOULD YOU LIKE TO ADD * AS A CONTACT *WOULD YOU LIKE TO ADD * AS A CONTACT ``` In this example, the first category has input pattern YES and the second category has input pattern *.  Both categories have the same that pattern, WOULD YOU LIKE TO ADD * AS A CONTACT, and the same topic pattern, ASKING TO ADD NEW CONTACTNAME. In AIML 2.0 the topic pattern may also be defined inside a category.  That is, a category has an input pattern specified by the tag, a that pattern specified by the tag, and a topic pattern specified by the tag.  If either or is omitted, the corresponding pattern is defined as * by default.   c. tag The basic unit of knowledge in AIML is a category.  The tag always contains an input and a response