;; @module wordnet
;; @description Queries a local copy of Wordnet 3.0 English lexical database from <a href="http://wordnet.princeton.edu/">wordnet.princeton.edu</a>
;; @version 0.31
;; @author Lutz Mueller, December 2007
;;
;; WordNet® is a large lexical database of English, developed under the direction 
;; of George A. Miller. Nouns, verbs, adjectives and adverbs are grouped into sets 
;; of cognitive synonyms (synsets), each expressing a distinct concept. Synsets are 
;; interlinked by means of conceptual-semantic and lexical relations. The resulting 
;; network of meaningfully related words and concepts can be navigated with the 
;; browser. WordNet is also freely and publicly available for download. WordNet's 
;; structure makes it a useful tool for computational linguistics and natural language 
;; processing. (<this paragraph copied from http://wordnet.princeton.edu>)
;;
;; This module has two interfaces to a local copy of WordNet-3.0. The simple interface
;; works via the command line utility: 'wn' part of the normal WordNet-3.0 installation.
;; The alternate interface is a shared library interface to a specially adapted
;; compilation of the 'wn' utility source code. Queries made with the shared library
;; interface are only about 25% faster than queries made through the simple
;; 'wn' commandline interface, but do not invoke a new process for every query. 
;; This module can be switched to use the simpleinterface editing the 'wn:SHARED_LIB' 
;; setting at the beginning of this file.
;;
;; Note that the function 'wn:morph' is only available in the shared library interface.
;;
;; <h3>Requirements</h3>
;; For the simple 'wn' command line interface a standard installation of WordNet 3.0
;; is necessary. Source code and binaries for Windows and Unix can be obtained at:
;; @link http://wordnet.princeton.edu/obtain http://wordnet.princeton.edu/obtain .
;; This module automatically adjusts to the standard Wordnet directory locations
;; on Windows and UNIX. If non-standard locations are used, the environment settings
;; at the beginning of this module file have to be adjusted.
;;
;; For the shared library interface the file 'libwn.c' needs to be compiled and
;; the resulting library be placed in '$WNHOME/lib' as either 'libwn.dylib' on
;; Mac OS X or 'libwn.so' on other UNIX. By default '$WNHOME is assumed to be
;; '/usr/local/WordNet-3.0>' on Unix or '%PROGRAMFILES%/WordNet-3.0/' on Win32.
;;
;; The source and a shell script to compile 
;; the libaray is available from the author of this module at: 
;; @link http://newlisp.org/code/wordnet-nl-03.tgz http://newlisp.org/code/wordnet-nl-03.tgz
;; The file 'libwn.c' is an adaptation of the 'wn.c' command line utility fromn 
;; the WordNet-3.0 source distribution.
;;
;; <h3>Functions in the API</h3>
;; The names of the functions are chosen corresponding to the options used in the WordNet
;; 'wn' command line utility. This facilitates usage by users familiar with WordNet.
;;
;; 'wn:morph      -' stem, variations (only on the shared library interface)<br>
;; 'wn:hypen      -' verb hypernyms<br>
;; 'wn:hypev      -' noun hypernyms<br>
;; 'wn:synsn      -' noun synonyms ordered by estimated frequency<br>
;; 'wn:synsv      -' verb synonyms ordered by estimated frequency<br>
;; 'wn:hypon      -' noun hyponyms<br>
;; 'wn:hypov      -' verb hyponyms<br>
;; 'wn:coorn      -' noun coordinates<br>
;; 'wn:coorv      -' verb coordinates<br>
;; 'wn:antsn      -' nound antonymns<br>
;; 'wn:antsv      -' verb antonyms<br>
;; 'wn:antsa      -' adjective antonyms<br>
;; <br>
;; 'wn:query      -' process iand returns an original 'wn' quer (used internally)<br>
;; 'wn:get-words' -' extracts words from an original 'wn' query (used internally)<br>
;;
;; Note that WordNet has many more possible queries, which easily can be entered using
;; the 'wn:query' and 'wn:get-words' functions.


; environment settings for standard WordNet installations

(if (= ostype "Win32")
	; Win32
	(begin
		(env "WNHOME" (string (env "PROGRAMFILES") "/WordNet-3.0"))
		(env "WNSEARCHDIR" (string (env "PROGRAMFILES") "/WordNet-3.0/dict")))
	; all Unix like Linux, BSDs, Mac OS X, etc.
	(begin
		(env "WNHOME" "/usr/local/WordNet-3.0")
		(env "WNSEARCHDIR" "/usr/local/WordNet-3.0/dict"))
)


(context 'wn)

; set to nil to use the simple 'wn' command line interface
(define SHARED_LIB true)
	
(when SHARED_LIB
	(if (= ostype "OSX")
		(set 'LIBNAME (string (env "WNHOME") "/lib/libwn.dylib"))
		(set 'LIBNAME (string (env "WNHOME") "/lib/libwn.so"))
	)

	(import LIBNAME "initialize")
	(import LIBNAME "querywn")
	(import LIBNAME "querywn")
	(import LIBNAME "morphstr")
	(initialize)
)

(constant 'NOUN    1)
(constant 'VERB    2)
(constant 'ADJ     3)
(constant 'ADV     4)

;; @syntax (wn:morph <str-word> [<int-pos>])
;; @param <str-word> The word for which to seach the morph.
;; @param <int-pos> The optional part of speech for which to search, 'wn:NOUN', 'wn:VERB', 'wn:ADJ', 'an:ADV'.
;; @return The word variant for the part of speech given, or a list of found variants, if not <int-pos> is spceified.
;;
;; @example
;; (wn:morph "shot") =&gt; (("shoot" wn:VERB))
;;
;; (wn:morph "shot" wn:VERB) =&gt; "shoot"
;;
;; (wn:morph "shot" wn:ADJ) =&gt; nil
;;
;; (wn:morph "forms") =&gt; (("form" wn:NOUN) ("form" wn:VERB))

(define (wn:morph word pos, result plist)
	(if pos
		(begin
			(set 'result (morphstr word pos))
			(if (!= result 0) (get-string result))
		)	
		; else
		(begin
			(set 'plist '())
			(for (p 4 1) 
				(set 'result (morphstr word p))
				(if (!= result 0) 
					(push (list (get-string result) (nth  p '(nil NOUN VERB ADJ ADV))) plist)
				)
			)
		plist
		)
	)
)

;; @syntax (wn:hypen <str-word>)
;; @param The word for which to search hypernym nouns.
;; @return List of words.
;;
;; This function does a '-hypen' query returning noun synonyms for the word entered.
;;
;; @example
;; (wn:hypen "motor") =&gt; 
;;
;; ("machine" "device" "instrumentality" "instrumentation" "artifact" "artefact" "whole" 
;;  "unit" "object" "physical object" "physical entity" "entity" "agent" "causal agent" 
;;  "cause" "causal agency" "physical entity" "entity")


(define (hypen word)
	(get-words (query (append word " -hypen")))
)

;; @syntax (wn:hypev <str-word>)
;; @param The word for which to search hypernym verbs.
;; @return List of words.
;;
;; This function does a '-hypev' query returning verb synonyms for the word entered.
;;
;; @example
;; (wn:hypev "motor") =&gt; ("travel" "go" "move" "locomote")
;;


(define (hypev word)
	(get-words (query (append word " -hypev")))
)

;; @syntax (wn:synsn <str-word>)
;; @param The word for which to search synonym nouns.
;; @return List of words.
;;
;; This function does a '-synsn' query returning noun synonyms for the word entered.
;;
;; @example
;; (wn:synsn "program") 
;;
;; =&gt; ("idea" "thought" "system" "system of rules" "show" "document" "written document" 
;;  "papers" "announcement" "promulgation" "information" "info" "software" "software program" 
;;  "computer software" "software system" "software package" "package" "performance")

(define (synsn word)
	(get-words (query (append word " -synsn")))
)

;; @syntax (wn:synsv <str-word>)
;; @param The word for which to search synonym verbs.
;; @return List of words.
;;
;; This function does a '-synsv' query returning verb synonyms for the word entered.
;;
;; @example
;; (wn:synsv "program") 
;;
;; =&gt; ("schedule" "create by mental act" "create mentally")

(define (synsv word)
	(get-words (query (append word " -synsv")))
)



;; @syntax (wn:hypon <str-word>)
;; @param The word for which to search hyponym nouns.
;; @return List of words.
;;
;; This function does a '-hypon' query returning noun hyponyms for the word entered.
;;
;; @example
;; (wn:hypon "train") 
;;
;; =&gt; ("boat train" "car train" "freight train" "rattler" "hospital train" "mail train" 
;; "passenger train" "streamliner" "subway train" "epicyclic train" "epicyclic gear train" 
;; "reduction gear")


(define (hypon word)
	(get-words (query (append word " -hypon")))
)


;; @syntax (wn:hypov <str-word>)
;; @param The word for which to search hyponym verbs.
;; @return List of words.
;;
;; This function does a '-hypov' query returning verb hyponyms for the word entered.
;;
;; @example
;; (wn:hypovv "program") 
;;
;; =&gt; ("hack" "hack on")

(define (hypov word)
	(get-words (query (append word " -hypov")))
)


;; @syntax (wn:coorn <str-word>)
;; @param The word for which to search coordinate nouns..
;; @return List of words.
;;
;; This function does a '-coorn' query returning noun coordinates for the word entered.
;;
;; @example
;; (wn:coorn "breakfast") 
;;
;; =&gt; ("mess" "square meal" "potluck" "refection" "breakfast" "brunch" "lunch" "luncheon" 
;;  "tiffin" "dejeuner" "tea" "afternoon tea" "teatime" "dinner" "supper" "buffet" "picnic" 
;;  "bite" "collation" "snack" "nosh-up" "ploughman's lunch" "banquet" "feast" "spread")


(define (coorn word)
	(get-words (query (append word " -coorn")))
)


;; @syntax (wn:coorv <str-word>)
;; @param The word for which to search coordinate verbs.
;; @return List of words.
;;
;; This function does a '-coorv' query returning verb coordinates for the word entered.
;;
;; @example
;; (wn:synsv "sleep") 
;;
;; =&gt; ("sleep" "kip" "slumber" "log Z's" "catch some Z's" "drowse" "sleep" "house" "seat")
 
(define (coorv word)
	(get-words (query (append word " -coorv")))
)


;; @syntax (wn:antsn <str-word>)
;; @param The word for which to search antonym nouns.
;; @return List of words.
;;
;; This function does a '-antsn' query returning noun antonyms for the word entered.
;;
;; @example
;; (wn:antsn "love")  =&gt; ("love" "hatred")


(define (antsn word)
	(get-words (query (append word " -antsn")))
)


;; @syntax (wn:antsv <str-word>)
;; @param The word for which to search antonym nouns.
;; @return List of words.
;;
;; This function does a '-antsv' query returning verb antonyms for the word entered.
;;
;; @example
;; (wn:antsv "love")  =&gt; ("hate" "detes")t


(define (antsv word)
	(get-words (query (append word " -antsv")))
)


;; @syntax (wn:antsa <str-word>)
;; @param The word for which to search antonym nouns.
;; @return List of words.
;;
;; This function does a '-antsa' query returning adjective antonyms for the word entered.
;;
;; @example
;; (wn:antsa "cool") =&gt; ("lukewarm" "tepid" "warmed" "warming" "hot" "cordial" "hearty")
;;

(define (antsa word)
	(get-words (query (append word " -antsa")))
)

; ------------------------------------- Utility functions ----------------------
;; <center>- &sect; -</center>
;; <center><h2>Utility Functions</h2></center>

;; @syntax (wn:query <str-query>)
;; @param <str-query> A query string exactly as used for the WordNet 'wn' command.
;;
;; This command is normally only used internally by this module, but can also be used to
;; add new functions to this module or make queries not covered by the other functions.
;;
;; @example
;; (wn:query "book -synsn") 
;; 
;; =&gt; generates same output as 'wn book -synsn' on command line

(if SHARED_LIB
	(define (query str-query) 
		(parse (get-string (querywn str-query)) "\n"))
	;else
	(define (query str-query)
		(exec (string (env "WNHOME") "/bin/wn " str-query)))
)

;; @syntax (wn:get-words <str-query-result>)
;; @param Parse out the wordsfrom a 'wn:query' results and return them in a list.
;; @return List of words.
;;
;; This command is normally only used internally by this module, but can also be used to
;; add new functions to this module or make queries not covered by the other functions.

;; @example
;; (wn:get-words (wn:query "old -synsn"))
;;
;; =&gt; ("past" "past times" "yesteryear")


(define (wn:get-words str-result)
	(let (f (filter (fn (l) (starts-with (trim l) "=>")) str-result))
		(map trim (flat (map (fn (l) (parse (2 (trim l)) ", ")) f)))
	)
)

; eof ;



syntax highlighting with newLISP and newLISPdoc