/*
   File:        constraint.h
   Author:      Andrew W. Moore
   Created:     Wed Jul 15 13:31:36 EDT 1998
   Description: Header for Constraints language to specify subsets of rows

   Copyright 1998, Andrew W. Moore
*/


#ifndef CONSTRAINT_H
#define CONSTRAINT_H
#include "dsut.h"

#define ALL_CONTYPE      0
#define MISSING_CONTYPE  1
#define EQUAL_CONTYPE    2
#define GREATER_CONTYPE  3
#define LESS_CONTYPE     4
#define ROWGREATER_CONTYPE  5
#define ROWLESS_CONTYPE     6

typedef struct constraint
{
  int contype;
  int attnum;
  int symbol_value;
  double real_thresh;
} constraint;

/* Constraint Syntax:

   <constraint> ::= all |
                    missing |
                    row < n |
                    row > n |
                    <symbolicattname> == <symbolicvalue> |
                    <realattname> < <number> |
                    <realattname> > <number> 

   A constraint can be evaluated on any requested row of the datset.

   An "all" constraint matches all rows

   A "missing" constraint is TRUE iff the row contains a missing value

   An == constraint evals to TRUE if and only if the value of the given
       attribute on the given row matches the specified value (it evals
       to false if the requested value is missing)

   A < (>) constraint evals to TRUE if and only if the value of the
       given attribute is strictly less than (greater than) the
       supplied number.
*/

/* Parses the tokens in the string array according to the
   above syntax. If it fails to parse legally, returns NULL and
   sets *r_errmess to point to a NULL-terminated NEWLY-ALLOCATED
   string with a short error message (the caller must free this
   string with the free_string( ) function). 

   If it DOES successfully parse, sets *r_errmess to NULL, and returns
   the new constraint. */
constraint *mk_constraint_from_string_array(datset *ds,string_array *sa,
                                            char **r_errmess);

/* Breaks the string into tokens and then parses according to the
   same convention as the above function */
constraint *mk_constraint_from_string(datset *ds,char *s,char **r_errmess);

/* MAKES a string which, if parsed, would re-produce the
   specified constriant. */
char *mk_string_from_constraint(datset *ds,constraint *cs);
   
/* MAKES a string_array which, if parsed, would re-produce the
   specified constriant. */
string_array *mk_string_array_from_constraint(datset *ds,constraint *cs);
 
/* Frees the constraint and all its contents */
void free_constraint(constraint *cs);

void fprintf_constraint(FILE *s,char *m1,datset *ds,constraint *cs,char *m2);

/* Returns TRUE if and only if the specified row matches the
   constraint according to the rules at the top of the file. */
bool ds_row_matches_constraint(datset *ds,constraint *cs,int row);

/* Makes a sorted ivec that contains only those rows in the dataset
   that match the constraint. */
ivec *mk_rows_matching_constraint(datset *ds,constraint *cs);

/* Makes a sorted ivec that contains only those rows in the
   dataset that both match the constraint AND appear in
   start_rows. If this function is called with start_rows==NULL,
   that is considered equivalent to "Please use ALL ROWS" */
ivec *mk_subrows_matching_constraint(datset *ds,constraint *cs,
                                     ivec *start_rows);

void process_marked_rows(datset *ds,constraint *cs,bool mark,
                         ivec *row_to_marked,int *num_marked);



#endif /* #ifndef CONSTRAINT_H */
