

Ask HN: Best way to implement natural language commands for todo's, reminder etc - fendale

I am working on an application that I want to allow users to enter commands in natural language, eg:<p>Followup in two days<p>Followup on November 23rd at 3pm<p>Remind me about my dentist appointment at 3.30pm on December 12th 2008<p>Clearly there can be lots of subtle variations on what exactly gets entered in these sort of scenarios which makes for a potentially tricky/interesting problem.<p>Listening to a podcast recently, Joel Spolsky mentioned that people with no knowledge of compilers would tend to tackle a parsing problem like this the 'hard way' (ie using regexes, searching strings etc) while they may be better using a lexer/compiler approach.  I have no knowledge of compilers, so my thinking right now is to scan for keywords and then things that look like dates using regexes.<p>Has anyone implemented anything that does this sort of this command processing and have any tips or tools to share?  My application is in Rails, but I am willing to experiment - I just don't want to have many hundreds of lines of code testing for all sorts of strange conditions making for a brittle maintenance nightmare!
======
markessien
You're going up the wrong tree entirely. What you're trying to do is one of
the oldest ideas in computing, and it does not work. They keep trying it, and
it keeps failing. Not technically, but from a user point of view. Typing stuff
out the way you want people to is not easy or convenient, and if there is even
the hint of uncertainty, most people will prefer not to do it. Considering
that you do not have a background in this, you will lots of unmatched items,
and 2/10 fails will consitute too much uncertainty for your users.

I have two ideas for alternatives that may or may not work, but at least have
not been tried as often:

1\. Autocomplete. When the user is typing, autocomplete his message, such that
there is always 100% certainty that the command will be executed properly.
Also, simplify the syntax, so I write 'remind' : 'December ...' : 'Dentist'.
Your syntax has to be consistent, so once learned, there is no relearning. I
don't want to have to figure out what the system wants me to type in as a
command.

2\. Visual. Use blocks and lines to create the actions. Humans have a very
good sense of geometry and relationships between physical objects. Leverage
that to make your app. Models of physical things are one of the few things we
can actually say is inherently intuitive for human beings.

~~~
fendale
Auto complete would be a good option, however I want people to be able to send
the commands in emails (with the option on the web page too).

Having started scanning about NLP, I can tell its a big area, and I don't
think I want to invest _lots_ of time into this. Perhaps a cutdown syntax is
the way to go. For my small set of commands, all I have now are TODOs,
Followups and Reminders. So a few ways of entering each of them and some
thinking about dates should get me something usable.

That said, I do have concerns about the ambiguity of what can be entered, and
what to do with failed commands etc.

Dates really are the pain point for entering things - date pickers are
generally annoying, and a series of drop downs are a pain too and people write
dates in so many different ways!

~~~
AvengerPenguin
Also remember that some ways are impossible to tell apart. 12/10/2008, for
example, is 12th October for us in the UK, but 10th December for Americans.
There's simply no way to guess at which it is without some context or the user
saying which.

What that shows is that while NLP can make systems seem quite intelligent,
it's really not a replacement for the user putting some thought into it too.
Forms work nicely as they can force input into certain formats. I like NLP, so
I always think systems could at least meet a human half way on this.

However, even if we were talking face to face, there's some social expectation
you'll try to make some sense (i.e. speak in English). You wouldn't just speak
Spanish to me if I hadn't indicated I could speak Spanish. AI-like systems are
meant to be intelligent, not psychic -- a point often forgotten by some
people.

A dialogue system would help uncertainties since it could ask for
clarification (which, frankly, is all we humans do if something's not clear
when talking to each other), but if you're talking over email, you really want
to get it right the first time as it's not the fastest system.

Again, off the top of my head: I'd say you could make it clear that the
subject of the email has to be one of "reminder", "followup" or "todo"... then
do some aggressive normalisation on the subject lines that come in (grab a
Porter Stemmer or even just take the first 3/4 letters maybe) then force to
upper or lower and then check against a massive list of synonyms. Then you
simply have to bounce with a help notice if someone really still managed to
enter something stupid.

Examples: Subject: Reminder -> REMINDER -> REM -> matches rule for
"REM/EVE/HOL" (Reminder, event, holiday) Subject: event -> EVENT -> EVE ->
matches rule for "REM/EVE/HOL" Subject: follow-up -> FOLLOW-UP -> FOL ->
matches rule for "FOL/REV" (follow-up, review)

That sort of idea. It accounts for RaNDom CapITAlisation, uncertain hyphen-
usage and plurals. Make those match rules long enough and you might get error
rate pretty low indeed.

I know you've probably already gone over this, but does it really need to be
email? Is that the best interface? Is it worth taking a step back (going
outside the box, as they say) and working out the most efficient method?

~~~
fendale
There is some good advice coming up in this thread.

A few people are suggesting email is not the correct medium, so I need to
explain more what it is I am trying to achieve. My app is sort of like 'I Want
Sandy' (I started working on this before I even heard about I Want Sandy, as I
only came to know of it now that its about to be shut down).

Basically, I want to be able to take an email sent to me, and forward it to a
drop box. I can either just send the email in as is (received emails have
certain information extracted from them and displayed on a dash board), or I
can send it in with a command on it, or several commands.

So I can fire in an email saying followup in 2 days/on Dec 12th etc, and in
two days time, the app will send me an email along with the original email
attached.

If I add a command as TODO, then it will add it to the TODO list attached to
that drop box etc.

There will of course be a non-ambiguous web front end to all this to manage
all the items, and add followups, todo's etc without an email, but my goal is
to be able to add items from your inbox.

~~~
AvengerPenguin
Ah, that's quite a neat idea really. I do think you're going to have to stick
to a fixed syntax here though. People are already familiar with the standards
of "Re: and Fw:" on the Internet, so it's not that far-fetched for people to
learn "Todo:", "Followup:" and "Remind:".

