OSDN Git Service

データ保存関連を整備。
[chnosproject/CHNOSProject.git] / CHNOSProject / AI003 / AI003 / memory.c
diff --git a/CHNOSProject/AI003/AI003/memory.c b/CHNOSProject/AI003/AI003/memory.c
new file mode 100644 (file)
index 0000000..4464f37
--- /dev/null
@@ -0,0 +1,252 @@
+//
+//  memory.c
+//  AI003
+//
+//  Created by 西田 耀 on 13/05/20.
+//  Copyright (c) 2013年 Hikaru Nishida. All rights reserved.
+//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "core.h"
+
+int AI_Memory_AddRootWordData(CHNLIB_String *tag)
+{
+    //WorkingSet.RootWordListに文字列を追加する。
+    //重複がある場合は警告を出し、追加しない。
+    //戻り値は追加されたまたは重複したタグのIndex.
+    
+    return CHNLIB_UIPArray_AppendLast_ProtectFromDuplication(&WorkingSet.RootWordList, 0, tag, &AI_Memory_AddRootWordData_IsDuplicated);
+}
+
+int AI_Memory_AddRootWordData_IsDuplicated(const void *listtag, const void *newtag)
+{
+    //CHNLIB_UIPArray_AppendLast_ProtectFromDuplicationに渡す関数ポインタ。
+    if(CHNLIB_StructureHeader_GetTypeID(listtag) != CHNLIB_STRUCT_ID_String){
+        return False;
+    }
+    if(CHNLIB_String_CompareString_Strict(listtag, newtag)){
+        //CHNLIB_ReportError("Word[%s] has already existed.", CHNLIB_DEBUG_ARGUMENTS, CHNLIB_String_GetReferencePointerOfCString(newtag));
+        return True;
+    }
+    return False;
+}
+
+int AI_Memory_AddRootMemoryData(CHNLIB_UIPArray *tag)
+{
+    //WorkingSet.RootWordListに文字列を追加する。
+    //重複がある場合は警告を出し、追加しない。
+    //戻り値は追加されたまたは重複したタグのIndex.
+    
+    return CHNLIB_UIPArray_AppendLast_ProtectFromDuplication(&WorkingSet.RootMemory, 0, tag, &AI_Memory_AddRootMemoryData_IsDuplicated);
+}
+
+int AI_Memory_AddRootMemoryData_IsDuplicated(const void *listtag, const void *newtag)
+{
+    //CHNLIB_UIPArray_AppendLast_ProtectFromDuplicationに渡す関数ポインタ。
+    CHNLIB_UIPArray *listtag_strArray, *newtag_strArray;
+    int i, i_max;
+    
+    if(CHNLIB_StructureHeader_GetTypeID(listtag) != CHNLIB_STRUCT_ID_UIPArray){
+        return False;
+    }
+    
+    listtag_strArray = CHNLIB_UIPArray_GetPointerByIndex(listtag, 0);
+    newtag_strArray = CHNLIB_UIPArray_GetPointerByIndex(newtag, 0);
+    
+    i_max = CHNLIB_UIPArray_GetNumberOfDatas(listtag_strArray);
+    if(i_max == CHNLIB_UIPArray_GetNumberOfDatas(newtag_strArray)){
+        //文字列配列の要素数が一致するので、内容も一致する可能性がある
+        for(i = 0; i < i_max; i++){
+            if(!CHNLIB_String_CompareString_Strict(CHNLIB_UIPArray_GetPointerByIndex(listtag_strArray, i), CHNLIB_UIPArray_GetPointerByIndex(newtag_strArray, i))){
+                //一致しないタグがあったので、不一致
+                return False;
+            }
+        }
+        //すべて一致したので、重複している
+        return True;
+    }
+    //文字列配列の要素数が一致しないので、不一致
+    return False;
+}
+
+//記憶ファイルの構成・書式
+//-config.txt
+//  一行目に単語リストファイル(words.txt)
+//  二行目に記憶データファイル(memory.txt)
+//  のファイル名を記述する。
+//
+//-words.txt
+//<単語カウント>:<単語文字列>
+//
+//-memory.txt
+//[<文字列単語>+<文字列単語>+...][<属性値1>,<属性値2>,...][<属性値a>,<属性値b>,...]
+//
+//
+void AI_System_LoadMemory(const char configfilename[])
+{
+    //指定されたファイル名のテキストファイルから設定を読み出す。
+    FILE *configfp, *readfp;
+    CHNLIB_String *line, *currentfilename;
+    uint wordCount;
+    char *invchar;
+    int tagIndex, i, i_max;
+    CHNLIB_UIPArray *separated, *dataArray, *subDataArray;
+    
+    configfp = fopen(configfilename, "rb");
+    
+    //単語リストの読み込み
+    currentfilename = CHNLIB_ReadLine(configfp);
+    readfp = fopen(CHNLIB_String_GetReferencePointerOfCString(currentfilename), "rb");
+    release(currentfilename);
+    
+    for(;;){
+        line = CHNLIB_ReadLine(readfp);
+        if(line == NULL){
+            break;
+        }
+        wordCount = (uint)strtol(CHNLIB_String_GetReferencePointerOfCString(line), &invchar, 0);
+        for(; *invchar != '\0'; invchar++){
+            if(*invchar == ':'){
+                invchar++;
+                break;
+            }
+        }
+        tagIndex = AI_Memory_AddRootWordData(autorelease(CHNLIB_String_Initialize(invchar)));
+        CHNLIB_UIPArray_SetData32ByIndex(WorkingSet.RootWordList, tagIndex, CHNLIB_UIPArray_GetData32ByIndex(WorkingSet.RootWordList, tagIndex) + wordCount);
+        release(line);
+    }
+    fclose(readfp);
+    
+    //記憶データの読み込み
+    currentfilename = CHNLIB_ReadLine(configfp);
+    readfp = fopen(CHNLIB_String_GetReferencePointerOfCString(currentfilename), "rb");
+    release(currentfilename);
+    
+    for(;;){
+        line = CHNLIB_ReadLine(readfp);
+        if(line == NULL){
+            break;
+        }
+        separated = CHNLIB_UIPArray_Initialize();
+        CHNLIB_UIPArray_GetSeparatedStringByUIPArray(&separated, WorkingSet.SystemWordList0, line);
+        
+        dataArray = CHNLIB_UIPArray_Initialize();
+        subDataArray = CHNLIB_UIPArray_Initialize();
+        
+        i_max = CHNLIB_UIPArray_GetNumberOfDatas(separated);
+        for(i = 0; i < i_max; i++){
+            switch (CHNLIB_UIPArray_GetData32ByIndex(separated, i)) {
+                case AI_SW_Delimiter_Colon:
+                    //:
+                    break;
+                    
+                case AI_SW_Delimiter_Comma:
+                    //,
+                    break;
+                    
+                case AI_SW_Delimiter_Plus:
+                    //+
+                    break;
+                    
+                case AI_SW_Bracket_Start:
+                    //[
+                    subDataArray = CHNLIB_UIPArray_Initialize();
+                    break;
+                    
+                case AI_SW_Bracket_End:
+                    //]
+                    CHNLIB_UIPArray_AppendLast(&dataArray, 0, subDataArray);
+                    release(subDataArray);
+                    break;
+                    
+                case 0:
+                    //文字列
+                    tagIndex = AI_Memory_AddRootWordData(CHNLIB_UIPArray_GetPointerByIndex(separated, i));
+                    CHNLIB_UIPArray_AppendLast(&subDataArray, 0, CHNLIB_UIPArray_GetPointerByIndex(WorkingSet.RootWordList, tagIndex));
+                    
+                    break;
+            }
+        }
+        if(dataArray != NULL){
+            AI_Memory_AddRootMemoryData(dataArray);
+            release(dataArray);
+        }
+        release(separated);
+        release(line);
+    }
+    fclose(readfp);
+    
+    //終了処理
+    fclose(configfp);
+    
+    return;
+}
+
+void AI_System_SaveMemory_RootWordList(const char wordlistfilename[])
+{
+    //指定されたファイル名へ単語リストを出力する。
+    FILE *writefp;
+    CHNLIB_UIPArray *sorted;
+    int i, i_max;
+    
+    writefp = fopen(wordlistfilename, "wb");
+    if(writefp == NULL){
+        puts("File open error.");
+    } else{
+        sorted = CHNLIB_UIPArray_GetSortedInDescendingOrderByData32(WorkingSet.RootWordList);
+        i_max = CHNLIB_UIPArray_GetNumberOfDatas(sorted);
+        for(i = 0; i < i_max; i++){
+            fprintf(writefp, "%10d:%s\n", CHNLIB_UIPArray_GetData32ByIndex(sorted, i), CHNLIB_String_GetReferencePointerOfCString(CHNLIB_UIPArray_GetPointerByIndex(sorted, i)));
+        }
+        fclose(writefp);
+        writefp = NULL;
+        release(sorted);
+        puts("Save RootWordList done.");
+    }
+    
+    return;
+}
+
+void AI_System_SaveMemory_RootMemory(const char memlistfilename[])
+{
+    //指定されたファイル名へ記憶データを出力する。
+    FILE *writefp;
+    CHNLIB_UIPArray *subArray;
+    int i, i_max;
+    int j, j_max;
+    int k, k_max;
+    
+    writefp = fopen(memlistfilename, "wb");
+    if(writefp == NULL){
+        puts("File open error.");
+    } else{
+        i_max = CHNLIB_UIPArray_GetNumberOfDatas(WorkingSet.RootMemory);
+        for(i = 0; i < i_max; i++){
+            subArray = CHNLIB_UIPArray_GetPointerByIndex(CHNLIB_UIPArray_GetPointerByIndex(WorkingSet.RootMemory, i), 0);
+            j_max = CHNLIB_UIPArray_GetNumberOfDatas(subArray);
+            fputc('[', writefp);
+            for(j = 0; j < j_max - 1; j++){
+                fprintf(writefp, "%s+", CHNLIB_String_GetReferencePointerOfCString(CHNLIB_UIPArray_GetPointerByIndex(subArray, j)));
+            }
+            fprintf(writefp, "%s]", CHNLIB_String_GetReferencePointerOfCString(CHNLIB_UIPArray_GetPointerByIndex(subArray, j)));
+            
+            k_max = CHNLIB_UIPArray_GetNumberOfDatas(CHNLIB_UIPArray_GetPointerByIndex(WorkingSet.RootMemory, i));
+            for(k = 1; k < k_max; k++){
+                subArray = CHNLIB_UIPArray_GetPointerByIndex(CHNLIB_UIPArray_GetPointerByIndex(WorkingSet.RootMemory, i), k);
+                j_max = CHNLIB_UIPArray_GetNumberOfDatas(subArray);
+                fputc('[', writefp);
+                for(j = 0; j < j_max - 1; j++){
+                    fprintf(writefp, "%s,", CHNLIB_String_GetReferencePointerOfCString(CHNLIB_UIPArray_GetPointerByIndex(subArray, j)));
+                }
+                fprintf(writefp, "%s]", CHNLIB_String_GetReferencePointerOfCString(CHNLIB_UIPArray_GetPointerByIndex(subArray, j)));
+            }
+            fputc('\n', writefp);
+        }
+        fclose(writefp);
+        writefp = NULL;
+        puts("Save RootMemory done.");
+    }
+    
+    return;
+}