• R/O
  • SSH
  • HTTPS

chaki: Commit


Commit MetaInfo

Revision35 (tree)
Time2008-12-06 21:13:20
Authortomorita

Log Message

(empty log message)

Change Summary

Incremental Difference

--- trunk/ChaKi.NET/src/CreateCorpus/CreateCorpus.cs (revision 34)
+++ trunk/ChaKi.NET/src/CreateCorpus/CreateCorpus.cs (revision 35)
@@ -16,6 +16,7 @@
1616
1717 private DBService m_Service = null;
1818 private Corpus m_Corpus = null;
19+ private string m_DefaultString;
1920
2021 public bool ParseArguments(string[] args)
2122 {
@@ -80,8 +81,10 @@
8081
8182 // DB初期化のためのサービスを得る
8283 m_Service = DBService.Create(m_Corpus.DBParam);
84+ m_DefaultString = m_Service.GetDefault(); // INSERT文のDEFAULT文字列
8385 try
8486 {
87+ m_Service.DropDatabase();
8588 m_Service.CreateDatabase();
8689 }
8790 catch (Exception ex)
@@ -197,9 +200,9 @@
197200 {
198201 Lexeme lex = entry.Value;
199202 lex.ID = n++;
200- cmd.CommandText = string.Format("INSERT INTO lexemes (id,surface,reading,pronunciation,base_lexeme_ref,part_of_speech_id,ctype_id,cform_id) VALUES ({0},'{1}','{2}','{3}',{4},{5},{6},{7})",
203+ cmd.CommandText = string.Format("INSERT INTO lexemes VALUES ({0},'{1}','{2}','{3}',{4},{5},{6},{7},{8},{9})",
201204 lex.ID, lex.Surface, lex.Reading, lex.Pronunciation, lex.BaseLexeme.ID,
202- lex.PartOfSpeech.ID, lex.CType.ID, lex.CForm.ID);
205+ lex.PartOfSpeech.ID, lex.CType.ID, lex.CForm.ID, m_DefaultString, m_DefaultString);
203206 cmd.ExecuteNonQuery();
204207 Console.Write("> {0}\r", entry.Value.ID+1);
205208 }
@@ -228,6 +231,7 @@
228231
229232 int senid = 0;
230233 int wordid = 0;
234+ int bunsetsuid = 0;
231235 foreach (Sentence sen in m_Corpus.Sentences)
232236 {
233237 sen.ID = senid++;
@@ -235,14 +239,37 @@
235239 sen.ID, sen.StartChar, sen.EndChar, sen.Text);
236240 cmd.ExecuteNonQuery();
237241
242+ foreach (Bunsetsu buns in sen.Bunsetsus)
243+ {
244+ // この文に属する文節すべてのIDを先に確定させておく。
245+ buns.ID = bunsetsuid++;
246+ }
247+
238248 foreach (Word word in sen.Words)
239249 {
240250 word.ID = wordid++;
241- cmd.CommandText = string.Format("INSERT INTO words (id,sentence_id,start_char,end_char,lexeme_id,position) VALUES ({0},{1},{2},{3},{4},{5})",
242- word.ID, word.Sen.ID, word.StartChar, word.EndChar, word.Lex.ID, word.Pos);
251+ cmd.CommandText = string.Format("INSERT INTO words VALUES ({0},{1},{2},{3},{4},{5},{6},{7})",
252+ word.ID, word.Sen.ID, word.StartChar, word.EndChar, word.Lex.ID,
253+ word.Bunsetsu.ID, m_DefaultString, word.Pos);
243254 cmd.ExecuteNonQuery();
244255 }
245256
257+ foreach (Bunsetsu buns in sen.Bunsetsus)
258+ {
259+ try
260+ {
261+ cmd.CommandText = string.Format("INSERT INTO bunsetsus VALUES({0},{1},{2},{3},'{4}')",
262+ buns.ID, buns.Pos, buns.Sen.ID,
263+ (buns.DependsTo == null) ? "null" : buns.DependsTo.ID.ToString(),
264+ buns.DependsAs);
265+ }
266+ catch (Exception ex)
267+ {
268+ Console.WriteLine(ex);
269+ }
270+ cmd.ExecuteNonQuery();
271+ }
272+
246273 if (senid > 0 && senid % 500 == 0)
247274 {
248275 trans.CommitAndContinue();
--- trunk/ChaKi.NET/src/Service/Database/DBService.cs (revision 34)
+++ trunk/ChaKi.NET/src/Service/Database/DBService.cs (revision 35)
@@ -81,6 +81,15 @@
8181 public abstract string GetConnectionString();
8282
8383 /// <summary>
84+ /// Insert文のデフォルト文字列を得る
85+ /// </summary>
86+ /// <returns></returns>
87+ public virtual string GetDefault()
88+ {
89+ return "DEFAULT";
90+ }
91+
92+ /// <summary>
8493 /// コーパス名に基づきデータベースを作成する
8594 /// </summary>
8695 public abstract void CreateDatabase();
@@ -104,6 +113,7 @@
104113 statements.Add(Resources.DropTableLexemesStatement);
105114 statements.Add(Resources.DropTableSentencesStatement);
106115 statements.Add(Resources.DropTableWordsStatement);
116+ statements.Add(Resources.DropTableBunsetsusStatement);
107117 statements.Add(Resources.DropTableSegmentsStatement);
108118 statements.Add(Resources.DropTableLinksStatement);
109119 statements.Add(Resources.DropTableGroupsStatement);
@@ -126,6 +136,7 @@
126136 statements.Add(Resources.CreateTableLexemesStatement);
127137 statements.Add(Resources.CreateTableSentencesStatement);
128138 statements.Add(Resources.CreateTableWordsStatement);
139+ statements.Add(Resources.CreateTableBunsetsusStatement);
129140 statements.Add(Resources.CreateTableSegmentsStatement);
130141 statements.Add(Resources.CreateTableLinksStatement);
131142 statements.Add(Resources.CreateTableGroupsStatement);
@@ -145,13 +156,22 @@
145156 statements.Add(Resources.CreateIndexCTypesStatement);
146157 statements.Add(Resources.CreateIndexCFormsStatement);
147158 statements.Add(Resources.CreateIndexCFormsCTypesStatement);
148- statements.Add(Resources.CreateIndexLexemesStatement);
149- statements.Add(Resources.CreateIndexSentencesStatement);
150- statements.Add(Resources.CreateIndexWordsStatement);
159+ statements.Add(Resources.CreateIndexLexemesStatement1);
160+ statements.Add(Resources.CreateIndexLexemesStatement2);
161+ statements.Add(Resources.CreateIndexLexemesStatement3);
162+ statements.Add(Resources.CreateIndexLexemesStatement4);
163+ statements.Add(Resources.CreateIndexLexemesStatement5);
164+ statements.Add(Resources.CreateIndexLexemesStatement6);
165+ statements.Add(Resources.CreateIndexLexemesStatement7);
166+ statements.Add(Resources.CreateIndexSentencesStatement1);
167+ statements.Add(Resources.CreateIndexSentencesStatement2);
151168 // statements.Add(Resources.CreateIndexWordsStatement1);
152169 // statements.Add(Resources.CreateIndexWordsStatement2);
153- statements.Add(Resources.CreateIndexSegmentsStatement);
154- statements.Add(Resources.CreateIndexLinksStatement);
170+ statements.Add(Resources.CreateIndexBunsetsusStatement);
171+ statements.Add(Resources.CreateIndexSegmentsStatement1);
172+ statements.Add(Resources.CreateIndexSegmentsStatement2);
173+ statements.Add(Resources.CreateIndexLinksStatement1);
174+ statements.Add(Resources.CreateIndexLinksStatement2);
155175 statements.Add(Resources.CreateIndexGroupsStatement);
156176 statements.Add(Resources.CreateIndexSegmentsGroupsStatement1);
157177 statements.Add(Resources.CreateIndexSegmentsGroupsStatement2);
@@ -185,6 +205,7 @@
185205 continue;
186206 }
187207 cmd.CommandText = statement;
208+ cmd.CommandTimeout = 600; // 10 minutes
188209 cmd.ExecuteNonQuery();
189210 }
190211 }
@@ -287,6 +308,8 @@
287308 cps.NWords = (int)(long)(query.UniqueResult());
288309 query = session.CreateQuery("select count(*) from Sentence");
289310 cps.NSentences = (int)(long)(query.UniqueResult());
311+ query = session.CreateQuery("select count(*) from Bunsetsu");
312+ cps.NBunsetsus = (int)(long)(query.UniqueResult());
290313 query = session.CreateQuery("select count(*) from Segment");
291314 cps.NSegments = (int)(long)(query.UniqueResult());
292315 query = session.CreateQuery("select count(*) from Link");
--- trunk/ChaKi.NET/src/Service/Database/SQLiteDBService.cs (revision 34)
+++ trunk/ChaKi.NET/src/Service/Database/SQLiteDBService.cs (revision 35)
@@ -3,6 +3,7 @@
33 using System.Text;
44 using System.Data.SQLite;
55 using System.Data.Common;
6+using System.IO;
67
78 namespace ChaKi.Service.Database
89 {
@@ -25,7 +26,7 @@
2526
2627 public override void DropDatabase()
2728 {
28- // dummy
29+ File.Delete(DBParam.Name);
2930 }
3031
3132
@@ -48,5 +49,10 @@
4849 {
4950 return new SQLiteConnection(GetConnectionString());
5051 }
52+
53+ public override string GetDefault()
54+ {
55+ return "\"\"";
56+ }
5157 }
5258 }
--- trunk/ChaKi.NET/src/Service/DependencyEdit/DepEditService.cs (revision 34)
+++ trunk/ChaKi.NET/src/Service/DependencyEdit/DepEditService.cs (revision 35)
@@ -202,12 +202,11 @@
202202 /// <summary>
203203 /// 指定した文節を指定した語位置で分離する。
204204 /// </summary>
205- /// <param name="bpos">文節の開始文字位置</param>
206- /// <param name="epos">文節の終了文字位置</param>
207- /// <param name="spos">分割文字位置</param>
208- public void SplitBunsetsu(int bpos, int epos, int spos)
205+ /// <param name="bpos">文節のPos</param>
206+ /// <param name="wpos">語のPos(文節内での位置ではなく、文内の位置)</param>
207+ public void SplitBunsetsu(int bpos, int wpos)
209208 {
210- DepOperation op = new DepOperation(DOType.Split, new object[] { bpos, epos, spos });
209+ DepOperation op = new DepOperation(DOType.Split, new object[] { bpos, wpos });
211210 op.Execute(m_Sentence, m_Session);
212211 m_History.Record(op);
213212 }
@@ -215,26 +214,25 @@
215214 /// <summary>
216215 /// 指定した文節を次の文節と併合する。
217216 /// </summary>
218- /// <param name="bpos">文節の開始文字位置</param>
219- /// <param name="epos">文節の終了文字位置</param>
220- /// <param name="spos">分割文字位置</param>
221- public void MergeBunsetsu(int bpos, int epos, int spos)
217+ /// <param name="bpos">文節のPos</param>
218+ /// <param name="wpos">語のPos(文節内での位置ではなく、文内の位置)</param>
219+ public void MergeBunsetsu(int bpos, int wpos)
222220 {
223- DepOperation op = new DepOperation(DOType.Merge, new object[] { bpos, epos, spos });
221+ DepOperation op = new DepOperation(DOType.Merge, new object[] { bpos, wpos });
224222 op.Execute(m_Sentence, m_Session);
225223 m_History.Record(op);
226224 }
227225
228- public void ChangeLinkEnd(Link link, Segment oldseg, Segment newseg)
226+ public void ChangeDependency(int bunsetsuId, int dep_org, int dep_new)
229227 {
230- DepOperation op = new DepOperation(DOType.ChangeLinkEnd, new object[] { link, oldseg, newseg });
228+ DepOperation op = new DepOperation(DOType.MoveArrow, new object[] { bunsetsuId, dep_org, dep_new });
231229 op.Execute(m_Sentence, m_Session);
232230 m_History.Record(op);
233231 }
234232
235- public void ChangeLinkTag(Link link, string oldtag, string newtag)
233+ public void ChangeDependencyTag(int bunsetsuId, string oldtag, string newtag)
236234 {
237- DepOperation op = new DepOperation(DOType.ChangeLinkTag, new object[] { link, oldtag, newtag });
235+ DepOperation op = new DepOperation(DOType.ChangeTag, new object[] { bunsetsuId, oldtag, newtag });
238236 op.Execute(m_Sentence, m_Session);
239237 m_History.Record(op);
240238 }
--- trunk/ChaKi.NET/src/Service/Readers/CabochaReader.cs (revision 34)
+++ trunk/ChaKi.NET/src/Service/Readers/CabochaReader.cs (revision 35)
@@ -18,16 +18,12 @@
1818 // 現在のChar Position
1919 int charPos = 0;
2020
21- // 文節データの一時リスト
22- CabochaBunsetsuList bunsetsuList = new CabochaBunsetsuList();
23-
24- int n = 0;
2521 using (TextReader streamReader = new StreamReader(path, Encoding.GetEncoding(encoding)))
2622 {
23+ int n = 0;
2724 string s;
2825 Sentence sen = new Sentence();
29- CabochaBunsetsu currentBunsetsu = null; // 最後に読んだ文節
30- CabochaBunsetsu terminalBunsetsu = null; // 現在の文内において、係り先が-1であるような文節
26+ Bunsetsu currentBunsetsu = null; // 最後に読んだ文節
3127 StringBuilder sb = new StringBuilder(); // Sentenceごとに平文内容を格納
3228
3329 while ((s = streamReader.ReadLine()) != null)
@@ -37,13 +33,8 @@
3733 //文節の開始
3834 try
3935 {
40- CabochaBunsetsu buns = this.ParseBunsetsu(sen, charPos, s);
36+ Bunsetsu buns = sen.AddBunsetsu(s);
4137 currentBunsetsu = buns;
42- if (buns.DependsTo == -1)
43- {
44- terminalBunsetsu = buns;
45- }
46- bunsetsuList.Add(buns);
4738 }
4839 catch (Exception)
4940 {
@@ -53,25 +44,12 @@
5344 else if (s.StartsWith("EOS"))
5445 {
5546 // 文の終わり
56- if (currentBunsetsu == null)
57- { // デフォルト文節を追加(入力がChasen/Mecabの場合のため)
58- CabochaBunsetsu buns = new CabochaBunsetsu(sen, sen.StartChar, 0, String.Empty, -1);
59- buns.EndPos = charPos;
60- bunsetsuList.Add(buns);
61- currentBunsetsu = buns;
62- terminalBunsetsu = buns;
63- }
64- // 終端ダミー文節を追加
65- CabochaBunsetsu dummy = new CabochaBunsetsu(sen, charPos, currentBunsetsu.BunsetsuPos + 1, String.Empty, -1);
66- bunsetsuList.Add(dummy);
67- // 係り先が-1である文節をdummyに係るようにする。
68- if (terminalBunsetsu != null)
47+ sen.CheckBunsetsus(); // デフォルト文節を追加。係り受け構造全体の整合性を取る。
48+
49+ if (++n % 1000 == 0)
6950 {
70- terminalBunsetsu.DependsTo = dummy.BunsetsuPos;
71- terminalBunsetsu.DependsAs = "D";
51+ Console.Write("> {0}\r", n);
7252 }
73-
74- Console.Write("> {0}\r", ++n);
7553 sen.Text = sb.ToString();
7654 sen.EndChar = charPos;
7755 m_Corpus.AddSentence(sen);
@@ -79,7 +57,6 @@
7957 sen = new Sentence();
8058 sen.StartChar = charPos;
8159 currentBunsetsu = null;
82- terminalBunsetsu = null;
8360 sb = new StringBuilder();
8461 }
8562 else if (s.Trim().Length > 0)
@@ -98,11 +75,8 @@
9875 Word w = sen.AddWord(m);
9976 w.StartChar = charPos;
10077 w.EndChar = charPos + w.CharLength;
101- if (currentBunsetsu != null) // currentBunsetsu はChaSenの場合はnull。
102- {
103- currentBunsetsu.AddWord(w);
104- }
105-// w.Bunsetsu = currentBunsetsu; // currentBunsetsu はChaSenの場合はnull。
78+ w.Bunsetsu = currentBunsetsu;
79+ w.Bunsetsu = currentBunsetsu; // currentBunsetsu はChaSenの場合はnull。
10680 // 日本語の場合:デリミタなしで平文を再現
10781 sb.Append(m.Surface);
10882 //@todo: 英語の場合:平文を再現するにはデリミタで単語を区切る必要がある
@@ -111,8 +85,10 @@
11185 }
11286 }
11387 }
88+ Console.Write("> {0} Sentences Found.\r", n);
11489 }
11590
91+#if false
11692 // BunsetsuをSegment&LinkとしてCorpusに登録
11793 Console.WriteLine("\nChecking Segments (Count={0})", bunsetsuList.Count);
11894 n = 0;
@@ -149,8 +125,10 @@
149125 }
150126 }
151127 Console.WriteLine("> {0}", bunsetsuList.Count);
128+#endif
152129 }
153130
131+#if flase
154132 private CabochaBunsetsu ParseBunsetsu(Sentence sen, int charPos, string s)
155133 {
156134 char[] bunsetsuSplitPattern = new char[] { ' ' };
@@ -178,5 +156,6 @@
178156 }
179157 return new CabochaBunsetsu(sen, charPos, bunsetsuPos, depType, depBunsetsuId);
180158 }
159+#endif
181160 }
182161 }
--- trunk/ChaKi.NET/src/Service/Search/QueryBuilder.cs (revision 34)
+++ trunk/ChaKi.NET/src/Service/Search/QueryBuilder.cs (revision 35)
@@ -248,13 +248,8 @@
248248 for (int i = 0; i < depCond.BunsetsuConds.Count; i++)
249249 {
250250 sb.Append(connector.Get());
251- sb.AppendFormat("Segment s{0}", i);
251+ sb.AppendFormat("Bunsetsu b{0}", i);
252252 }
253- for (int i = 0; i < depCond.LinkConds.Count; i++)
254- {
255- sb.Append(connector.Get());
256- sb.AppendFormat("Link k{0}", i);
257- }
258253
259254 sb.Append(" where ");
260255 sb.Append(QueryBuilder.BuildDepSearchQueryWhereClause(iPivot, depCond, lexemeResultSet));
@@ -277,9 +272,9 @@
277272 // かつ、候補LexemeのどれかにIDが一致していること。
278273 sb.Append(connector.Get());
279274 sb.AppendFormat("w{0}.Lex.ID in {1}", result.No, QueryBuilder.BuildLexemeIDList(result.LexemeList));
280- // かつ、その語がSegment(i)に属していること
275+ // かつ、その語がBunsetsu(i)に属していること
281276 sb.Append(connector.Get());
282- sb.AppendFormat("w{0}.StartChar >= s{1}.StartChar and w{0}.StartChar < s{1}.EndChar", result.No, result.BunsetsuNo);
277+ sb.AppendFormat("w{0}.Bunsetsu.ID = b{1}.ID", result.No, result.BunsetsuNo);
283278 // 語の間の順序関係
284279 if (result.Cond.LeftConnection == '-')
285280 {
@@ -298,8 +293,9 @@
298293 }
299294 else if (result.Cond.RightConnection == '$')
300295 {
301- sb.Append(connector.Get());
302- sb.AppendFormat("w{0}.EndChar = s{1}.EndChar", result.No, result.BunsetsuNo);
296+ throw new NotImplementedException("'$' is not implemented yet");
297+// sb.Append(connector.Get());
298+// sb.AppendFormat("w{0}.EndChar = s{1}.EndChar", result.No, result.BunsetsuNo);
303299 }
304300 }
305301 // Segment間の順序関係
@@ -308,27 +304,29 @@
308304 if (tcond.LeftConnection == '^')
309305 {
310306 sb.Append(connector.Get());
311- sb.AppendFormat("s{0}.StartChar = sen.StartChar", i);
307+ sb.AppendFormat("s{0}.Pos=0", i);
312308 }
313309 else if (tcond.LeftConnection == '-')
314310 {
315311 sb.Append(connector.Get());
316- sb.AppendFormat("s{0}.EndChar = s{1}.StartChar", i-1, i);
312+ sb.AppendFormat("s{0}.Pos = s{1}.Pos-1", i-1, i);
317313 }
318314 else if (tcond.LeftConnection == '<')
319315 {
320316 sb.Append(connector.Get());
321- sb.AppendFormat("s{0}.StartChar < s{1}.StartChar", i-1, i);
317+ sb.AppendFormat("s{0}.Pos < s{1}.Pos", i-1, i);
322318 }
323319 else if (tcond.RightConnection == '$')
324320 {
325- sb.Append(connector.Get());
326- sb.AppendFormat("s{0}.EndChar = sen.EndChar", i);
321+ throw new NotImplementedException("'$' is not implemented yet");
322+// sb.Append(connector.Get());
323+// sb.AppendFormat("s{0}.EndChar = sen.EndChar", i);
327324 }
328325 }
329326 // Segment間のLink条件
330327 for (int i = 0; i < depCond.LinkConds.Count; i++)
331328 {
329+ /*
332330 LinkCondition kcond = depCond.LinkConds[i];
333331 sb.Append(connector.Get());
334332 sb.AppendFormat("k{0}.From = s{1} and k{0}.To = s{2}", i, kcond.SegidFrom, kcond.SegidTo);
@@ -337,6 +335,7 @@
337335 sb.Append(connector.Get());
338336 sb.AppendFormat("k{0}.Text = '{1}'", i, kcond.Text);
339337 }
338+ */
340339 }
341340 return sb.ToString();
342341 }
--- trunk/ChaKi.NET/src/Service/Properties/Resources.Designer.cs (revision 34)
+++ trunk/ChaKi.NET/src/Service/Properties/Resources.Designer.cs (revision 35)
@@ -61,9 +61,17 @@
6161 }
6262
6363 /// <summary>
64- /// CREATE INDEX cforms_ctypes_index ON cforms_ctypes (
65- /// cform_id, ctype_id ) に類似しているローカライズされた文字列を検索します。
64+ /// CREATE INDEX bunsetsu_index ON bunsetsus (sentence_id) に類似しているローカライズされた文字列を検索します。
6665 /// </summary>
66+ internal static string CreateIndexBunsetsusStatement {
67+ get {
68+ return ResourceManager.GetString("CreateIndexBunsetsusStatement", resourceCulture);
69+ }
70+ }
71+
72+ /// <summary>
73+ /// CREATE INDEX cforms_ctypes_index ON cforms_ctypes (cform_id, ctype_id) に類似しているローカライズされた文字列を検索します。
74+ /// </summary>
6775 internal static string CreateIndexCFormsCTypesStatement {
6876 get {
6977 return ResourceManager.GetString("CreateIndexCFormsCTypesStatement", resourceCulture);
@@ -71,9 +79,7 @@
7179 }
7280
7381 /// <summary>
74- /// CREATE INDEX cforms_index ON cforms (
75- /// id, cform )
76- /// に類似しているローカライズされた文字列を検索します。
82+ /// CREATE INDEX cforms_index ON cforms (cform) に類似しているローカライズされた文字列を検索します。
7783 /// </summary>
7884 internal static string CreateIndexCFormsStatement {
7985 get {
@@ -91,9 +97,7 @@
9197 }
9298
9399 /// <summary>
94- /// CREATE INDEX ctypes_index ON ctypes (
95- /// id, name1, name2, ctype )
96- /// に類似しているローカライズされた文字列を検索します。
100+ /// CREATE INDEX ctypes_index ON ctypes (ctype) に類似しているローカライズされた文字列を検索します。
97101 /// </summary>
98102 internal static string CreateIndexCTypesStatement {
99103 get {
@@ -102,8 +106,7 @@
102106 }
103107
104108 /// <summary>
105- /// CREATE INDEX groups_index ON groups ( id )
106- /// に類似しているローカライズされた文字列を検索します。
109+ /// に類似しているローカライズされた文字列を検索します。
107110 /// </summary>
108111 internal static string CreateIndexGroupsStatement {
109112 get {
@@ -112,32 +115,89 @@
112115 }
113116
114117 /// <summary>
115- /// CREATE INDEX lexemes_index ON lexemes (
116- /// id, surface, reading, pronunciation, base_lexeme_ref,
117- /// part_of_speech_id, ctype_id, cform_id )
118- /// に類似しているローカライズされた文字列を検索します。
118+ /// CREATE INDEX lexemes_surface_index ON lexemes (surface) に類似しているローカライズされた文字列を検索します。
119119 /// </summary>
120- internal static string CreateIndexLexemesStatement {
120+ internal static string CreateIndexLexemesStatement1 {
121121 get {
122- return ResourceManager.GetString("CreateIndexLexemesStatement", resourceCulture);
122+ return ResourceManager.GetString("CreateIndexLexemesStatement1", resourceCulture);
123123 }
124124 }
125125
126126 /// <summary>
127- /// CREATE INDEX link_index ON links (
128- /// id, from_segment_id, to_segment_id ) に類似しているローカライズされた文字列を検索します。
127+ /// CREATE INDEX lexemes_reading_index ON lexemes (reading) に類似しているローカライズされた文字列を検索します。
129128 /// </summary>
130- internal static string CreateIndexLinksStatement {
129+ internal static string CreateIndexLexemesStatement2 {
131130 get {
132- return ResourceManager.GetString("CreateIndexLinksStatement", resourceCulture);
131+ return ResourceManager.GetString("CreateIndexLexemesStatement2", resourceCulture);
133132 }
134133 }
135134
136135 /// <summary>
137- /// CREATE INDEX parts_of_speech_index ON parts_of_speech (
138- /// id, name1, name2, name3, name4, part_of_speech )
139- /// に類似しているローカライズされた文字列を検索します。
136+ /// CREATE INDEX lexemes_pronunciation_index ON lexemes (pronunciation) に類似しているローカライズされた文字列を検索します。
140137 /// </summary>
138+ internal static string CreateIndexLexemesStatement3 {
139+ get {
140+ return ResourceManager.GetString("CreateIndexLexemesStatement3", resourceCulture);
141+ }
142+ }
143+
144+ /// <summary>
145+ /// CREATE INDEX lexemes_base_lexeme_index ON lexemes (base_lexeme_ref) に類似しているローカライズされた文字列を検索します。
146+ /// </summary>
147+ internal static string CreateIndexLexemesStatement4 {
148+ get {
149+ return ResourceManager.GetString("CreateIndexLexemesStatement4", resourceCulture);
150+ }
151+ }
152+
153+ /// <summary>
154+ /// CREATE INDEX lexemes_part_of_speech_index ON lexemes (part_of_speech_id) に類似しているローカライズされた文字列を検索します。
155+ /// </summary>
156+ internal static string CreateIndexLexemesStatement5 {
157+ get {
158+ return ResourceManager.GetString("CreateIndexLexemesStatement5", resourceCulture);
159+ }
160+ }
161+
162+ /// <summary>
163+ /// CREATE INDEX lexemes_ctype_index ON lexemes (ctype_id) に類似しているローカライズされた文字列を検索します。
164+ /// </summary>
165+ internal static string CreateIndexLexemesStatement6 {
166+ get {
167+ return ResourceManager.GetString("CreateIndexLexemesStatement6", resourceCulture);
168+ }
169+ }
170+
171+ /// <summary>
172+ /// CREATE INDEX lexemes_cform_index ON lexemes (cform_id) に類似しているローカライズされた文字列を検索します。
173+ /// </summary>
174+ internal static string CreateIndexLexemesStatement7 {
175+ get {
176+ return ResourceManager.GetString("CreateIndexLexemesStatement7", resourceCulture);
177+ }
178+ }
179+
180+ /// <summary>
181+ /// CREATE INDEX link_from_segment_index ON links (from_segment_id) に類似しているローカライズされた文字列を検索します。
182+ /// </summary>
183+ internal static string CreateIndexLinksStatement1 {
184+ get {
185+ return ResourceManager.GetString("CreateIndexLinksStatement1", resourceCulture);
186+ }
187+ }
188+
189+ /// <summary>
190+ /// CREATE INDEX link_to_segment_index ON links (to_segment_id ) に類似しているローカライズされた文字列を検索します。
191+ /// </summary>
192+ internal static string CreateIndexLinksStatement2 {
193+ get {
194+ return ResourceManager.GetString("CreateIndexLinksStatement2", resourceCulture);
195+ }
196+ }
197+
198+ /// <summary>
199+ /// CREATE INDEX parts_of_speech_index ON parts_of_speech (part_of_speech) に類似しているローカライズされた文字列を検索します。
200+ /// </summary>
141201 internal static string CreateIndexPartsOfSpeechStatement {
142202 get {
143203 return ResourceManager.GetString("CreateIndexPartsOfSpeechStatement", resourceCulture);
@@ -163,43 +223,44 @@
163223 }
164224
165225 /// <summary>
166- /// CREATE INDEX segment_index ON segments (
167- /// id, start_char, end_char )
168- /// に類似しているローカライズされた文字列を検索します。
226+ /// CREATE INDEX segment_start_char_index ON segments (start_char) に類似しているローカライズされた文字列を検索します。
169227 /// </summary>
170- internal static string CreateIndexSegmentsStatement {
228+ internal static string CreateIndexSegmentsStatement1 {
171229 get {
172- return ResourceManager.GetString("CreateIndexSegmentsStatement", resourceCulture);
230+ return ResourceManager.GetString("CreateIndexSegmentsStatement1", resourceCulture);
173231 }
174232 }
175233
176234 /// <summary>
177- /// CREATE INDEX sentences_index ON sentences (
178- /// id )
179- /// に類似しているローカライズされた文字列を検索します。
235+ /// CREATE INDEX segment_end_char_index ON segments (end_char) に類似しているローカライズされた文字列を検索します。
180236 /// </summary>
181- internal static string CreateIndexSentencesStatement {
237+ internal static string CreateIndexSegmentsStatement2 {
182238 get {
183- return ResourceManager.GetString("CreateIndexSentencesStatement", resourceCulture);
239+ return ResourceManager.GetString("CreateIndexSegmentsStatement2", resourceCulture);
184240 }
185241 }
186242
187243 /// <summary>
188- /// CREATE INDEX words_index ON words (
189- ///id, sentence_id, lexeme_id )
190- /// に類似しているローカライズされた文字列を検索します。
244+ /// CREATE INDEX sentences_start_char_index ON sentences (start_char) に類似しているローカライズされた文字列を検索します。
191245 /// </summary>
192- internal static string CreateIndexWordsStatement {
246+ internal static string CreateIndexSentencesStatement1 {
193247 get {
194- return ResourceManager.GetString("CreateIndexWordsStatement", resourceCulture);
248+ return ResourceManager.GetString("CreateIndexSentencesStatement1", resourceCulture);
195249 }
196250 }
197251
198252 /// <summary>
199- /// CREATE INDEX words_sentence_id_index ON words (
200- /// sentence_id ASC)
201- /// に類似しているローカライズされた文字列を検索します。
253+ /// CREATE INDEX sentences_end_char_index ON sentences (end_char) に類似しているローカライズされた文字列を検索します。
202254 /// </summary>
255+ internal static string CreateIndexSentencesStatement2 {
256+ get {
257+ return ResourceManager.GetString("CreateIndexSentencesStatement2", resourceCulture);
258+ }
259+ }
260+
261+ /// <summary>
262+ /// CREATE INDEX words_sentence_id_index ON words (sentence_id ASC) に類似しているローカライズされた文字列を検索します。
263+ /// </summary>
203264 internal static string CreateIndexWordsStatement1 {
204265 get {
205266 return ResourceManager.GetString("CreateIndexWordsStatement1", resourceCulture);
@@ -216,6 +277,21 @@
216277 }
217278
218279 /// <summary>
280+ /// CREATE TABLE bunsetsus (
281+ /// id int primary key,
282+ /// position int,
283+ /// sentence_id int,
284+ /// dep_bunsetsu_id int,
285+ /// dep_relation varchar(16)
286+ ///) に類似しているローカライズされた文字列を検索します。
287+ /// </summary>
288+ internal static string CreateTableBunsetsusStatement {
289+ get {
290+ return ResourceManager.GetString("CreateTableBunsetsusStatement", resourceCulture);
291+ }
292+ }
293+
294+ /// <summary>
219295 /// CREATE TABLE cforms_ctypes (
220296 /// cform_id int,
221297 /// ctype_id int) に類似しているローカライズされた文字列を検索します。
@@ -285,10 +361,11 @@
285361 /// reading varchar(255) default &apos;&apos;,
286362 /// pronunciation varchar(255) default &apos;&apos;,
287363 /// base_lexeme_ref int not null references lexemes (id),
288- /// updated_at timestamp,
289364 /// part_of_speech_id int not null references parts_of_speech (id),
290365 /// ctype_id int not null references ctypes (id),
291- /// cform_id int not null references cform (id)
366+ /// cform_id int not null references cform (id),
367+ /// updated_at timestamp,
368+ /// frequency int default 0
292369 ///) に類似しているローカライズされた文字列を検索します。
293370 /// </summary>
294371 internal static string CreateTableLexemesStatement {
@@ -378,6 +455,7 @@
378455 /// start_char int not null,
379456 /// end_char int not null,
380457 /// lexeme_id int not null references lexemes (id),
458+ /// bunsetsu_id int not null,
381459 /// updated_at timestamp,
382460 /// position int
383461 ///) に類似しているローカライズされた文字列を検索します。
@@ -389,6 +467,15 @@
389467 }
390468
391469 /// <summary>
470+ /// DROP TABLE IF EXISTS bunsetsus に類似しているローカライズされた文字列を検索します。
471+ /// </summary>
472+ internal static string DropTableBunsetsusStatement {
473+ get {
474+ return ResourceManager.GetString("DropTableBunsetsusStatement", resourceCulture);
475+ }
476+ }
477+
478+ /// <summary>
392479 /// DROP TABLE IF EXISTS cforms_ctypes に類似しているローカライズされた文字列を検索します。
393480 /// </summary>
394481 internal static string DropTableCFormsCTypesStatement {
--- trunk/ChaKi.NET/src/ChaKi.NET/ToolDialogs/LexiconDataRetriever.cs (nonexistent)
+++ trunk/ChaKi.NET/src/ChaKi.NET/ToolDialogs/LexiconDataRetriever.cs (revision 35)
@@ -0,0 +1,77 @@
1+using System;
2+using System.Collections.Generic;
3+using System.Text;
4+using ChaKi.VirtualGrid;
5+using System.Data;
6+
7+namespace ChaKi.ToolDialogs
8+{
9+ /// <summary>
10+ /// 参考ページ:「方法 Windows フォーム DataGridView コントロールで
11+ /// Just-In-Time データ読み込みを使用して仮想モードを実装する」
12+ /// http://msdn2.microsoft.com/ja-jp/library/ms171625(VS.80).aspx
13+ ///
14+ /// 次に、DataRetriever クラスを定義するコード例を次に示します。
15+ /// このクラスは、データのページをサーバーから取得する IDataPageRetriever インターフェイスを
16+ /// 実装します。DataRetriever クラスは、Columns プロパティと RowCount プロパティも提供します。
17+ /// DataGridView コントロールは、これらのプロパティを使用して、必要な列を作成し、
18+ /// 適切な数の空の行を Rows コレクションに追加します。
19+ /// 空の行の追加は、テーブル内のデータがすべて存在するようにコントロールが動作するうえで必要です。
20+ /// これにより、スクロール バーのスクロール ボックスが適切なサイズになり、ユーザーがテーブル内の
21+ /// 任意の行にアクセスできるようになります。行は、スクロール表示されたときにのみ、
22+ /// CellValueNeeded イベント ハンドラによって値が設定されます。
23+ /// </summary>
24+ public class LexiconDataRetriever : IDataPageRetriever
25+ {
26+ public LexiconDataRetriever()
27+ {
28+ }
29+
30+ public int RowCount
31+ {
32+ get
33+ {
34+ return 0;
35+ }
36+ }
37+
38+ private DataColumnCollection columnsValue = null;
39+
40+ public DataColumnCollection Columns
41+ {
42+ get
43+ {
44+ // Return the existing value if it has already been determined.
45+ if (columnsValue != null)
46+ {
47+ return columnsValue;
48+ }
49+ DataTable table = new DataTable();
50+ DataColumn col;
51+ col = new DataColumn("System.StartDate");
52+ table.Columns.Add(col);
53+ col = new DataColumn("System.ItemPathDisplay");
54+ table.Columns.Add(col);
55+ col = new DataColumn("System.Size");
56+ table.Columns.Add(col);
57+ return table.Columns;
58+ }
59+ }
60+
61+ private string commaSeparatedListOfColumnNamesValue = "System.ItemPathDisplay,System.Size";
62+
63+ private string CommaSeparatedListOfColumnNames
64+ {
65+ get
66+ {
67+ return commaSeparatedListOfColumnNamesValue;
68+ }
69+ }
70+
71+ public DataTable SupplyPageOfData(int lowerPageBoundary, int rowsPerPage)
72+ {
73+ DataTable dt = new DataTable();
74+ return dt;
75+ }
76+ }
77+}
--- trunk/ChaKi.NET/src/ChaKi.NET/ToolDialogs/CorpusInfo.cs (revision 34)
+++ trunk/ChaKi.NET/src/ChaKi.NET/ToolDialogs/CorpusInfo.cs (revision 35)
@@ -1,10 +1,8 @@
11 using System;
22 using System.Collections.Generic;
3-using System.ComponentModel;
43 using System.Data;
5-using System.Drawing;
6-using System.Text;
74 using System.Windows.Forms;
5+using ChaKi.VirtualGrid;
86 using ChaKi.Entity.Corpora;
97 using System.Collections;
108
@@ -13,11 +11,15 @@
1311 public partial class CorpusInfo : Form
1412 {
1513 private Corpus m_Corpus;
14+ private Cache m_MemoryCache;
1615
1716 public CorpusInfo()
1817 {
1918 InitializeComponent();
2019 m_Corpus = null;
20+
21+ this.dataGridView2.VirtualMode = true;
22+ this.dataGridView2.CellValueNeeded += new DataGridViewCellValueEventHandler(dataGridView2_CellValueNeeded);
2123 }
2224
2325 public void SetCorpus(Corpus c)
@@ -54,6 +56,18 @@
5456 {
5557 Lexicon lexicon = m_Corpus.Lex;
5658 DataGridView dg = this.dataGridView2;
59+
60+ /*
61+ LexiconDataRetriever retriever = new LexiconDataRetriever();
62+ m_MemoryCache = new Cache(retriever, 16);
63+ foreach (DataColumn column in retriever.Columns)
64+ {
65+ dataGridView1.Columns.Add(column.ColumnName, column.ColumnName);
66+ }
67+ dg.RowCount = retriever.RowCount;
68+ */
69+ dg.RowCount = m_Corpus.Lex.Entries.Count;
70+/*
5771 int r = 0;
5872 foreach (KeyValuePair<string, Lexeme> pair in lexicon.Entries)
5973 {
@@ -68,8 +82,35 @@
6882 dg[6, r].Value = lex.CForm.Name;
6983 r++;
7084 }
85+ * */
7186 }
7287
88+ private void dataGridView2_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
89+ {
90+ Lexeme lex = null;
91+ try
92+ {
93+ lex = m_Corpus.Lex.Entries.Values[e.RowIndex];
94+ }
95+ catch (Exception)
96+ {
97+ return;
98+ }
99+
100+ switch (e.ColumnIndex)
101+ {
102+ case 0: e.Value = lex.Surface; break;
103+ case 1: e.Value = lex.Reading; break;
104+ case 2: e.Value = lex.Pronunciation; break;
105+ case 3: e.Value = (lex.BaseLexeme != null) ? lex.BaseLexeme.Surface : ""; break;
106+ case 4: e.Value = lex.PartOfSpeech.Name; break;
107+ case 5: e.Value = lex.CType.Name; break;
108+ case 6: e.Value = lex.CForm.Name; break;
109+ case 7: e.Value = lex.Frequency; break;
110+ }
111+// e.Value = this.m_MemoryCache.RetrieveElement(e.RowIndex, e.ColumnIndex);
112+ }
113+
73114 private void LoadPOS()
74115 {
75116 this.propertyTree1.Cps = m_Corpus;
--- trunk/ChaKi.NET/src/ChaKi.NET/VirtualGrid/GridCache.cs (nonexistent)
+++ trunk/ChaKi.NET/src/ChaKi.NET/VirtualGrid/GridCache.cs (revision 35)
@@ -0,0 +1,175 @@
1+using System;
2+using System.Collections.Generic;
3+using System.Text;
4+using System.Data;
5+
6+namespace ChaKi.VirtualGrid
7+{
8+ /// <summary>
9+ /// 参考ページ:「方法 Windows フォーム DataGridView コントロールで
10+ /// Just-In-Time データ読み込みを使用して仮想モードを実装する」
11+ /// http://msdn2.microsoft.com/ja-jp/library/ms171625(VS.80).aspx
12+ ///
13+ /// 次に、Cache クラスを定義するコード例を示します。このクラスは、
14+ /// IDataPageRetriever 実装によって設定される 2 ページのデータを管理します。
15+ /// Cache クラスは、内側の DataPage 構造体を定義します。
16+ /// この構造体は、値を 1 つのキャッシュ ページに保存する DataTable を含み、
17+ /// ページの上下の境界を表す行インデックスを計算します。
18+ ///
19+ /// Cache クラスは、構築時に 2 ページのデータを読み込みます。
20+ /// CellValueNeeded イベントが値を要求すると、Cache オブジェクトは、
21+ /// その 2 ページのいずれかに値が存在するかどうか確認し、値が存在する場合には返します。
22+ /// 値がローカルに存在しない場合、Cache は、2 つのページのうちで、
23+ /// 現在表示されている行から遠い方のページを特定し、そのページを、
24+ /// 要求されている値を含む新しいページと置き換えて、値を返します。
25+ ///
26+ /// データ ページの行数と、画面に同時に表示できる行数が一致することを前提に、
27+ /// このモデルでは、テーブルをページングしているユーザーが、
28+ /// 直前に表示されたページに効率的に復帰できます。
29+ /// </summary>
30+ public class Cache
31+ {
32+ private static int RowsPerPage;
33+
34+ // Represents one page of data.
35+ public struct DataPage
36+ {
37+ public DataTable table;
38+ private int lowestIndexValue;
39+ private int highestIndexValue;
40+
41+ public DataPage(DataTable table, int rowIndex)
42+ {
43+ this.table = table;
44+ lowestIndexValue = MapToLowerBoundary(rowIndex);
45+ highestIndexValue = MapToUpperBoundary(rowIndex);
46+ System.Diagnostics.Debug.Assert(lowestIndexValue >= 0);
47+ System.Diagnostics.Debug.Assert(highestIndexValue >= 0);
48+ }
49+
50+ public int LowestIndex
51+ {
52+ get
53+ {
54+ return lowestIndexValue;
55+ }
56+ }
57+
58+ public int HighestIndex
59+ {
60+ get
61+ {
62+ return highestIndexValue;
63+ }
64+ }
65+
66+ public static int MapToLowerBoundary(int rowIndex)
67+ {
68+ // Return the lowest index of a page containing the given index.
69+ return (rowIndex / RowsPerPage) * RowsPerPage;
70+ }
71+
72+ private static int MapToUpperBoundary(int rowIndex)
73+ {
74+ // Return the highest index of a page containing the given index.
75+ return MapToLowerBoundary(rowIndex) + RowsPerPage - 1;
76+ }
77+ }
78+
79+ private DataPage[] cachePages;
80+ private IDataPageRetriever dataSupply;
81+
82+ public Cache(IDataPageRetriever dataSupplier, int rowsPerPage)
83+ {
84+ dataSupply = dataSupplier;
85+ Cache.RowsPerPage = rowsPerPage;
86+ LoadFirstTwoPages();
87+ }
88+
89+ // Sets the value of the element parameter if the value is in the cache.
90+ private bool IfPageCached_ThenSetElement(int rowIndex, int columnIndex, ref string element)
91+ {
92+ if (IsRowCachedInPage(0, rowIndex))
93+ {
94+ element = cachePages[0].table.Rows[rowIndex % RowsPerPage][columnIndex].ToString();
95+ return true;
96+ }
97+ else if (IsRowCachedInPage(1, rowIndex))
98+ {
99+ element = cachePages[1].table.Rows[rowIndex % RowsPerPage][columnIndex].ToString();
100+ return true;
101+ }
102+
103+ return false;
104+ }
105+
106+ public string RetrieveElement(int rowIndex, int columnIndex)
107+ {
108+ string element = null;
109+
110+ if (IfPageCached_ThenSetElement(rowIndex, columnIndex, ref element))
111+ {
112+ return element;
113+ }
114+ else
115+ {
116+ return RetrieveData_CacheIt_ThenReturnElement(rowIndex, columnIndex);
117+ }
118+ }
119+
120+ private void LoadFirstTwoPages()
121+ {
122+ cachePages = new DataPage[]{
123+ new DataPage(dataSupply.SupplyPageOfData(DataPage.MapToLowerBoundary(0), RowsPerPage), 0),
124+ new DataPage(dataSupply.SupplyPageOfData(DataPage.MapToLowerBoundary(RowsPerPage), RowsPerPage), RowsPerPage)};
125+ }
126+
127+ private string RetrieveData_CacheIt_ThenReturnElement(int rowIndex, int columnIndex)
128+ {
129+ // Retrieve a page worth of data containing the requested value.
130+ DataTable table = dataSupply.SupplyPageOfData(DataPage.MapToLowerBoundary(rowIndex), RowsPerPage);
131+
132+ // Replace the cached page furthest from the requested cell
133+ // with a new page containing the newly retrieved data.
134+ cachePages[GetIndexToUnusedPage(rowIndex)] = new DataPage(table, rowIndex);
135+
136+ return RetrieveElement(rowIndex, columnIndex);
137+ }
138+
139+ // Returns the index of the cached page most distant from the given index
140+ // and therefore least likely to be reused.
141+ private int GetIndexToUnusedPage(int rowIndex)
142+ {
143+ if (rowIndex > cachePages[0].HighestIndex &&
144+ rowIndex > cachePages[1].HighestIndex)
145+ {
146+ int offsetFromPage0 = rowIndex - cachePages[0].HighestIndex;
147+ int offsetFromPage1 = rowIndex - cachePages[1].HighestIndex;
148+ if (offsetFromPage0 < offsetFromPage1)
149+ {
150+ return 1;
151+ }
152+ return 0;
153+ }
154+ else
155+ {
156+ int offsetFromPage0 = cachePages[0].LowestIndex - rowIndex;
157+ int offsetFromPage1 = cachePages[1].LowestIndex - rowIndex;
158+ if (offsetFromPage0 < offsetFromPage1)
159+ {
160+ return 1;
161+ }
162+ return 0;
163+ }
164+
165+ }
166+
167+ // Returns a value indicating whether the given row index is contained
168+ // in the given DataPage.
169+ private bool IsRowCachedInPage(int pageNumber, int rowIndex)
170+ {
171+ return rowIndex <= cachePages[pageNumber].HighestIndex &&
172+ rowIndex >= cachePages[pageNumber].LowestIndex;
173+ }
174+ }
175+}
--- trunk/ChaKi.NET/src/ChaKi.NET/VirtualGrid/IDataRetriever.cs (nonexistent)
+++ trunk/ChaKi.NET/src/ChaKi.NET/VirtualGrid/IDataRetriever.cs (revision 35)
@@ -0,0 +1,26 @@
1+using System;
2+using System.Collections.Generic;
3+using System.Text;
4+using System.Data;
5+
6+namespace ChaKi.VirtualGrid
7+{
8+ /// <summary>
9+ /// 参考ページ:「方法 Windows フォーム DataGridView コントロールで
10+ /// Just-In-Time データ読み込みを使用して仮想モードを実装する」
11+ /// http://msdn2.microsoft.com/ja-jp/library/ms171625(VS.80).aspx
12+ ///
13+ /// DataRetriever クラスによって実装される IDataPageRetriever インターフェイスを定義する
14+ /// コード例を次に示します。このインターフェイスで宣言されているメソッドは、
15+ /// 初期行インデックスと 1 ページのデータの行数を要求する SupplyPageOfData メソッドだけです。
16+ /// これらの値は、データ ソースからデータのサブセットを取得する実装側で使用されます。
17+ ///
18+ /// Cache オブジェクトは、このインターフェイスの実装を構築時に使用して、
19+ /// データの最初の 2 ページを読み込みます。未キャッシュのデータが必要になると、
20+ /// キャッシュはこれらのページのいずれかを破棄し、IDataPageRetriever にその値を含む新しいページを要求します。
21+ /// </summary>
22+ public interface IDataPageRetriever
23+ {
24+ DataTable SupplyPageOfData(int lowerPageBoundary, int rowsPerPage);
25+ }
26+}
--- trunk/ChaKi.NET/src/Entity/Corpora/Corpus.cs (revision 34)
+++ trunk/ChaKi.NET/src/Entity/Corpora/Corpus.cs (revision 35)
@@ -24,6 +24,7 @@
2424 public int NLexemes { get; set; }
2525 public int NWords { get; set; }
2626 public int NSentences { get; set; }
27+ public int NBunsetsus { get; set; }
2728 public int NSegments { get; set; }
2829 public int NLinks { get; set; }
2930 public int NGroups { get; set; }
@@ -129,6 +130,7 @@
129130 cprops.Add(new CorpusProperty("#Words", this.NWords.ToString()));
130131 cprops.Add(new CorpusProperty("#Lexemes", this.NLexemes.ToString()));
131132 cprops.Add(new CorpusProperty("#Sentences", this.NSentences.ToString()));
133+ cprops.Add(new CorpusProperty("#Bunsetsu", this.NBunsetsus.ToString()));
132134 cprops.Add(new CorpusProperty("#Segments", this.NSegments.ToString()));
133135 cprops.Add(new CorpusProperty("#Links", this.NLinks.ToString()));
134136 cprops.Add(new CorpusProperty("#Groups", this.NGroups.ToString()));
--- trunk/ChaKi.NET/src/Entity/Corpora/Word.cs (revision 34)
+++ trunk/ChaKi.NET/src/Entity/Corpora/Word.cs (revision 35)
@@ -33,7 +33,7 @@
3333
3434 private Sentence sen;
3535 private Lexeme lexeme;
36- private Segment bunsetsu;
36+ private Bunsetsu bunsetsu;
3737
3838 public static void ResetOrder()
3939 {
@@ -71,6 +71,11 @@
7171 get { return lexeme; }
7272 set { lexeme = value; }
7373 }
74+ public virtual Bunsetsu Bunsetsu
75+ {
76+ get { return bunsetsu; }
77+ set { bunsetsu = value; }
78+ }
7479
7580 public virtual int CharLength
7681 {
--- trunk/ChaKi.NET/src/Entity/Corpora/Word.hbm.xml (revision 34)
+++ trunk/ChaKi.NET/src/Entity/Corpora/Word.hbm.xml (revision 35)
@@ -10,6 +10,7 @@
1010
1111 <many-to-one name="Sen" class="ChaKi.Entity.Corpora.Sentence, ChaKiEntity" column="sentence_id"/>
1212 <many-to-one name="Lex" class="ChaKi.Entity.Corpora.Lexeme, ChaKiEntity" column="lexeme_id"/>
13+ <many-to-one name="Bunsetsu" class="ChaKi.Entity.Corpora.Bunsetsu, ChaKiEntity" column="bunsetsu_id"/>
1314 <property name="Pos" column="position" type="Int32"/>
1415 <property name="StartChar" column="start_char" type="Int32"/>
1516 <property name="EndChar" column="end_char" type="Int32"/>
--- trunk/ChaKi.NET/src/Entity/Corpora/Lexeme.hbm.xml (revision 34)
+++ trunk/ChaKi.NET/src/Entity/Corpora/Lexeme.hbm.xml (revision 35)
@@ -16,6 +16,7 @@
1616 <many-to-one name="PartOfSpeech" class="ChaKi.Entity.Corpora.PartOfSpeech, ChaKiEntity" column="part_of_speech_id"/>
1717 <many-to-one name="CType" class="ChaKi.Entity.Corpora.CType, ChaKiEntity" column="ctype_id"/>
1818 <many-to-one name="CForm" class="ChaKi.Entity.Corpora.CForm, ChaKiEntity" column="cform_id"/>
19+ <property name="Frequency" column="frequency" type="Int32"/>
1920 </class>
2021
2122 </hibernate-mapping>
--- trunk/ChaKi.NET/src/Entity/Corpora/Lexeme.cs (revision 34)
+++ trunk/ChaKi.NET/src/Entity/Corpora/Lexeme.cs (revision 35)
@@ -118,6 +118,7 @@
118118
119119 private int id;
120120 private Dictionary<LP, object> properties;
121+ private int frequency;
121122
122123 public virtual int ID
123124 {
@@ -159,6 +160,11 @@
159160 get { return properties[LP.CForm] as CForm; }
160161 set { properties[LP.CForm] = value; }
161162 }
163+ public virtual int Frequency
164+ {
165+ get { return this.frequency; }
166+ set { this.frequency = value; }
167+ }
162168
163169 public virtual object GetProperty( LP tag )
164170 {
--- trunk/ChaKi.NET/src/Entity/Corpora/Lexicon.cs (revision 34)
+++ trunk/ChaKi.NET/src/Entity/Corpora/Lexicon.cs (revision 35)
@@ -6,11 +6,11 @@
66 {
77 public class Lexicon
88 {
9- private Dictionary<string, Lexeme> m_entries;
9+ private SortedList<string, Lexeme> m_entries;
1010
1111 public Lexicon()
1212 {
13- m_entries = new Dictionary<string, Lexeme>();
13+ m_entries = new SortedList<string, Lexeme>();
1414
1515 PartsOfSpeech = new Dictionary<string, PartOfSpeech>();
1616 CTypes = new Dictionary<string, CType>();
@@ -17,7 +17,7 @@
1717 CForms = new Dictionary<string, CForm>();
1818 }
1919
20- public Dictionary<string, Lexeme> Entries
20+ public SortedList<string, Lexeme> Entries
2121 {
2222 get { return m_entries; }
2323 set { m_entries = value; }
--- trunk/ChaKi.NET/src/Entity/Corpora/Sentence.cs (revision 34)
+++ trunk/ChaKi.NET/src/Entity/Corpora/Sentence.cs (revision 35)
@@ -38,6 +38,15 @@
3838 set { words = value; }
3939 }
4040
41+ /// <summary>
42+ /// Set of Bunsetsu
43+ /// </summary>
44+ public virtual IList Bunsetsus
45+ {
46+ get { return bunsetsus; }
47+ set { bunsetsus = value; }
48+ }
49+
4150 public virtual string Text
4251 {
4352 get { return text; }
@@ -66,17 +75,118 @@
6675 }
6776
6877 /// <summary>
78+ /// Cabochaフォーマットの文節タグを元にBunsetsuオブジェクトを作成し、
79+ /// このSentenceに登録する。
80+ /// すべての文節を作った後、EOSを見た時点でCheckBunsetsusを呼び出して、
81+ /// 整合を取る必要がある。
82+ /// </summary>
83+ /// <param name="s"></param>
84+ public virtual Bunsetsu AddBunsetsu(string s)
85+ {
86+ char[] bunsetsuSplitPattern = new char[] { ' ' };
87+ char[] numberPattern = new char[] { '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0' };
88+
89+ // "* 0 -D 0/0 0.00000000"の形式の行をパースする
90+ string[] bunsetsuparams = s.Split(bunsetsuSplitPattern);
91+ if (bunsetsuparams.Length < 3)
92+ {
93+ return null;
94+ }
95+ int bunsetsuId = -1;
96+ int depBunsetsuId = -1;
97+ string depType = null;
98+ try
99+ {
100+ bunsetsuId = Int32.Parse(bunsetsuparams[1]);
101+ int pos = bunsetsuparams[2].LastIndexOfAny(numberPattern);
102+ if (pos < 0 || pos + 1 > bunsetsuparams[2].Length - 1)
103+ {
104+ return null;
105+ }
106+ depBunsetsuId = Int32.Parse(bunsetsuparams[2].Substring(0, pos + 1));
107+ depType = bunsetsuparams[2].Substring(pos + 1, bunsetsuparams[2].Length - pos - 1);
108+
109+ // パラメータが正しければ、文節オブジェクトを作成し、Setnenceに追加登録
110+ if (bunsetsuId >= 0 && depType != null)
111+ {
112+ int newsize = Math.Max(bunsetsuId, depBunsetsuId) + 1;
113+ if (this.bunsetsus.Count < newsize)
114+ {
115+ // Bunsetsus配列を拡大
116+ for (int i = this.bunsetsus.Count; i < newsize; i++)
117+ {
118+ this.bunsetsus.Add(new Bunsetsu());
119+ }
120+ }
121+ Bunsetsu ph = this.bunsetsus[bunsetsuId] as Bunsetsu;
122+ ph.Pos = bunsetsuId;
123+ ph.Sen = this;
124+ if (depBunsetsuId >= 0)
125+ {
126+ ph.DependsTo = this.bunsetsus[depBunsetsuId] as Bunsetsu;
127+ }
128+ ph.DependsAs = depType;
129+ return ph;
130+ }
131+ }
132+ catch (Exception)
133+ {
134+ return null;
135+ }
136+ return null;
137+ }
138+
139+
140+ /// <summary>
141+ /// 文節データの整合性を取る。
142+ /// 具体的には、
143+ /// ・文節がまだひとつもなければ、デフォルト文節を1つ作成し、すべてのWordがそれに属するようにする。
144+ /// さらに
145+ /// ・末尾に空の文節を1つ作成し、DependsTo==nullの文節がそれに係るようにする。
146+ /// </summary>
147+ public virtual void CheckBunsetsus()
148+ {
149+ if (this.bunsetsus.Count == 0)
150+ {
151+ Bunsetsu defaultBunsetsu = new Bunsetsu();
152+ defaultBunsetsu.Pos = 0;
153+ defaultBunsetsu.Sen = this;
154+ this.bunsetsus.Add(defaultBunsetsu);
155+ foreach (Word w in this.Words)
156+ {
157+ w.Bunsetsu = defaultBunsetsu;
158+ }
159+ }
160+ Bunsetsu lastBunsetsu = new Bunsetsu();
161+ lastBunsetsu.Pos = this.bunsetsus.Count;
162+ lastBunsetsu.Sen = this;
163+ this.bunsetsus.Add(lastBunsetsu);
164+
165+ foreach (Bunsetsu b in this.bunsetsus)
166+ {
167+ if (b != lastBunsetsu && b.DependsTo == null)
168+ {
169+ b.DependsTo = lastBunsetsu;
170+ }
171+ }
172+
173+ for (int i = 0; i < this.bunsetsus.Count; i++)
174+ {
175+ Debug.Assert(((Bunsetsu)this.bunsetsus[i]).Pos == i);
176+ }
177+ }
178+
179+ /// <summary>
69180 /// 指定した語の後ろで文節を2つに分離する.
70181 /// </summary>
71182 /// <param name="bunsetsuPos">文内の文節番号(Bunsetsu.Pos)</param>
72183 /// <param name="wordPos">文内の語番号(Word.Pos)</param>
73- public virtual Segment SplitBunsetsu(int bunsetsuPos, int wordPos)
184+ public virtual Bunsetsu SplitBunsetsu(int bunsetsuPos, int wordPos)
74185 {
75-#if false
76186 // 分割対象文節
77- Segment b_src = null;
187+ Bunsetsu b_src = null;
78188 // 文節番号がbunsetsuPosよりも大きい文節の番号をすべて+1する
79- foreach (Segment b in this.bunsetsus)
189+ foreach (Bunsetsu b in this.bunsetsus)
80190 {
81191 if (b.Pos > bunsetsuPos)
82192 {
@@ -89,7 +199,7 @@
89199 Trace.Assert( b_src != null );
90200
91201 // 新しい文節を文節番号=bunsetsuPos+1として作成する
92- Segment b_new = new Segment();
202+ Bunsetsu b_new = new Bunsetsu();
93203 b_new.Sen = this;
94204 b_new.Pos = bunsetsuPos + 1;
95205 b_new.DependsTo = b_src.DependsTo;
@@ -108,9 +218,6 @@
108218
109219 // 追加された文節を返す。
110220 return b_new;
111-#else
112- return null;
113-#endif
114221 }
115222
116223 /// <summary>
@@ -117,20 +224,19 @@
117224 /// 指定した位置の文節とその右の文節を併合する。
118225 /// </summary>
119226 /// <param name="bunsetsuPos"></param>
120- public virtual Segment MergeBunsetsu(int bunsetsuPos)
227+ public virtual Bunsetsu MergeBunsetsu(int bunsetsuPos)
121228 {
122-#if false
123229 if (bunsetsuPos < 0 || bunsetsuPos >= this.bunsetsus.Count-1)
124230 {
125231 return null;
126232 }
127- Segment b_merging = (Segment)this.bunsetsus[bunsetsuPos];
128- Segment b_merged = (Segment)this.bunsetsus[bunsetsuPos+1];
233+ Bunsetsu b_merging = (Bunsetsu)this.bunsetsus[bunsetsuPos];
234+ Bunsetsu b_merged = (Bunsetsu)this.bunsetsus[bunsetsuPos+1];
129235
130236 // 指定した位置の右にある文節を削除
131237 this.bunsetsus.RemoveAt(bunsetsuPos + 1);
132238 // 文節番号がbunsetsuPosよりも大きい文節の番号をすべて-1する
133- foreach (Segment b in this.bunsetsus)
239+ foreach (Bunsetsu b in this.bunsetsus)
134240 {
135241 if (b.Pos > bunsetsuPos)
136242 {
@@ -141,7 +247,7 @@
141247 // マージして残る文節の係り先を、削除した文節の係り先に変更
142248 b_merging.DependsTo = b_merged.DependsTo;
143249 // 削除した文節への係りをすべてマージ先の文節に変更
144- foreach (Segment b in this.bunsetsus)
250+ foreach (Bunsetsu b in this.bunsetsus)
145251 {
146252 if (b.DependsTo == b_merged)
147253 {
@@ -159,9 +265,6 @@
159265
160266 // 削除された文節を返す。
161267 return b_merged;
162-#else
163- return null;
164-#endif
165268 }
166269 }
167270 }
--- trunk/ChaKi.NET/src/Entity/Corpora/Sentence.hbm.xml (revision 34)
+++ trunk/ChaKi.NET/src/Entity/Corpora/Sentence.hbm.xml (revision 35)
@@ -12,6 +12,11 @@
1212 <index column="position"/>
1313 <one-to-many class="ChaKi.Entity.Corpora.Word, ChaKiEntity"/>
1414 </list>
15+ <list name="Bunsetsus" table="bunsetsus" batch-size="20">
16+ <key column="sentence_id"/>
17+ <index column="position"/>
18+ <one-to-many class="ChaKi.Entity.Corpora.Bunsetsu, ChaKiEntity"/>
19+ </list>
1520 <property name="Text" column="text" type="String"/>
1621 <property name="StartChar" column="start_char" type="Int32"/>
1722 <property name="EndChar" column="end_char" type="Int32"/>
--- trunk/ChaKi.NET/src/Entity/Corpora/Bunsetsu.hbm.xml (revision 34)
+++ trunk/ChaKi.NET/src/Entity/Corpora/Bunsetsu.hbm.xml (revision 35)
@@ -10,7 +10,7 @@
1010 <property name="Pos" column="position" type="Int32"/>
1111 <many-to-one name="Sen" class="ChaKi.Entity.Corpora.Sentence, ChaKiEntity" column="sentence_id"/>
1212 <many-to-one name="DependsTo" class="ChaKi.Entity.Corpora.Bunsetsu, ChaKiEntity" column="dep_bunsetsu_id"/>
13- <property name="DependsAs" column="dep_relation" type="String" length="256"/>
13+ <property name="DependsAs" column="dep_relation" type="String" length="255"/>
1414 </class>
1515
1616 </hibernate-mapping>
--- trunk/ChaKi.NET/src/Entity/Corpora/Bunsetsu.cs (revision 34)
+++ trunk/ChaKi.NET/src/Entity/Corpora/Bunsetsu.cs (revision 35)
@@ -66,6 +66,5 @@
6666 private Sentence m_Sen;
6767 private Bunsetsu m_DependsTo;
6868 private string m_DependsAs;
69-
7069 }
7170 }
Show on old repository browser