/********************************************************************************
**
** conditions.h Data structure for homomorphisms search J. D. Mitchell
**
** Copyright (C) 2019 - J. D. Mitchell
**
** This file is free software, see the digraphs/LICENSE.
**
********************************************************************************/
#ifndef DIGRAPHS_SRC_CONDITIONS_H_
#define DIGRAPHS_SRC_CONDITIONS_H_
// C headers
#include <stdbool.h> // for false, true
#include <stdint.h> // for uint16_t, uint64_t
#include <string.h> // for NULL, memcpy, size_t
// GAP headers
#include "gap-includes.h" // for ALWAYS_INLINE
// Digraphs headers
#include "bitarray.h" // for BitArray, intersect_bit_arrays, size_b...
#include "digraphs-debug.h" // for DIGRAPHS_ASSERT
// This file contains a data structure for keeping track of what possible
// values a uint16_t can be mapped to by a partially defined homomorphism, given
// the existing values of the homomorphism.
//
// If <nr1> is the number of vertices in the source di/graph and <nr2> is the
// number of vertices in the range di/graph, then a Conditions object looks
// like:
//
// ^
// |
// |
//
// n +------------+
// r | BitArray* |
// 1 | length nr2 |
// +------------+ +------------+
// r | BitArray* | | BitArray* |
// o | length nr2 | | length nr2 |
// w +------------+------------+ +------------+
// s | BitArray* | BitArray* | | BitArray* |
// | length nr2 | length nr2 | | length nr2 |
// | +------------+------------+------------+ - - -+------------+
// | | BitArray* | BitArray* | BitArray* | | BitArray* |
// | | length nr2 | length nr2 | length nr2 | | length nr2 |
// v +------------+------------+------------+ - - -+------------+
//
// <----------------------- nr1 columns ----------------------->
//
// The BitArray pointed to in row <i+1> and column <j> row is the intersection
// of the BitArray pointed to in row <i> and column <j> with some other
// BitArray (the things adjacent to some uint16_t in di/graph2).
//
struct conditions_struct {
BitArray** bit_array; // nr1 * nr1 array of bit arrays of length nr2
uint16_t* changed;
uint16_t* height;
uint16_t* sizes;
uint16_t nr1;
uint16_t nr2;
uint64_t size;
};
typedef struct conditions_struct Conditions;
//! Returns a pointer to a Conditions with one complete row where every bit is
//! set to true.
Conditions* new_conditions(uint16_t const nr1, uint16_t const nr2);
//! Clears all the information in the Conditions object, and puts it back into
//! the state it was when it was initially created. The second and third
//! arguments indicate how much of the Conditions object is to be cleared. I.e.
//! if we want to use the Conditions object in a homomorphism search for graphs
//! with 5 and 19 vertices, then we clear the Conditions object with 2nd and
//! 3rd parameters 5, and 19.
static inline void clear_conditions(Conditions* const conditions,
uint16_t const nr1,
uint16_t const nr2) {
DIGRAPHS_ASSERT(conditions != NULL);
DIGRAPHS_ASSERT(nr1 != 0);
DIGRAPHS_ASSERT(nr2 != 0);
for (uint64_t i = 0; i < nr1 * nr1; i++) {
init_bit_array(conditions->bit_array[i], false, nr2);
}
for (uint64_t i = 0; i < nr1; i++) {
init_bit_array(conditions->bit_array[i], true, nr2);
conditions->changed[i + 1] = i;
conditions->changed[(nr1 + 1) * i] = 0;
conditions->height[i] = 1;
}
conditions->changed[0] = nr1;
conditions->nr1 = nr1;
conditions->nr2 = nr2;
}
//! Free an entire Conditions object pointed to by
void free_conditions(Conditions* const conditions);
//! Returns the top most BitArray* in column \p i.
static inline BitArray* get_conditions(Conditions const* const conditions,
uint16_t const i) {
DIGRAPHS_ASSERT(conditions != NULL);
DIGRAPHS_ASSERT(i < conditions->nr1);
return conditions
->bit_array[conditions->nr1 * (conditions->height[i] - 1) + i];
}
//! Store the size of the BitArray pointed to at the top of column \p i.
static inline void store_size_conditions(Conditions* const conditions,
uint16_t const i) {
DIGRAPHS_ASSERT(conditions != NULL);
DIGRAPHS_ASSERT(i < conditions->nr1);
uint16_t const nr1 = conditions->nr1;
conditions->sizes[nr1 * (conditions->height[i] - 1) + i] =
size_bit_array(get_conditions(conditions, i), conditions->nr2);
}
//! Copy the top of the <i>th column of the <conditions> and intersect it with
//! <bit_array> and then push this onto the top of the <i>th column.
static ALWAYS_INLINE void push_conditions(Conditions* const conditions,
uint16_t const depth,
uint16_t const i,
BitArray const* const bit_array) {
DIGRAPHS_ASSERT(conditions != NULL);
DIGRAPHS_ASSERT(i < conditions->nr1);
DIGRAPHS_ASSERT(depth < conditions->nr1);
uint16_t const nr1 = conditions->nr1;
memcpy((void*) conditions->bit_array[nr1 * conditions->height[i] + i]->blocks,
(void*) conditions->bit_array[nr1 * (conditions->height[i] - 1) + i]
->blocks,
(size_t) conditions->bit_array[0]->nr_blocks * sizeof(Block));
conditions->changed[(nr1 + 1) * depth]++;
conditions
->changed[(nr1 + 1) * depth + conditions->changed[(nr1 + 1) * depth]] = i;
conditions->height[i]++;
if (bit_array != NULL) {
intersect_bit_arrays(
get_conditions(conditions, i), bit_array, conditions->nr2);
}
}
//! Pop the tops off all of the columns which were pushed on at depth \p depth.
static inline void pop_conditions(Conditions* const conditions,
uint16_t const depth) {
DIGRAPHS_ASSERT(conditions != NULL);
DIGRAPHS_ASSERT(depth < conditions->nr1);
uint16_t const nr1 = conditions->nr1;
for (uint16_t i = 1; i < conditions->changed[(nr1 + 1) * depth] + 1; i++) {
conditions->height[conditions->changed[(nr1 + 1) * depth + i]]--;
}
conditions->changed[(nr1 + 1) * depth] = 0;
}
//! Return the size of the BitArray pointed to by the top of the \p i-th
//! column.
static inline uint16_t size_conditions(Conditions const* const conditions,
uint16_t const i) {
DIGRAPHS_ASSERT(conditions != NULL);
DIGRAPHS_ASSERT(i < conditions->nr1);
return conditions->sizes[conditions->nr1 * (conditions->height[i] - 1) + i];
}
#endif // DIGRAPHS_SRC_CONDITIONS_H_
¤ Dauer der Verarbeitung: 0.1 Sekunden
(vorverarbeitet am 2026-11-04)
¤
*© Formatika GbR, Deutschland