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;
}
int
main(int argc, char *argv[])
{
    Context ctx;
    int i, tic, toc, total_toc, total_tic;
    double duration;
    int error;

    if (argc < 6) {
        fprintf(stderr, "%s TEST.conf TEST.data SEED_VAL DEBUG_VAL "
            "ENGINE_TYPE(0 fuzzy, 1 ann, 2 naive, "
            "3 fuzzy_no_simplification) [MAX_MEMORY_FOR_OBSERVATION] "
            "[ANN_CACHE_SIZE] [ANN_PSEUDO_REHEARSAL_STRATETY (1 for true, 0 for false)]\n",
            argv[0]);
        fprintf(stderr,
            "Eg: %s simple_office.conf simple_office.forget_lights_on.data "
            "30 1 1\n",
            argv[0]);
        return 1;
    }

    ctx.rand = g_rand_new_with_seed(atoi(argv[3]));
    ctx.debug = !!atoi(argv[4]);

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

    if (!read_config(argv[1], &ctx)) {
        fprintf(stderr, "Failed to read configuration: %s\n", argv[1]);
        return 3;
    }

    if (!read_values(argv[2], &ctx)) {
        fprintf(stderr, "Failed to read data: %s\n", argv[2]);
        return 4;
    }

    add_time_day(&ctx);

    sml_set_read_state_callback(ctx.sml, read_state_cb, &ctx);
    sml_set_output_state_changed_callback(ctx.sml, output_state_changed_cb,
        &ctx);
    sml_set_stabilization_hits(ctx.sml, 0);
    if (ctx.engine_type == FUZZY_ENGINE_NO_SIMPLIFICATION)
        sml_fuzzy_set_simplification_disabled(ctx.sml, true);

    if (argc >= 7) {
        int observations = atoi(argv[6]);
        if (observations < 0) {
            fprintf(stderr, "MAX_MEMORY_FOR_OBSERVATIOS (%s) must be a non "
                "negative value\n", argv[6]);
            return 5;
        }
        sml_set_max_memory_for_observations(ctx.sml, observations);
    }

    if (ctx.engine_type == ANN_ENGINE) {
        if (argc >= 8) {
            int cache_size = atoi(argv[7]);
            if (cache_size < 0 || cache_size >= UINT16_MAX) {
                fprintf(stderr, "ANN_CACHE_SIZE (%s) must be greater or equal "
                    "to 0 an less or equal to %d\n", argv[7], UINT16_MAX);
                return 6;
            }
            sml_ann_set_cache_max_size(ctx.sml, cache_size);
        }
        if (argc >= 9)
            sml_ann_use_pseudorehearsal_strategy(ctx.sml, atoi(argv[8]) != 0);
    }

    if (ctx.debug)
        print_scenario(&ctx);

    ctx.max_iteration_duration = -1;
    total_tic = clock();
    for (i = 0; i < ctx.reads; i++) {
        tic = clock();
        if ((error = sml_process(ctx.sml))) {
            fprintf(stderr, "=== Unexpected error in simulation. "
                "Error code: %d ===\n", error);
            break;
        }
        toc = clock();
        duration = ((double)toc - tic) / CLOCKS_PER_SEC;
        _process_results(&ctx, duration);
    }
    total_toc = clock();
    ctx.duration = ((double)total_toc - total_tic) / CLOCKS_PER_SEC;

    // scenario may changes thanks to new events created automatically
    if (ctx.debug) {
        print_scenario(&ctx);
        sml_print_debug(ctx.sml, true);
    }
    print_results(&ctx);

    sml_free(ctx.sml);

    g_list_free_full(ctx.inputs, free_variable);
    g_list_free_full(ctx.outputs, free_variable);
    g_list_free_full(ctx.expectations, free_expectation);
    g_list_free_full(ctx.expectation_blocks, free_element);
    g_rand_free(ctx.rand);

    return 0;
}