Added good functions and extended conditions for k=4

This commit is contained in:
2018-04-28 01:04:44 +03:00
parent af0343076c
commit 494e697738

152
main.cpp
View File

@@ -22,7 +22,7 @@
using namespace std; using namespace std;
const CellType CUR_BASE = 3; const CellType CUR_BASE = 4;
const int ARGS_COUNT = 2; const int ARGS_COUNT = 2;
const string CLASSES_FILENAME = "classes.txt"; const string CLASSES_FILENAME = "classes.txt";
@@ -130,9 +130,10 @@ bool is_one_arg_func(const TripleArgsFiniteFunction &h) {
for (CellType x = 0; x < CUR_BASE; ++x) for (CellType x = 0; x < CUR_BASE; ++x)
for (CellType y = 0; y < CUR_BASE; ++y) { for (CellType y = 0; y < CUR_BASE; ++y) {
for (CellType z = 0; z < CUR_BASE; ++z) { for (CellType z = 0; z < CUR_BASE; ++z) {
is_equaled_x = is_equaled_x && (h(x,y,z) == x); auto h_res = h(x,y,z);
is_equaled_y = is_equaled_y && (h(x,y,z) == y); is_equaled_x = is_equaled_x && (h_res == x);
is_equaled_z = is_equaled_z && (h(x,y,z) == z); is_equaled_y = is_equaled_y && (h_res == y);
is_equaled_z = is_equaled_z && (h_res == z);
} }
if ( !is_equaled_x && !is_equaled_y && !is_equaled_z ) if ( !is_equaled_x && !is_equaled_y && !is_equaled_z )
return false; return false;
@@ -140,6 +141,29 @@ bool is_one_arg_func(const TripleArgsFiniteFunction &h) {
return true; return true;
} }
template<class FourthArgsFiniteFunction>
bool is_one_arg_func_fourth(const FourthArgsFiniteFunction &h) {
bool is_equaled_x = true;
bool is_equaled_y = true;
bool is_equaled_z = true;
bool is_equaled_w = true;
for (CellType x = 0; x < CUR_BASE; ++x)
for (CellType y = 0; y < CUR_BASE; ++y) {
for (CellType z = 0; z < CUR_BASE; ++z) {
for (CellType w = 0; w < CUR_BASE; ++w) {
auto h_res = h(x,y,z,w);
is_equaled_x = is_equaled_x && (h_res == x);
is_equaled_y = is_equaled_y && (h_res == y);
is_equaled_z = is_equaled_z && (h_res == z);
is_equaled_w = is_equaled_w && (h_res == w);
}
}
if ( !is_equaled_x && !is_equaled_y && !is_equaled_z && !is_equaled_w)
return false;
}
return true;
}
template<class TripleArgsFiniteFunction> template<class TripleArgsFiniteFunction>
bool is_projection(const TripleArgsFiniteFunction &h) { bool is_projection(const TripleArgsFiniteFunction &h) {
bool is_projection = true; bool is_projection = true;
@@ -153,6 +177,20 @@ bool is_projection(const TripleArgsFiniteFunction &h) {
return is_projection; return is_projection;
} }
template<class FourthArgsFiniteFunction>
bool is_projection_fourth(const FourthArgsFiniteFunction &h) {
bool is_projection = true;
for (CellType x = 0; x < CUR_BASE; ++x)
for (CellType y = 0; y < CUR_BASE; ++y) {
is_projection = (is_projection
&& h(x,x,x,y) == h(x,x,y,x)
&& h(x,x,y,x) == h(x,y,x,x)
&& h(x,y,x,x) == h(y,x,x,x)
&& h(y,x,x,x) == x);
}
return is_projection;
}
template<class TripleArgsFiniteFunction> template<class TripleArgsFiniteFunction>
bool is_semiprojection(const TripleArgsFiniteFunction &h) { bool is_semiprojection(const TripleArgsFiniteFunction &h) {
bool is_equaled_x = true; bool is_equaled_x = true;
@@ -164,13 +202,57 @@ bool is_semiprojection(const TripleArgsFiniteFunction &h) {
// если все различны, то не рассматриваем // если все различны, то не рассматриваем
if ( x != y && x != z && y != z ) if ( x != y && x != z && y != z )
continue; continue;
is_equaled_x = is_equaled_x && (h(x,y,z) == x);
is_equaled_y = is_equaled_y && (h(x,y,z) == y); auto h_res = h(x,y,z);
is_equaled_z = is_equaled_z && (h(x,y,z) == z); is_equaled_x = is_equaled_x && (h_res == x);
is_equaled_y = is_equaled_y && (h_res == y);
is_equaled_z = is_equaled_z && (h_res == z);
if (
!is_equaled_x
&& !is_equaled_y
&& !is_equaled_z
)
return false;
} }
return is_equaled_x || is_equaled_y || is_equaled_z; return is_equaled_x || is_equaled_y || is_equaled_z;
} }
template<class FourthArgsFiniteFunction>
bool is_semiprojection_fourth(const FourthArgsFiniteFunction &h) {
bool is_equaled_x = true;
bool is_equaled_y = true;
bool is_equaled_z = true;
bool is_equaled_w = true;
for (CellType x = 0; x < CUR_BASE; ++x)
for (CellType y = 0; y < CUR_BASE; ++y)
for (CellType z = 0; z < CUR_BASE; ++z) {
for (CellType w = 0; w < CUR_BASE; ++w) {
set<CellType> s;
s.insert(x);
s.insert(y);
s.insert(z);
s.insert(w);
if ( s.size() == 4 )
// если все различны, то не рассматриваем
continue;
auto h_res = h(x,y,z,w);
is_equaled_x = is_equaled_x && (h_res == x);
is_equaled_y = is_equaled_y && (h_res == y);
is_equaled_z = is_equaled_z && (h_res == z);
is_equaled_w = is_equaled_w && (h_res == w);
if (
!is_equaled_x
&& !is_equaled_y
&& !is_equaled_z
&& !is_equaled_w
)
return false;
}
}
return is_equaled_x || is_equaled_y || is_equaled_z || is_equaled_w;
}
bool is_passed_rosenberg(const FiniteFunction<CUR_BASE> &f) { bool is_passed_rosenberg(const FiniteFunction<CUR_BASE> &f) {
auto h_1 = [f](const CellType x, const CellType y, CellType z) -> CellType { auto h_1 = [f](const CellType x, const CellType y, CellType z) -> CellType {
return f( f(x,y), f(x,z) ); return f( f(x,y), f(x,z) );
@@ -203,6 +285,49 @@ bool is_passed_rosenberg(const FiniteFunction<CUR_BASE> &f) {
if ( is_projection(h_4) || is_semiprojection(h_4) ) if ( is_projection(h_4) || is_semiprojection(h_4) )
return false; return false;
} }
if ( CUR_BASE == 4 ) {
auto g_1 = [f, h_1](const CellType x, const CellType y, CellType z, CellType u) -> CellType {
return f( h_1(x,y,z), u );
};
if ( !is_one_arg_func_fourth(g_1) ) {
if ( is_projection_fourth(g_1) || is_semiprojection_fourth(g_1) )
return false;
}
auto g_2 = [f, h_2](const CellType x, const CellType y, CellType z, CellType u) -> CellType {
return f( h_2(x,y,z), u );
};
if ( !is_one_arg_func_fourth(g_2) ) {
if ( is_projection_fourth(g_2) || is_semiprojection_fourth(g_2) )
return false;
}
auto g_3 = [f, h_3](const CellType x, const CellType y, CellType z, CellType u) -> CellType {
return f( h_3(x,y,z), u );
};
if ( !is_one_arg_func_fourth(g_3) ) {
if ( is_projection_fourth(g_3) || is_semiprojection_fourth(g_3) )
return false;
}
auto g_4 = [f, h_4](const CellType x, const CellType y, CellType z, CellType u) -> CellType {
return f( h_4(x,y,z), u );
};
if ( !is_one_arg_func_fourth(g_4) ) {
if ( is_projection_fourth(g_4) || is_semiprojection_fourth(g_4) )
return false;
}
auto g_both = [f](const CellType x, const CellType y, CellType z, CellType u) -> CellType {
return f( f(x,y), f(z,u) );
};
if ( !is_one_arg_func_fourth(g_both) ) {
if ( is_projection_fourth(g_both) || is_semiprojection_fourth(g_both) )
return false;
}
}
return true; return true;
} }
@@ -381,6 +506,7 @@ vector<FunctionTask> processed_task_list;
mutex processed_task_mutex; mutex processed_task_mutex;
set<FiniteFunction<CUR_BASE>> bad_functions; set<FiniteFunction<CUR_BASE>> bad_functions;
set<FiniteFunction<CUR_BASE>> good_functions;
atomic<int> current_max_coeff; atomic<int> current_max_coeff;
void do_work() { void do_work() {
@@ -499,6 +625,14 @@ void process_task_lists() {
vector<decltype(shared_function_classes)::iterator> functions_to_remove; vector<decltype(shared_function_classes)::iterator> functions_to_remove;
is_need_append = !is_bad_class(task.current, bad_functions); is_need_append = !is_bad_class(task.current, bad_functions);
for (auto&& f: task.current)
if ( good_functions.find(f) == good_functions.end() ) {
is_need_append = false;
break;
}
/*for (auto it = shared_function_classes.begin(); it != shared_function_classes.end(); ++it) { /*for (auto it = shared_function_classes.begin(); it != shared_function_classes.end(); ++it) {
if ( func_class.size() < it->size() ) { if ( func_class.size() < it->size() ) {
if (includes( if (includes(
@@ -592,15 +726,13 @@ int main() {
decltype(FiniteFunctionHasher) decltype(FiniteFunctionHasher)
> allowed_functions(funcs.begin(), funcs.end(), 128, FiniteFunctionHasher); > allowed_functions(funcs.begin(), funcs.end(), 128, FiniteFunctionHasher);
cout << identical_x.get_hash() << endl;
cout << identical_y.get_hash() << endl;
allowed_functions.erase(identical_x); allowed_functions.erase(identical_x);
allowed_functions.erase(identical_y); allowed_functions.erase(identical_y);
completed_tasks = 0; completed_tasks = 0;
current_max_coeff = 1; current_max_coeff = 1;
for (auto&& func: allowed_functions) { for (auto&& func: allowed_functions) {
good_functions.insert(func);
FunctionTask task; FunctionTask task;
task.current = {func}; task.current = {func};
task.is_finished = false; task.is_finished = false;