/* * cl_intervals_src.ch * * Created on: 15/02/2017 * Author: pedro */ #if CL_D_TYPE == CL_INTERVAL #ifndef __OPENCL_VERSION__ #include #include #include #include "../utils/cl_syntax.h" #endif #include "../domains.h" #include "cl_aux_functions.h" #include "cl_intervals.h" #include "cl_variables.h" #include "../config.h" #include "cl_ttl.h" #ifndef M1 #define M1 NOTHING #endif #ifndef M2 #define M2 NOTHING #endif #ifndef M3 #define M3 NOTHING #endif #ifndef M4 #define M4 NOTHING #endif #ifndef FUNC_NAME # define CONCAT(name, suffix) name ## suffix # define FUNC_NAME(name, suffix) CONCAT(name, suffix) # define FUNC(name) FUNC_NAME(name, SUFFIX) #endif #if SUFFIX == _pg || SUFFIX == _gp || SUFFIX == _mg || SUFFIX == _n /* * Create a new domain with the received values * d - new domain to create * d_vals - vector with all the values allowed for the new variable * n_vals - number of domain values in values vector * */ void FUNC(cl_d_new_vals)(M1 interval* d, M2 int* d_vals, int n_vals TTL_CTR) { int min, max, i; min = CL_D_MAX; max = 0; for (i = 0; i < n_vals; i++) { if (d_vals[i] > max) { max = d_vals[i]; } if (d_vals[i] < min) { min = d_vals[i]; } } (*d).s0 = min; (*d).s1 = max; } #endif #if SUFFIX == _m || SUFFIX == _n || SUFFIX == _g /* * Check if domain is empty * empty - will be 1 if domain is empty or 0 if not * d - domain to check if empty */ void FUNC(cl_d_is_empty)(bool* empty, M1 interval* d TTL_CTR) { *empty = 0; if ((*d).s0 > (*d).s1) { *empty = 1; } } #endif #if SUFFIX == _g /* * calculate the minimum of the domain. (Assume domain is not empty) * min - the minimum value will be placed here * d - domain to calculate minimum value */ void FUNC(cl_d_calc_min_val)(int* min, M1 interval* d TTL_CTR) { *min = (*d).s0; } #endif #if SUFFIX == _m || SUFFIX == _pm || SUFFIX == _mp || SUFFIX == _n /* * Calculate the minimum of the variable domain. (Assume variable is not empty) * v - variable to calculate minimum value */ // Host configuration void FUNC(cl_v_calc_min_val)(M1 cl_var_p_interval* v TTL_CTR) { } #endif #if SUFFIX == _n /* * calculate the maximum of the domain. (Assume domain is not empty) * max - the maximum value will be placed here * d - domain to calculate maximum value */ void FUNC(cl_d_calc_max_val)(int* max, M1 interval* d TTL_CTR) { *max = (*d).s1; } #endif #if SUFFIX == _m || SUFFIX == _pm || SUFFIX == _mp || SUFFIX == _n /* * Calculate the maximum value of the variable domain. (Assume variable is not empty) * v - variable to calculate and return the maximum value */ void FUNC(cl_v_calc_max_val)(M1 cl_var_p_interval* v TTL_CTR) { } #endif #if SUFFIX == _n || SUFFIX == _m /* * Count the number of values in the variable domain * (uses popcount if OpenCL version is 1.2 or newer) * d - domain to count values * n_vals - where to place the calculated number of values */ void FUNC(cl_d_cnt_vals)(M1 interval* d, int* n_vals TTL_CTR) { } #endif #if SUFFIX == _m || SUFFIX == _pm || SUFFIX == _mp || SUFFIX == _n /* * Count the the number of values in the variable domain * n_vals - where to place the calculated number of values * v - variable to count values */ void FUNC(cl_v_cnt_vals)(M1 cl_var_p_interval* v TTL_CTR) { } #endif #if SUFFIX == _m3 || SUFFIX == _n || SUFFIX == _bd || SUFFIX == _vsg /* * Place the nth values of the domain in vals array. (Assume domain is not empty) * d - domain to get nth value from * first_nth - first nth value to get from the domain (from 1 to max value) * last_nth - last nth value to get from the domain (from 1 to max value) * vals - array where to save values */ void FUNC(cl_d_get_nth_vals)(M3 interval* d, int first_nth, int last_nth, M4 int* vals TTL_CTR) { int i; for (i = 0; i < last_nth - first_nth + 1; i++) { CHECK_TTL(ttl_ctr, 102) vals[i] = (*d).s0 + first_nth - 1 + i; } } #endif #if SUFFIX == _pm /* * Check if domains are equal * equal - will be 1 if domains are equal or 0 if not * d1 - domain 1 * d2 - domain 2 */ void FUNC(cl_ds_equal)(bool* equal, M1 interval* d1, M2 interval* d2 TTL_CTR) { if ((*d1).s0 == (*d2).s0 && (*d1).s1 == (*d2).s1) { *equal = 1; } *equal = 0; } #endif #if SUFFIX == _mg || SUFFIX == _g || SUFFIX == _gm || SUFFIX == _mbd || SUFFIX == _mvs /* * Copy d_src domain to d_dest domain * d_dest - where to copy the values * d_src - domain to copy */ void FUNC(cl_d_copy)(M1 interval* d_dest, M2 interval* d_src TTL_CTR) { (*d_dest).s0 = (*d_src).s0; (*d_dest).s1 = (*d_src).s1; } #endif #if SUFFIX == _pm || SUFFIX == _m /* * Copy v_src variable to v_dest variable (including to_prop and to_label) * v_dest - where to copy the values * v_src - variable to copy */ void FUNC(cl_v_copy)(M1 cl_var_p_interval* v_dest, M2 cl_var_p_interval* v_src TTL_CTR) { v_dest->prop_d.s0 = v_src->prop_d.s0; v_dest->prop_d.s1 = v_src->prop_d.s1; v_dest->to_prop = v_src->to_prop; } #endif #if SUFFIX == _m /* * Check if the variable contains the value * contains - will be 1 if domain contains the value or 0 if not * v - variable to check if contains value * val - value to check if contained */ void FUNC(cl_v_contains_val)(bool* contains, M1 cl_var_p_interval* v, int val) { *contains = 0; if ((v->prop_d).s0 <= val && (v->prop_d).s1 >= val) { *contains = 1; } } #endif #if SUFFIX == _n || SUFFIX == _g /* * Set domain to empty * d - domain to clear */ void FUNC(cl_d_clear)(M1 interval* d TTL_CTR) { (*d).s0 = 1; (*d).s1 = 0; } #endif #if SUFFIX == _m || SUFFIX == _n /* * set the variable as empty * v - variable to clear */ void FUNC(cl_v_clear)(M1 cl_var_p_interval* v TTL_CTR) { FUNC(cl_d_clear)(&v->prop_d TTL_CTR_V); } #endif #if SUFFIX == _mp || SUFFIX == _pm /* * Do operation d1 = d1 & d2 * changed - will be 1 if domain was changed or 0 if not * d1 - domain to save operation * d2 - domain to do AND with */ void FUNC(cl_d_intersect_d)(bool* changed, M1 interval* d1, M2 interval* d2 TTL_CTR) { *changed = 0; if ((*d1).s0 > (*d2).s1 || (*d1).s1 < (*d2).s0) { (*d1).s0 = 1; (*d1).s1 = 0; *changed = 1; } else { if ((*d2).s0 > (*d1).s0) { (*d1).s0 = (*d2).s0; *changed = 1; } if ((*d1).s1 > (*d2).s1) { (*d1).s1 = (*d2).s1; *changed = 1; } } } #endif #if SUFFIX == _m || SUFFIX == _pm || SUFFIX == _mp /* * Do operation v1 = v1 & v2 * changed - will be 1 if domain was changed or 0 if not * v1 - variable to save operation * v2 - variable to do AND with */ void FUNC(cl_v_intersect_v)(bool* changed, M1 cl_var_p_interval* v1, M2 cl_var_p_interval* v2 TTL_CTR) { *changed = 0; if ((v1->prop_d).s0 > (v2->prop_d).s1 || (v1->prop_d).s1 < (v2->prop_d).s0) { (v1->prop_d).s0 = 1; (v1->prop_d).s1 = 0; *changed = 1; } else { if ((v2->prop_d).s0 > (v1->prop_d).s0) { (v1->prop_d).s0 = (v2->prop_d).s0; *changed = 1; } if ((v1->prop_d).s1 > (v2->prop_d).s1) { (v1->prop_d).s1 = (v2->prop_d).s1; *changed = 1; } } } #endif #if SUFFIX == _pm /* * Do operation d1 = d1 | d2 * changed - will be 1 if domain was changed or 0 if not * d1 - domain to save operation * d2 - domain to do OR with */ void FUNC(cl_d_union_d)(bool* changed, M1 interval* d1, M2 interval* d2 TTL_CTR) { *changed = 0; if ((*d1).s0 > (*d2).s0) { (*d1).s0 = (*d2).s0; *changed = 1; } if ((*d1).s1 < (*d2).s1) { (*d1).s1 = (*d2).s1; *changed = 1; } } #endif #if SUFFIX == _pm /* * Do operation v1 = v1 | v2 * changed - will be 1 if domain was changed or 0 if not * v1 - variable to save operation * v2 - variable to do or with */ void FUNC(cl_v_union_v)(bool* changed, M1 cl_var_p_interval* v1, M2 cl_var_p_interval* v2 TTL_CTR) { *changed = 0; if ((v1->prop_d).s0 > (v2->prop_d).s0) { (v1->prop_d).s0 = (v2->prop_d).s0; *changed = 1; } if ((v1->prop_d).s1 < (v2->prop_d).s1) { (v1->prop_d).s1 = (v2->prop_d).s1; *changed = 1; } } #endif #if SUFFIX == _g /* * remove value from domain * d - domain to remove value from * val - value to remove from domain */ void FUNC(cl_d_del_val_no_tests)(M1 interval* d, int val) { if ((*d).s0 == val) { ((*d).s0)++; } if ((*d).s1 == val) { ((*d).s1)--; if ((*d).s1 == 65535) { (*d).s1 = 0; (*d).s0 = 1; } } } #endif #if SUFFIX == _g /* * remove value from domain * changed - will be 1 if domain was changed or 0 if not * d - domain to remove value from * val - value to remove from domain */ void FUNC(cl_d_del_val)(bool* changed, M1 interval* d, int val TTL_CTR) { *changed = 0; if (!(val < (*d).s0 || val > (*d).s1)) { if ((*d).s0 == val) { ((*d).s0)++; *changed = 1; } if ((*d).s1 == val) { ((*d).s1)--; *changed = 1; if ((*d).s1 == 65535) { (*d).s1 = 0; (*d).s0 = 1; } } } } #endif #if SUFFIX == _m /* * remove value from reification (boolean) variable when it has always 2 values (0 and 1) * v - reification variable with values 0 and 1 to remove value from * val - value to remove from variable */ void FUNC(cl_v_bool_del_val)(M1 cl_var_p_interval* v, int val TTL_CTR) { if (val == 0) { v->prop_d.s1 = 1; v->prop_d.s0 = 1; } else { v->prop_d.s1 = 0; v->prop_d.s0 = 0; } } #endif #if SUFFIX == _m || SUFFIX == _n /* * remove value from variable * changed - will be 1 if domain was changed or 0 if not * v - variable to remove value from * val - value to remove from variable */ void FUNC(cl_v_del_val)(bool* changed, M1 cl_var_p_interval* v, int val TTL_CTR) { FUNC(cl_d_del_val)(changed, &v->prop_d, val TTL_CTR_V); } #endif #if SUFFIX == _g /* * Remove from the domain all the values less than val * changed - will be 1 if domain was changed or 0 if not * d - domain to remove values from * val - minimum value to keep at domain */ void FUNC(cl_d_del_lt)(bool* changed, M1 interval* d, int val TTL_CTR) { *changed = 0; if (val > (*d).s1) { (*d).s0 = 1; (*d).s1 = 0; *changed = 1; } else if (val > (*d).s0) { (*d).s0 = val; *changed = 1; } } #endif #if SUFFIX == _m || SUFFIX == _n /* * Remove from the variable all the values less than val * changed - will be 1 if domain was changed or 0 if not * v - variable to remove values from * val - minimum value to keep at domain */ void FUNC(cl_v_del_lt)(bool* changed, M1 cl_var_p_interval* v, int val TTL_CTR) { FUNC(cl_d_del_lt)(changed, &v->prop_d, val TTL_CTR_V); } #endif #if SUFFIX == _g /* * Remove from the domain all the values less or equal to val. Doesn't test if domain changes neither if it has values for deletion * changed - will be 1 if domain was changed or 0 if not * d - domain to remove values from * val - minimum value to remove from domain */ void FUNC(cl_d_del_le_no_tests)(M1 interval* d_to_chg, int val TTL_CTR) { (*d_to_chg).s0 = val + 1; } #endif #if SUFFIX == _g /* * Remove from the domain all the values less or equal to val * changed - will be 1 if domain was changed or 0 if not * d - domain to remove values from * val - minimum value to remove from domain */ void FUNC(cl_d_del_le)(bool* changed, M1 interval* d_to_chg, int val TTL_CTR) { *changed = 0; if (val >= (*d_to_chg).s1) { (*d_to_chg).s0 = 1; (*d_to_chg).s1 = 0; *changed = 1; } else if (val >= (*d_to_chg).s0) { (*d_to_chg).s0 = val + 1; *changed = 1; } } #endif #if SUFFIX == _m /* * Remove from the variable all the values less or equal to val * changed - will be 1 if domain was changed or 0 if not * v - variable to remove values from * val - minimum value to remove from domain */ void FUNC(cl_v_del_le)(bool* changed, M1 cl_var_p_interval* v, int val TTL_CTR) { FUNC(cl_d_del_le)(changed, &v->prop_d, val TTL_CTR_V); } #endif #if SUFFIX == _g /* * Remove from the domain all the values greater than val * changed - will be 1 if domain was changed or 0 if not * d - domain to remove values from * val - maximum value to keep at domain */ void FUNC(cl_d_del_gt)(bool* changed, M1 interval* d_to_chg, int val TTL_CTR) { *changed = 0; if (val < (*d_to_chg).s0) { (*d_to_chg).s0 = 1; (*d_to_chg).s1 = 0; *changed = 1; } else if (val < (*d_to_chg).s1) { (*d_to_chg).s1 = val; *changed = 1; } } #endif #if SUFFIX == _m /* * Remove from the variable all the values greater than val. Doesn't test if domain changes neither if it has values for deletion * changed - will be 1 if domain was changed or 0 if not * v - variable to remove values from * val - maximum value to keep at domain */ void FUNC(cl_v_del_gt_no_tests)(M1 cl_var_p_interval* v, int val TTL_CTR) { (v->prop_d).s1 = val; } #endif #if SUFFIX == _m || SUFFIX == _n /* * Remove from the variable all the values greater than val * changed - will be 1 if domain was changed or 0 if not * v - variable to remove values from * val - maximum value to keep at domain */ void FUNC(cl_v_del_gt)(bool* changed, M1 cl_var_p_interval* v, int val TTL_CTR) { FUNC(cl_d_del_gt)(changed, &v->prop_d, val TTL_CTR_V); } #endif #if SUFFIX == _m /* * Remove from the variable all the values lesser than val * changed - will be 1 if domain was changed or 0 if not * v - variable to remove values from * val - maximum value to remove from the domain */ void FUNC(cl_v_del_ge)(bool* changed, M1 cl_var_p_interval* v, int val TTL_CTR) { FUNC(cl_v_del_gt)(changed, v, --val TTL_CTR_V); } #endif #if SUFFIX == _m || SUFFIX == _n /* * Clear all values from variable, except val if present * changed - will be 1 if domain was changed or 0 if not * v - variable to clear all values except val * val - value to keep in variable if present */ void FUNC(cl_v_del_all_except_val)(bool* changed, M1 cl_var_p_interval* v, int val TTL_CTR) { *changed = 0; // do not contain val if (val < (v->prop_d).s0 || val > (v->prop_d).s1) { (v->prop_d).s0 = 1; (v->prop_d).s1 = 0; *changed = 1; // contains only val } else if ((v->prop_d).s0 == (v->prop_d).s1) { *changed = 0; // contains more than val } else { (v->prop_d).s0 = val; (v->prop_d).s1 = val; *changed = 1; } } #endif #undef FUNC #undef FUNC_NAME #undef CONCAT #endif