aboutsummaryrefslogtreecommitdiff
path: root/ic-reals-6.3/save-real.h
blob: 572b2d7a0192fe3cee5b66c0e8de5086e510f99e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
/*
 * Copyright (C) 2000, Imperial College
 *
 * This file is part of the Imperial College Exact Real Arithmetic Library.
 * See the copyright notice included in the distribution for conditions
 * of use.
 */

/*
 * This is the include for all applications using reals. It defines all
 * the types the user sees, principally Real and Bool, and the prototypes
 * functions which operate on these types.
 *
 * It also defines the various types of objects in the heap. Each is a
 * structure, the first word of which is a tag, containing amongst other
 * things a code to identify the type of object.
 */

#include <gmp.h>

typedef union _Real * Real;
typedef union _Bool * Bool;

/*
 * Each object in the heap is assigned one of the following codes.
 */
typedef enum {
	ALT,		/* selects amongst boolean guarded expressions */
	VECTOR,		/* a vector (ie rational) */
	MATX,		/* a matrix (the X reflects that there is one argument) */
	TENXY,		/* a tensor (with two arguments) */
	DIGSX,		/* a string or sequence of digits */
	SIGNX,		/* this holds one of the sign values */
	CLOSURE,	/* usually used to lazily produce futher lfts in expressions */
	BOOLX,		/* propositional operator with one argument, eg negation */
	BOOLXY,		/* operator with two arguments, eg conjunction */
	PREDX		/* predicate over reals with one argument, eg x > 0 */
} ObjType;

typedef enum {FALSE = 0, TRUE = 1} bool;
typedef enum {LT = -1, EQ = 0, GT = 1} Comparison;

/*
 * The first word of each structure in the heap is a tag word defined
 * below. 
 */
typedef struct {
	unsigned type : 4;		/* an ObjType as defined above */
	unsigned dumped : 1;	/* for traversing recursively when printing */
	unsigned value : 3;		/* sign or boolean value */
	unsigned isSigned : 1;	/* true when a real must be signed */
	unsigned nodeId : 21;	/* each node has a unique id for debugging */
} Tag;

/*
 * The next segment of the file defines the structures and constants
 * dealing with reals.
 */

/*
 * Next we define the possible sign constant which includes a constant 
 * indicating that the sign is unknown.
 * The order of the entries in the enum which follows is significant. It
 * reflects our preference for SZERO. However, note that changing the order of
 * the constants below is not sufficient to change the preference. One
 * must also modify emitSign.c.
 */
typedef enum {SZERO, SINF, SPOS, SNEG, SIGN_UNKN} Sign;
typedef enum {DPOS = 1, DNEG = -1, DZERO = 0} Digit;

/*
 * We define the LFTS: vector, matrix and tensor. There are two
 * varieties of each: one in which the entries are machine sized integers
 * and the other in which the entries are GMP large integers.
 *
 * Vectors, matrices and tensors are arrays rather than structs. That
 * way they have size and yet are passed as pointers (lvalues). This
 * avoids some referencing and dereferencing. It turns out to be more
 * convenient to define tensors as arrays of vectors rather than pairs
 * of matrices since often we need to pull out columns without respecting
 * matrix boundaries.
 */
typedef mpz_t Vector[2];
typedef Vector Matrix[2];
typedef Vector Tensor[4];

typedef int SmallVector[2];
typedef SmallVector SmallMatrix[2];
typedef SmallVector SmallTensor[4];

typedef union {
	Vector Vec;
	Matrix Mat;
	Tensor Ten;
} LFT;

/*
 * This defines the fields which are common to all real continuations.
 */
typedef struct {
	Tag tag;
} Generic;

typedef struct {
	Bool guard;
	Real x;
} GuardedExpr;

typedef struct {
	Tag tag;
	void (*force)();	/* is this needed ? */
	Real redirect;		/* this is the ultimate value of the conditional */
	int nextGE;			/* index of next guarded expression to force */
	int numGE;			/* number of guarded expressions in the list */
	GuardedExpr *GE;	/* the list of guarded expressions */
} Alt;

/*
 * The x field below is the alternative representation of the real the 
 * Closure denotes. That is, when the closure is forced, it struct points
 * to the object it unfolds to. That way, any subsequent request to the
 * closure, won't force a second distinct unfolding.
 */
typedef struct {
	Tag tag;
	void (*force)();
	void *userData;
	Real redirect;	
} Cls;

/*
Heap elements which hold lfts have a strm field. This hold a real stream 
(ie a list of DigsX structures possibly prefixed by a SignX). This real 
denotes the same value as the expression rooted by the lft. In some cases
having both representations is necessary. For top level vectors and matrices,
having the stream representation allows us to extract information from
the lft when demanded for printing. At the same time, the vectors and
matrices are still available should they become the argument of another
lft whereupon we want to reduce. The strm field is used by tensors since
reduction against a tensor argument is not possible and we must emit
imformation. However, it is sometimes not possible to create the stream
in advance. If the tensor has an argument guarded by an alt, then the alt
might eventually reduce to a vector and the tensor reduce to a matrix.
*/
 
