5 // Created by 西田 耀 on 13/01/28.
\r
6 // Copyright (c) 2013年 Hikaru Nishida. All rights reserved.
\r
17 //Define static values
\r
20 AI_WorkingSet WorkingSet;
\r
22 int main(int argc, const char * argv[])
\r
26 CHNLIB_String *input, *temp;
\r
27 CHNLIB_UIPArray *separated, *sorted;
\r
31 CHNLIB_Environment_SetCurrentWorkingDirectory(argv[0]);
\r
33 CHNLIB_Debug("Hello, World.", CHNLIB_DEBUG_ARGUMENTS);
\r
35 AI_System_InitializeSystemWorkingSet();
\r
37 AI_System_LoadMemory(AI_CONFIG_FILE_NAME);
\r
44 input = CHNLIB_ReadLine(stdin);
\r
46 input = CHNLIB_ReadLine(readfp);
\r
50 puts(CHNLIB_String_GetReferencePointerOfCString(input));
\r
54 if(CHNLIB_String_CompareStringWithCString(input, "::")){
\r
57 separated = CHNLIB_UIPArray_Initialize();
\r
58 CHNLIB_UIPArray_GetSeparatedStringByUIPArray(&separated, WorkingSet.SystemWordList0, input);
\r
60 temp = CHNLIB_UIPArray_GetPointerByIndex(separated, 2);
\r
62 if(CHNLIB_String_CompareStringWithCString(temp, "info")){
\r
63 printf("AI internal information:\n");
\r
64 } else if(CHNLIB_String_CompareStringWithCString(temp, "exit")){
\r
66 } else if(CHNLIB_String_CompareStringWithCString(temp, "wordlist")){
\r
67 sorted = CHNLIB_UIPArray_SortInDescendingOrderByData32(WorkingSet.RootWordList);
\r
68 i_max = CHNLIB_UIPArray_GetNumberOfDatas(sorted);
\r
69 for(i = 0; i < i_max; i++){
\r
70 printf("word%3d:%3d:%s\n", i, CHNLIB_UIPArray_GetData32ByIndex(sorted, i), CHNLIB_String_GetReferencePointerOfCString(CHNLIB_UIPArray_GetPointerByIndex(sorted, i)));
\r
72 CHNLIB_UIPArray_FreeOnlyArray(&sorted);
\r
73 } else if(CHNLIB_String_CompareStringWithCString(temp, "readfile")){
\r
74 //::readfile:filename
\r
75 readfp = fopen(CHNLIB_String_GetReferencePointerOfCString(CHNLIB_UIPArray_GetPointerByIndex(separated, 4)), "rb");
\r
77 puts("File open error.");
\r
84 //WorkingSet.SystemWordList0を使っているので、解放しないように注意
\r
85 CHNLIB_UIPArray_FreeSelectedAll(&separated);
\r
90 //::readfile:AITestData_ja.txt
\r
91 AI_Think_LearnWordFromInputString(input);
\r
93 CHNLIB_UIPArray_AppendLast(&WorkingSet.InputHistory, CHNLIB_UIPArray_GetNumberOfDatas(WorkingSet.InputHistory), input);
\r
100 void AI_Think_LearnWordFromInputString(CHNLIB_String *input)
\r
102 //入力文字列から単語を抽出して記憶する。
\r
103 CHNLIB_UIPArray *candidateWordList;
\r
105 int tagIndex, maxExistingWordIndex;
\r
107 candidateWordList = CHNLIB_UIPArray_Initialize();
\r
108 candidateWordList = AI_Think_SlideLookUpWordByHistory(input);
\r
109 i_max = CHNLIB_UIPArray_GetNumberOfDatas(candidateWordList);
\r
110 maxExistingWordIndex = CHNLIB_UIPArray_GetNumberOfDatas(WorkingSet.RootWordList) - 1;
\r
112 printf("Index(Decimal),CountOfContain(Decimal), String\n");
\r
113 for(i = 0; i < i_max; i++){
\r
114 printf("%d,%d,%s\n", i, CHNLIB_UIPArray_GetData32ByIndex(candidateWordList, i), CHNLIB_String_GetReferencePointerOfCString(CHNLIB_UIPArray_GetPointerByIndex(candidateWordList, i)));
\r
117 tagIndex = AI_Memory_AddRootWordData(CHNLIB_UIPArray_GetPointerByIndex(candidateWordList, i));
\r
119 CHNLIB_UIPArray_SetData32ByIndex(WorkingSet.RootWordList, tagIndex, CHNLIB_UIPArray_GetData32ByIndex(WorkingSet.RootWordList, tagIndex) + CHNLIB_UIPArray_GetData32ByIndex(candidateWordList, i));
\r
121 if(tagIndex <= maxExistingWordIndex){
\r
122 //既存のタグなので、解放されるようにdata32をFalseにしておく。
\r
123 CHNLIB_UIPArray_SetData32ByIndex(candidateWordList, i, False);
\r
125 //新規追加されたタグについては0以上の値つまりTrueが設定されているはずなので、解放されない。
\r
127 //data32 == Falseのタグ、つまり既存のタグと同じだったもののみ解放する。
\r
128 CHNLIB_UIPArray_FreeSelectedAll(&candidateWordList);
\r
133 CHNLIB_UIPArray *AI_Think_SlideLookUpWordByHistory(CHNLIB_String *input)
\r
136 //入力文字列と履歴文字列を照らし合わせ、単語の候補を抜き出す。
\r
137 //候補単語は、新たに確保されたUIPArrayに格納され、そのArrayへのポインタを返す。
\r
138 //data32=入力文字列中に含まれる候補単語の数。
\r
139 //pointer=候補単語を示すCHNLIB_String.
\r
140 CHNLIB_UIPArray *candidatewordlist;
\r
144 const char *cstr_input, *cstrp_input;
\r
145 const char *cstr_history, *cstrp_history;
\r
146 int candidatelength, templength;
\r
147 int cstrp_input_length;
\r
149 candidatewordlist = CHNLIB_UIPArray_Initialize();
\r
150 i_max = CHNLIB_UIPArray_GetNumberOfDatas(WorkingSet.InputHistory);
\r
152 cstr_input = CHNLIB_String_GetReferencePointerOfCString(input);
\r
153 k_max = CHNLIB_UTF8_GetStringLengthByCharacter(cstr_input);
\r
154 cstrp_input = cstr_input;
\r
156 for(k = 0; k < k_max; k++){
\r
157 //input character loop
\r
158 candidatelength = 0;
\r
159 cstrp_input_length = CHNLIB_UTF8_GetStringLengthByCharacter(cstrp_input);
\r
160 for(i = 0; i < i_max; i++){
\r
161 //history entry loop
\r
162 cstr_history = CHNLIB_String_GetReferencePointerOfCString(CHNLIB_UIPArray_GetPointerByIndex(WorkingSet.InputHistory, i));
\r
163 j_max = CHNLIB_UTF8_GetStringLengthByCharacter(cstr_history);
\r
164 cstrp_history = cstr_history;
\r
166 for(j = 0; j < j_max; j++){
\r
167 //history character loop
\r
168 templength = CHNLIB_UTF8_CompareString_LeftHand(cstrp_history, cstrp_input);
\r
169 if(templength > candidatelength && templength != cstrp_input_length){
\r
170 //前方一致の長さが、これまで見つかった単語よりも長く、かつ入力文字列の検索部分の全長ではない場合、
\r
172 candidatelength = templength;
\r
174 CHNLIB_UTF8_GetNextUnicodeOfCharacter(cstrp_history, &cstrp_history);
\r
177 if(candidatelength > 0){
\r
178 CHNLIB_UIPArray_AppendLast_ProtectFromDuplication(&candidatewordlist, 0, CHNLIB_String_ExtractByLength(input, CHNLIB_UTF8_GetByteSizeFromLengthByCharacter(cstr_input, 0, k - 1), CHNLIB_UTF8_GetByteSizeFromLengthByCharacter(cstrp_input, 0, candidatelength - 1)), &AI_Memory_AddRootWordData_IsDuplicated);
\r
180 CHNLIB_UTF8_GetNextUnicodeOfCharacter(cstrp_input, &cstrp_input);
\r
183 //各候補単語が履歴文字列にいくつ含まれているかをdata32に保存する。
\r
184 k_max = CHNLIB_UIPArray_GetNumberOfDatas(candidatewordlist);
\r
185 for(k = 0; k < k_max; k++){
\r
187 cstr_input = CHNLIB_String_GetReferencePointerOfCString(CHNLIB_UIPArray_GetPointerByIndex(candidatewordlist, k));
\r
188 for(i = 0; i < i_max; i++){
\r
189 cstr_history = CHNLIB_String_GetReferencePointerOfCString(CHNLIB_UIPArray_GetPointerByIndex(WorkingSet.InputHistory, i));
\r
190 j += CHNLIB_UTF8_GetCountOfContain(cstr_history, cstr_input);
\r
193 CHNLIB_UIPArray_SetData32ByIndex(candidatewordlist, k, j);
\r
197 AI_Think_CandidateWordList_Filter01(&candidatewordlist, 1);
\r
198 AI_Think_CandidateWordList_Filter00(&candidatewordlist);
\r
200 return candidatewordlist;
\r
203 int AI_Think_CandidateWordList_Filter00(CHNLIB_UIPArray **candidatewordlist)
\r
205 //[Not implemented]
\r
207 //AI_Think_SlideLookUpWordByHistoryで返されたArray内の候補単語に対して、フィルターをかける。
\r
208 //00:長い単語に含まれており、かつ出現頻度が長い単語と等しい単語を削除
\r
210 CHNLIB_String *nowstr, *basestr;
\r
211 int basestrCoC; //CountOfContainInHistoryStrings
\r
213 i_max = CHNLIB_UIPArray_GetNumberOfDatas(*candidatewordlist);
\r
214 basestr = CHNLIB_UIPArray_GetPointerByIndex(*candidatewordlist, 0);
\r
215 basestrCoC = CHNLIB_UIPArray_GetData32ByIndex(*candidatewordlist, 0);
\r
216 for(i = 1; i < i_max; i++){
\r
217 nowstr = CHNLIB_UIPArray_GetPointerByIndex(*candidatewordlist, i);
\r
218 if(CHNLIB_UTF8_GetCountOfContain(CHNLIB_String_GetReferencePointerOfCString(basestr), CHNLIB_String_GetReferencePointerOfCString(nowstr)) > 0){
\r
219 //nowstrはbasestrに含まれている
\r
220 if(basestrCoC == CHNLIB_UIPArray_GetData32ByIndex(*candidatewordlist, i)){
\r
221 //かつ出現頻度が等しいので不要な単語
\r
222 //出現頻度を0にして、後で削除する。
\r
223 CHNLIB_UIPArray_SetData32ByIndex(*candidatewordlist, i, 0);
\r
227 if(CHNLIB_UIPArray_GetData32ByIndex(*candidatewordlist, i) != 0){
\r
228 //単語は削除されなかった、つまり異なる単語なので、basestrを更新
\r
230 basestrCoC = CHNLIB_UIPArray_GetData32ByIndex(*candidatewordlist, i);
\r
234 for(i = 1; i < i_max; i++){
\r
235 if(CHNLIB_UIPArray_GetData32ByIndex(*candidatewordlist, i) == 0){
\r
237 CHNLIB_UIPArray_RemoveByIndex(candidatewordlist, i);
\r
246 int AI_Think_CandidateWordList_Filter01(CHNLIB_UIPArray **candidatewordlist, int length)
\r
248 //[Not implemented]
\r
250 //AI_Think_SlideLookUpWordByHistoryで返されたArray内の候補単語に対して、フィルターをかける。
\r
251 //01:length以下の文字数の単語を削除
\r
255 i_max = CHNLIB_UIPArray_GetNumberOfDatas(*candidatewordlist);
\r
256 for(i = 0; i < i_max; i++){
\r
257 if(CHNLIB_UTF8_GetStringLengthByCharacter(CHNLIB_String_GetReferencePointerOfCString(CHNLIB_UIPArray_GetPointerByIndex(*candidatewordlist, i))) <= length){
\r
258 CHNLIB_UIPArray_RemoveByIndex(candidatewordlist, i);
\r
267 int AI_Memory_AddRootWordData(CHNLIB_String *tag)
\r
269 //WorkingSet.RootWordListに文字列を追加する。
\r
270 //重複がある場合は警告を出し、追加しない。
\r
271 //戻り値は追加されたまたは重複したタグのIndex.
\r
273 return CHNLIB_UIPArray_AppendLast_ProtectFromDuplication(&WorkingSet.RootWordList, 0, tag, &AI_Memory_AddRootWordData_IsDuplicated);
\r
276 int AI_Memory_AddRootWordData_IsDuplicated(const void *listtag, const void *newtag)
\r
278 //CHNLIB_UIPArray_AppendLast_ProtectFromDuplicationに渡す関数ポインタ。
\r
279 if(CHNLIB_StructureHeader_GetTypeID(listtag) != CHNLIB_STRUCT_ID_String){
\r
282 if(CHNLIB_String_CompareString_Strict(listtag, newtag)){
\r
283 CHNLIB_ReportError("Word[%s] has already existed.", CHNLIB_DEBUG_ARGUMENTS, CHNLIB_String_GetReferencePointerOfCString(newtag));
\r
289 void AI_System_InitializeSystemWorkingSet(void)
\r
291 //WorkingSetを初期化する。
\r
292 WorkingSet.SystemWordList0 = CHNLIB_UIPArray_Initialize();
\r
293 CHNLIB_UIPArray_AppendLast(&WorkingSet.SystemWordList0, True, CHNLIB_String_Initialize(":"));
\r
294 CHNLIB_UIPArray_AppendLast(&WorkingSet.SystemWordList0, True, CHNLIB_String_Initialize(","));
\r
296 WorkingSet.InputHistory = CHNLIB_UIPArray_Initialize();
\r
301 void AI_System_LoadMemory(const char configfilename[])
\r
303 //指定されたファイル名のテキストファイルから設定を読み出す。
\r
305 CHNLIB_String *line, *currentfilename;
\r
308 fp = fopen(configfilename, "rb");
\r
309 currentfilename = CHNLIB_ReadLine(fp);
\r
312 fp = fopen(CHNLIB_String_GetReferencePointerOfCString(currentfilename), "rb");
\r
314 WorkingSet.RootWordList = CHNLIB_UIPArray_Initialize();
\r
316 line = CHNLIB_ReadLine(fp);
\r
320 CHNLIB_UIPArray_AppendLast(&WorkingSet.RootWordList, i, line);
\r
321 //CHNLIB_String_Free(line);リストに登録している実体なので解放の必要なし!
\r
324 CHNLIB_String_Free(currentfilename);
\r
326 //CHNLIB_Debug_PrintStructureData(WorkingSet.RootWordList, 0);
\r