00001 /* 00002 * Copyright (C) 1997-2004 The CDG Team <cdg@nats.informatik.uni-hamburg.de> 00003 * 00004 * This file is free software; as a special exception the author gives 00005 * unlimited permission to copy and/or distribute it, with or without 00006 * modifications, as long as this notice is preserved. 00007 * 00008 * This program is distributed in the hope that it will be useful, but 00009 * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 00010 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00011 * 00012 * Author: Ingo Schroeder (see also AUTHORS and THANKS for more) 00013 * Birth: 24/2/97 00014 * 00015 * $Id: cdg.c,v 1.87 2004/09/27 17:07:02 micha Exp $ 00016 */ 00017 00018 /* ------------------------------------------------------------------------- 00019 * @addtogroup Cdg Cdg - The Root Module 00020 * 00021 * Initialization of the \c CDG system on startup. 00022 * 00023 * This is the so called root module of the library with the following purpose: 00024 * - initialization of the \c CDG system at startup 00025 * - finalization at shutdown 00026 * - container for globally used functions and definitions 00027 * - owner of the symbol table 00028 * 00029 * All other modules depend on this module and include cdg.h 00030 * @{ 00031 */ 00032 00033 /* ---------------------------------------------------------------------- */ 00034 #include <config.h> 00035 #include <stdio.h> 00036 #include <stdarg.h> 00037 #include <string.h> 00038 #include <pwd.h> 00039 #include <readline/readline.h> 00040 #include "cdg.h" 00041 #include "parsing.h" 00042 #include "input.h" 00043 #include "command.h" 00044 #include "statistics.h" 00045 #include "constraintnet.h" 00046 #include "hook.h" 00047 #include "timer.h" 00048 #include "incrementalcompletion.h" 00049 #include "eval.h" 00050 #include "parse.h" 00051 #include "frobbing.h" 00052 #include "write.h" 00053 #include "search.h" 00054 #ifndef DARWIN 00055 #include "compile.h" 00056 #endif 00057 #include "netsearch.h" 00058 #include "set.h" 00059 #include "gls.h" 00060 #include "tagger.h" 00061 #include "chunker.h" 00062 #include "cdgdb.h" 00063 #include "shift.h" 00064 00065 /* ---------------------------------------------------------------------- */ 00066 /* ---------------------------------------------------------------------- */ 00067 /* -- VARIABLES --------------------------------------------------------- */ 00068 00069 00070 /* ------------------------------------------------------------------------- 00071 * indicator flag set by the signal handler of ctrl-c. 00072 * If \ref cdgCtrlCAllowed is TRUE and the user presses ctrl-c 00073 * the flag \c cdgCtrlCTrapped is set to TRUE. It's the responsibility 00074 * of the current function to re-act to the interruption. 00075 */ 00076 Boolean cdgCtrlCTrapped = FALSE; 00077 00078 /* ------------------------------------------------------------------------- 00079 * allow a ctrl-c event. 00080 * This flag is used to allow the signal handler to indicate a ctrl-c event. 00081 * If TRUE the signal handler will set \ref cdgCtrlCTrapped, if FALSE it 00082 * will not. 00083 */ 00084 Boolean cdgCtrlCAllowed = FALSE; 00085 00086 /* ------------------------------------------------------------------------- 00087 * xcdg indicator flag. 00088 * If TRUE we're running under XCDG. 00089 */ 00090 Boolean cdgXCDG = FALSE; 00091 00092 /* ------------------------------------------------------------------------- 00093 * time limit in milliseconds used by netsearch, frobbing and gls. 00094 * The value of \c cdgTimeLimit is normaly used to install a timer alarm 00095 * as in \c timerSetAlarm(cdgTimeLimit); 00096 */ 00097 unsigned long cdgTimeLimit = 0; 00098 00099 /* ------------------------------------------------------------------------- 00100 If set, pseudo-umlaut sequences typed into the CDG shell will 00101 be turned into real 8bit umlauts: "a ==> ä 00102 */ 00103 Boolean cdgEncodeUmlauts = FALSE; 00104 00105 /* ------------------------------------------------------------------------- 00106 * user name currently running the \c CDG system. 00107 * On startup the user name is stored into this place and 00108 * propagated to newly computed parses. 00109 */ 00110 String cdgUser = NULL; 00111 00112 Hashtable cdgNets; /**< all existing ConstraintNets */ 00113 Hashtable cdgParses; /**< all existing Parses */ 00114 Hashtable cdgProblems; /**< all existing Problems */ 00115 00116 00117 /* ---------------------------------------------------------------------- */ 00118 /* ---------------------------------------------------------------------- */ 00119 00120 /* ---------------------------------------------------------------------- 00121 * wrapper for strDelete 00122 * This function is our wrapper arround the strDelete() of the blah lib. 00123 * By default this is a NOP, that is: we don't call strDelete(). You might 00124 * switch on the call to strDelete() at compile time, if you are brave enuf 00125 * and wanna help to debug string programming. 00126 */ 00127 void cdgFreeString(String str) 00128 { 00129 #if 0 00130 strDelete(str); 00131 #endif 00132 } 00133 00134 00135 /* ---------------------------------------------------------------------- 00136 * helper function for agInsert. 00137 * This function calls agInsert and emits truncation warnings using 00138 * the cdgPrintf mechanism. 00139 */ 00140 inline void cdgAgInsert(Agenda a, double score, Pointer state) 00141 { 00142 if (!agInsert(a, score, state)) { 00143 if (agVerbosity(a)) { 00144 cdgPrintf(CDG_WARNING, 00145 "WARNING: truncating agenda, result may be incorrect\n"); 00146 } 00147 } 00148 } 00149 00150 /* ---------------------------------------------------------------------- 00151 * system initialization. 00152 * This is the initialization of the root module that initializes all 00153 * other modules containing an initialization callback. It is absolutely 00154 * necessary to call this function before starting to use the \c CDG 00155 * library. In general this is done by the cdgp commandline frontend 00156 * or by the tcl and perl language extension while loading the bindings. 00157 * When finishing the \c CDG library the cousin of this function - cdgFinalize() - 00158 * is to be called. 00159 */ 00160 void cdgInitialize(void) 00161 { 00162 String userId; 00163 struct passwd *pwdLine; 00164 00165 /* initialize the blah library */ 00166 blahInitialize(); 00167 00168 /* force an early readline initialization: 00169 * this is needed cus readline overwrites our locale settings 00170 * the first tine readline() is executed in commandLoop() 00171 */ 00172 rl_initialize(); 00173 00174 /* identify the cdg user */ 00175 #ifdef __USE_XOPEN 00176 userId = cuserid(NULL); 00177 #else 00178 userId = getenv("USER"); 00179 if (userId == NULL) 00180 userId = getenv("LOGNAME"); 00181 #endif 00182 00183 /* test if we could be identified in the system */ 00184 if (userId != NULL) { 00185 pwdLine = getpwnam(userId); 00186 if (pwdLine != NULL) { 00187 cdgUser = strRegister(pwdLine->pw_gecos); 00188 } 00189 } 00190 00191 /* default user */ 00192 if (cdgUser == NULL) { 00193 cdgUser = strRegister("Mac Hine"); 00194 } 00195 endpwent(); 00196 00197 /* initialize modules */ 00198 hkInitialize(); 00199 inputInitialize(); 00200 evalInitialize(); 00201 icInitialize(); 00202 writeInitialize(); 00203 timerInitialize(); 00204 #ifndef DARWIN 00205 comInitialize(); 00206 #endif 00207 nsInitialize(); 00208 cnInitialize(); 00209 statInitialize(); 00210 lgInitialize(); 00211 scInitialize(); 00212 glsInitialize(); 00213 parseInitialize(); 00214 taggerInitialize(); 00215 frobInitialize(); 00216 chunkerInitialize(); 00217 shiftInitialize(); 00218 dbInitialize(); 00219 00220 setRegister("encode-umlauts", SET_BOOL, &cdgEncodeUmlauts, NULL, NULL, NULL, NULL); 00221 setRegister("timelimit", SET_UNSLONG, &cdgTimeLimit, NULL, NULL, NULL, NULL); 00222 00223 cdgNets = 00224 hashNew( 500, 0.8, hashStringHashFunction, hashStringEqualFunction ); 00225 cdgParses = 00226 hashNew( 500, 0.8, hashStringHashFunction, hashStringEqualFunction ); 00227 cdgProblems = 00228 hashNew( 500, 0.8, hashStringHashFunction, hashStringEqualFunction ); 00229 00230 } 00231 00232 /* ---------------------------------------------------------------------- 00233 Delete all existing constraint nets, parses and problems. 00234 00235 This should always be used after changing the constraint grammar in any 00236 way, because there is no guarantee that the previously computed 00237 structures still make sense with the new grammar defnition. A constraint 00238 net might contain an LV that used to be allowed, but is now forbidden by 00239 a unary hard constraint so that it would not have been built at all under 00240 the new regime. Conversely, if the constraint that forbade building a 00241 particular LV were turned off, an existing constraint net would become 00242 incomplete, and solving it could miss a solution that would be possible 00243 under the new conditions. 00244 00245 */ 00246 void cdgDeleteComputed(void) { 00247 00248 List l, m; 00249 00250 /* Notify Tcl. 00251 00252 Tcl keeps annotated versions of core CDG structures, in particular, 00253 graphical representations of Parses. Since this function deletes 00254 the core structures, we have to notify Tcl to remove all dangling 00255 references. 00256 */ 00257 cdgExecHook(HOOK_RESET); 00258 00259 if(hashSize(cdgNets) > 0 || 00260 hashSize(cdgParses) > 0 || 00261 hashSize(cdgProblems) > 0) { 00262 cdgPrintf(CDG_INFO, "INFO: deleting all constraint nets\n"); 00263 } 00264 00265 l = hashListOfKeys(cdgNets); 00266 for(m = l; m != NULL; m = listNext(m)) { 00267 String id = listElement(m); 00268 ConstraintNet net = hashRemove(cdgNets, id); 00269 cnDelete(net); 00270 } 00271 listDelete(m); 00272 00273 l = hashListOfKeys(cdgParses); 00274 for(m = l; m != NULL; m = listNext(m)) { 00275 String id = listElement(m); 00276 Parse p = hashRemove(cdgParses, id); 00277 parseDelete(p); 00278 } 00279 listDelete(m); 00280 00281 l = hashListOfKeys(cdgProblems); 00282 for(m = l; m != NULL; m = listNext(m)) { 00283 String id = listElement(m); 00284 Problem P = hashRemove(cdgProblems, id); 00285 deleteProblem(P); 00286 } 00287 listDelete(m); 00288 00289 cnMostRecentlyCreatedNet = NULL; 00290 parseMostRecentlyCreatedParse = NULL; 00291 inputMostRecentlyCreatedLattice = NULL; 00292 00293 } 00294 00295 00296 /* ---------------------------------------------------------------------- 00297 Execute all #pragma commands seen during last load operation. 00298 00299 The #pragma commands are stored in the input as they are seen during 00300 parsing, but they are not executed until after the load. There are two 00301 reasons for this: 00302 00303 1. a #pragma can refer to structures that are loaded from the same 00304 file as the #pragma -- so executing it immediately would be too early. 00305 00306 2. if a load operation fails, it should not affect the state of the 00307 program at all. 00308 */ 00309 void cdgExecPragmas(List pragmas) { 00310 List l; 00311 String command; 00312 00313 for(l = pragmas; l != NULL; l = listNext(l)) { 00314 command = listElement(l); 00315 commandEval(command); 00316 } 00317 } 00318 00319 00320 /* ---------------------------------------------------------------------- 00321 * finalize the \c CDG library. 00322 * When shutting down the system each module gets the chance to clean 00323 * up things that might be worth it calling their finalization callback. 00324 * Be aware that order of finalization might matter. So the hook module 00325 * gets finalized at last. 00326 */ 00327 void cdgFinalize(void) 00328 { 00329 /* use this define for memory debugging only: 00330 * but be warned that a module which definitely needs finalization 00331 * should not be covered by this ifdef 00332 */ 00333 //#define SERIOUS_FINALIZATION 00334 00335 /* finalize modules */ 00336 writeFinalize(); 00337 00338 #ifdef SERIOUS_FINALIZATION 00339 00340 /* delete any remaining parsing structures */ 00341 cdgDeleteComputed(); 00342 00343 #ifndef DARWIN 00344 comFinalize(); 00345 #endif 00346 inputFinalize(); 00347 evalFinalize(); 00348 parseFinalize(); 00349 frobbingFinalize(); 00350 icFinalize(); 00351 parseFinalize(); 00352 taggerFinalize(); 00353 setFinalize(); 00354 cdgFreeString(cdgUser); 00355 shiftFinalize(); 00356 #endif 00357 00358 dbFinalize(); 00359 /* must be last because cdgPrintf() uses hkHooks! */ 00360 hkFinalize(); 00361 blahFinalize(); 00362 } 00363 00364 /* ---------------------------------------------------------------------- */ 00365 /* ---------------------------------------------------------------------- */ 00366 /** @} */