My overall suggestion would be to go with that (you could even tell users to
press the "forward" button then replace "fw" with one of three commands). Then
you can go with my suggestion of normalising caps, punctuation and even
stemming to the first few letters to as to make it as forgiving as possible.
e.g., FOL would even match a typo like Fololw-up ;-)

That way, it could expect all subject lines in the form:

    
    
      Command: Text @ Date
    

with date being optional perhaps. A standard regex or even just a split()
would be fine here. If there's an error at any point, a standard help bounce
would be good (think the --help text you get when you misuse a UNIX command).

I really don't think it's unreasonable to expect users to get the command bit
right, so the problem really is reduced to getting the date bit parsed
correctly for which I've seen two suggestions here already.

p.s. One possible future thing could be to make extensions for things like
Thunderbird that actually gives a "Todo", "Remind" and "Follow-up" buttons
alongside the "Reply" and "Forward" buttons ;-)

~~~
fendale
p.s. One possible future thing could be to make extensions for things like
Thunderbird that actually gives a "Todo", "Remind" and "Follow-up" buttons
alongside the "Reply" and "Forward" buttons ;-)

That would be very much in the future! I actually have a a prototype working
at the moment, but its for my eyes only for a while yet until I can iron a few
things out!

Good tip on the stemming - I will certainly give that a go.

------
AvengerPenguin
"Remind" might solve the date side of it, but you'll still need to parse it
out. I've thought about a similar thing before and the approach I was looking
to take was using something like: <http://www.nltk.org/> to create grammar
trees (read up on how grammars/parsers work at least on Wikipedia) for an
acceptable subset of English.

You might notice things like a time is always after "at", a date "on" and a
relative date "in". Ideas for rules:

    
    
      Event -> Title When
      Title -> <anything>
      When -> TimeSpecifier When
      TimeSpecifier -> "at" Time
      TimeSpecifier -> "in" RelativeTime
      TimeSpecifier -> "on" Date
      ...
    

Then you use semantics stuff to get the parser to return some expression that
you can use, say a Python call: event(title=<title>, at=<time>, on=<date>).

Just some things to think about and if you don't know grammars, then read up
until you understand the example I gave at least. I just wrote it off the top
of my head too, so I'm sure someone might find a mistake with it :-)

p.s. If you're as weird as me, you might even consider Prolog for parsing ;-)

------
drewp
One trick for training users on your grammar is to have the program always
talk _to_ the user with it. If the program imports my existing calendar and
talks about stuff like "lunch with fendale in 3 days" all the time, I'll talk
back to the program in similar language. Making users learn syntaxes,
especially with any punctuation that you don't pronounce out loud, is lousy.

Then, don't be afraid of ambiguity. In many cases, you can Branch Both Ways.
12/10/2008 could refer to two dates, so put the item on both, showing clearly
why it's there. "Lunch with Bill" could refer to a few people in my address
book, so just link all of them. If your software manages to get some
additional data, sort the choices so the likely one is on top.

~~~
fendale
I like that tip about talking to the user in the language as the APP expects -
hadn't though of that myself.

------
olefoo
The cheap and cheerful way to cheat this problem is to use a restricted
grammar that allows synonyms. And one of the many libraries that wrap strptime
for date parsing.

In other words; schedule, remind, tell, add; might all represent the same
operation.

If you go this route, do write a BNF grammar, do test with a reasonably large
corpus of 'live' requests.

here is a link that should get you started.
[http://www.antlr.org/wiki/display/ANTLR3/Quick+Starter+on+Pa...](http://www.antlr.org/wiki/display/ANTLR3/Quick+Starter+on+Parser+Grammars+-+No+Past+Experience+Required)

------
AvengerPenguin
The old unix reminder system, "remind", is what I use as the core of my
calendar system. It's very good at parsing dates in different formats and is
based on text files with lines such as "REM <date string> MSG <text relevant
to event>".

The reason I like it is the fact systems such as your idea there could
possibly be built on top of it. Say you parsed out any portion you saw as a
date string and put that at the front, it might be smart enough to handle
several date string formats.

------
astrec
DateJS (<http://www.datejs.com/>) might have some interesting ideas you can
borrow.

------
fugue88
It sounds like you want to rewrite Sandy (<http://www.iwantsandy.com/>), which
is good because they're closing down.

They show several examples of commands that Sandy accepts. That might help
give you a little direction designing your system.

~~~
fendale
Actually I started this before I heard about iwantsandy.com, which I only
heard about last week when it was shutting down. At that point I
simultaneously thought 'damit, there is a tool to do what I wanted and here is
me wasting time writing one to scratch my own itch' and 'interesting, outrage
at this shutting down and I am working on something similar'.

I have started taking a bit of a different approach to the problem though, in
that I want to create a drop box per work area (in my day job, I tend to have
many mini-projects to manage at once, each lasting only a month or two) to
help me keep track of things without excel.

I guess Basecamp or Highrise may get me what I wanted too, but I wanted a
small project that is achievable in a reasonable time working 10 hours a week
on it, so I am giving it a go!

------
ahsonwardak
We already do that at ShareMeme - <http://sharememe.com/welcome/quickmode>.
You have to a be registered user to use this, and we also offer up the simple
forms as well.

~~~
fendale
I have seen a few places that do these things, but how is the question. Care
to elaborate on how you go about it? What tools/libraries you use etc and how
successful it has been?

------
slig
Try searching for NLP - natural language processing

------
graham
parsedatetime (<http://code.google.com/p/parsedatetime/>) is a fantastic
Python library for parsing natural language date / time strings.

------
eru
I am surprised that Bayesian Reasoning has not yet been suggested.

