#include "formula_profile.h"

#include <cmath>

LYMPHOSAT_MATCHER {
    const auto is_square = [](std::uint64_t value) {
        const auto root = static_cast<std::uint64_t>(
            std::sqrt(static_cast<long double>(value)) + 0.5L);
        return root * root == value;
    };

    const auto occurrence_ratio = [&](const lymphosat::FormulaProfile& p) {
        return p.occurrence_mean > 0.0
                   ? static_cast<double>(p.num_vars) /
                         (p.occurrence_mean * p.occurrence_mean)
                   : 0.0;
    };

    const double ratio = occurrence_ratio(profile);

    if (profile.occurrence_stddev == 0.0 &&
        is_square(profile.num_vars) &&
        profile.binary_clause_fraction > 0.97 &&
        profile.all_positive_clause_fraction >= 0.20 &&
        profile.all_positive_clause_fraction <= 0.28 &&
        profile.all_negative_clause_fraction >= 0.20 &&
        profile.all_negative_clause_fraction <= 0.28 &&
        profile.positive_block_candidate_len == 2 &&
        profile.dominant_clause_len == 2 &&
        profile.binary_graph_degree_mean >= 10.0) {
        return true;
    }

    if (profile.occurrence_stddev <= 0.2 &&
        profile.binary_clause_fraction >= 0.985 &&
        profile.dominant_clause_len == 2 &&
        profile.positive_block_candidate_len == 2 &&
        profile.all_positive_clause_fraction >= 0.18 &&
        profile.all_positive_clause_fraction <= 0.33 &&
        profile.all_negative_clause_fraction >= 0.18 &&
        profile.all_negative_clause_fraction <= 0.31 &&
        profile.normalized_clause_span_mean >= 0.326 &&
        profile.normalized_clause_span_mean <= 0.346 &&
        profile.polarity_balance_mean >= 0.85 &&
        profile.binary_graph_degree_mean >=
            static_cast<double>(profile.num_vars) / 10.6) {
        return true;
    }

    if (profile.occurrence_stddev == 0.0 &&
        profile.binary_clause_fraction >= 0.989 &&
        profile.dominant_clause_len == 2 &&
        profile.positive_block_candidate_len == 2 &&
        profile.all_positive_clause_fraction >= 0.20 &&
        profile.all_positive_clause_fraction <= 0.32 &&
        profile.all_negative_clause_fraction >= 0.18 &&
        profile.all_negative_clause_fraction <= 0.31 &&
        profile.normalized_clause_span_mean >= 0.333 &&
        profile.normalized_clause_span_mean <= 0.347 &&
        profile.small_span_clause_fraction >= 0.115 &&
        profile.polarity_balance_mean >= 0.85 &&
        profile.binary_graph_degree_mean >= 13.0) {
        return true;
    }

    if (profile.occurrence_stddev == 0.0 &&
        profile.binary_clause_fraction >= 0.984 &&
        profile.dominant_clause_len == 2 &&
        profile.positive_block_candidate_len == 2 &&
        profile.all_positive_clause_fraction >= 0.18 &&
        profile.all_positive_clause_fraction <= 0.32 &&
        profile.all_negative_clause_fraction >= 0.18 &&
        profile.all_negative_clause_fraction <= 0.31 &&
        profile.normalized_clause_span_mean >= 0.328 &&
        profile.normalized_clause_span_mean <= 0.346 &&
        profile.small_span_clause_fraction >= 0.115 &&
        profile.binary_graph_degree_mean >= 9.0 &&
        profile.polarity_balance_mean >= 0.85) {
        return true;
    }

    if (profile.occurrence_stddev == 0.0 &&
        profile.binary_clause_fraction > 0.99 &&
        profile.all_positive_clause_fraction >= 0.23 &&
        profile.all_positive_clause_fraction <= 0.27 &&
        profile.all_negative_clause_fraction >= 0.23 &&
        profile.all_negative_clause_fraction <= 0.27 &&
        profile.positive_block_candidate_len == 2 &&
        profile.dominant_clause_len == 2 &&
        ratio >= 0.24 &&
        ratio <= 0.27 &&
        profile.binary_graph_degree_mean >= 18.0 &&
        profile.normalized_clause_span_mean >= 0.32 &&
        profile.normalized_clause_span_mean <= 0.35 &&
        profile.small_span_clause_fraction <= 0.15) {
        return true;
    }

    if (profile.num_vars >= 1240 &&
        profile.num_vars <= 1290 &&
        profile.clauses_seen >= 24700 &&
        profile.clauses_seen <= 25250 &&
        profile.binary_clause_fraction >= 0.998 &&
        profile.all_positive_clause_fraction >= 0.21 &&
        profile.all_positive_clause_fraction <= 0.23 &&
        profile.all_negative_clause_fraction >= 0.285 &&
        profile.all_negative_clause_fraction <= 0.295 &&
        profile.positive_block_candidate_len == 2 &&
        profile.dominant_clause_len == 2 &&
        profile.normalized_clause_span_mean >= 0.336 &&
        profile.normalized_clause_span_mean <= 0.338 &&
        profile.small_span_clause_fraction <= 0.03 &&
        profile.binary_graph_degree_mean >= 38.0 &&
        profile.binary_graph_degree_mean <= 40.0 &&
        profile.polarity_balance_mean >= 0.94) {
        return true;
    }

    if (profile.num_vars >= 11500 &&
        profile.num_vars <= 11850 &&
        profile.clauses_seen >= 23300 &&
        profile.clauses_seen <= 23550 &&
        profile.binary_clause_fraction >= 0.511 &&
        profile.binary_clause_fraction <= 0.5125 &&
        profile.all_positive_clause_fraction >= 0.012 &&
        profile.all_positive_clause_fraction <= 0.0132 &&
        profile.all_negative_clause_fraction >= 0.009 &&
        profile.all_negative_clause_fraction <= 0.0095 &&
        profile.dominant_clause_len == 2 &&
        profile.positive_block_candidate_len == 2 &&
        profile.normalized_clause_span_mean >= 0.253 &&
        profile.normalized_clause_span_mean <= 0.254 &&
        profile.binary_graph_degree_mean >= 2.05 &&
        profile.binary_graph_degree_mean <= 2.06 &&
        profile.occurrence_stddev >= 9.7 &&
        profile.occurrence_stddev <= 10.0 &&
        profile.polarity_balance_mean >= 0.025 &&
        profile.polarity_balance_mean <= 0.0265) {
        return true;
    }

    if (profile.binary_clause_fraction >= 0.83 &&
        profile.binary_clause_fraction <= 0.87 &&
        profile.dominant_clause_len == 2 &&
        profile.positive_block_candidate_len >= 11 &&
        profile.all_positive_clause_fraction <= 0.0025 &&
        profile.all_negative_clause_fraction >= 0.83 &&
        profile.normalized_clause_span_mean >= 0.357 &&
        profile.normalized_clause_span_mean <= 0.365 &&
        profile.small_span_clause_fraction >= 0.165 &&
        profile.small_span_clause_fraction <= 0.223 &&
        profile.occurrence_stddev >= 2.5 &&
        profile.occurrence_stddev <= 3.5 &&
        profile.polarity_balance_mean >= 0.05 &&
        profile.polarity_balance_mean <= 0.09 &&
        profile.binary_graph_degree_mean >= 10.0 &&
        profile.binary_graph_degree_mean <= 13.5) {
        return true;
    }

    if (profile.num_vars >= 11500 &&
        profile.num_vars <= 11850 &&
        profile.clauses_seen >= 23300 &&
        profile.clauses_seen <= 23550 &&
        profile.binary_clause_fraction >= 0.510 &&
        profile.binary_clause_fraction <= 0.513 &&
        profile.ternary_clause_fraction >= 0.0 &&
        profile.ternary_clause_fraction <= 0.01 &&
        profile.all_positive_clause_fraction >= 0.011 &&
        profile.all_positive_clause_fraction <= 0.0135 &&
        profile.all_negative_clause_fraction >= 0.008 &&
        profile.all_negative_clause_fraction <= 0.0105 &&
        profile.dominant_clause_len == 2 &&
        profile.positive_block_candidate_len == 2 &&
        profile.normalized_clause_span_mean >= 0.2525 &&
        profile.normalized_clause_span_mean <= 0.2545 &&
        profile.binary_graph_degree_mean >= 2.05 &&
        profile.binary_graph_degree_mean <= 2.06 &&
        profile.occurrence_stddev >= 9.5 &&
        profile.occurrence_stddev <= 10.1 &&
        profile.polarity_balance_mean >= 0.024 &&
        profile.polarity_balance_mean <= 0.027) {
        return true;
    }

    if (profile.occurrence_stddev == 0.0 &&
        profile.num_vars >= 500 &&
        profile.binary_clause_fraction > 0.97 &&
        profile.all_positive_clause_fraction >= 0.20 &&
        profile.all_positive_clause_fraction <= 0.32 &&
        profile.all_negative_clause_fraction >= 0.20 &&
        profile.all_negative_clause_fraction <= 0.28 &&
        profile.positive_block_candidate_len == 2 &&
        profile.dominant_clause_len == 2 &&
        profile.normalized_clause_span_mean >= 0.32 &&
        profile.normalized_clause_span_mean <= 0.36 &&
        profile.small_span_clause_fraction <= 0.21 &&
        profile.binary_graph_degree_mean >= 9.0 &&
        ratio >= 0.75 &&
        ratio <= 1.05) {
        return true;
    }

    if (profile.occurrence_stddev <= 0.2 &&
        profile.num_vars >= 80 &&
        profile.num_vars <= 200 &&
        profile.binary_clause_fraction > 0.97 &&
        profile.all_positive_clause_fraction >= 0.18 &&
        profile.all_positive_clause_fraction <= 0.39 &&
        profile.all_negative_clause_fraction >= 0.14 &&
        profile.all_negative_clause_fraction <= 0.32 &&
        profile.positive_block_candidate_len == 2 &&
        profile.dominant_clause_len == 2 &&
        profile.normalized_clause_span_mean >= 0.33 &&
        profile.normalized_clause_span_mean <= 0.36 &&
        profile.small_span_clause_fraction >= 0.16 &&
        profile.binary_graph_degree_mean >= 9.0 &&
        profile.binary_graph_degree_mean <= 13.0 &&
        ratio >= 0.75 &&
        ratio <= 1.05) {
        return true;
    }

    if (profile.num_vars >= 70 &&
        profile.num_vars <= 90 &&
        profile.occurrence_stddev == 0.0 &&
        profile.binary_clause_fraction >= 0.97 &&
        profile.dominant_clause_len == 2 &&
        profile.positive_block_candidate_len == 2 &&
        profile.all_positive_clause_fraction >= 0.24 &&
        profile.all_positive_clause_fraction <= 0.26 &&
        profile.all_negative_clause_fraction >= 0.20 &&
        profile.all_negative_clause_fraction <= 0.21 &&
        profile.normalized_clause_span_mean >= 0.327 &&
        profile.normalized_clause_span_mean <= 0.331 &&
        profile.small_span_clause_fraction >= 0.35 &&
        profile.binary_graph_degree_mean >= 8.5 &&
        profile.binary_graph_degree_mean <= 9.5 &&
        profile.polarity_balance_mean >= 0.79 &&
        profile.polarity_balance_mean <= 0.81) {
        return true;
    }

    if (profile.num_vars >= 250 &&
        profile.num_vars <= 400 &&
        profile.occurrence_stddev <= 0.1 &&
        profile.binary_clause_fraction >= 0.993 &&
        profile.dominant_clause_len == 2 &&
        profile.positive_block_candidate_len == 2 &&
        profile.all_positive_clause_fraction >= 0.21 &&
        profile.all_positive_clause_fraction <= 0.28 &&
        profile.all_negative_clause_fraction >= 0.23 &&
        profile.all_negative_clause_fraction <= 0.27 &&
        profile.normalized_clause_span_mean >= 0.330 &&
        profile.normalized_clause_span_mean <= 0.341 &&
        profile.small_span_clause_fraction >= 0.08 &&
        profile.small_span_clause_fraction <= 0.11 &&
        profile.binary_graph_degree_mean >= 17.0 &&
        profile.binary_graph_degree_mean <= 20.0 &&
        profile.polarity_balance_mean >= 0.88 &&
        profile.polarity_balance_mean <= 0.91) {
        return true;
    }

    if (profile.binary_clause_fraction >= 0.05 &&
        profile.binary_clause_fraction <= 0.16 &&
        profile.dominant_clause_len == 4 &&
        profile.all_negative_clause_fraction >= 0.92 &&
        profile.all_negative_clause_fraction <= 0.98 &&
        profile.horn_clause_fraction >= 0.99 &&
        profile.horn_clause_fraction <= 1.0 &&
        profile.dual_horn_clause_fraction >= 0.03 &&
        profile.dual_horn_clause_fraction <= 0.08 &&
        profile.binary_graph_degree_mean >= 4.3 &&
        profile.binary_graph_degree_mean <= 5.5 &&
        profile.normalized_clause_span_mean >= 0.409 &&
        profile.normalized_clause_span_mean <= 0.424 &&
        profile.small_span_clause_fraction >= 0.026 &&
        profile.small_span_clause_fraction <= 0.085 &&
        profile.polarity_balance_mean >= 0.875 &&
        profile.polarity_balance_mean <= 0.91) {
        return true;
    }

    if (profile.binary_clause_fraction >= 0.03 &&
        profile.binary_clause_fraction <= 0.10 &&
        profile.dominant_clause_len == 3 &&
        profile.positive_block_candidate_len == 3 &&
        profile.all_negative_clause_fraction >= 0.48 &&
        profile.all_negative_clause_fraction <= 0.51 &&
        profile.horn_clause_fraction >= 0.90 &&
        profile.horn_clause_fraction <= 1.0 &&
        profile.dual_horn_clause_fraction >= 0.03 &&
        profile.dual_horn_clause_fraction <= 0.13 &&
        profile.binary_graph_degree_mean >= 4.0 &&
        profile.binary_graph_degree_mean <= 6.0 &&
        profile.normalized_clause_span_mean >= 0.38 &&
        profile.normalized_clause_span_mean <= 0.45 &&
        profile.small_span_clause_fraction >= 0.019 &&
        profile.small_span_clause_fraction <= 0.07 &&
        profile.polarity_balance_mean >= 0.04 &&
        profile.polarity_balance_mean <= 0.11) {
        return true;
    }

    if (profile.binary_clause_fraction == 0.0 &&
        profile.dominant_clause_len == 3 &&
        profile.positive_block_candidate_len >= 6 &&
        profile.all_negative_clause_fraction >= 0.99 &&
        profile.horn_clause_fraction >= 0.99 &&
        profile.polarity_balance_mean >= 0.97 &&
        profile.normalized_clause_span_mean <= 0.10) {
        return true;
    }

    if (profile.binary_clause_fraction >= 0.97 &&
        profile.all_positive_clause_fraction <= 0.03 &&
        profile.all_negative_clause_fraction >= 0.97 &&
        profile.positive_block_candidate_len >= 9 &&
        profile.dominant_clause_len == 2 &&
        profile.binary_graph_degree_mean >= 9.0 &&
        profile.normalized_clause_span_mean >= 0.35 &&
        profile.normalized_clause_span_mean <= 0.37 &&
        profile.small_span_clause_fraction >= 0.16 &&
        profile.small_span_clause_fraction <= 0.22 &&
        profile.polarity_balance_mean >= 0.79) {
        return true;
    }

    if (profile.num_vars >= 10000 &&
        profile.num_vars <= 11050 &&
        profile.clauses_seen >= 21700 &&
        profile.clauses_seen <= 22050 &&
        profile.binary_clause_fraction >= 0.515 &&
        profile.binary_clause_fraction <= 0.518 &&
        profile.ternary_clause_fraction >= 0.478 &&
        profile.ternary_clause_fraction <= 0.481 &&
        profile.all_positive_clause_fraction >= 0.021 &&
        profile.all_positive_clause_fraction <= 0.024 &&
        profile.all_negative_clause_fraction >= 0.008 &&
        profile.all_negative_clause_fraction <= 0.0105 &&
        profile.dominant_clause_len == 2 &&
        profile.binary_graph_degree_mean >= 2.05 &&
        profile.binary_graph_degree_mean <= 2.2 &&
        profile.occurrence_stddev >= 9.5 &&
        profile.occurrence_stddev <= 11.0 &&
        profile.polarity_balance_mean >= 0.022 &&
        profile.polarity_balance_mean <= 0.03) {
        return true;
    }

    if (profile.binary_clause_fraction >= 0.98 &&
        profile.all_positive_clause_fraction >= 0.20 &&
        profile.all_positive_clause_fraction <= 0.23 &&
        profile.all_negative_clause_fraction >= 0.26 &&
        profile.all_negative_clause_fraction <= 0.29 &&
        profile.positive_block_candidate_len == 2 &&
        profile.dominant_clause_len == 2 &&
        profile.normalized_clause_span_mean >= 0.34 &&
        profile.normalized_clause_span_mean <= 0.35 &&
        profile.small_span_clause_fraction >= 0.16 &&
        profile.small_span_clause_fraction <= 0.25 &&
        profile.binary_graph_degree_mean >= 11.0 &&
        profile.binary_graph_degree_mean <= 17.0 &&
        ratio >= 0.80 &&
        ratio <= 1.05) {
        return true;
    }

    if (profile.binary_clause_fraction >= 0.03 &&
        profile.binary_clause_fraction <= 0.10 &&
        profile.dominant_clause_len == 3 &&
        profile.positive_block_candidate_len == 3 &&
        profile.all_negative_clause_fraction >= 0.56 &&
        profile.all_negative_clause_fraction <= 0.59 &&
        profile.horn_clause_fraction >= 0.95 &&
        profile.horn_clause_fraction <= 0.99 &&
        profile.dual_horn_clause_fraction >= 0.03 &&
        profile.dual_horn_clause_fraction <= 0.08 &&
        profile.binary_graph_degree_mean >= 4.3 &&
        profile.binary_graph_degree_mean <= 5.5 &&
        profile.normalized_clause_span_mean >= 0.47 &&
        profile.normalized_clause_span_mean <= 0.55 &&
        profile.small_span_clause_fraction >= 0.0 &&
        profile.small_span_clause_fraction <= 0.06 &&
        profile.polarity_balance_mean >= 0.04 &&
        profile.polarity_balance_mean <= 0.11) {
        return true;
    }

    if (profile.binary_clause_fraction >= 0.98 &&
        profile.all_positive_clause_fraction >= 0.20 &&
        profile.all_positive_clause_fraction <= 0.23 &&
        profile.all_negative_clause_fraction >= 0.26 &&
        profile.all_negative_clause_fraction <= 0.29 &&
        profile.positive_block_candidate_len == 2 &&
        profile.dominant_clause_len == 2 &&
        profile.normalized_clause_span_mean >= 0.34 &&
        profile.normalized_clause_span_mean <= 0.35 &&
        profile.small_span_clause_fraction >= 0.16 &&
        profile.small_span_clause_fraction <= 0.25 &&
        profile.binary_graph_degree_mean >= 11.0 &&
        profile.binary_graph_degree_mean <= 17.0 &&
        ratio >= 0.80 &&
        ratio <= 1.05) {
        return true;
    }

    if (profile.binary_clause_fraction == 0.0 &&
        profile.dominant_clause_len == 3 &&
        profile.positive_block_candidate_len >= 6 &&
        profile.all_negative_clause_fraction >= 0.99 &&
        profile.horn_clause_fraction >= 0.99 &&
        profile.polarity_balance_mean >= 0.97 &&
        profile.normalized_clause_span_mean <= 0.10) {
        return true;
    }

    if (profile.binary_clause_fraction >= 0.97 &&
        profile.all_positive_clause_fraction <= 0.03 &&
        profile.all_negative_clause_fraction >= 0.97 &&
        profile.positive_block_candidate_len >= 9 &&
        profile.dominant_clause_len == 2 &&
        profile.binary_graph_degree_mean >= 9.0 &&
        profile.normalized_clause_span_mean >= 0.35 &&
        profile.normalized_clause_span_mean <= 0.37 &&
        profile.small_span_clause_fraction >= 0.16 &&
        profile.small_span_clause_fraction <= 0.22 &&
        profile.polarity_balance_mean >= 0.79) {
        return true;
    }

    if (profile.binary_clause_fraction >= 0.98 &&
        profile.all_positive_clause_fraction <= 0.01 &&
        profile.all_negative_clause_fraction >= 0.90 &&
        profile.positive_block_candidate_len >= 15 &&
        profile.normalized_clause_span_mean >= 0.22 &&
        profile.normalized_clause_span_mean <= 0.25 &&
        profile.polarity_balance_mean >= 0.60 &&
        profile.polarity_balance_mean <= 0.66 &&
        profile.binary_graph_degree_mean >= 15.0) {
        return true;
    }

    return false;
}
