Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Parsing natural language is non-trivial, if you want a true natural language parser I'd recommend that you try and use an existing project or library. Here's a <a href="http://naturalparsing.com/browserparser/parse" rel="nofollow">web based parser</a>, based on the <a href="http://nlp.stanford.edu/software/lex-parser.shtml" rel="nofollow">Stanford Parser</a>. Or <a href="http://en.wikipedia.org/wiki/Natural_language_processing" rel="nofollow">wikipedia</a> is a good jumping off point. </p> <p>Having said that, if you're willing to restrict the syntax and the keywords involved you might be able to simplify it. First you need to know what's important -- you have 'things' (lights, fan) in 'places' (bedroom, kitchen) that need to go into a specific state ('on', 'off'). </p> <p>I would get the string into an array of words, either using <a href="http://php.net/manual/en/function.strtok.php" rel="nofollow">str_tok</a>, or just explode on <code>' '</code>. </p> <p>Now you have an array of words start at the <em>end</em> and go backwards looking for a 'state' -- on or off. Then follow that backwards looking for a 'thing', and finally a 'place'. If you hit another state then you can start again. </p> <p>Let me try and do that in pseudocode: </p> <pre><code>// array of words is inArray currentPlace = null; currentThing = null; currentState = null; for (i = (inArray.length - 1); i &gt;= 0; i--) { word = inArray[i]; if (isState(word)) { currentState = word; currentPlace = null; currentThing = null; } else if (currentState) { if (isThing(word)) { currentThing = word; currentPlace = null; } else if (currentThing) { if (isPlace(word)) { currentPlace = word // Apply currentState to currentThing in currentPlace } // skip non-place, thing or state word. } // Skip when we don't have a thing to go with our state } // Skip when we don't have a current state and we haven't found a state } </code></pre> <p>And, having written that, it's pretty clear that it should have used a state machine and switch statements -- which goes to show I should have designed it on paper first. If you get anymore complex you want to use a state machine to implement the logic -- states would be 'lookingForState', 'lookingForThing', etc</p> <p>Also you don't really need <code>currentPlace</code> as a variable, but I'll leave it as it makes the logic clearer. </p> <p><strong>EDIT</strong></p> <p>If you want to support 'turn the lights in the bedroom on' you'll need to be adjust the logic (you need to save the 'place' if when you don't have a thing). If you also want to support 'turn on the lights in the bedroom' you'll need to go even further. </p> <p>Thinking about it, I wonder if you can just do: </p> <pre><code>have a currentState variable and arrays for currentPlace and currentThing for each word if it's a state: store it in currentState if it's a thing, or place: add it to the approriate array if currentState is set and there is content in currentPlaces and currentThings: apply currentState to all currentThings in all currentPlaces </code></pre> <p>That's not quite there, but one of those implementations might give you a starting point.</p> <p><strong>EDIT 2</strong></p> <p>OK, I tested it out and there's a few issues due to the way English is structured. The problem is if you want to support 'Turn on ...' and 'Turn ... on' then you need to use my second pseudo-code but that doesn't work easily because of the 'and's in the sentence. For example: </p> <p>Turn my kitchen lights on <em>and</em> my bedroom <strong>and</strong> living room lights off.</p> <p>The first and joins two statements, the second and joins to places. The correct way to do this is to <a href="http://en.wikipedia.org/wiki/Sentence_diagram" rel="nofollow">diagram the sentence</a> to work out what applies to what. </p> <p>There are two quick options, first you could insist on using a different word or phrase to join two commands: </p> <p>Turn my kitchen lights on <em>then</em> my bedroom <strong>and</strong> living room lights off. Turn my kitchen lights on <em>and also</em> my bedroom <strong>and</strong> living room lights off.</p> <p>Alternatively, and this is probably easier you can insist on only having commands of the form 'Turn ... off/on'. This works with my first psuedocode above. </p> <p><a href="http://jsfiddle.net/SpaceDog/hyhua/2/" rel="nofollow">JavaScript Example</a> of first psuedocode. </p> <p>Note, you'll probably need to heavily pre-process the string if there's any chance of punctuation, etc. You might also want to look at replacing 'living room' (and similar two word phrases) with 'livingroom' rather than just matching one word and hoping for the best like I'm doing. Also, the code could be simplified a bit, but I wanted to keep it close to the psuedocode example.</p> <p><strong>EDIT 3</strong></p> <p><a href="http://jsfiddle.net/SpaceDog/pGJSY/1/" rel="nofollow">New Javascript Example</a></p> <p>This handles some extra sentences and is cleaned up a bit better, it still relies on the 'state' coming at the end of each clause as that's what it uses as a trigger to apply the actions (this version could probably read forwards instead of backwards). Also, it will not handle something like:</p> <pre><code>Turn my kitchen fan and my bedroom lights on and living room lights off. </code></pre> <p>You have to do something more complex to understand the relationship between 'kitchen' and 'fan' and 'bedroom' and 'lights'. </p> <p>Some combination of those techniques is probably enough to do something fairly impressive, as long as whoever's entering / speaking the commands follows some basic rules.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload