funcadd.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  1. /****************************************************************
  2. Copyright (C) 1997-2001 Lucent Technologies
  3. All Rights Reserved
  4. Permission to use, copy, modify, and distribute this software and
  5. its documentation for any purpose and without fee is hereby
  6. granted, provided that the above copyright notice appear in all
  7. copies and that both that the copyright notice and this
  8. permission notice and warranty disclaimer appear in supporting
  9. documentation, and that the name of Lucent or any of its entities
  10. not be used in advertising or publicity pertaining to
  11. distribution of the software without specific, written prior
  12. permission.
  13. LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  14. INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
  15. IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
  16. SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  17. WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
  18. IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  19. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
  20. THIS SOFTWARE.
  21. ****************************************************************/
  22. #ifndef FUNCADD_H_INCLUDED
  23. #define FUNCADD_H_INCLUDED
  24. #include "stdio1.h" /* for ANSI and any printing */
  25. #ifndef VA_LIST
  26. #define VA_LIST va_list
  27. #endif
  28. #ifdef _WIN32
  29. #define Stdio_redefs
  30. #endif
  31. typedef struct cryptblock cryptblock;
  32. #ifdef __cplusplus
  33. #undef KR_headers
  34. extern "C" {
  35. #endif
  36. #ifndef real
  37. typedef double real;
  38. #endif
  39. typedef struct arglist arglist;
  40. typedef struct function function;
  41. typedef struct TVA TVA;
  42. typedef struct AmplExports AmplExports;
  43. typedef struct AuxInfo AuxInfo;
  44. typedef struct TableInfo TableInfo;
  45. typedef struct TMInfo TMInfo;
  46. #ifndef No_arglist_def
  47. #undef Const
  48. #ifdef KR_headers
  49. #define Const /* nothing */
  50. #else
  51. #define Const const
  52. #endif
  53. struct
  54. arglist { /* Information sent to user-defined functions */
  55. int n; /* number of args */
  56. int nr; /* number of real input args */
  57. int *at; /* argument types -- see DISCUSSION below */
  58. real *ra; /* pure real args (IN, OUT, and INOUT) */
  59. Const char **sa; /* symbolic IN args */
  60. real *derivs; /* for partial derivatives (if nonzero) */
  61. real *hes; /* for second partials (if nonzero) */
  62. char *dig; /* if (dig && dig[i]) { partials w.r.t. */
  63. /* ra[i] will not be used } */
  64. Char *funcinfo; /* for use by the function (if desired) */
  65. AmplExports *AE; /* functions made visible (via #defines below) */
  66. function *f; /* for internal use by AMPL */
  67. TVA *tva; /* for internal use by AMPL */
  68. char *Errmsg; /* to indicate an error, set this to a */
  69. /* description of the error */
  70. TMInfo *TMI; /* used in Tempmem calls */
  71. Char *Private;
  72. /* The following fields are relevant */
  73. /* only when imported functions are called */
  74. /* by AMPL commands (not declarations). */
  75. int nin; /* number of input (IN and INOUT) args */
  76. int nout; /* number of output (OUT and INOUT) args */
  77. int nsin; /* number of symbolic input arguments */
  78. int nsout; /* number of symbolic OUT and INOUT args */
  79. };
  80. typedef real (*rfunc) ANSI((arglist *));
  81. typedef real (ufunc) ANSI((arglist *));
  82. #endif /* No_arglist_def */
  83. enum AMPLFUNC_AT_BITS { /* Intrepretation of at[i] when the type */
  84. /* arg to addfunc has the */
  85. /* FUNCADD_OUTPUT_ARGS bit on.*/
  86. AMPLFUNC_INARG = 1, /* IN or INOUT */
  87. AMPLFUNC_OUTARG = 2, /* OUT or INOUT */
  88. AMPLFUNC_STRING = 4, /* Input value is a string (sa[i]) */
  89. AMPLFUNC_STROUT = 8 /* String output value allowed */
  90. };
  91. enum FUNCADD_TYPE { /* bits in "type" arg to addfunc */
  92. /* The type arg to addfunc should consist of one of the */
  93. /* following values ... */
  94. FUNCADD_REAL_VALUED = 0, /* real (double) valued function */
  95. FUNCADD_STRING_VALUED = 2, /* char* valued function (AMPL only) */
  96. FUNCADD_RANDOM_VALUED = 4, /* real random valued */
  97. FUNCADD_012ARGS = 6, /* Special case: real random valued */
  98. /* with 0 <= nargs <= 2 arguments */
  99. /* passed directly, rather than in */
  100. /* an arglist structure (AMPL only). */
  101. /* possibly or-ed with the following... */
  102. FUNCADD_STRING_ARGS = 1, /* allow string args */
  103. FUNCADD_OUTPUT_ARGS = 16, /* allow output args (AMPL only) */
  104. FUNCADD_TUPLE_VALUED = 32, /* not yet allowed */
  105. /* internal use */
  106. FUNCADD_NO_ARGLIST = 8,
  107. FUNCADD_NO_DUPWARN = 64, /* no complaint if already defined */
  108. FUNCADD_NONRAND_BUILTIN = 128 /* mean, variance, moment, etc. */
  109. };
  110. /* If a constraint involves an imported function and presolve fixes all
  111. * the arguments of the function, AMPL may later need to ask the
  112. * function for its partial derivatives -- even though the solver had
  113. * no reason to call the function. If so, it will pass an arglist *al
  114. * with al->derivs nonzero, and it will expect the function to set
  115. * al->derivs[i] to the partial derivative of the function with respect
  116. * to al->ra[i]. Solvers that need to evaluate an imported function
  117. * work the same way -- they set al->derivs to a nonzero value if they
  118. * require both the function value and its first derivatives. Solvers
  119. * that expect Hessians to be supplied to them also set al->hes to a
  120. * nonzero value if they require second derivatives at the current
  121. * argument. In this case, the function should set
  122. * al->hes[i + j*(j+1)/2] to the partial derivative of the function with
  123. * respect to al->ra[i] and al->ra[j] for all 0 <= i <= j < al->nr.
  124. */
  125. typedef void AddFunc ANSI((
  126. const char *name,
  127. rfunc f, /* cast f to (rfunc) if it returns char* */
  128. int type, /* see FUNCADD_TYPE above */
  129. int nargs, /* >= 0 ==> exactly that many args
  130. * <= -1 ==> at least -(nargs+1) args
  131. */
  132. void *funcinfo, /* for use by the function (if desired) */
  133. AmplExports *ae
  134. ));
  135. typedef void AddRand ANSI((
  136. const char *name,
  137. rfunc f, /* assumed to be a random function */
  138. rfunc icdf, /* inverse CDF */
  139. int type, /* FUNCADD_STRING_ARGS or 0 */
  140. int nargs, /* >= 0 ==> exactly that many args
  141. * <= -1 ==> at least -(nargs+1) args
  142. */
  143. void *funcinfo, /* for use by the function (if desired) */
  144. AmplExports *ae
  145. ));
  146. typedef void (*RandSeedSetter) ANSI((void*, unsigned long));
  147. typedef void AddRandInit ANSI((AmplExports *ae, RandSeedSetter, void*));
  148. typedef void Exitfunc ANSI((void*));
  149. struct
  150. AuxInfo {
  151. AuxInfo *next;
  152. char *auxname;
  153. void *v;
  154. void (*f) ANSI((AmplExports*, void*, ...));
  155. };
  156. struct
  157. AmplExports {
  158. FILE *StdErr;
  159. AddFunc *Addfunc;
  160. long ASLdate;
  161. int (*FprintF) ANSI((FILE*, const char*, ...));
  162. int (*PrintF) ANSI((const char*, ...));
  163. int (*SprintF) ANSI((char*, const char*, ...));
  164. int (*VfprintF) ANSI((FILE*, const char*, VA_LIST));
  165. int (*VsprintF) ANSI((char*, const char*, VA_LIST));
  166. double (*Strtod) ANSI((const char*, char**));
  167. cryptblock *(*Crypto) ANSI((char *key, size_t scrbytes));
  168. Char *asl;
  169. void (*AtExit) ANSI((AmplExports *ae, Exitfunc*, void*));
  170. void (*AtReset) ANSI((AmplExports *ae, Exitfunc*, void*));
  171. Char *(*Tempmem) ANSI((TMInfo*, size_t));
  172. void (*Add_table_handler) ANSI((
  173. int (*DbRead) (AmplExports *ae, TableInfo *TI),
  174. int (*DbWrite)(AmplExports *ae, TableInfo *TI),
  175. char *handler_info,
  176. int flags,
  177. void *Vinfo
  178. ));
  179. Char *Private;
  180. void (*Qsortv) ANSI((void*, size_t, size_t, int(*)(const void*,const void*,void*), void*));
  181. /* More stuff for stdio in DLLs... */
  182. FILE *StdIn;
  183. FILE *StdOut;
  184. void (*Clearerr) ANSI((FILE*));
  185. int (*Fclose) ANSI((FILE*));
  186. FILE* (*Fdopen) ANSI((int, const char*));
  187. int (*Feof) ANSI((FILE*));
  188. int (*Ferror) ANSI((FILE*));
  189. int (*Fflush) ANSI((FILE*));
  190. int (*Fgetc) ANSI((FILE*));
  191. char* (*Fgets) ANSI((char*, int, FILE*));
  192. int (*Fileno) ANSI((FILE*));
  193. FILE* (*Fopen) ANSI((const char*, const char*));
  194. int (*Fputc) ANSI((int, FILE*));
  195. int (*Fputs) ANSI((const char*, FILE*));
  196. size_t (*Fread) ANSI((void*, size_t, size_t, FILE*));
  197. FILE* (*Freopen) ANSI((const char*, const char*, FILE*));
  198. int (*Fscanf) ANSI((FILE*, const char*, ...));
  199. int (*Fseek) ANSI((FILE*, long, int));
  200. long (*Ftell) ANSI((FILE*));
  201. size_t (*Fwrite) ANSI((const void*, size_t, size_t, FILE*));
  202. int (*Pclose) ANSI((FILE*));
  203. void (*Perror) ANSI((const char*));
  204. FILE* (*Popen) ANSI((const char*, const char*));
  205. int (*Puts) ANSI((const char*));
  206. void (*Rewind) ANSI((FILE*));
  207. int (*Scanf) ANSI((const char*, ...));
  208. void (*Setbuf) ANSI((FILE*, char*));
  209. int (*Setvbuf) ANSI((FILE*, char*, int, size_t));
  210. int (*Sscanf) ANSI((const char*, const char*, ...));
  211. char* (*Tempnam) ANSI((const char*, const char*));
  212. FILE* (*Tmpfile) ANSI((void));
  213. char* (*Tmpnam) ANSI((char*));
  214. int (*Ungetc) ANSI((int, FILE*));
  215. AuxInfo *AI;
  216. char* (*Getenv) ANSI((const char*));
  217. void (*Breakfunc) ANSI((int,void*));
  218. Char *Breakarg;
  219. /* Items available with ASLdate >= 20020501 start here. */
  220. int (*SnprintF) ANSI((char*, size_t, const char*, ...));
  221. int (*VsnprintF) ANSI((char*, size_t, const char*, VA_LIST));
  222. AddRand *Addrand; /* for random function/inverse CDF pairs */
  223. AddRandInit *Addrandinit; /* for adding a function to receive a new random seed */
  224. };
  225. extern const char *i_option_ASL, *ix_details_ASL[];
  226. #define funcadd funcadd_ASL
  227. #ifdef _WIN32
  228. __declspec(dllexport)
  229. #endif
  230. extern void funcadd ANSI((AmplExports*)); /* dynamically linked */
  231. extern void af_libnamesave_ASL ANSI((AmplExports*, const char *fullname, const char *name, int nlen));
  232. extern void note_libuse_ASL ANSI((void)); /* If funcadd() does not provide any imported */
  233. /* functions, it can call note_libuse_ASL() to */
  234. /* keep the library loaded; note_libuse_ASL() is */
  235. /* called, e.g., by the tableproxy table handler. */
  236. #ifdef __cplusplus
  237. }
  238. #endif
  239. typedef struct
  240. DbCol {
  241. real *dval;
  242. char **sval;
  243. } DbCol;
  244. struct
  245. TableInfo {
  246. int (*AddRows) ANSI((TableInfo *TI, DbCol *cols, long nrows));
  247. char *tname; /* name of this table */
  248. char **strings;
  249. char **colnames;
  250. DbCol *cols;
  251. char *Missing;
  252. char *Errmsg;
  253. void *Vinfo;
  254. TMInfo *TMI;
  255. int nstrings;
  256. int arity;
  257. int ncols;
  258. int flags;
  259. long nrows;
  260. void *Private;
  261. int (*Lookup) ANSI((real*, char**, TableInfo*));
  262. long (*AdjustMaxrows) ANSI((TableInfo*, long new_maxrows));
  263. void *(*ColAlloc) ANSI((TableInfo*, int ncol, int sval));
  264. long maxrows;
  265. };
  266. enum { /* return values from (*DbRead)(...) and (*DbWrite)(...) */
  267. DB_Done = 0, /* Table read or written. */
  268. DB_Refuse = 1, /* Refuse to handle this table. */
  269. DB_Error = 2 /* Error reading or writing table. */
  270. };
  271. enum { /* bits in flags field of TableInfo */
  272. DBTI_flags_IN = 1, /* table has IN or INOUT entities */
  273. DBTI_flags_OUT = 2, /* table has OUT or INOUT entities */
  274. DBTI_flags_INSET = 4 /* table has "in set" phrase: */
  275. /* DbRead could omit rows for */
  276. /* which Lookup(...) == -1; AMPL */
  277. /* will ignore such rows if DbRead */
  278. /* offers them. */
  279. };
  280. #endif /* FUNCADD_H_INCLUDED */
  281. #ifndef No_AE_redefs
  282. /* Assume "{extern|static} AmplExports *ae;" is given elsewhere. */
  283. #undef Stderr
  284. #undef addfunc
  285. #undef fprintf
  286. #undef getenv
  287. #undef printf
  288. #undef sprintf
  289. #undef snprintf
  290. #undef strtod
  291. #undef vfprintf
  292. #undef vsprintf
  293. #undef vsnprintf
  294. #define Stderr (ae->StdErr)
  295. #define addfunc(a,b,c,d,e) (*ae->Addfunc)(a,b,c,d,e,ae)
  296. #define addrand(a,b,c,d,e,f) (*ae->Addrand)(a,b,c,d,e,f,ae)
  297. #define addrandinit(a,b) (*ae->Addrandinit)(ae,a,b)
  298. #define printf (*ae->PrintF)
  299. #define fprintf (*ae->FprintF)
  300. #define snprintf (*ae->SnprintF)
  301. #define sprintf (*ae->SprintF)
  302. #define strtod (*ae->Strtod)
  303. #define vfprintf (*ae->VfprintF)
  304. #define vsprintf (*ae->VsprintF)
  305. #define vsnprintf (*ae->VsnprintF)
  306. #define TempMem(x,y) (*ae->Tempmem)(x,y)
  307. #define at_exit(x,y) (*ae->AtExit)(ae,x,y)
  308. #define at_reset(x,y) (*ae->AtReset)(ae,x,y)
  309. #define add_table_handler(a,b,c,d,e) (*ae->Add_table_handler)(a,b,c,d,e)
  310. #define qsortv(a,b,c,d,e) (*ae->Qsortv)(a,b,c,d,e)
  311. #define getenv(x) (*ae->Getenv)(x)
  312. #ifdef Stdio_redefs
  313. #undef clearerr
  314. #undef fclose
  315. #undef fdopen
  316. #undef feof
  317. #undef ferror
  318. #undef fflush
  319. #undef fgetc
  320. #undef fgets
  321. #undef fileno
  322. #undef fopen
  323. #undef fputc
  324. #undef fputs
  325. #undef fread
  326. #undef freopen
  327. #undef fscanf
  328. #undef fseek
  329. #undef ftell
  330. #undef fwrite
  331. #undef getc
  332. #undef getchar
  333. #undef gets
  334. #undef pclose
  335. #undef perror
  336. #undef popen
  337. #undef putc
  338. #undef putchar
  339. #undef puts
  340. #undef rewind
  341. #undef scanf
  342. #undef setbuf
  343. #undef setvbuf
  344. #undef sscanf
  345. #undef tempnam
  346. #undef tmpfile
  347. #undef tmpnam
  348. #undef ungetc
  349. #undef vprintf
  350. #define clearerr (*ae->Clearerr)
  351. #define fclose (*ae->Fclose)
  352. #define fdopen (*ae->Fdopen)
  353. #define feof (*ae->Feof)
  354. #define ferror (*ae->Ferror)
  355. #define fflush (*ae->Fflush)
  356. #define fgetc (*ae->Fgetc)
  357. #define fgets (*ae->Fgets)
  358. #define fileno (*ae->Fileno)
  359. #define fopen (*ae->Fopen)
  360. #define fputc (*ae->Fputc)
  361. #define fputs (*ae->Fputs)
  362. #define fread (*ae->Fread)
  363. #define freopen (*ae->Freopen)
  364. #define fscanf (*ae->Fscanf)
  365. #define fseek (*ae->Fseek)
  366. #define ftell (*ae->Ftell)
  367. #define fwrite (*ae->Fwrite)
  368. #define getc (*ae->Fgetc)
  369. #define getchar() (*ae->Getc)(ae->StdIn)
  370. #define gets Error - use "fgets" rather than "gets"
  371. #define pclose (*ae->Pclose)
  372. #define perror (*ae->Perror)
  373. #define popen (*ae->Popen)
  374. #define putc (*ae->Fputc)
  375. #define putchar(x) (*ae->Fputc)(ae->StdOut,(x))
  376. #define puts (*ae->Puts)
  377. #define rewind (*ae->Rewind)
  378. #define scanf (*ae->Scanf)
  379. #define setbuf (*ae->Setbuf)
  380. #define setvbuf (*ae->Setvbuf)
  381. #define sscanf (*ae->Sscanf)
  382. #define tempnam (*ae->Tempnam)
  383. #define tmpfile (*ae->Tmpfile)
  384. #define tmpnam (*ae->Tmpnam)
  385. #define ungetc (*ae->Ungetc)
  386. #define vprintf(x,y) (*ae->VfprintF)(ae->StdOut,(x),(y))
  387. #define Stdin (ae->StdIn)
  388. #define Stdout (ae->StdOut)
  389. #ifndef No_std_FILE_redefs /* may elicit compiler warnings */
  390. #undef stdin
  391. #undef stdout
  392. #undef stderr
  393. #define stdin (ae->StdIn)
  394. #define stdout (ae->StdOut)
  395. #define stderr (ae->StdErr)
  396. #endif /* No_std_FILE_redefs */
  397. #endif /* Stdio_redefs */
  398. #endif /* ifndef No_AE_redefs */
  399. /* DISCUSSION: the "at" field of an arglist...
  400. *
  401. * OUT and INOUT arguments are only permitted in AMPL commands,
  402. * such as "let" and "call" commands (and not in declarations, e.g.,
  403. * of constraints and variables).
  404. *
  405. * When addfunc was called with type <= 6 (so there can be no OUT or
  406. * INOUT arguments), for 0 <= i < n,
  407. * at[i] >= 0 ==> arg i is ra[at[i]]
  408. * at[i] < 0 ==> arg i is sa[-(at[i]+1)].
  409. *
  410. * When addfunc was called with type & FUNCADD_OUTPUT_ARGS on (permitting
  411. * OUT and INOUT arguments), arg i is in ra[i] or sa[i] (as explained
  412. * below), derivs and hes are both null, and at[i] is the union of bits
  413. * that describe arg i:
  414. * AMPLFUNC_INARG = 1 ==> input arg;
  415. * AMPLFUNC_OUTARG = 2 ==> output arg;
  416. * AMPLFUNC_STROUT = 4 ==> can be assigned a string value.
  417. *
  418. * INOUT args have both the AMPLFUNC_INARG and the AMPLFUNC_OUTARG bits
  419. * are on, i.e., (at[i] & 3) == 3.
  420. *
  421. * Symbolic OUT and INOUT arguments are a bit complicated. They can only
  422. * correspond to symbolic parameters in AMPL, which may have either a
  423. * string or a numeric value. Thus there is provision for specifying
  424. * output values to be either numbers or strings. For simplicity, when
  425. * the function accepts output arguments, ra[i] and sa[i] together describe
  426. * argument i. In general (whentype & FUNCADD_OUTPUT_ARGS is nonzero in
  427. * the addfunc call), the incoming value of argument i is ra[i]
  428. * (a numeric value) if sa[i] is null and is otherwise sa[i].
  429. * To assign a value to argument i, either assign a numeric value to
  430. * ra[i] and set sa[i] = 0, or assign a non-null value to sa[i]
  431. * (in which case ra[i] will be ignored). A value assigned to argument
  432. * i is ignored unless at[i] & AMPLFUNC_OUTARG is nonzero; if so
  433. * and if (at[i] & AMPLFUNC_STROUT) == 0, string values cause an error
  434. * message.
  435. */