typedef struct {
	Tag tag;
	void (*force)();
	Real strm;
	Vector vec;
} Vec;

typedef struct {
	Tag tag;
	void (*force)();
	Real strm;
	Real x;
	int totalEmitted;
	Matrix mat;
} MatX;

typedef struct {
	Tag tag;
	void (*forceX)();
	void (*forceY)();
	Real strm;
	Real x;
	Real y;
	signed short totalEmitted;
	signed short tensorFairness; /* counts left vs right absorptions */
	int xDigitsNeeded;
	Tensor ten;
} TenXY;

typedef struct {
	Tag tag;
	void (*force)();
	Real x;
} SignX;

/*
 * Sequences of digits are represented by ``characteristic pairs''. 
 * This is a pair of integers (n,c) in which c is the coding of
 * n digits. When n <= DIGITS_PER_WORD, then c can be represented in a
 * machine word. Otherwise we need a big integer.
 *
 * Below we use the value 30. In fact it is possible to use 31. The problem
 * is that we need DIGITS_PER_WORD + 1 bits when we form a matrix.
 * Setting it to 30 ensures that it always yields a matrix which fits
 * into a signed machine word.
 */
#define DIGITS_PER_WORD 29

typedef struct _DigsX {
	Tag tag;
	void (*force)();
	Real x;
	unsigned count;
	union {
		int small;
		mpz_t big;
	} word;
} DigsX;

union _Real {
	Generic gen;
	Alt alt;
	Vec vec;
	SignX signX;
	MatX matX;
	DigsX digsX;
	TenXY tenXY;
	Cls cls;
};

/*
 * The next segment of the file defines the structures and constants
 * dealing with the lazy boolean type.
 *
 * I'm not very happy with the names of things here. There is too much
 * overloading of the term bool (in both upper and lower case).
 *
 * bool : this is the usual booleans (two-valued) and used internally
 *        instead of int (and 0/1) simply as a matter of style.
 * BoolVal : this is three valued boolean type
 * Bool : this is the lazy boolean type which takes on values from BoolVal.
 *        The type is a union of the various heap allocated structures
 *        relevant to lazy booleans.
 */
typedef enum {LAZY_TRUE, LAZY_FALSE, LAZY_UNKNOWN} BoolVal;

/*
 * This is the constant to flag the default case in the realAlt function.
 * The second of these is for backwards compatibility.
 */
#define DEFAULT_GUARD ((unsigned) 0xffffffffL)
#define B_DEFAULT (DEFAULT_GUARD)

typedef struct {
	Tag tag;
	void (*force)();
	Real x;
} PredX;

typedef struct {
	Tag tag;
	void (*force)();
	Bool x;
} BoolX;

typedef struct {
	Tag tag;
	void (*force)();
	Bool x;
	Bool y;
} BoolXY;

union _Bool {
	struct {
		Tag tag;
		void (*force)();
	} gen;
	BoolX boolX;
	BoolXY boolXY;
	PredX predX;
};

void initReals();

Real consCN(Real, char *, int, int, int);

void dumpReal(Real);
void dumpBool(Bool);
void dumpCell(void *);

/*
 * An application can set the following string to the name of the 
 * application, typically argv[0].
 */
extern char *MyName;
 
void force_R_Dec(Real, int);
void force_R_Digs(Real, int);

void print_R_Dec(Real, int);
void print_R_Digs(Real, int);

void print_R(Real);

double realToDouble(Real);

/*
 * Basic LFT creation. This list includes the preferred names (real_*, lft_*)
 * and the older names which may disappear in a future release.
 */
Real real_QInt(int, int);
Real real_QZ(mpz_t, mpz_t);

Real lft_R_Int(Real, int, int, int, int);
Real lft_R_Z(Real, mpz_t, mpz_t, mpz_t, mpz_t);

Real lft_R_R_Int(Real, Real, int, int, int, int, int, int, int, int);
Real lft_R_R_Z(Real, Real, mpz_t, mpz_t, mpz_t, mpz_t,
                           mpz_t, mpz_t, mpz_t, mpz_t);

Real vector_Int(int, int);
Real vector_Z(mpz_t, mpz_t);

Real matrix_Int(Real, int, int, int, int);
Real matrix_Z(Real, mpz_t, mpz_t, mpz_t, mpz_t);

Real tensor_Int(Real, Real, int, int, int, int, int, int, int, int);
Real tensor_Z(Real, Real, mpz_t, mpz_t, mpz_t, mpz_t,
                          mpz_t, mpz_t, mpz_t, mpz_t);

Real makeStream(Real);

/*
 * Basic arithmetic functions
 */
Real add_R_R(Real, Real);
Real add_R_Int(Real, int);
Real add_R_QInt(Real, int, int);
Real add_R_QZ(Real, mpz_t, mpz_t);

Real sub_R_R(Real, Real);
Real sub_R_Int(Real, int);
Real sub_R_QInt(Real, int, int);
Real sub_Int_R(int, Real);
Real sub_QInt_R(int, int, Real);

