In this step, we'll flesh out the DecompAssemblyRule class so that we can finish
building RememberPattern. The two stubbed DecompAssemblyRule methods we need to
flesh out are:
public bool CanDecompose
(string input);
public string GenerateResponse
(string input);
Writing CanDecompose()
CanDecompose() checks whether the user's input matches the decomposition rule.
Eliza's REMEMBER pattern defines two decomposition rules:
decomp: * i remember *
decomp: * do you remember *
Both rules consist of a phrase being matched (e.g. "I REMEMBER"), optional
text before the phrase, and text after the phrase. Let's take a stab at writing
the psuedo-code for CanDecompose().
check if the input contains the phrase being searched for;
if it doesn't
return false;
extract the text element that occurs before the phrase;
extract the text element that occurs after the phrase;
store the text elements for later use by GenerateResponse();
return true;
Recall the first decomposition/assembly rule for the REMEMBER pattern:
decomp: * i remember *
reasmb: Do you often think of (2)?
reasmb: Does thinking of (2) bring anything else to mind?
reasmb: What else do you recollect?
reasmb: Why do you recollect (2) just now?
reasmb: What in the present situation reminds you of (2)?
reasmb: What is the connection between me and (2)?
If the user entered:
ONCE IN A WHILE I REMEMBER PLAYING IN A BAND WHEN I WAS A TEENAGER.
CanDecompose() would break this down into:
- Phrase searched for: "I REMEMBER"
- Text element before phrase: "ONCE IN A WHILE"
- Text element after phrase: "PLAYING IN A BAND WHEN I WAS A TEENAGER"
Because we're storing the text elements for later
use by GenerateResponse(), we'll need to add a new private variable to DecompAssemblyRule
to hold them.
/// <summary>
/// The text elements in the user's input.
/// </summary>
private List<string> _textElements;
The following methods of the
string
class may come in handy when writing CanDecompose().
GO AHEAD AND WRITE DecompAssemblyRule.CanDecompose(). THEN COMPARE YOUR CODE WITH THIS.
Notice how our code comments match the psuedo-code? That's an example of well-documented
code.
Writing GenerateResponse()
Now it's time to write GenerateResponse(). This method generates a response from the
next available reassembly string. Running CanDecompose() gave us the following results:
- Phrase searched for: "I REMEMBER"
- Text element before phrase: "ONCE IN A WHILE"
- Text element after phrase: "PLAYING IN A BAND WHEN I WAS A TEENAGER"
GenerateResponse() will take the first available reassembly string from this list:
reasmb: Do you often think of (2)?
reasmb: Does thinking of (2) bring anything else to mind?
reasmb: What else do you recollect?
reasmb: Why do you recollect (2) just now?
reasmb: What in the present situation reminds you of (2)?
reasmb: What is the connection between me and (2)?
which is:
reasmb: Do you often think of (2)?
The "(2)" in the reassembly string will be replaced with the second text element, i.e.
"PLAYING IN A BAND WHEN I WAS A TEENAGER". However, before replacement, the text
element is transformed using these "post transformation" rules (see
Eliza's
script
). (I added some that were missing.)
post: am are
post: are am
post: was were
post: were was
post: your my
post: my your
post: i you
post: you I
post: i'm you are
post: you're I am
post: me you
post: myself yourself
post: yourself myself
resulting in:
PLAYING IN A BAND WHEN YOU WERE A TEENAGER
Replacing the (2) in "Do you often think of (2)?" with the transformed text element
causes GenerateResponse() to return:
DO YOU OFTEN THINK OF PLAYING IN A BAND WHEN YOU WERE A TEENAGER?
Before we can finish writing GenerateResponse(), we need a means to transform text
elements as shown above. We'll delegate this task to a new helper class, StringTransformer.
StringTransformer
Create a StringTransformer class with the static method PostTransform(), like so:
PostTransform() will need to:
- Split the incoming text into words.
- Transform each word (if necessary).
- Return the transformed sentence.
You may find these methods helpful when writing PostTransform():
GO AHEAD AND WRITE StringTransformer. THEN COMPARE YOUR CODE WITH THIS.
Now that we have a way to transform text elements, we're ready to write GenerateResponse().
GO AHEAD AND WRITE GenerateResponse(). THEN COMPARE YOUR CODE WITH THIS.
Testing our work
It's time to test our work. Run Eliza and verify that it cycles through different
responses when responding to input that contains "I REMEMBER" and "DO YOU REMEMBER".
What's next?
If you take a look at Eliza's script, you'll notice it contains several patterns whose
decompose/reassembly rules are similar to RememberPattern. In the next step, we'll add these
patterns to Eliza, thereby increasing her "intelligence". We'll also polish up her behavior a bit.
|