<commit_before>#include "isl_mat.h"
#include "isl_map_private.h"
#include "isl_tab.h"
#include "isl_seq.h"

/*
 * The implementation of tableaus in this file was inspired by Section 8
 * of <NAME>, <NAME> and <NAME>, "Simplify: a theorem
 * prover for program checking".
 */

struct isl_tab *isl_tab_alloc(struct isl_ctx *ctx,
	unsigned n_row, unsigned n_var, unsigned M)
{
	int i;
	struct isl_tab *tab;
	unsigned off = 2 + M;

	tab = isl_calloc_type(ctx, struct isl_tab);
	if (!tab)
		return NULL;
	tab->mat = isl_mat_alloc(ctx, n_row, off + n_var);
	if (!tab->mat)
		goto error;
	tab->var = isl_alloc_array(ctx, struct isl_tab_var, n_var);
	if (!tab->var)
		goto error;
	tab->con = isl_alloc_array(ctx, struct isl_tab_var, n_row);
	if (!tab->con)
		goto error;
	tab->col_var = isl_alloc_array(ctx, int, n_var);
	if (!tab->col_var)
		goto error;
	tab->row_var = isl_alloc_array(ctx, int, n_row);
	if (!tab->row_var)
		goto error;
	for (i = 0; i < n_var; ++i) {
		tab->var[i].index = i;
		tab->var[i].is_row = 0;
		tab->var[i].is_nonneg = 0;
		tab->var[i].is_zero = 0;
		tab->var[i].is_redundant = 0;
		tab->var[i].frozen = 0;
		tab->var[i].negated = 0;
		tab->col_var[i] = i;
	}
	tab->n_row = 0;
	tab->n_con = 0;
	tab->n_eq = 0;
	tab->max_con = n_row;
	tab->n_col = n_var;
	tab->n_var = n_var;
	tab->max_var = n_var;
	tab->n_param = 0;
	tab->n_div = 0;
	tab->n_dead = 0;
	tab->n_redundant = 0;
	tab->need_undo = 0;
	tab->rational = 0;
	tab->empty = 0;
	tab->in_undo = 0;
	tab->M = M;
	tab->bottom.type = isl_tab_undo_bottom;
	tab->bottom.next = NULL;
	tab->top = &tab->bottom;
	return tab;
error:
	isl_tab_free(tab);
	return NULL;
}

int isl_tab_extend_cons(struct isl_tab *tab, unsigned n_new)
{
	unsigned off = 2 + tab->M;
	if (tab->max_con < tab->n_con + n_new) {
		struct isl_tab_var *con;

		con = isl_realloc_array(tab->mat->ctx, tab->con,
				    struct isl_tab_var, tab->max_con + n_new);
		if (!con)
			return -1;
		tab->con = con;
		tab->max_con += n_new;
	}
	if (tab->mat->n_row < tab->n_row + n_new) {
		int *row_var;

		tab->mat = isl_mat_extend(tab->mat,
					tab->n_row + n_new, off + tab->n_col);
		if (!tab->mat)
			return -1;
		row_var = isl_realloc_array(tab->mat->ctx, tab->row_var,
					    int, tab->mat->n_row);
		if (!row_var)
			return -1;
		tab->row_var = row_var;
		if (tab->row_sign) {
			enum isl_tab_row_sign *s;
			s = isl_realloc_array(tab->mat->ctx, tab->row_sign,
					enum isl_tab_row_sign, tab->mat->n_row);
			if (!s)
				return -1;
			tab->row_sign = s;
		}
	}
	return 0;
}

/* Make room for at least n_new extra variables.
 * Return -1 if anything went wrong.
 */
int isl_tab_extend_vars(struct isl_tab *tab, unsigned n_new)
{
	struct isl_tab_var *var;
	unsigned off = 2 + tab->M;

	if (tab->max_var < tab->n_var + n_new) {
		var = isl_realloc_array(tab->mat->ctx, tab->var,
				    struct isl_tab_var, tab->n_var + n_new);
		if (!var)
			return -1;
		tab->var = var;
		tab->max_var += n_new;
	}

	if (tab->mat->n_col < off + tab->n_col + n_new) {
		int *p;

		tab->mat = isl_mat_extend(tab->mat,
				    tab->mat->n_row, off + tab->n_col + n_new);
		if (!tab->mat)
			return -1;
		p = isl_realloc_array(tab->mat->ctx, tab->col_var,
					    int, tab->mat->n_col);
		if (!p)
			return -1;
		tab->col_var = p;
	}

	return 0;
}

struct isl_tab *isl_tab_extend(struct isl_tab *tab, unsigned n_new)
{
	if (isl_tab_extend_cons(tab, n_new) >= 0)
		return tab;

	isl_tab_free(tab);
	return NULL;
}