Real mul_R_R(Real, Real);
Real mul_R_Int(Real, int);
Real mul_R_QInt(Real, int, int);
Real mul_R_QZ(Real, mpz_t, mpz_t);

Real div_R_R(Real, Real);
Real div_R_Int(Real, int);
Real div_R_QInt(Real, int, int);
Real div_Int_R(int, Real);
Real div_QInt_R(int, int, Real);

Real pow_R_R(Real, Real);

Real abs_R(Real);

Real neg_R(Real);

/*
 * Analytic functions
 */
Real tan_R(Real);
Real tan_QZ(mpz_t, mpz_t);
Real tan_QInt(int, int);

Real atan_R(Real);
Real atan_QZ(mpz_t, mpz_t);
Real atan_QInt(int, int);

Real tanh_R(Real);
Real tanh_QZ(mpz_t, mpz_t);
Real tanh_QInt(int, int);

Real atanh_R(Real);
Real atanh_QZ(mpz_t, mpz_t);
Real atanh_QInt(int, int);

Real sin_R(Real);
Real sin_QZ(mpz_t, mpz_t);
Real sin_QInt(int, int);

Real asin_R(Real);
Real asin_QZ(mpz_t, mpz_t);
Real asin_QInt(int, int);

Real sinh_R(Real);
Real sinh_QZ(mpz_t, mpz_t);
Real sinh_QInt(int, int);

Real asinh_R(Real);
Real asinh_QZ(mpz_t, mpz_t);
Real asinh_QInt(int, int);

Real cos_R(Real);
Real cos_QZ(mpz_t, mpz_t);
Real cos_QInt(int, int);

Real acos_R(Real);
Real acos_QZ(mpz_t, mpz_t);
Real acos_QInt(int, int);

Real cosh_R(Real);
Real cosh_QZ(mpz_t, mpz_t);
Real cosh_QInt(int, int);

Real acosh_R(Real);
Real acosh_QZ(mpz_t, mpz_t);
Real acosh_QInt(int, int);

Real sec_R(Real);
Real sec_QInt(int, int);
Real sec_QZ(mpz_t, mpz_t);

Real asec_R(Real);
Real asec_QInt(int, int);
Real asec_QZ(mpz_t, mpz_t);

Real sech_R(Real);
Real sech_QInt(int, int);
Real sech_QZ(mpz_t, mpz_t);

Real asech_R(Real);
Real asech_QInt(int, int);
Real asech_QZ(mpz_t, mpz_t);

Real cosec_R(Real);
Real cosec_QInt(int, int);
Real cosec_QZ(mpz_t, mpz_t);

Real acosec_R(Real);
Real acosec_QInt(int, int);
Real acosec_QZ(mpz_t, mpz_t);

Real cosech_R(Real);
Real cosech_QInt(int, int);
Real cosech_QZ(mpz_t, mpz_t);

Real acosech_R(Real);
Real acosech_QInt(int, int);
Real acosech_QZ(mpz_t, mpz_t);

Real cotan_R(Real);
Real cotan_QInt(int, int);
Real cotan_QZ(mpz_t, mpz_t);

Real acotan_R(Real);
Real acotan_QInt(int, int);
Real acotan_QZ(mpz_t, mpz_t);

Real cotanh_R(Real);
Real cotanh_QInt(int, int);
Real cotanh_QZ(mpz_t, mpz_t);

Real acotanh_R(Real);
Real acotanh_QInt(int, int);
Real acotanh_QZ(mpz_t, mpz_t);

Real Pi;
Real E;

Real sqrt_R(Real);
Real sqrt_QZ(mpz_t, mpz_t);
Real sqrt_QInt(int, int);

Real exp_R(Real);
Real exp_QZ(mpz_t, mpz_t);
Real exp_QInt(int, int);

Real log_R(Real);
Real log_QZ(mpz_t, mpz_t);
Real log_QInt(int, int);

/*
 * Predicates, boolean operators and the conditional.
 */
Bool ltEq_R_0(Real);
Bool lt_R_0(Real);

Bool lt_R_R(Real, Real);
Bool ltEq_R_R(Real, Real);

Bool ltEq_R_QInt(Real, int, int);
Bool lt_R_QInt(Real, int, int);

Bool gtEq_R_0(Real);
Bool gt_R_0(Real);

Bool gtEq_R_QInt(Real, int, int);
Bool gt_R_QInt(Real, int, int);

Bool gt_R_R(Real, Real);
Bool gtEq_R_R(Real, Real);

Bool and_B_B(Bool, Bool);
Bool or_B_B(Bool, Bool);
Bool not_B(Bool);

/* BoolVal boolValue(Bool b) */

#define boolValue(b) ((b)->gen.tag.value)

Real realIf(int, ...);
Real realError(char *);

typedef void * Delay_Arg;
typedef Real (*Delay_Fun)(Delay_Arg);

char *digitToString(Digit);
char *signToString(Sign);

void retrieveInfo(Real, Sign *, int *, mpz_t);
Digit takeDigit(int *, mpz_t);