/* Vladimir Kotlyar  February 1996


 */

#ifndef _a_ineq_h
#define _a_ineq_h

#include <stdio.h>

#ifndef _a_matrix_h
#include "alpha_matrix.h"
#endif

#include "alpha_ineq_private.h"

/***********************************************************************
 *			     INEQUALITIES
 ***********************************************************************/

typedef xa_ineq 	AlphaIneq;
typedef xa_ineq_term 	AlphaIneqTerm;

#define a_varind_term(t)	xa_varind_term(t)
#define a_coeff_term(t)		xa_coeff_term(t)

#define	a_nterm_ineq(i)		xa_nterm_ineq(i)
#define a_const_ineq(i)		xa_const_ineq(i)
#define a_tag_ineq(i)		xa_tag_ineq(i)
#define a_term_ineq(i,k)       	xa_term_ineq(i,k)
#define a_varind_ineq(i,k)	xa_varind_ineq(i,k)
#define a_coeff_ineq(i,k)	xa_coeff_ineq(i,k)
#define a_maxvarind_ineq(i)	xa_maxvarind_ineq(i)  /* not an l-value */
#define a_is_normalized_ineq(i) xa_is_normalized_ineq(i)

#define A_FOR_TERMS_IN_INEQ(ineq,varind,coeff) \
  XA_FOR_TERMS_IN_INEQ((ineq),varind,coeff)

#define A_END_TERMS_IN_INEQ  XA_END_TERMS_IN_INEQ

/*
 * Here are different ways that we need to create inequalities:
 * (1)  Copy from another inequality
 * (2)  saxpy of two other inequalities
 * (3)	From dense vector
 */
AlphaIneq	a_make_ineq_copy (arena_info *arena, AlphaIneq src);
AlphaIneq	a_make_ineq_saxpy (arena_info *arena, int a1, AlphaIneq i1, int a2, AlphaIneq i2);
AlphaIneq	a_make_ineq_from_dense (arena_info *arena, AlphaVector a, int b);
AlphaIneq	a_make_ineq_var_transform (arena_info *arena, AlphaIneq ineq, AlphaVector X0, AlphaMatrix H);
AlphaIneq	a_make_ineq_neg (arena_info *arena, AlphaIneq ineq);

int		a_coeff4var_ineq (AlphaIneq ineq, int varind);
int		a_is_same_coeff_ineq (AlphaIneq i1, AlphaIneq i2);
int		a_is_opposite_coeff_ineq (AlphaIneq i1, AlphaIneq i2);
int		a_normalize_ineq (AlphaIneq ineq);

void		a_dump_ineq (FILE *fp, AlphaIneq ineq);


/***********************************************************************
 *			LISTS OF INEQUALITIES
 ***********************************************************************/

typedef xa_ineq_list AlphaIneqList;

#define a_is_equal_ineq_list_elt(e1,e2)  xa_is_equal_ineq_list_elt((e1),(e2))
#define a_make_ineq_list(arena)		xa_make_ineq_list(arena)
#define a_add_ineq_list(arena,l,ineq)	xa_add_ineq_list(arena,l,ineq)
#define a_delete_ineq_list_elt(l,elt)	xa_delete_ineq_list_elt(l,elt)
#define a_clear_ineq_list(l)		xa_clear_ineq_list(l)
#define a_length_ineq_list(l)		xa_length_ineq_list(l)

#define A_FOR_INEQ_IN_LIST(l,ineq,elt) \
   XA_FOR_INEQ_IN_LIST((l),ineq,elt) 

#define A_END_INEQ_IN_LIST \
   XA_END_INEQ_IN_LIST

void 		a_normalize_ineq_list (AlphaIneqList l);
AlphaIneqList 	a_make_ineq_list_copy (arena_info *arena, AlphaIneqList l);
void 		a_dump_ineq_list (FILE *fp, AlphaIneqList l);
void		a_print_ineq_list (FILE *fp, AlphaIneqList l);

/* A and B are assumed to have been zeroed out on entry */
void		a_ineq_list2matrix_form (AlphaIneqList l, AlphaMatrix A, AlphaVector B);

void		a_matrix_form2ineq_list (arena_info *arena, AlphaMatrix A, AlphaVector B, AlphaIneqList l);

void		a_transform_ineq_list (arena_info *arena, AlphaIneqList from, AlphaVector T0, 
				       AlphaMatrix H, AlphaIneqList to);

int		a_is_satisfied_ineq_list (AlphaIneqList C, AlphaVector X);

#endif




