rwdeliza 0.03
Sign up to get free protection for your applications and to get access to all the features.
- data/ElizaData/database/db.1 +7015 -0
- data/ElizaData/database/db.10 +7001 -0
- data/ElizaData/database/db.11 +7001 -0
- data/ElizaData/database/db.12 +7003 -0
- data/ElizaData/database/db.13 +7003 -0
- data/ElizaData/database/db.14 +7008 -0
- data/ElizaData/database/db.15 +7001 -0
- data/ElizaData/database/db.16 +7001 -0
- data/ElizaData/database/db.17 +7001 -0
- data/ElizaData/database/db.18 +7001 -0
- data/ElizaData/database/db.19 +7001 -0
- data/ElizaData/database/db.2 +7001 -0
- data/ElizaData/database/db.20 +5467 -0
- data/ElizaData/database/db.3 +7001 -0
- data/ElizaData/database/db.4 +7001 -0
- data/ElizaData/database/db.5 +7001 -0
- data/ElizaData/database/db.6 +7001 -0
- data/ElizaData/database/db.7 +7001 -0
- data/ElizaData/database/db.8 +7001 -0
- data/ElizaData/database/db.9 +7001 -0
- data/ElizaData/responses/hello.res +1 -0
- data/ElizaData/responses/i_agree.res +1 -0
- data/ElizaData/responses/i_am_listening_to_you.res +1 -0
- data/ElizaData/responses/please_explain.res +1 -0
- data/ElizaData/responses/thank_you.res +1 -0
- data/ElizaData/tiny.dict +211 -0
- data/ElizaData/words/adjectives1.words +906 -0
- data/ElizaData/words/adjectives2w.words +1 -0
- data/ElizaData/words/noun0.words +15 -0
- data/ElizaData/words/noun1.words +1391 -0
- data/ElizaData/words/noun2.words +1924 -0
- data/ElizaData/words/noun4.words +330 -0
- data/ElizaData/words/pronoun1.words +6 -0
- data/ElizaData/words/verb4.words +350 -0
- data/ElizaData/words/verb42.words +391 -0
- data/ElizaData/words/verb42w.words +1 -0
- data/ElizaData/words/verb43.words +402 -0
- data/ElizaData/words/verb43w.words +1 -0
- data/ElizaData/words/verb45.words +452 -0
- data/ElizaData/words/verb4w.words +1 -0
- data/ElizaData/words/verb5.words +13 -0
- data/ElizaData/words/verb61.words +35 -0
- data/ElizaData/words/verb62.words +41 -0
- data/ElizaData/words/verb83.words +17 -0
- data/Readme.txt +462 -0
- data/bin/rwdeliza +19 -0
- data/code/01rwdcore/01rwdcore.rb +29 -0
- data/code/01rwdcore/02helptexthashbegin.rb +4 -0
- data/code/01rwdcore/03helptexthash.rb +23 -0
- data/code/01rwdcore/04helptextend.rb +6 -0
- data/code/01rwdcore/jumplinkcommand.rb +26 -0
- data/code/01rwdcore/openhelpwindow.rb +31 -0
- data/code/01rwdcore/returntomain.rb +10 -0
- data/code/01rwdcore/rundocuments.rb +10 -0
- data/code/01rwdcore/runeditconfiguration.rb +10 -0
- data/code/01rwdcore/runhelpabout.rb +10 -0
- data/code/01rwdcore/runopentinkerdocument.rb +7 -0
- data/code/01rwdcore/rwdtinkerversion.rb +22 -0
- data/code/01rwdcore/rwdwindowreturn.rb +9 -0
- data/code/01rwdcore/selectiontab.rb +9 -0
- data/code/01rwdcore/setuphelpaboutoptions.rb +13 -0
- data/code/01rwdcore/setuptinkerdocuments.rb +6 -0
- data/code/01rwdcore/test_cases.rb +109 -0
- data/code/01rwdcore/test_harness.rb +13 -0
- data/code/01rwdcore/uploadreturns.rb +62 -0
- data/code/dd0viewphoto/dd0viewphoto.rb +3 -0
- data/code/superant.com.rwdeliza/0uninstallapplet.rb +10 -0
- data/code/superant.com.rwdeliza/eliza01.rb +45 -0
- data/code/superant.com.rwdeliza/helptexthashrwdeliza.rb +39 -0
- data/code/superant.com.rwdeliza/openhelpwindowrwdeliza.rb +23 -0
- data/code/superant.com.rwdeliza/runrwdshellwindow.rb +12 -0
- data/code/superant.com.rwdeliza/rwdtinkerversion.rb +10 -0
- data/code/superant.com.rwdeliza/tagsentence.rb +39 -0
- data/code/superant.com.rwdtinkerbackwindow/diagnostictab.rb +19 -0
- data/code/superant.com.rwdtinkerbackwindow/helptexthashtinkerwin2.rb +61 -0
- data/code/superant.com.rwdtinkerbackwindow/initiateapplets.rb +240 -0
- data/code/superant.com.rwdtinkerbackwindow/installgemapplet.rb +34 -0
- data/code/superant.com.rwdtinkerbackwindow/installremotegem.rb +20 -0
- data/code/superant.com.rwdtinkerbackwindow/listgemdirs.rb +12 -0
- data/code/superant.com.rwdtinkerbackwindow/listgemzips.rb +53 -0
- data/code/superant.com.rwdtinkerbackwindow/listinstalledfiles.rb +12 -0
- data/code/superant.com.rwdtinkerbackwindow/listzips.rb +27 -0
- data/code/superant.com.rwdtinkerbackwindow/loadconfigurationrecord.rb +22 -0
- data/code/superant.com.rwdtinkerbackwindow/loadconfigurationvariables.rb +14 -0
- data/code/superant.com.rwdtinkerbackwindow/network.rb +87 -0
- data/code/superant.com.rwdtinkerbackwindow/openappletname.rb +19 -0
- data/code/superant.com.rwdtinkerbackwindow/openhelpwindowtinkerwin2.rb +38 -0
- data/code/superant.com.rwdtinkerbackwindow/remotegemlist.rb +24 -0
- data/code/superant.com.rwdtinkerbackwindow/removeapplet.rb +46 -0
- data/code/superant.com.rwdtinkerbackwindow/removeappletvariables.rb +52 -0
- data/code/superant.com.rwdtinkerbackwindow/runremoteinstall.rb +11 -0
- data/code/superant.com.rwdtinkerbackwindow/runrwdtinkerbackwindow.rb +15 -0
- data/code/superant.com.rwdtinkerbackwindow/rwdtinkerwin2version.rb +13 -0
- data/code/superant.com.rwdtinkerbackwindow/saveconfigurationrecord.rb +19 -0
- data/code/superant.com.rwdtinkerbackwindow/viewappletcontents.rb +22 -0
- data/code/superant.com.rwdtinkerbackwindow/viewgemappletcontents.rb +24 -0
- data/code/superant.com.words/dictlookup.rb +20 -0
- data/code/superant.com.words/runfortunewindow.rb +14 -0
- data/code/superant.com.words/runrwdwordsbackwindow.rb +10 -0
- data/code/superant.com.words/runrwdwordsversion.rb +14 -0
- data/code/superant.com.words/rwdtinkerversion.rb +10 -0
- data/code/zz0applicationend/zz0end.rb +4 -0
- data/configuration/language.dist +8 -0
- data/configuration/rwdapplicationidentity.dist +3 -0
- data/configuration/rwdtinker.dist +18 -0
- data/configuration/rwdweliza-0.03.dist +31 -0
- data/configuration/tinkerwin2variables.dist +17 -0
- data/gui/00coreguibegin/applicationguitop.rwd +4 -0
- data/gui/frontwindow0/cc0openphoto.rwd +22 -0
- data/gui/frontwindowselections/00selectiontabbegin.rwd +11 -0
- data/gui/frontwindowselections/jumplinkcommands.rwd +15 -0
- data/gui/frontwindowselections/wwselectionend.rwd +3 -0
- data/gui/frontwindowtdocuments/00documentbegin.rwd +6 -0
- data/gui/frontwindowtdocuments/tinkerdocuments.rwd +14 -0
- data/gui/frontwindowtdocuments/zzdocumentend.rwd +8 -0
- data/gui/helpaboutbegin/zzzrwdlasttab.rwd +6 -0
- data/gui/helpaboutbegin/zzzzhelpscreenstart.rwd +3 -0
- data/gui/helpaboutbegin/zzzzzzhelpabouttab.rwd +15 -0
- data/gui/helpaboutzend/helpscreenend.rwd +3 -0
- data/gui/helpaboutzend/zhelpscreenstart2.rwd +3 -0
- data/gui/helpaboutzend/zzzzhelpabout2.rwd +15 -0
- data/gui/helpaboutzend/zzzzhelpscreen2end.rwd +3 -0
- data/gui/tinkerbackwindows/superant.com.refreshwindow/fortunerefreshwindowtwo.rwd +9 -0
- data/gui/tinkerbackwindows/superant.com.rwdeliza/1appname.rwd +5 -0
- data/gui/tinkerbackwindows/superant.com.rwdeliza/1eliza.rwd +21 -0
- data/gui/tinkerbackwindows/superant.com.rwdeliza/4sentance.rwd +21 -0
- data/gui/tinkerbackwindows/superant.com.rwdeliza/98jumplinkcommands.rwd +17 -0
- data/gui/tinkerbackwindows/superant.com.rwdeliza/zbackend.rwd +6 -0
- data/gui/tinkerbackwindows/superant.com.rwdschedulebackwindow/1appname.rwd +5 -0
- data/gui/tinkerbackwindows/superant.com.rwdschedulebackwindow/20downloadftp.rwd +45 -0
- data/gui/tinkerbackwindows/superant.com.rwdschedulebackwindow/67viewconfiguration.rwd +29 -0
- data/gui/tinkerbackwindows/superant.com.rwdschedulebackwindow/70rwddiagnostics.rwd +16 -0
- data/gui/tinkerbackwindows/superant.com.rwdschedulebackwindow/m01menubegin.rwd +18 -0
- data/gui/tinkerbackwindows/superant.com.rwdschedulebackwindow/zvbackend.rwd +6 -0
- data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/1appname.rwd +5 -0
- data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/40rwdlistzips.rwd +41 -0
- data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/45installremotezip.rwd +44 -0
- data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/50rwdlistapplets.rwd +44 -0
- data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/60editconfiguration.rwd +30 -0
- data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/70rwddiagnostics.rwd +29 -0
- data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/81jumplinkcommands.rwd +17 -0
- data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/9backend.rwd +6 -0
- data/gui/tinkerbackwindows/superant.com.tinkerhelpwindow/1appname.rwd +31 -0
- data/gui/tinkerbackwindows/superant.com.tinkerhelpwindow/9end.rwd +4 -0
- data/gui/tinkerbackwindows/superant.com.versionwindow/1appname.rwd +19 -0
- data/gui/tinkerbackwindows/superant.com.versionwindow/helpaboutwindow.rwd +17 -0
- data/gui/tinkerbackwindows/superant.com.words/1appname.rwd +4 -0
- data/gui/tinkerbackwindows/superant.com.words/1dictionary.rwd +19 -0
- data/gui/tinkerbackwindows/superant.com.words/3rwdfortune.rwd +14 -0
- data/gui/tinkerbackwindows/superant.com.words/77jumplinkcommands.rwd +17 -0
- data/gui/tinkerbackwindows/superant.com.words/z9end.rwd +6 -0
- data/gui/zzcoreguiend/yy9rwdend.rwd +4 -0
- data/init.rb +277 -0
- data/installed/rwdweliza-0.03.inf +24 -0
- data/installed/temp.rb +1 -0
- data/lang/en/rwdcore/languagefile.rb +58 -0
- data/lang/es/rwdcore/languagefile-es.rb +62 -0
- data/lang/fr/rwdcore/languagefile.rb +64 -0
- data/lang/jp/rwdcore/languagefile.rb +72 -0
- data/lang/nl/rwdcore/languagefile.rb +75 -0
- data/lib/dict.rb +438 -0
- data/lib/druida.rb +499 -0
- data/lib/hashslice.rb +71 -0
- data/lib/linguistics.rb +360 -0
- data/lib/linguistics/en.rb +1601 -0
- data/lib/linguistics/en/infinitive.rb +1148 -0
- data/lib/linguistics/en/linkparser.rb +142 -0
- data/lib/linguistics/en/wordnet.rb +253 -0
- data/lib/linguistics/iso639.rb +456 -0
- data/lib/linkparser.rb +461 -0
- data/lib/linkparser/connection.rb +81 -0
- data/lib/linkparser/connector.rb +201 -0
- data/lib/linkparser/definition.rb +225 -0
- data/lib/linkparser/dictionary.rb +208 -0
- data/lib/linkparser/linkage.rb +185 -0
- data/lib/linkparser/log.rb +39 -0
- data/lib/linkparser/sentence.rb +79 -0
- data/lib/linkparser/utils.rb +540 -0
- data/lib/linkparser/word.rb +92 -0
- data/lib/rconftool.rb +380 -0
- data/lib/rwd/browser.rb +123 -0
- data/lib/rwd/ftools.rb +174 -0
- data/lib/rwd/mime.rb +328 -0
- data/lib/rwd/net.rb +866 -0
- data/lib/rwd/ruby.rb +889 -0
- data/lib/rwd/rwd.rb +1942 -0
- data/lib/rwd/sgml.rb +236 -0
- data/lib/rwd/thread.rb +63 -0
- data/lib/rwd/tree.rb +371 -0
- data/lib/rwd/xml.rb +101 -0
- data/lib/zip/ioextras.rb +114 -0
- data/lib/zip/stdrubyext.rb +111 -0
- data/lib/zip/tempfile_bugfixed.rb +195 -0
- data/lib/zip/zip.rb +1378 -0
- data/lib/zip/zipfilesystem.rb +558 -0
- data/lib/zip/ziprequire.rb +61 -0
- data/rwd_files/HowTo_Eliza.txt +195 -0
- data/rwd_files/HowTo_Tinker.txt +471 -0
- data/rwd_files/HowTo_TinkerWin2.txt +202 -0
- data/rwd_files/Readme.txt +57 -0
- data/rwd_files/RubyWebDialogs.html +6 -0
- data/rwd_files/favicon.ico +0 -0
- data/rwd_files/rdoc-style.css +175 -0
- data/rwd_files/rwdapplications.html +54 -0
- data/rwd_files/tinker.png +0 -0
- data/rwdconfig.dist +21 -0
- data/rwdeliza.rb +1 -0
- data/tests/RubyGauge.rb +179 -0
- data/tests/checkdepends.sh +4 -0
- data/tests/cleancnf.sh +6 -0
- data/tests/makedist-rwdweliza.rb +56 -0
- data/tests/makedist.rb +66 -0
- data/tests/rdep.rb +354 -0
- data/tests/totranslate.lang +93 -0
- data/zips/rwdwaddresses-1.05.zip +0 -0
- data/zips/rwdwcalc-0.61.zip +0 -0
- data/zips/rwdwgutenberg-0.09.zip +0 -0
- data/zips/rwdwschedule-1.04.zip +0 -0
- data/zips/rwdwshell-1.04.zip +0 -0
- data/zips/temp.rb +1 -0
- data/zips/wrubyslippers-1.06.zip +0 -0
- metadata +282 -0
data/lib/linkparser.rb
ADDED
@@ -0,0 +1,461 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
#
|
3
|
+
# Ruby-LinkParser - a english grammar parser based on the link-grammar idea
|
4
|
+
#
|
5
|
+
# == Synopsis
|
6
|
+
#
|
7
|
+
# require "linkparser"
|
8
|
+
#
|
9
|
+
# dict_opts = Hash.new('')
|
10
|
+
# dict_opts[dict] = 'tiny.dict'
|
11
|
+
# dict_opts[datadir] = nil
|
12
|
+
# parse_opts = Hash.new
|
13
|
+
# parser = LinkParser::new(dict_opts, parse_opts)
|
14
|
+
#
|
15
|
+
# sentence = parser.parse($stdin.getline)
|
16
|
+
# puts sentence.diagram
|
17
|
+
#
|
18
|
+
# == Rcsid
|
19
|
+
#
|
20
|
+
# $Id: linkparser.rb,v 1.22 2003/08/28 04:49:33 stillflame Exp $
|
21
|
+
#
|
22
|
+
# == Authors
|
23
|
+
#
|
24
|
+
# Martin Chase <stillflame@FaerieMUD.org>
|
25
|
+
#
|
26
|
+
#:include: COPYRIGHT
|
27
|
+
#
|
28
|
+
#---
|
29
|
+
#
|
30
|
+
# Please see the file COPYRIGHT for licensing details.
|
31
|
+
#
|
32
|
+
|
33
|
+
|
34
|
+
require "linkparser/dictionary"
|
35
|
+
require "linkparser/definition"
|
36
|
+
require "linkparser/sentence"
|
37
|
+
require "linkparser/linkage"
|
38
|
+
require "linkparser/utils"
|
39
|
+
require "linkparser/word"
|
40
|
+
# require "linkparser/log"
|
41
|
+
|
42
|
+
|
43
|
+
### The main class for the link parser system. An object of this class contains
|
44
|
+
### the dictionaries being used and has all the functional methods to parse
|
45
|
+
### sentences.
|
46
|
+
class LinkParser
|
47
|
+
|
48
|
+
### The errors thrown during the parse of a sentence.
|
49
|
+
class ParseError < Exception; end
|
50
|
+
|
51
|
+
### Struct to contain the elements of the parse.
|
52
|
+
ParseState = Struct::new("ParseState", *(
|
53
|
+
%w{sentence results right inner left right_set inner_set
|
54
|
+
left_set right_conn inner_conn left_conn right_word
|
55
|
+
inner_word left_word connection mode all_connectors}
|
56
|
+
))
|
57
|
+
LEFT_MODE = 1
|
58
|
+
RIGHT_MODE = 2
|
59
|
+
INNER_MODE = 4
|
60
|
+
OUTER_MODE = 8
|
61
|
+
FORCE_MODE = 16
|
62
|
+
UNSATISFIED = nil
|
63
|
+
|
64
|
+
|
65
|
+
# Initializes a new parser, using the option hashes given
|
66
|
+
def initialize( dict_opts, parse_opts )
|
67
|
+
@dictionary = LinkParser::Dictionary::new(dict_opts)
|
68
|
+
@parseOptions = parse_opts
|
69
|
+
end
|
70
|
+
|
71
|
+
# Takes a string and tries to parse it into a Sentence object
|
72
|
+
def parse( string )
|
73
|
+
raise ParseError.new("Unable to parse nothing.") unless
|
74
|
+
string && !string.empty?
|
75
|
+
words = string.split
|
76
|
+
|
77
|
+
words = @dictionary.affix(words)
|
78
|
+
|
79
|
+
# Create LinkParser::Word objects out of the words and their definitions
|
80
|
+
sentence = Sentence::new
|
81
|
+
# if @dictionary.has_key?('LEFT-WALL')
|
82
|
+
# sentence.definitions << @dictionary['LEFT-WALL']
|
83
|
+
# sentence.names << 'LEFT-WALL'
|
84
|
+
# end
|
85
|
+
words.each {|word|
|
86
|
+
# :!: This should be doing something to incorporate all the different "word.*"'s :!:
|
87
|
+
#if(found = @dictionary.dict.find {|w,d| %r$#{word}(\.\w)?$.match(w)})
|
88
|
+
# sentence.definitions << found[1]
|
89
|
+
if @dictionary.has_key?(word)
|
90
|
+
sentence.definitions << @dictionary[word]
|
91
|
+
sentence.names << word
|
92
|
+
else
|
93
|
+
# raise ParseError::new("The word '#{word}' is not in the dictionary.")
|
94
|
+
sentence.definitions << @dictionary["UNKNOWN"]
|
95
|
+
sentence.names << "UNKNOWN"
|
96
|
+
end
|
97
|
+
}
|
98
|
+
# if @dictionary.has_key?('RIGHT-WALL')
|
99
|
+
# sentence.definitions << @dictionary['RIGHT-WALL']
|
100
|
+
# sentence.names << 'RIGHT-WALL'
|
101
|
+
# end
|
102
|
+
|
103
|
+
# Find the linkages
|
104
|
+
sentence.linkages = find_linkages(sentence)
|
105
|
+
|
106
|
+
return sentence
|
107
|
+
end
|
108
|
+
|
109
|
+
### Finds all valid linkages in the sentence
|
110
|
+
def find_linkages(sentence)
|
111
|
+
# Log.debug( "find_linkages start" )
|
112
|
+
ps = ParseState::new
|
113
|
+
ps.sentence = sentence
|
114
|
+
# :MC: To be used for pruning, but not until profiling/benchmarking is
|
115
|
+
# done. The idea will be to check each <side>_conn to see if it has any
|
116
|
+
# chance of connecting, and if not, skipping the entire set.
|
117
|
+
ps.all_connectors = make_connector_hash(ps.sentence)
|
118
|
+
# Log.debug( "Connector hash created => #{ps.all_connectors.inspect}" )
|
119
|
+
ps.results = []
|
120
|
+
ps.left = 0
|
121
|
+
ps.right = sentence.definitions.length - 1
|
122
|
+
satisfied = false
|
123
|
+
for ps.right_set in ps.sentence.definitions[ps.right].connector_sets do
|
124
|
+
next unless ps.right_set.right.all_pass?(:optional?)
|
125
|
+
# :MC: For pruning.
|
126
|
+
next if ps.right_set.find {|c| (! c.optional?) and (ps.all_connectors[c].empty? or c.cost > 0)}
|
127
|
+
for ps.left_set in ps.sentence.definitions[ps.left].connector_sets do
|
128
|
+
next unless ps.left_set.left.all_pass?(:optional?)
|
129
|
+
# :MC: For pruning.
|
130
|
+
next if ps.left_set.find {|c| (! c.optional?) and (ps.all_connectors[c].empty? or c.cost > 0)}
|
131
|
+
matched = false
|
132
|
+
for ps.right_conn in ps.right_set.left do
|
133
|
+
for ps.left_conn in ps.left_set.right do
|
134
|
+
if ps.left_conn.match(ps.right_conn)
|
135
|
+
matched = true
|
136
|
+
ps.mode = OUTER_MODE
|
137
|
+
flag = add_connection(ps)
|
138
|
+
satisfaction = true unless flag == UNSATISFIED
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
unless matched
|
143
|
+
ps.right_conn = ps.left_conn = nil
|
144
|
+
ps.mode = OUTER_MODE | FORCE_MODE
|
145
|
+
flag = add_connection(ps)
|
146
|
+
satisfaction = true unless flag == UNSATISFIED
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
ps.results = ps.results.find_all {|linkage|
|
151
|
+
linkage.valid? && linkage.connected?
|
152
|
+
}
|
153
|
+
ps.results.uniq!
|
154
|
+
if satisfaction
|
155
|
+
# Log.debug( "find_linkages finished - %d results" % ps.results.length )
|
156
|
+
else
|
157
|
+
# Log.debug( "find_linkages finished - unsatisfied" )
|
158
|
+
end
|
159
|
+
return ps.results
|
160
|
+
end
|
161
|
+
|
162
|
+
|
163
|
+
### Recursive body of the find_linkages method. See presentation for a
|
164
|
+
### general algorithm explaination.
|
165
|
+
def re_find_linkages(ps)
|
166
|
+
# Log.debug("re_find_linkages(%d, %d) start - (%s, %s)" % [
|
167
|
+
# ps.left, ps.right, ps.left_set.right, ps.right_set.left])
|
168
|
+
# test for stopping recursion.
|
169
|
+
if(ps.left == (ps.right - 1))
|
170
|
+
if( ! (ps.left_set.right.all_pass?(:optional?) and
|
171
|
+
ps.right_set.left.all_pass?(:optional?)) )
|
172
|
+
return UNSATISFIED
|
173
|
+
else
|
174
|
+
return []
|
175
|
+
end
|
176
|
+
end
|
177
|
+
results = []
|
178
|
+
ps.right_conn = ps.left_conn = ps.inner_conn = nil
|
179
|
+
satisfied = false
|
180
|
+
for ps.inner in (ps.left+1)..(ps.right-1) do
|
181
|
+
for ps.inner_set in ps.sentence.definitions[ps.inner].connector_sets do
|
182
|
+
# :MC: For pruning.
|
183
|
+
next if ps.inner_set.find {|c| (! c.optional?) and (ps.all_connectors[c].empty? or c.cost > 0)}
|
184
|
+
for ps.inner_conn in ps.inner_set.left do
|
185
|
+
for ps.left_conn in ps.left_set.right do
|
186
|
+
if ps.inner_conn.match(ps.left_conn)
|
187
|
+
# Log.debug( "(left)Connecting %s and %s" % [ps.left_conn, ps.inner_conn])
|
188
|
+
ps.mode = LEFT_MODE | INNER_MODE
|
189
|
+
# in the following call to add_connection, ps is
|
190
|
+
# modified to include all the valid partial linkages
|
191
|
+
# on this particular connection made using one of
|
192
|
+
# the inner word's connectors on the left side.
|
193
|
+
satisfied = true unless add_connection(ps) == UNSATISFIED
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
lefties = ps.results
|
198
|
+
# check for needed recursion.
|
199
|
+
if( lefties.empty? and (ps.inner != ps.left + 1) and
|
200
|
+
( ! (ps.left_set.right.all_pass?(:optional?) and
|
201
|
+
ps.inner_set.left.all_pass?(:optional?) ) ) )
|
202
|
+
ps.mode = LEFT_MODE | INNER_MODE | FORCE_MODE
|
203
|
+
lefties = add_connection(ps)
|
204
|
+
end
|
205
|
+
ps.results = []
|
206
|
+
ps.left_conn = nil
|
207
|
+
for ps.inner_conn in ps.inner_set.right do
|
208
|
+
for ps.right_conn in ps.right_set.left do
|
209
|
+
if ps.inner_conn.match(ps.right_conn)
|
210
|
+
# Log.debug( "(right)Connecting %s and %s" % [ps.inner_conn, ps.right_conn] )
|
211
|
+
ps.mode = RIGHT_MODE | INNER_MODE
|
212
|
+
# add_conneciton here makes ps.results include all
|
213
|
+
# valid partial linkages between the inner word and
|
214
|
+
# the right side word.
|
215
|
+
satisfied = true unless add_connection(ps) == UNSATISFIED
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
219
|
+
righties = ps.results
|
220
|
+
# check for needed recursion.
|
221
|
+
if( righties.empty? and (ps.inner != ps.right - 1) and
|
222
|
+
( ! (ps.inner_set.right.all_pass?(:optional?) and
|
223
|
+
ps.right_set.left.all_pass?(:optional?)) ) )
|
224
|
+
ps.mode = RIGHT_MODE | INNER_MODE | FORCE_MODE
|
225
|
+
righties = add_connection(ps)
|
226
|
+
end
|
227
|
+
ps.results = []
|
228
|
+
unless( (lefties == UNSATISFIED) or (righties == UNSATISFIED) )
|
229
|
+
results += lefties.set_combine(righties)
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
return UNSATISFIED unless satisfied
|
234
|
+
return ps.results = results
|
235
|
+
end
|
236
|
+
|
237
|
+
### With a connection having been found between two words, or assumed to be
|
238
|
+
### so, create it if possible, recurse where needed, and combine it all into
|
239
|
+
### the results. The "force" modes are where no actual connection has been
|
240
|
+
### made, but recursion is still needed to connect the words inbetween the
|
241
|
+
### inner word under consideration and both edge words.
|
242
|
+
def add_connection(ps)
|
243
|
+
if (ps.mode & INNER_MODE).nonzero?
|
244
|
+
if (ps.mode & FORCE_MODE).nonzero?
|
245
|
+
r = inner_force_recursion(ps)
|
246
|
+
# Log.debug( "inner_force_recursion finished" )
|
247
|
+
r
|
248
|
+
else
|
249
|
+
r = inner_add_connection(ps)
|
250
|
+
# Log.debug( "inner_add_connection finished" )
|
251
|
+
r
|
252
|
+
end
|
253
|
+
elsif (ps.mode & FORCE_MODE).nonzero?
|
254
|
+
r = outer_force_recursion(ps)
|
255
|
+
# Log.debug( "outer_force_recursion finished" )
|
256
|
+
r
|
257
|
+
else
|
258
|
+
r = outer_add_connection(ps)
|
259
|
+
# Log.debug( "outer_add_connection finished" )
|
260
|
+
r
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
### In the outer call of find_linkages, a connection has been found, so
|
265
|
+
### create it and recurse into the inner words.
|
266
|
+
def outer_add_connection(ps)
|
267
|
+
ps.left_word, ps.right_word, ps.connection =
|
268
|
+
create_connection( ps.sentence, ps.left, ps.right, ps.left_conn,
|
269
|
+
ps.right_conn )
|
270
|
+
# Log.debug( "outer_add_connection with %s." % ps.connection )
|
271
|
+
new_ps = ParseState::new(*ps.to_a)
|
272
|
+
new_ps.update( {:results => []} )
|
273
|
+
new_ps.update( {:left_set => ps.left_set - [ps.left_conn]} ) unless
|
274
|
+
ps.left_conn.multiple?
|
275
|
+
new_ps.update( {:right_set => ps.right_set - [ps.right_conn]} ) unless
|
276
|
+
ps.right_conn.multiple?
|
277
|
+
results = re_find_linkages(new_ps)
|
278
|
+
if results == UNSATISFIED
|
279
|
+
# Log.debug("re_find_linkages(%d, %d) end - unsatisfied" %
|
280
|
+
# [new_ps.left, new_ps.right])
|
281
|
+
return results
|
282
|
+
end
|
283
|
+
# Log.debug("re_find_linkages(%d, %d) end - %d results" %
|
284
|
+
# [new_ps.left, new_ps.right, results.length])
|
285
|
+
results << Linkage::new(ps.sentence.names.map{nil}) if results.empty?
|
286
|
+
ps.results += results.collect {|linkage|
|
287
|
+
linkage.insert(ps.connection, ps.left, ps.right,
|
288
|
+
ps.left_word, ps.right_word)
|
289
|
+
}
|
290
|
+
end
|
291
|
+
|
292
|
+
### In the outer call of find_linkages, no connection was found between a
|
293
|
+
### pair of sets, but recurse anyway into the inner words.
|
294
|
+
def outer_force_recursion(ps)
|
295
|
+
# Log.debug( "outer_force_recursion on '%s' and '%s'" %
|
296
|
+
# [ps.left_set, ps.right_set] )
|
297
|
+
new_ps = ParseState::new(*ps.to_a)
|
298
|
+
new_ps.results = []
|
299
|
+
results = re_find_linkages(new_ps)
|
300
|
+
if results == UNSATISFIED
|
301
|
+
# Log.debug( "re_find_linkages(%d, %d) end - unsatisfied" %
|
302
|
+
# [new_ps.left, new_ps.right])
|
303
|
+
return results
|
304
|
+
end
|
305
|
+
# Log.debug( "re_find_linkages(%d, %d) end - %d results" %
|
306
|
+
# [new_ps.left, new_ps.right, new_ps.results.length] )
|
307
|
+
ps.results += results
|
308
|
+
end
|
309
|
+
|
310
|
+
### Inside of a recurse, pretend there is a connection between two words to
|
311
|
+
### find any connections that may exist to the words in between, and if
|
312
|
+
### those connections are enough to satisfy the conditions of connectivity
|
313
|
+
### and satisfaction.
|
314
|
+
def inner_force_recursion(ps)
|
315
|
+
# Log.debug( "inner_force_recursion start" )
|
316
|
+
new_ps = ParseState::new(*ps.to_a)
|
317
|
+
if (ps.mode & RIGHT_MODE).nonzero?
|
318
|
+
left, right = ps.inner, ps.right
|
319
|
+
new_ps.update({ :results => [],
|
320
|
+
:left => ps.inner,
|
321
|
+
})
|
322
|
+
else # LEFT_MODE
|
323
|
+
left, right = ps.left, ps.inner
|
324
|
+
new_ps.update({ :results => [],
|
325
|
+
:right => ps.inner,
|
326
|
+
})
|
327
|
+
end
|
328
|
+
results = re_find_linkages(new_ps)
|
329
|
+
if results == UNSATISFIED
|
330
|
+
# Log.debug( "re_find_linkages(%d, %d) end - unsatisfied" %
|
331
|
+
# [new_ps.left, new_ps.right])
|
332
|
+
else
|
333
|
+
# Log.debug("re_find_linkages(%d, %d) end - %d results" %
|
334
|
+
# [new_ps.left, new_ps.right, results.length])
|
335
|
+
end
|
336
|
+
return results
|
337
|
+
end
|
338
|
+
|
339
|
+
### Inside of recursion, create the connection, recurse on either side,
|
340
|
+
### combine the results of each. This mostly just rearranges the parse
|
341
|
+
### state for the recursions to follow.
|
342
|
+
def inner_add_connection(ps)
|
343
|
+
new_ps = ParseState::new(*ps.to_a)
|
344
|
+
new_ps.inner_set = new_ps.inner = new_ps.inner_conn = nil
|
345
|
+
if (ps.mode & RIGHT_MODE).nonzero?
|
346
|
+
left, right, ps.left_word, ps.right_word, ps.connection =
|
347
|
+
ps.inner, ps.right,
|
348
|
+
*create_connection(ps.sentence, ps.inner, ps.right,
|
349
|
+
ps.inner_conn, ps.right_conn)
|
350
|
+
new_ps.update({ :results => [],
|
351
|
+
:left => ps.inner,
|
352
|
+
})
|
353
|
+
if ps.inner_conn.multiple?
|
354
|
+
new_ps.update({:left_set => ps.inner_set})
|
355
|
+
else
|
356
|
+
new_ps.update({:left_set => ps.inner_set - [ps.inner_conn]})
|
357
|
+
end
|
358
|
+
new_ps.update({:right_set => ps.right_set - [ps.right_conn]}) unless
|
359
|
+
ps.right_conn.multiple?
|
360
|
+
else # LEFT_MODE
|
361
|
+
left, right, ps.left_word, ps.right_word, ps.connection =
|
362
|
+
ps.left, ps.inner,
|
363
|
+
*create_connection(ps.sentence, ps.left, ps.inner,
|
364
|
+
ps.left_conn, ps.inner_conn)
|
365
|
+
new_ps.update({ :results => [],
|
366
|
+
:right => ps.inner,
|
367
|
+
})
|
368
|
+
new_ps.update({:left_set => ps.left_set - [ps.left_conn]}) unless
|
369
|
+
ps.left_conn.multiple?
|
370
|
+
if ps.inner_conn.multiple?
|
371
|
+
new_ps.update({:right_set => ps.inner_set})
|
372
|
+
else
|
373
|
+
new_ps.update({:right_set => ps.inner_set - [ps.inner_conn]})
|
374
|
+
end
|
375
|
+
end
|
376
|
+
# Log.debug( "inner_add_connection start with %s" % ps.connection )
|
377
|
+
results = re_find_linkages(new_ps)
|
378
|
+
if results == UNSATISFIED
|
379
|
+
# Log.debug( "re_find_linkages(%d, %d) end - unsatisfied" %
|
380
|
+
# [new_ps.left, new_ps.right])
|
381
|
+
return results
|
382
|
+
end
|
383
|
+
# Log.debug("re_find_linkages(%d, %d) end - %d results" %
|
384
|
+
# [new_ps.left, new_ps.right, results.length])
|
385
|
+
results << Linkage::new(ps.sentence.names.map{nil}) if results.empty?
|
386
|
+
ps.results += results.collect {|linkage|
|
387
|
+
linkage.insert(ps.connection, left, right,
|
388
|
+
ps.left_word, ps.right_word)
|
389
|
+
}
|
390
|
+
end
|
391
|
+
|
392
|
+
### Makes the Word and Connection objects out of the Sentence, indicies and
|
393
|
+
### Connectors.
|
394
|
+
def create_connection(sentence, left, right, left_conn, right_conn)
|
395
|
+
left_word = Word::new(sentence, left)
|
396
|
+
right_word = Word::new(sentence, right)
|
397
|
+
connection = Connection::new(left_conn, right_conn, left_word, right_word)
|
398
|
+
left_word.right << connection
|
399
|
+
right_word.left << connection
|
400
|
+
return [left_word, right_word, connection]
|
401
|
+
end
|
402
|
+
|
403
|
+
# Creates a hash of connectors to the words that have matching connectors.
|
404
|
+
def make_connector_hash( sentence )
|
405
|
+
connectors = {}
|
406
|
+
sentence.definitions.each {|word|
|
407
|
+
word.connector_sets.each {|set|
|
408
|
+
set.each {|connector|
|
409
|
+
# :TODO: add in pruning somewhere around here
|
410
|
+
connectors[connector] = nil
|
411
|
+
}
|
412
|
+
}
|
413
|
+
}
|
414
|
+
connectors.each {|connector,val|
|
415
|
+
connectors[connector] = connectors.keys.find_all {|conn| conn.match(connector)}
|
416
|
+
}
|
417
|
+
return connectors
|
418
|
+
end
|
419
|
+
|
420
|
+
# does post-processing of a sentence
|
421
|
+
def postProcess( sentence )
|
422
|
+
sentence #:TODO:
|
423
|
+
end
|
424
|
+
|
425
|
+
# the dictionary
|
426
|
+
attr_reader :dictionary
|
427
|
+
|
428
|
+
# the options for parsing
|
429
|
+
attr_reader :parseOptions
|
430
|
+
|
431
|
+
|
432
|
+
end # class LinkParser
|
433
|
+
|
434
|
+
|
435
|
+
if $0 == __FILE__
|
436
|
+
d_o = Hash::new('')
|
437
|
+
d_o['datadir'] = File.join(File.dirname(File.dirname(File.dirname(__FILE__))), "data")
|
438
|
+
d_o['dict'] = 'tiny.dict'
|
439
|
+
d_o['affix'] = nil
|
440
|
+
lp = LinkParser::new(d_o,{})
|
441
|
+
sent = LinkParser::Sentence.new
|
442
|
+
sent.names = %w{1 2 3 4}
|
443
|
+
first = LinkParser::Definition.new( "A+" )
|
444
|
+
# second = LinkParser::Definition.new( "E+" )
|
445
|
+
third = LinkParser::Definition.new( "A- & D+" )
|
446
|
+
forth = LinkParser::Definition.new( "D-" )
|
447
|
+
sent.definitions = [first, third, forth]
|
448
|
+
|
449
|
+
sent.linkages = lp.find_linkages(sent)
|
450
|
+
|
451
|
+
puts
|
452
|
+
sent.linkages.each {|link| puts link.inspect}
|
453
|
+
s = lp.parse("he is a dog")
|
454
|
+
s.definitions.each {|w|
|
455
|
+
w.defs.compact.each {|d|
|
456
|
+
puts d.to_connectors
|
457
|
+
}
|
458
|
+
} if false
|
459
|
+
puts
|
460
|
+
puts s.linkages.inspect
|
461
|
+
end
|