Recognizing Concepts with DMAP
A Direct Memory Access Parser reads text and identifies the concepts in memory that text refers to. It does this by matching phrasal patterns attached to those concepts (mops).
Attaching Phrases to Concepts
For example, suppose we wanted to read texts about economic arguments, as given by people such as Milton Friedman and Lester Thurow.
The first thing we have to do is define concepts for those arguments, those economists, and for the event of economists presenting arguments. We'll simply define Milton Friedman, a claim that interest rates are rising, and a communication event. We also have to define a number of the primitive parts of these concepts. (This example is defined in dmap-test.lisp.)
(DEFMOP M-HUMAN (M-ROOT)) (DEFMOP M-ECONOMIST (M-HUMAN)) (DEFMOP M-VARIABLE (M-ROOT)) (DEFMOP M-CHANGE (M-ROOT)) (DEFMOP M-EVENT (M-ROOT)) (DEFMOP M-CHANGE-EVENT (M-EVENT) :VARIABLE M-VARIABLE :CHANGE M-CHANGE) (DEFMOP M-COMMUNICATION-EVENT (M-EVENT) :ACTOR M-HUMAN :INFO M-EVENT) (DEFINSTANCE M-MILTON-FRIEDMAN (M-ECONOMIST)) (DEFINSTANCE M-INTEREST-RATES (M-VARIABLE)) (DEFINSTANCE M-INCREASE (M-CHANGE))
Next we have to attach to these concepts phrases that are used to refer to them. Some phrases are just sequences of English words.
(DEFPHRASE M-ROOT SOMETHING) (DEFPHRASE M-HUMAN SOMEONE) (DEFPHRASE M-ECONOMIST SOME ECONOMIST) (DEFPHRASE M-MILTON-FRIEDMAN MILTON FRIEDMAN) (DEFPHRASE M-INTEREST-RATES INTEREST RATES) (DEFPHRASE M-INCREASE RISING)
More complex concepts, such as a change in an economic variable, or a communication about an event, require phrasal patterns . A phrasal pattern is a sequence of words and role names. The role names refer to the roles in the associated concept. A role name in a pattern will match a reference to any subconcept that could fill that role in this main concept.
For example, the concept m-change-event has the role :variable which can be filled by any m-variable , such as m-interest-rates . Attached to m-change-event is the phrasal pattern (:variable) are (:change) . This will match, in order, a reference to an instance of m-variable , the word are , and a reference to an m-change . Since "interest rates" references m-interest-rates and "rising" references m-increase , the text "interest rates are rising" matches the phrasal pattern. Therefore, that text references an instance of m-change-event .
(DEFPHRASE M-CHANGE-EVENT (:VARIABLE) ARE (:CHANGE)) (DEFPHRASE M-COMMUNICATION-EVENT (:ACTOR) SAYS (:INFO))
The Concept Recognition Algorithm
From the Friedman example, we can see that we want the following kinds of events to occur:
- When the words "interest rates" are recognized, the phrase (INTEREST RATES) should be matched and the concept M-INTEREST-RATES recognized.
- When the word "rising" is recognized, the phrase (RISING) should be matched and the concept M-INCREASE recognized.
- When the sequence of concepts and words M-INTEREST-RATES are M-INCREASE are recognized, the phrase ((:VARIABLE) ARE (:CHANGE)) should be matched and the concept M-CHANGE-EVENT recognized.
The algorithm implemented in dmap.lisp uses the following approach. Every time the first element of a phrase is seen in a sentence, an object, called a concept sequence (cseq for short), is created. A concept sequence contains
- the part of the phrase not yet matched
- the position in the sentence that matched the the start of the phrase
- the concept that the phrase was attached to, called the target concept
As each new word comes in, the concept sequences are passed the word and its position in the sentence. For each concept sequence:
- If the new word matches the leading word in the sequence's phrase, the phrase is advanced to the next word.
- Otherwise the sequence is left unchanged.
In addition, new concept sequences are created for any phrases whose first words were just matched.
When any phrase in a sequence is completely matched, all concept sequences are passed the target concept of that sequence and the positions (start and end) of the phrase that was matched. For each concept sequence:
- If the leading element of the phrase is a role name, and the input concept is a valid filler of that role in the sequence's target concept, then the phrase is advanced. In addition, a pair is created linking the role to the input concept.
- Otherwise the sequence is left unchanged.
The reason for tracking the positions of words and phrases in the text is to allow DMAP to use word order, avoid using the same phrase twice, and so on. The reason for linking roles to concepts is to allow new instances of the target concept with the given role fillers to be created.
Getting Output from DMAP
Unlike standard parsers, DMAP doesn't construct a parse tree or semantic interpretation. DMAP searches memory for existing concepts and adds new concepts only when necessary. Hence, DMAP doesn't have simple return value.
To see what DMAP has found, when debugging, or to hook DMAP into other code, you can tell DMAP to call a function whenever it recognizes concepts of interest. These functions are called monitors. If you put a monitor on a concept, then the monitor will be called for every instance of that concept that DMAP recognizes during text understanding.
(with-monitors (monitor-list) . body) (add-monitor concept-name [tag function]) (remove-monitors [concept-name [tag]])
with-monitors is a macro. Use it to temporarily specify one or more monitors that will be in place during the execution of the expressions in body. Each entry in monitor-list should either a concept name or a list of the form (concept-name [tag [function]]). concept-name and tag are not evaluatd, but function is.
tag is used to distinguish different kinds of monitors, e.g., you might have monitors to print values for debugging, and others to collect values for passing to other code. tag defaults to :print.
When an instance of concept-name is recognized, function will be called with 3 arguments: the instance recognized, and the start and end positions of the input text that triggered this recognition. function> defaults to a function that prints the instance recognized.
For example, if m-root is the abstraction of all concepts, then you could print every instance of m-root recognized with
(with-monitors (m-root) (dmap:parse ...))
Monitors may also be installed and removed globally, using add-monitor and remove-monitors. remove-monitors will remove the monitors for the given concept name and tag. For both arguments, nil is equivalent to a wildcard, so (remove-monitors 'm-root) would remove all monitors on m-root, (remove-monitors nil :print) would remove all monitors with the tag :print, and (remove-monitors) would remove all monitors.