Mercurial > hip
changeset 6:98935af12b04
Debugged the recursive part of the parsing algorithm, so it now recognizes multiple prepositions in any order. Still some bugs.
author | jonathandicarlo@jonathan-dicarlos-macbook-pro.local |
---|---|
date | Wed, 14 May 2008 13:25:17 -0700 |
parents | a049cb93db46 |
children | aab0d14248f5 |
files | hip.html hip.js |
diffstat | 2 files changed, 66 insertions(+), 37 deletions(-) [+] |
line wrap: on
line diff
--- a/hip.html Tue May 13 18:57:55 2008 -0700 +++ b/hip.html Wed May 14 13:25:17 2008 -0700 @@ -8,6 +8,7 @@ <title></title> </head> <body> + <div id="status-line">Ubiquity!</div> <input id="search-box" type="text" size="40" /> <div id="autocomplete-popup"></div> </body>
--- a/hip.js Tue May 13 18:57:55 2008 -0700 +++ b/hip.js Wed May 14 13:25:17 2008 -0700 @@ -1,3 +1,14 @@ +function dictDeepCopy( dict ) { + var newDict = {}; + for (var i in dict ) { + newDict[i] = dict[i]; + } + return newDict; +}; + +function dictKeys( dict ) { + return [ key for ( key in dict ) ]; +} function NounType( name, expectedWords ) { this._init( name, expectedWords ); @@ -44,6 +55,7 @@ var anyWord = { // a singleton object which can be used in place of a NounType. + _name: "text", match: function( fragment ) { return true; }, @@ -64,7 +76,20 @@ }, getCompletionText: function() { - // returns completed and canonicalized sentence + // return plain text that we should set the input box to if user hits + // space bar on this sentence. + var sentence = this._verb._name; + if ( this._DO ) { + sentence = sentence + " " + this._DO; + } + for ( var x in this._modifiers ) { + sentence = sentence + " " + x + " " + this._modifiers[x]; + } + return sentence; + }, + + getDisplayText: function() { + // returns html formatted sentence for display in suggestion list var sentence = this._verb._name; if ( this._verb._DOType ) { if ( this._DO ) { @@ -74,11 +99,11 @@ } } - for ( var x in this._verb._modifiers ) { + for ( var x in this._verb._modifiers ) { // was this._verb._modifiers if ( this._modifiers[ x ] ) { - sentence = sentence + " " + x + " " + this._modifiers[x]; + sentence = sentence + " <b>" + x + " " + this._modifiers[x] + "</b>"; } else { - sentence = sentence + " <span class=\"needarg\">(" + this._verb._modifiers[x]._name + ")</span>"; + sentence = sentence + " <span class=\"needarg\">(" + x + " " + this._verb._modifiers[x]._name + ")</span>"; } } return sentence; @@ -86,6 +111,7 @@ getDescription: function() { // returns a string describing what the sentence will do if executed + return this._verb.getDescription( this._DO, this._modifiers ); } }; @@ -106,12 +132,17 @@ // example: { "from" : City, "to" : City, "on" : Day } }, + getDescription: function() { + // returns a string describing what the sentence will do if executed + return this._verb.getDescription( this._DO, this._modifiers ); + } + recursiveParse: function( unusedWords, filledMods, unfilledMods ) { var x; var suggestions = []; var completions = []; var directObject = ""; - if ( [key for (key in unfilledMods)].length == 0 ) { + if ( dictKeys( unfilledMods ).length == 0 ) { // Done with modifiers, try to parse direct object. if ( unusedWords.length == 0 ) { // No words left, no direct object. Try parsing sentence @@ -141,14 +172,11 @@ return []; } } - } - }, - - /* - else { + } else { // "pop" a preposition off of the properties of unfilledMods - var preposition = [key for (key in unfilledMods)][0]; - var newUnfilledMods = unfilledMods.splice(); + var preposition = dictKeys( unfilledMods )[0]; + // newUnfilledMods is the same as unfilledMods without preposition + var newUnfilledMods = dictDeepCopy( unfilledMods ); delete newUnfilledMods[preposition]; // Look for a match for this preposition @@ -156,7 +184,7 @@ var matchIndices = []; for ( var x = 0; x < unusedWords.length - 1; x++ ) { if ( preposition.indexOf( unusedWords[x] ) == 0 ) { - if ( nounType.match( unusedWords[ x + 1 ] ) == 0 ) { + if ( nounType.match( unusedWords[ x + 1 ] ) ) { // Match for the preposition at index x followed by // an appropriate noun at index x+1 matchIndices.push( x ); @@ -167,31 +195,33 @@ // no match for this preposition. // Leave it blank and try to parse the rest: filledMods[preposition] = ""; - return recursiveParse( unusedWords, filledMods, newUnfilledMods ); + var directObject = unusedWords.join( " " ); + return [ new ParsedSentence( this, directObject, filledMods ) ]; + //return this.recursiveParse( unusedWords, filledMods, newUnfilledMods ); } else { + // this is placeholder, destroy it. for ( x in matchIndices ) { - // remove the words that matched the preposition and following - // noun: var noun = unusedWords[ matchIndices[x]+1 ]; var newUnusedWords = unusedWords.slice(); - newUnusedWords.splice( possibilities[x], 2 ); - // add every noun completion from every possibility... + newUnusedWords.splice( matchIndices[x], 2 ); + var directObject = newUnusedWords.join( " " ); + suggestions = nounType.suggest( noun ); for ( var y in suggestions ) { - var newFilledMods = filledMods.slice(); + var newFilledMods = dictDeepCopy( filledMods ); newFilledMods[ preposition ] = suggestions[y]; - var newCompletions = recursiveParse( newUnusedWords, - newFilledMods, - newUnfilledMods ); + var newCompletions = this.recursiveParse( newUnusedWords, + newFilledMods, + newUnfilledMods ); completions = completions.concat( newCompletions ); } } return completions; - } + } } - }, */ + }, - parse: function( words ) { + getCompletions: function( words ) { /* returns a list of ParsedSentences. */ /* words is an array of words that were space-separated. The first word, which matched this verb, has already been removed. @@ -203,11 +233,6 @@ return this.recursiveParse( words, {}, this._modifiers ); }, - getCompletions: function( words ) { - var sentences = this.parse( words ); - return [ sentences[x].getCompletionText() for ( x in sentences ) ]; - }, - match: function( sentence ) { // returns a float from 0 to 1 telling how good of a match the input // is to this verb. @@ -254,7 +279,7 @@ _init: function( ) { this._lockedInSentence = null; this._hilitedSuggestion = 0; - this._suggestionList = []; + this._suggestionList = []; // a list of ParsedSentences. }, updateSuggestionList: function( query ) { @@ -267,12 +292,13 @@ completions = verb.getCompletions( words.slice(1) ); this._suggestionList = this._suggestionList.concat( completions ); } - } // TODO sort in order of match quality + } + // TODO sort in order of match quality this._hilitedSuggestion = 0; }, - getSuggestions : function() { - return this._suggestionList; + getSuggestionsAsHtml : function() { + return [ this._suggestionList[x].getDisplayText() for ( x in this._suggestionList ) ]; }, indicationDown: function( ) { @@ -297,7 +323,7 @@ autocomplete: function( query ) { var hilited = this.getHilitedSuggestion(); if ( hilited > -1 ) { - var newText = this._suggestionList[ hilited ] + " "; + var newText = this._suggestionList[ hilited ].getCompletionText() + " "; } else { newText = query; } @@ -330,7 +356,7 @@ } function updateDisplay( ) { - var suggestions = gQs.getSuggestions(); + var suggestions = gQs.getSuggestionsAsHtml(); var hilitedSuggestion = gQs.getHilitedSuggestion(); var ac = $("#autocomplete-popup"); ac.html( makeSuggestionHtml( "div", suggestions, hilitedSuggestion ) ); @@ -377,6 +403,7 @@ } $(document).ready( function() { + $("#status-line").html( "Welcome to Ubiquity." ); $("#search-box").focus(); $("#search-box").keyup( searchBoxQuery ); $("#autocomplete-popup").css( @@ -386,6 +413,7 @@ }); /* Minor problems: -1. verbs with indirect objects are returning empty completion lists 2. multiple word direct objects are truncated to single word +3. prepositional phrases past the first don't get matched? +4. sentences need to have descriptions */