Next: , Previous: , Up: Top   [Contents][Index]


5 CALIB General Representation

CALIB provides a general representation (or “genrep” for short) that can hold any type of symbolic expression handled by CALIB. One may access CALIB’s genrep facilities as follows:

	#include "calib/genrep.h"

For example, it is possible to read a symbolic expression from a text file yielding the corresponding generep gp, which can then be converted into a value in various other CALIB algebraic domains. Similarly, each CALIB algebraic domain D provides the ability to convert a given value of D into genrep form.

CALIB provides various functions to “pretty print” expressions in genrep form, and print them to files in various syntaxes.

The general representation is therefore the “common format” by which the various CALIB algebraic domains communicate with the outside world. Other than the various expression parsers, printers, pretty-printers and functions to construct/destruct various flavors of primitive genrep objects, no substantive “algebraic algorithms” (beyond a few simplifications) are provided for expressions in the genrep form. The general representation is primarily a communication medium between the various parts of CALIB.

The general representation consists of several types of objects, as follows:

struct calib_genrep {
	char	op;	/* Operator. */
	union {
		struct calib_genrep_list *	list;	/* List of operand subexprs */
		char *				var;	/* Variable */
		calib_si_t			siop;	/* Signed integer */
		mpz_ptr				zop;	/* Integer operand */
		mpq_ptr				qop;	/* Rational operand */
		struct {
			struct calib_genrep *	base;
			int			power;
		} ipow;
		struct {
			struct calib_genrep *		func;
			struct calib_genrep_list *	args;
		} func;
	} u;
};

struct calib_genrep_list {
	struct calib_genrep *		operand;	/* Current operand */
	struct calib_genrep_list *	next;		/* List of other operands */
};

