OSDN Git Service

自動追尾を再実装。
[chnosproject/AI004.git] / memdb / memorydb.js
1 // 知識表現を保存するデータベース
2
3 function MemoryDB(){
4         //ルート
5         this.root = new Array();
6         // タグタイプリスト(各タグのfunctionオブジェクトの配列)
7         this.tagTypeList = new Array();
8         /*
9         //サブリスト
10         this.candidateWordList = new Array();
11         this.candidateWordListLastModifiedDate = new Date();
12         this.candidateWordListLastCleanedDate = new Date();
13         //
14         this.wordList = new Array();
15         this.wordListLastModifiedDate = new Date();
16         //
17         this.notWordList = new Array();
18         this.notWordListLastModifiedDate = new Date();
19         //
20         this.patternList = new Array();
21         //
22         this.dbInfo = new AI_DatabaseInfoTag();
23         */
24 }
25 MemoryDB.prototype = {
26         headerUUID: "42e11880-62b8-46ea-a1c4-481264d4440d",     // UUID_Mode_ReadMemory
27         memoryDataString: function(){
28                 var s = "#" + this.headerUUID + "\n";
29                 var cl = this.root;
30                 var k;
31                 for(var i = 0, iLen = cl.length; i < iLen; i++){
32                         if(cl[i] instanceof AI_MemoryTag){
33                                 k = cl[i].parseToStringData();
34                                 if(k !== undefined){
35                                         s += k + "\n";
36                                 }
37                         }
38                 }
39                 //dbInfoタグの保存
40                 k = this.dbInfo.parseToStringData();
41                 if(k !== undefined){
42                         s += k + "\n";
43                 }
44                 //
45                 /*
46                 var d = new Blob([s]);
47                 if(d){
48                         m.showDownloadLink(d);
49                 }
50                 */
51                 return s;
52         },
53         loadMemory: function(str){
54                 var a, t, d, m, q;
55                 
56                 // this.env.debug("Memory loading...\n");
57                 a = str.splitByArray(["\n"]);
58                 
59                 for(var i = 1, iLen = a.length; i < iLen; i++){
60                         try{
61                                 d = eval(a[i]);
62                         } catch(e){
63                                 // this.env.debug(i + ": " + e + "\n");
64                                 continue;
65                         }
66                         if(d === undefined){
67                                 continue;
68                         }
69                         q = d.type;
70                         if(q == AI_MemoryTag.prototype.Type_CandidateWord){
71                                 t = new AI_CandidateWordTag();
72                         } else if(q == AI_MemoryTag.prototype.Type_Word){
73                                 t = new AI_WordTag();
74                         } else if(q == AI_MemoryTag.prototype.Type_NotWord){
75                                 t = new AI_NotWordTag();
76                         } else if(q == AI_MemoryTag.prototype.Type_DatabaseInfo){
77                                 t = new AI_DatabaseInfoTag();
78                         } else{
79                                 t = new AI_MemoryTag();
80                         }
81                         AI_MemoryTag.prototype.loadFromMemoryData.call(t, d);
82                         this.appendMemoryTag(t);
83                 }
84                 this.verifyMemoryStructure();
85                 this.env.debug("Memory loading done.\n" + this.root.length + " tags exist.\n");
86         },
87         appendMemoryTag: function(tag){
88                 //同じUUIDのタグがあった場合はデバッグ表示をして、追加しようとしているものに置き換える。
89                 //ただし、初期データに入っているものは警告を発さず上書きする。
90                 var s = this.root.isIncluded(tag, function(a, b){ return (a.uuid == b.uuid); });
91                 
92                 //タグに合わせて追加条件を満たしているか確認し、それぞれのサブリストに分配
93                 if(tag instanceof AI_CandidateWordTag){
94                         this.candidateWordList.push(tag);
95                         this.candidateWordListLastModifiedDate = new Date();
96                 } else if(tag instanceof AI_WordTag){
97                         if(this.wordList.isIncluded(tag, function(a, b){ return ((a.str == b.str) && (a !== s)); })){
98                                 this.env.debug("appendMemoryTag: Duplicated word [" + tag.str + "].\n");
99                                 return;
100                         }
101                         if(tag.str == undefined || tag.str.length == 0){
102                                 this.env.debug("appendMemoryTag: Invalid word [" + tag.str + "].\n");
103                                 return;
104                         }
105                         this.wordList.push(tag);
106                         this.wordListLastModifiedDate = new Date();
107                 } else if(tag instanceof AI_NotWordTag){
108                         if(this.notWordList.isIncluded(tag, function(a, b){ return ((a.str == b.str) && (a !== s)); })){
109                                 this.env.debug("appendMemoryTag: Duplicated notWord [" + tag.str + "].\n");
110                                 return;
111                         }
112                         if(tag.str == undefined || tag.str.length == 0){
113                                 this.env.debug("appendMemoryTag: Invalid notWord [" + tag.str + "].\n");
114                                 return;
115                         }
116                         this.notWordList.push(tag);
117                         this.notWordListLastModifiedDate = new Date();
118                 } else if(tag instanceof AI_PatternTag){
119                         this.patternList.push(tag);
120                 } else if(tag instanceof AI_DatabaseInfoTag){
121                         //データベースデータに反映させて、タグ自体は破棄する
122                         tag.bindDatabaseInfo(this);
123                         return;
124                 }
125                 
126                 //すでにあった重複UUIDの削除
127                 if(s){
128                         if(s.isBootstrap === undefined){
129                                 this.env.debug("appendMemoryTag: duplicated UUID " + tag.uuid + ", overwritten.\n");
130                         }
131                         this.removeMemoryTagByObject(s);
132                 }
133                 //ルートに追加
134                 this.root.push(tag);
135         },
136         /*
137         appendMemoryTagFromString: function(str){
138                 //retv:isAppended
139                 var d;
140                 var q;
141                 var t;
142                 try{
143                         d = eval(str);
144                 } catch(e){
145                         this.env.debug(""i + ": " + e + "\n");
146                         return false;
147                 }
148                 if(d === undefined){
149                         return false;
150                 }
151                 q = d.type;
152                 if(q == AI_MemoryTag.prototype.Type_CandidateWord){
153                         t = new AI_CandidateWordTag();
154                 } else{
155                         t = new AI_MemoryTag();
156                 }
157                 AI_MemoryTag.prototype.loadFromMemoryData.call(t, d);
158                 this.appendMemoryTag(t);
159         },
160         */
161         removeMemoryTagByObject: function(obj){
162                 this.root.removeAnObject(obj);
163                 if(this.candidateWordList.removeAnObject(obj)){
164                         this.candidateWordListLastModifiedDate = new Date();
165                 }
166                 if(this.wordList.removeAnObject(obj)){
167                         this.wordListLastModifiedDate = new Date();
168                 }
169         },
170         verifyMemoryStructure: function(){
171                 //メモリ構造検査・修復
172                 //単語が単語候補に残っていた場合は単語候補から削除
173                 for(var i = 0, iLen = this.wordList.length; i < iLen; i++){
174                         var w = this.wordList[i].str;
175                         for(var j = 0, jLen = this.candidateWordList.length; j < jLen; j++){
176                                 if(this.candidateWordList[j].str == w){
177                                         this.env.debug("Word duplicated in CWL. Removed.\n");
178                                         this.removeMemoryTagByObject(this.candidateWordList[j]);
179                                         j--;
180                                         jLen--;
181                                 }
182                         }
183                 }
184                 
185                 this.env.wordRecognition.cleanCandidateWordList();
186                 //候補リスト並べ替え
187                 this.env.wordRecognition.sortCandidateWordListByWordCount();
188                 this.env.wordRecognition.computeEachWordLevel();
189                 this.env.wordRecognition.sortCandidateWordListByWordLevel();
190                 //
191                 this.env.debug("Memory verifying done.\n");
192         },
193         getTagFromWordInNotWord: function(str){
194                 return this.notWordList.isIncluded(str, function(a, b){ return a.str == b; });
195         },
196         getUUIDFromWord: function(str){
197                 var t = this.wordList.isIncluded(str, function(a, b){ return a.str == b; });
198                 if(!t){
199                         return this.env.UUID_Meaning_UndefinedString;
200                 }
201                 return t.uuid;
202         },
203         /*
204         getUUIDFromWordInNotWord: function(str){
205                 var t = this.getTagFromWordInNotWord(str);
206                 if(!t){
207                         return this.env.UUID_Meaning_UndefinedString;
208                 }
209                 return t.uuid;
210         },
211         */
212 }
213
214 function MemoryDBTag(typeUUIDStr){
215         //保存対象
216         this.uuid = null;
217         this.createdDate = new Date();
218         
219         //初期化
220         this.initUUID();
221 }
222 AI_MemoryTag.prototype = {
223         Type_CandidateWord: "2fba8fc1-2b9a-46e0-8ade-455c0bd30637",
224         Type_Word: "d5eef85c-a796-4d04-bb72-8d45c94c5e4f",
225         Type_Pattern: "8085e53e-0e99-4221-821c-057f38e35ed9",
226         Type_Meaning: "dec1789a-9200-4f9b-9248-177495f47f7d",
227         Type_DatabaseInfo: "4e7b3a3e-bb8c-4315-b3d0-6b25f9aead61",
228         Type_NotWord: "505dbc8d-fa0a-4d0f-b625-d6065738f63d",
229         Type_Null: "00000000-0000-0000-0000-000000000000",
230         AppendType_Manual: "a2aaf202-7a6c-4dc5-b394-da9592410195",
231         type: "00000000-0000-0000-0000-000000000000",
232         //http://codedehitokoto.blogspot.jp/2012/01/javascriptuuid.html
233         initUUID: function(){
234                 if(!this.uuid){
235                         var f = this.initUUIDSub;
236                         this.uuid = f() + f() + "-" + 
237                                                 f() + "-" + 
238                                                 f() + "-" + 
239                                                 f() + "-" + 
240                                                 f() + f() + f();
241                 }
242         },
243         initUUIDSub: function(){
244                 return (((1 + Math.random()) * 0x10000) | 0).toString(16).toLowerCase().substring(1);
245         },
246         parseToStringData: function(data){
247                 //uuid:type:
248                 var d = new Object();
249                 //
250                 d.id = this.uuid;
251                 d.type = this.type;
252                 d.cDate = this.createdDate.toUTCString();
253                 //
254                 d.data = data;
255                 //
256                 return this.parseArrayToStringSource(d);
257         },
258         loadFromMemoryData: function(data){
259                 this.uuid = data.id;
260                 this.type = data.type;
261                 this.createdDate = new Date(data.cDate);
262                 if(data.data){
263                         if(this.loadFromMemoryData != AI_MemoryTag.prototype.loadFromMemoryData){
264                                 this.loadFromMemoryData(data.data);
265                         }
266                 }
267         },
268         parseArrayToStringSource: function(anArray){
269                 if(!anArray){
270                         return "null";
271                 }
272                 var srcstr = "var t=";
273                 srcstr += this.parseArrayToStringSourceSub(anArray);
274                 srcstr += ";t;";
275                 return srcstr;
276         },
277         parseArrayToStringSourceSub: function(anArray){
278                 if(!anArray){
279                         return "null";
280                 }
281                 var srcstr = "{";
282                 for(var k in anArray){
283                         var v = anArray[k];
284                         var t = Object.prototype.toString.call(v);
285                         if(v instanceof Array){
286                                 srcstr += k + ":" + this.parseArrayToStringSourceSub(v) + ",";
287                         } else if(!isNaN(v) && v.toString().replace(/\s+/g, "").length > 0){
288                                 //isNaNだけでは数値判定できないので、文字列化後の空白文字を削除した長さも検査している。
289                                 srcstr += k + ":" + v + ",";
290                         } else if(t == "[object String]"){
291                                 //文字列として変換
292                                 srcstr += k + ":'" + v + "',";
293                         } else if(t == "[object Object]"){
294                                 srcstr += k + ":" + this.parseArrayToStringSourceSub(v) + ",";
295                         } else{
296                                 srcstr += k + ":undefined,";
297                         }
298                 }
299                 if(srcstr.charAt(srcstr.length - 1) == ","){
300                         //最後の余計なカンマを削除
301                         srcstr = srcstr.slice(0, srcstr.length - 1);
302                 }
303                 srcstr += "}";
304                 return srcstr;
305         },
306 }