static void free_undo(struct isl_tab *tab)
{
	struct isl_tab_undo *undo, *next;

	for (undo = tab->top; undo && undo != &tab->bottom; undo = next) {
		next = undo->next;
		free(undo);
	}
	tab->top = undo;
}

void isl_tab_free(struct isl_tab *tab)
{
	if (!tab)
		return;
	free_undo(tab);
	isl_mat_free(tab->mat);
	isl_vec_free(tab->dual);
	isl_basic_set_free(tab->bset);
	free(tab->var);
	free(tab->con);
	free(tab->row_var);
	free(tab->col_var);
	free(tab->row_sign);
	isl_mat_free(tab->samples);
	free(tab);
}

struct isl_tab *isl_tab_dup(struct isl_tab *tab)
{
	int i;
	struct isl_tab *dup;

	if (!tab)
		return NULL;

	dup = isl_calloc_type(tab->ctx, struct isl_tab);
	if (!dup)
		return NULL;
	dup->mat = isl_mat_dup(tab->mat);
	if (!dup->mat)
		goto error;
	dup->var = isl_alloc_array(tab->ctx, struct isl_tab_var, tab->max_var);
	if (!dup->var)
		goto error;
	for (i = 0; i < tab->n_var; ++i)
		dup->var[i] = tab->var[i];
	dup->con = isl_alloc_array(tab->ctx, struct isl_tab_var, tab->max_con);
	if (!dup->con)
		goto error;
	for (i = 0; i < tab->n_con; ++i)
		dup->con[i] = tab->con[i];
	dup->col_var = isl_alloc_array(tab->ctx, int, tab->mat->n_col);
	if (!dup->col_var)
		goto error;
	for (i = 0; i < tab->n_var; ++i)
		dup->col_var[i] = tab->col_var[i];
	dup->row_var = isl_alloc_array(tab->ctx, int, tab->mat->n_row);
	if (!dup->row_var)
		goto error;
	for (i = 0; i < tab->n_row; ++i)
		dup->row_var[i] = tab->row_var[i];
	if (tab->row_sign) {
		dup->row_sign = isl_alloc_array(tab->ctx, enum isl_tab_row_sign,
						tab->mat->n_row);
		if (!dup->row_sign)
			goto error;
		for (i = 0; i < tab->n_row; ++i)<commit_msg>isl_tab_dup: avoid out-of-bounds array access<commit_after>#include "isl_mat.h"
#include "isl_map_private.h"
#include "isl_tab.h"
#include "isl_seq.h"

/*
 * The implementation of tableaus in this file was inspired by Section 8
 * of <NAME>, <NAME> and <NAME>, "Simplify: a theorem
 * prover for program checking".
 */

struct isl_tab *isl_tab_alloc(struct isl_ctx *ctx,
	unsigned n_row, unsigned n_var, unsigned M)
{
	int i;
	struct isl_tab *tab;
	unsigned off = 2 + M;

	tab = isl_calloc_type(ctx, struct isl_tab);
	if (!tab)
		return NULL;
	tab->mat = isl_mat_alloc(ctx, n_row, off + n_var);
	if (!tab->mat)
		goto error;
	tab->var = isl_alloc_array(ctx, struct isl_tab_var, n_var);
	if (!tab->var)
		goto error;
	tab->con = isl_alloc_array(ctx, struct isl_tab_var, n_row);
	if (!tab->con)
		goto error;
	tab->col_var = isl_alloc_array(ctx, int, n_var);
	if (!tab->col_var)
		goto error;
	tab->row_var = isl_alloc_array(ctx, int, n_row);
	if (!tab->row_var)
		goto error;
	for (i = 0; i < n_var; ++i) {
		tab->var[i].index = i;
		tab->var[i].is_row = 0;
		tab->var[i].is_nonneg = 0;
		tab->var[i].is_zero = 0;
		tab->var[i].is_redundant = 0;
		tab->var[i].frozen = 0;
		tab->var[i].negated = 0;
		tab->col_var[i] = i;
	}
	tab->n_row = 0;
	tab->n_con = 0;
	tab->n_eq = 0;
	tab->max_con = n_row;
	tab->n_col = n_var;
	tab->n_var = n_var;
	tab->max_var = n_var;
	tab->n_param = 0;
	tab->n_div = 0;
	tab->n_dead = 0;
	tab->n_redundant = 0;
	tab->need_undo = 0;
	tab->rational = 0;
	tab->empty = 0;
	tab->in_undo = 0;
	tab->M = M;
	tab->bottom.type = isl_tab_undo_bottom;
	tab->bottom.next = NULL;
	tab->top = &tab->bottom;
	return tab;
error:
	isl_tab_free(tab);
	return NULL;
}

int isl_tab_extend_cons(struct isl_tab *tab, unsigned n_new)
{
	unsigned off = 2 + tab->M;
	if (tab->max_con < tab->n_con + n_new) {
		struct isl_tab_var *con;

		con = isl_realloc_array(tab->mat->ctx, tab->con,
				    struct isl_tab_var, tab->max_con + n_new);
		if (!con)
			return -1;
		tab->con = con;
		tab->max_con += n_new;
	}
	if (tab->mat->n_row < tab->n_row + n_new) {
		int *row_var;

		tab->mat = isl_mat_extend(tab->mat,
					tab->n_row + n_new, off + tab->n_col);
		if (!tab->mat)
			return -1;
		row_var = isl_realloc_array(tab->mat->ctx, tab->row_var,
					    int, tab->mat->n_row);
		if (!row_var)
			return -1;
		tab->row_var = row_var;
		if (tab->row_sign) {
			enum isl_tab_row_sign *s;
			s = isl_realloc_array(tab->mat->ctx, tab->row_sign,
					enum isl_tab_row_sign, tab->mat->n_row);
			if (!s)
				return -1;
			tab->row_sign = s;
		}
	}
	return 0;
}

/* Make room for at least n_new extra variables.
 * Return -1 if anything went wrong.
 */
int isl_tab_extend_vars(struct isl_tab *tab, unsigned n_new)
{
	struct isl_tab_var *var;
	unsigned off = 2 + tab->M;

	if (tab->max_var < tab->n_var + n_new) {
		var = isl_realloc_array(tab->mat->ctx, tab->var,
				    struct isl_tab_var, tab->n_var + n_new);
		if (!var)
			return -1;
		tab->var = var;
		tab->max_var += n_new;
	}

	if (tab->mat->n_col < off + tab->n_col + n_new) {
		int *p;

		tab->mat = isl_mat_extend(tab->mat,
				    tab->mat->n_row, off + tab->n_col + n_new);
		if (!tab->mat)
			return -1;
		p = isl_realloc_array(tab->mat->ctx, tab->col_var,
					    int, tab->n_col + n_new);
		if (!p)
			return -1;
		tab->col_var = p;
	}

	return 0;
}

struct isl_tab *isl_tab_extend(struct isl_tab *tab, unsigned n_new)
{
	if (isl_tab_extend_cons(tab, n_new) >= 0)
		return tab;

	isl_tab_free(tab);
	return NULL;
}

static void free_undo(struct isl_tab *tab)
{
	struct isl_tab_undo *undo, *next;

	for (undo = tab->top; undo && undo != &tab->bottom; undo = next) {
		next = undo->next;
		free(undo);
	}
	tab->top = undo;
}

void isl_tab_free(struct isl_tab *tab)
{
	if (!tab)
		return;
	free_undo(tab);
	isl_mat_free(tab->mat);
	isl_vec_free(tab->dual);
	isl_basic_set_free(tab->bset);
	free(tab->var);
	free(tab->con);
	free(tab->row_var);
	free(tab->col_var);
	free(tab->row_sign);
	isl_mat_free(tab->samples);
	free(tab);
}

struct isl_tab *isl_tab_dup(struct isl_tab *tab)
{
	int i;
	struct isl_tab *dup;
	unsigned off;

	if (!tab)
		return NULL;

	off = 2 + tab->M;
	dup = isl_calloc_type(tab->ctx, struct isl_tab);
	if (!dup)
		return NULL;
	dup->mat = isl_mat_dup(tab->mat);
	if (!dup->mat)
		goto error;
	dup->var = isl_alloc_array(tab->ctx, struct isl_tab_var, tab->max_var);
	if (!dup->var)
		goto error;
	for (i = 0; i < tab->n_var; ++i)
		dup->var[i] = tab->var[i];
	dup->con = isl_alloc_array(tab->ctx, struct isl_tab_var, tab->max_con);
	if (!dup->con)
		goto error;
	for (i = 0; i < tab->n_con; ++i)
		dup->con[i] = tab->con[i];
	dup->col_var = isl_alloc_array(tab->ctx, int, tab->mat->n_col - off);
	if (!dup->col_var)
		goto error;
	for (i = 0; i < tab->n_col; ++i)
		dup->col_var[i] = tab->col_var[i];
	dup->row_var = isl_alloc_array(tab->ctx, int, tab->mat->n_row);
	if (!dup->row_var)
		goto error;
	for (i = 0; i < tab->n_row; ++i)
		dup->row_var[i] = tab->row_var[i];
	if (tab->row_sign) {
		dup->row_sign = isl_alloc_array(tab->ctx, enum isl_tab_row_sign,
						tab->mat->n_row);
		if (!dup->row_sign)
			goto error;
		for (i = 0; i < tab->n_row; ++i)
{'fraction_non_alphanumeric': 0.17893911167761545, 'fraction_numerical': 0.0075497597803706245, 'mean_word_length': 3.511278195488722, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 303, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1710924', 'n_tokens_mistral': 4926, 'n_tokens_neox': 4591, 'n_words': 990}