The genrep op field has one of the following symbolic values (#define’d in calib/genrep.h):

	CALIB_GENREP_OP_ADD	/* sum of zero or more genreps */
	CALIB_GENREP_OP_MUL	/* product of zero or more genreps */
	CALIB_GENREP_OP_IPOW	/* integer power of a genrep */
	CALIB_GENREP_OP_VAR	/* a single variable */
	CALIB_GENREP_OP_SI	/* a signed integer */
	CALIB_GENREP_OP_Z	/* a GMP integer */
	CALIB_GENREP_OP_Q	/* a GMP rational */
	CALIB_GENREP_OP_FUNC	/* a function invocation */

The u.list member is used for sums and products, which each permit a linked-list of zero or more sub-operand genreps.

One additional structure is provided in the genrep header:

struct calib_genrep_varlist {
	int			nvars;	/* Number of vars in the list */
	const char * const *	vlist;	/* List of variable names.  Note */
					/* that vlist[nvars] EQ NULL. */
};

This object is used to hold a (usually alphabetized) list of all the variables appearing within a given genrep.

The "calib/genrep.h" header provides the following global functions:

calib_genrep_add2:

	struct calib_genrep *
		calib_genrep_add2 (const struct calib_genrep *	op1,
				   const struct calib_genrep *	op2);

Returns a dynamically allocated genrep for the sum of the two given genreps, where:

op1is the first genrep oprand; and
op2is the second genrep operand.

calib_genrep_clear_varlist:

	void	calib_genrep_clear_varlist (
				struct calib_genrep_varlist *	list);

Clear out the given genrep varlist, where:

listis the genrep varlist to be cleared.

calib_genrep_convert_abs_Z_to_decimal_string:

	size_t	calib_genrep_convert_abs_Z_to_decimal_string (
				mpz_srcptr	zval,
				char **		str_out);

Sets *str_out to a nul-terminated, dynamically allocated string containing the absolute value of zval as decimal digits, and returning the number of decimal digits in the string, where:

zvalis the integer whose absolute value is to be converted; and
str_outis the address of the char * variable to receive the dynamically-allocated string.

It is the responsibility of the caller to free() the string it receives from this function.

calib_genrep_div2:

	struct calib_genrep *
		calib_genrep_div2 (const struct calib_genrep *	op1,
				   const struct calib_genrep *	op2);

Returns a dynamically allocated genrep for op1 / op2, where:

op1is the first genrep oprand; and
op2is the second genrep operand.

This function will gladly produce a genrep that (symbolically) represents division by zero.

calib_genrep_dup:

	struct calib_genrep *
		calib_genrep_dup (const struct calib_genrep *	op);

Returns a dynamically-allocated “deep copy” of the given genrep, where:

opis genrep to be recursively duplicated.

calib_genrep_dup_list:

	struct calib_genrep_list *
		calib_genrep_dup_list (const struct calib_genrep_list *	list);

Returns a dynamically-allocated “deep copy” of the given genrep_list, where:

listis genrep_list to be recursively duplicated.

calib_genrep_fread:

	struct calib_genrep *
		calib_genrep_fread (FILE * fp, int * status);

Read an expression (terminated by a semicolon) from the given input stream, returning it as a dynamically-allocated genrep, where:

fpis the input stream from which to read the expression; and
statusis the address of an int variable set to zero upon success and one if a syntax error is encountered.

Valid combinations of (return value, status) are as follows:

(NULL, 0)End of file.
(NULL, 1)Syntax error in expression.
(non-NULL, 0)Expression read successfully.

Note: calib_genrep_fread supports both C and C++ style comments. Unless the input stream is a (presumably interactive) TTY, such comments are automatically echoed to stdout.

calib_genrep_free:

	void	calib_genrep_free (struct calib_genrep *	op);

Recursively free the given genrep, where:

opis genrep to be recursively freed.

calib_genrep_free_list:

	void	calib_genrep_free_list (struct calib_genrep_list *	list);

Recursively free the given genrep_list, where:

listis genrep_list to be recursively freed.

calib_genrep_fprint:

	void	calib_genrep_fprint (FILE *				fp,
				     const struct calib_genrep *	op);

Display the given genrep to the given output stream using the default maximum width, where:

fpis the output stream to write into; and
opis genrep to be written.

Note: this is an old “pretty printer” that is obsolete because considers many expressions to be “too wide to print.”

calib_genrep_fwprint:

	void	calib_genrep_fwprint (FILE *				fp,
				      const struct calib_genrep *	op,
				      int				width);

Display the given genrep to the given output stream using the given maximum width, where:

fpis the output stream to write into;
opis genrep to be written; and
widthis the maximum width to use.

Note: this is an old “pretty printer” that is obsolete because considers many expressions to be “too wide to print.”

calib_genrep_get_varlist:

	void	calib_genrep_get_varlist (
				struct calib_genrep_varlist *	list,
				const struct calib_genrep *	op);

Scan the given genrep to determine the names of all variables appearing within the expression, then fill in the given varlist with a sorted list of the variable names, where:

listis the genrep varlist to be filled in; and
opis the genrep to be recursively scanned for variable names.

calib_genrep_ipow:

	struct calib_genrep *
		calib_genrep_ipow (const calib_genrep *	op1, int op2);

Returns a dynamically-allocated genrep opt1^op2, where:

op1is the genrep to be exponentiated; and
op2is the integer power to use.

calib_genrep_mul2:

	struct calib_genrep *
		calib_genrep_mul2 (const struct calib_genrep *	op1,
				   const struct calib_genrep *	op2);

Returns a dynamically allocated genrep for the product of the two given genreps, where:

op1is the first genrep oprand; and
op2is the second genrep operand.

calib_genrep_neg:

	struct calib_genrep *
		calib_genrep_neg (const struct calib_genrep *	op);

Returns a dynamically allocated genrep for the negative of the given genrep, where:

opis the genrep oprand to be negated.

calib_genrep_new_list:

	struct calib_genrep_list *
		calib_genrep_new_list (struct calib_genrep *		op,
				       struct calib_genrep_list *	next);

Return a dynamically-allocated genreplist whose operand and next fields are given, where:

opis the new genrep_list’s operand field; and
nextis the new genrep_list’s next field.

calib_genrep_poly_term:

	struct calib_genrep *
		calib_genrep_poly_term (struct calib_genrep *	coeff,
					const char *		var,
					int			pow);

Return a dynamically-allocated genrep that represents coeff*var^pow, where:

coeffis the coefficient of the polynomial term;
varis the polynomial variable; and
powis the exponent (degree) of the polynomial term.

calib_genrep_prettyprint:

	void	calib_genrep_prettyprint (const struct calib_genrep *	op);

Pretty-print the given genrep to stdout using the default width (determined from the terminal width if stdout refers to some sort of tty whose width can be determined), where:

opis the genrep to be prettyprinted.

This uses the new prettyprinting algorithm that uses dynamic programming to optimize the layout of the various sub-expression tiles.

calib_genrep_prettyprint_file:

	void	calib_genrep_prettyprint_file (
					FILE *				fp,
					const struct calib_genrep *	op);

Pretty-print the given genrep to the given output stream using the default width (determined from the terminal width if the given output stream refers to some sort of tty whose width can be determined), where:

fpis the output stream into which the expression is prettyprinted; and
opis the genrep to be prettyprinted.

This uses the new prettyprinting algorithm that uses dynamic programming to optimize the layout of the various sub-expression tiles.

calib_genrep_prettyprint_file_width:

	void	calib_genrep_prettyprint_file_width (
					FILE *				fp,
					const struct calib_genrep *	op,
					int				width);

Pretty-print the given genrep to the given output stream using the given width, where:

fpis the output stream into which the expression is prettyprinted;
opis the genrep to be prettyprinted; and
widthis the maximum display width to use.

This uses the new prettyprinting algorithm that uses dynamic programming to optimize the layout of the various sub-expression tiles.

calib_genrep_print_maxima:

	void	calib_genrep_print_maxima (
					FILE *				fp,
					const struct calib_genrep *	op,
					int				width);

Print the given genrep (in syntax readable by Maxima) to the given output stream using the given maximum line width, where:

fpis the output stream into which the expression is printed;
opis the genrep to be printed; and
widthis the maximum line width to use.

calib_genrep_prettyprint_width:

	void	calib_genrep_prettyprint_width (
					const struct calib_genrep *	op,
					int				width);

Pretty-print the given genrep to stdout using the given width, where:

opis the genrep to be prettyprinted; and
widthis the maximum display width to use.

This uses the new prettyprinting algorithm that uses dynamic programming to optimize the layout of the various sub-expression tiles.

calib_genrep_print:

	void	calib_genrep_print (const struct calib_genrep *	op);

Display the given genrep to stdout using the default maximum width, where:

opis genrep to be written.

Note: this is an old “pretty printer” that is obsolete because considers many expressions to be “too wide to print.”

calib_genrep_q:

	struct calib_genrep *
		calib_genrep_ (mpq_srcptr	op);

Returns a dynamically-allocated genrep representing the given rational value, where:

opis the rational value to be converted into genrep form.

calib_genrep_read:

	struct calib_genrep *
		calib_genrep_read (int * status);

Read an expression (terminated by a semicolon) from stdin, returning it as a dynamically-allocated genrep, where:

statusis the address of an int variable set to zero upon success and one if a syntax error is encountered.

Valid combinations of (return value, status) are as follows:

(NULL, 0)End of file.
(NULL, 1)Syntax error in expression.
(non-NULL, 0)Expression read successfully.

Note: calib_genrep_read upports both C and C++ style comments. Unless the input stream is a (presumably interactive) TTY, such comments are automatically echoed to stdout.

calib_genrep_si:

	struct calib_genrep *
		calib_genrep_si (calib_si_t	op);

Returns a dynamically-allocated genrep representing the given integer value, where:

opis the integer value to be converted into genrep form.

calib_genrep_sub2:

	struct calib_genrep *
		calib_genrep_sub2 (const struct calib_genrep *	op1,
				   const struct calib_genrep *	op2);

Returns a dynamically allocated genrep for the difference of the two given genreps, where:

op1is the first genrep oprand; and
op2is the second genrep operand.

calib_genrep_var:

	struct calib_genrep *
		calib_genrep_var (const char *	var);

Returns a dynamically-allocated genrep representing the given variable, where:

varis the variable to be converted into genrep form.

calib_genrep_wprint:

	void	calib_genrep_wprint (const struct calib_genrep *	op,
				     int				width);

Display the given genrep to stdout using the given maximum width, where:

opis genrep to be written; and
widthis the maximum width to use.

Note: this is an old “pretty printer” that is obsolete because considers many expressions to be “too wide to print.”

calib_genrep_z:

	struct calib_genrep *
		calib_genrep_z (int	op);

Returns a dynamically-allocated genrep representing the given GMP integer value, where:

opis the GMP integer value to be converted into genrep form.

Next: , Previous: , Up: Top   [Contents][Index]