static bool
_initialize_sml(Context *ctx)
{
    sml_set_stabilization_hits(ctx->sml, 0);
    sml_set_read_state_callback(ctx->sml, _read_state_cb, ctx);
    if (ctx->sml_engine == ANN_ENGINE)
        sml_ann_set_initial_required_observations(ctx->sml, REQUIRED_OBS);

    ctx->offense1 = _create_input(ctx, "red_striker");
    ctx->defense1 = _create_input(ctx, "red_goalkeeper");
    ctx->offense2 = _create_input(ctx, "yellow_striker");
    ctx->defense2 = _create_input(ctx, "yellow_goalkeeper");

    //number of the winner team
    ctx->winner = sml_new_output(ctx->sml, "winner");
    sml_variable_set_range(ctx->sml, ctx->winner, 0, 2);
    if (ctx->sml_engine == FUZZY_ENGINE) {
        sml_fuzzy_variable_add_term_ramp(ctx->sml, ctx->winner, "none",
            0 + DISCRETE_THRESHOLD, 0, 1);
        sml_fuzzy_variable_add_term_triangle(ctx->sml, ctx->winner,
            "red_winner", WINNER1 - DISCRETE_THRESHOLD, WINNER1,
            WINNER1 + DISCRETE_THRESHOLD, 1);
        sml_fuzzy_variable_add_term_ramp(ctx->sml, ctx->winner, "yellow_winner",
            WINNER2 - DISCRETE_THRESHOLD, WINNER2,
            1);
    }

    return true;
}
int
main(int argc, char **argv)
{
    Air_Conditioner_Controller acc;
    struct sml_variable *temp, *presence, *power;
    struct sml_object *sml;

    _initialize_acc(&acc);

    if (argc != 2) {
        fprintf(stderr, "Usage: %s <engine_type (0 fuzzy, 1 ann)>\n", argv[0]);
        fprintf(stderr, "Fuzzy Test: %s 0\n", argv[0]);
        fprintf(stderr, "Ann Test: %s 1\n", argv[0]);
        return -1;
    }

    sml = _sml_new(atoi(argv[1]));
    if (!sml) {
        sml_critical("Failed to create sml");
        return -1;
    }

    sml_main_loop_init();

    //Set stabilization hits and initial required obs to a low value because
    //this is a simulation and we don't want to wait for a long time before
    //getting interesting results
    sml_set_stabilization_hits(sml, STABILIZATION_HITS);
    sml_ann_set_initial_required_observations(sml, INITIAL_REQUIRED_OBS);

    //Create temperature input
    temp = sml_new_input(sml, "Temperature");
    sml_variable_set_range(sml, temp, 0, 48);
    sml_fuzzy_variable_set_default_term_width(sml, temp, 16);

    //Create presence input
    presence = sml_new_input(sml, "Presence");
    sml_variable_set_range(sml, presence, 0, 1);
    sml_fuzzy_variable_set_default_term_width(sml, presence, 0.5);

    //Create power output
    power = sml_new_output(sml, "Power");
    sml_variable_set_range(sml, power, 0, 3);
    sml_fuzzy_variable_set_default_term_width(sml, power, 1);
    sml_fuzzy_variable_set_is_id(sml, power, true);

    //set SML callbacks
    sml_set_read_state_callback(sml, _read_state_cb, &acc);
    sml_main_loop_schedule_sml_process(sml, READ_TIMEOUT);
    sml_set_output_state_changed_callback(sml, _output_state_changed_cb, &acc);

    sml_main_loop_run();

    sml_free(sml);
    sml_main_loop_shutdown();
    return 0;
}
static Variable *
add_output(Context *ctx, const char *name, float min, float max)
{
    Variable *var = calloc(1, sizeof(Variable));

    strncpy(var->name, name, NAME_SIZE);
    var->name[NAME_SIZE - 1] = '\0';
    var->sml_var = sml_new_output(ctx->sml, name);
    var->min = min;
    var->max = max;
    sml_variable_set_range(ctx->sml, var->sml_var, min, max);
    ctx->outputs = g_list_append(ctx->outputs, var);
    return var;
}
static bool
_initialize_sml(Context *ctx)
{
    sml_set_stabilization_hits(ctx->sml, 0);
    sml_set_read_state_callback(ctx->sml, _read_state_cb, ctx);
    if (ctx->sml_engine == ANN_ENGINE)
        sml_ann_set_initial_required_observations(ctx->sml, REQUIRED_OBS);

    ctx->offense1 = _create_input(ctx, "red_striker");
    ctx->defense1 = _create_input(ctx, "red_goalkeeper");
    ctx->offense2 = _create_input(ctx, "yellow_striker");
    ctx->defense2 = _create_input(ctx, "yellow_goalkeeper");

    //number of the winner team
    ctx->winner = sml_new_output(ctx->sml, "winner");
    sml_variable_set_range(ctx->sml, ctx->winner, 0, 2);
    sml_fuzzy_variable_set_default_term_width(ctx->sml, ctx->winner, 1);
    sml_fuzzy_variable_set_is_id(ctx->sml, ctx->winner, true);

    return true;
}
int
main(int argc, char *argv[])
{
    unsigned int inputs, outputs, executions, num_terms;
    char strbuf[STRLEN];
    struct sml_variable *var;
    struct sml_object *sml;

    if (argc < 5) {
        fprintf(stderr, "Usage: %s <engine type (0 fuzzy, 1 ann)> <inputs> "
            "<outputs> <executions> <num_terms> <seed>\n", argv[0]);
        fprintf(stderr, "Fuzzy Test: %s 0 10 2 100 10\n", argv[0]);
        fprintf(stderr, "ANN Test: %s 1 10 2 100 10\n", argv[0]);
        return 1;
    }

    inputs = atoi(argv[2]);
    outputs = atoi(argv[3]);
    executions = atoi(argv[4]);
    num_terms = atoi(argv[5]);

    if (argc > 6)
        srand((unsigned int)atol(argv[6]));
    else
        srand(time(NULL));

    if (num_terms < 1) {
        fprintf(stderr, "num_terms must be a positive value\n");
        return 1;
    }

    sml = _sml_new(atoi(argv[1]));
    if (!sml) {
        fprintf(stderr, "Failed to create sml\n");
        return 1;
    }


    sml_set_read_state_callback(sml, _read_state_cb, &executions);
    sml_set_stabilization_hits(sml, 0);

    while (inputs) {
        snprintf(strbuf, STRLEN, "input%d", inputs);
        var = sml_new_input(sml, strbuf);
        sml_variable_set_range(sml, var, 0, RAND_MAX);
        _add_terms(sml, var, strbuf, inputs, num_terms);

        inputs--;
    }

    while (outputs) {
        snprintf(strbuf, STRLEN, "output%d", outputs);
        var = sml_new_output(sml, strbuf);
        sml_variable_set_range(sml, var, 0, RAND_MAX);
        _add_terms(sml, var, strbuf, outputs, num_terms);
        outputs--;
    }

    while (sml_process(sml) == 0) ;
    sml_free(sml);

    return 0;
}