1

Please be patient and read my current scenario. My question is below.

My application takes in speech input and is successfully able to group words that match together to form either one word or a group of words - called phrases; be it a name, an action, a pet, or a time frame.

I have a master list of the phrases that are allowed and are stored in their respective arrays. So I have the following arrays validNamesArray, validActionsArray, validPetsArray, and a validTimeFramesArray.

A new array of phrases is returned each and every time the user stops speaking.

NSArray *phrasesBeingFedIn = @[@"CHARLIE", @"EAT", @"AT TEN O CLOCK", 
                                @"CAT", 
                                @"DOG", "URINATE", 
                                @"CHILDREN", @"ITS TIME TO", @"PLAY"];

Knowing that its ok to have the following combination to create a command:

COMMAND 1: NAME + ACTION + TIME FRAME
COMMAND 2: PET + ACTION 
COMMAND n: n + n, .. + n

//In the example above, only the groups of phrases 'Charlie eat at ten o clock' and 'dog urinate'
//would be valid commands, the phrase 'cat' would not qualify any of the commands
//and will therefor be ignored

Question

What is the best way for me to parse through the phrases being fed in and determine which combination phrases will satisfy my list of commands?

POSSIBLE solution I've come up with One way is to step through the array and have if and else statements that check the phrases ahead and see if they satisfy any valid command patterns from the list, however my solution is not dynamic, I would have to add a new set of if and else statements for every single new command permutation I create.

My solution is not efficient. Any ideas on how I could go about creating something like this that will work and is dynamic no matter if I add a new command sequence of phrase combination?

2

I have minimal experience with objective-c so I'm going to run though the solution I would build using c#, but will explain as I go. It should be easy to replicate in any similar language.

I would start with defining an enum to specify the phrase types:

enum PhraseTypes {
    name = 0,
    action = 1,
    pet = 2,
    timeFrames = 3
}

I would then define a Rule as having the following structure:

class Rule {
    List<PhraseTypes> components;
    Action action; //or whatever makes sense for your app
}

The users command could then be represented as:

List<String> command;

The valid phrases could be:

List<String> validNamesArray;
List<String> validActionsArray;
// ...

And then compiled into:

List<List<String>> validPhrases = new List<List<String>>( new List<String>[]
                {validNamesArray, validActionsArray, validPetsArray, validTimeFramesArray}
                                                        );

Performing a check against the rules, and calling the correct action could then be done like this:

bool CheckCommandAgainstRules(Rules rules, List<String> command) {
    foreach (Rule rule in rules) {
        if (CheckCommandAgainstRule(rule, command)) {
            rule.Action(command);  //or whatever makes sense for your app
            return true;
        }
    }
    return false;
}

bool CheckCommandAgainstRule(Rule rule, List<String> command) {
    for (i = 0; i < rule.components.length; i++) {
        PhraseType phraseType = rule.components[i];
        String phrase = command[i];
        if(!validPhrases[(int)phraseType].Contains(phrase)) {
            return false;
        }
    }
    return true;
}

This overall structure should easily scale to any number of rules and/or phrase types.

Edit:

1) Yeah, I figured that once you have solved the problem of determining if a command is valid, and identified which rule it matches the next issue is triggering some kind of action. One way is to let the Rule know which action is required.. In c# I would use a delegate or a class with a known interface so I could call it's .run() method. The best is likely vary from language to language.

2) My understanding was that you are using phrase to mean an atomic group of one or more words e.g. "AT TEN O CLOCK" , "DOG" or "PLAY". I have used command to represent a list of phrases as derived from user input. Rereading your question it looks like you have used command to refer to a valid combinations of phrase types, this something I have been calling a Rule.

  • Hey kelly, I am online and have been waiting for something to pop up. I was hoping for something that used enums as a way to declare phrase types which you've done. Exciting. I'm just trying to decipher your code bit by bit. It looks a lot simimlar to java. Towards the end it gets a bit more cryptic for me! But one moment and I will have some questions for you – Pavan Jan 17 '14 at 5:19
  • 1) Oh fantastic, I was just going to ask what class Rule { List<PhraseTypes> components; Action action; //or whatever makes sense for your app } the action part of this code segment was, but it seems you've already gone onto the next step and that is CALL my final output, be it an animation block or for a method to be executed. Is that what your intention was for that action variable? Because thats what I understand it would do. I'm glad you fully understood the nature of my question. – Pavan Jan 17 '14 at 5:21
  • 2) Can I just make the distinction between the word phrase and command that I'm loosely using. Phrases are either a word or a few words long, but each phrase is one entity - a string. A command will be a set of phrases following a pattern based on the combination of phrase types that will form it. Based on a predefined list of commands (each will have their own rule), I am looking to see if there are any valid commands that can be found in my array of ordered phrases that they com in from my speech input. I just wanted to make sure we both were on the same page, are we? – Pavan Jan 17 '14 at 5:25
  • Hey thank you, im just in the process of implementing this algorithm of yours by porting it over to objective-c. Im trying to understand this section of code: List<List<String>> validPhrases = new List<List<String>>( new List<String>[] {validNamesArray, validActionsArray, validPetsArray, validTimeFramesArray} ); At first i thought it was an array of an array, where the inner array is an array that holds all valid phrases. But is there a reason why you would have an array holding an array of valid phrases? – Pavan Jan 18 '14 at 3:13
  • Continued. would it not be one array? What is it that you're doing there? And if I'm correct why is it a multidimensional array and how would it work in the example you've given? perhaps if you could show an example data set that would go in that array as I'm having a hard time trying to visualise/figure out whats going on there Kelly. – Pavan Jan 18 '14 at 3:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.