static bool
_do_prediction(Context *ctx)
{
    char *result = "";
    float prediction;

    sml_variable_set_value(ctx->sml, ctx->offense1, ctx->val_offense1);
    sml_variable_set_value(ctx->sml, ctx->defense1, ctx->val_defense1);
    sml_variable_set_value(ctx->sml, ctx->offense2, ctx->val_offense2);
    sml_variable_set_value(ctx->sml, ctx->defense2, ctx->val_defense2);
    sml_variable_set_value(ctx->sml, ctx->winner, NAN);

    sml_predict(ctx->sml);
    ctx->reads++;
    prediction = roundf(sml_variable_get_value(ctx->sml, ctx->winner));

    if (!isnan(prediction)) {
        ctx->predictions++;
        if (ctx->val_winner == ((int)prediction)) {
            ctx->rights++;
            result = "right";
        } else
            result = "wrong";
    }

    printf("Game %d team 1 (%d, %d) x team2 (%d, %d): predicted winner: %.0f "
        "real winner: %d %s\n", ctx->reads,
        ctx->val_offense1, ctx->val_defense1, ctx->val_offense2,
        ctx->val_defense2, prediction, ctx->val_winner, result);


    return true;
}
static bool
read_state_cb(struct sml_object *sml, void *data)
{
    float time, weekday;
    Context *ctx = data;
    GList *itr;

    time = get_time(ctx);
    weekday = get_weekday(ctx->read_counter, ctx->read_freq);

    if (ctx->time)
        sml_variable_set_value(sml, ctx->time, time);
    if (ctx->weekday)
        sml_variable_set_value(sml, ctx->weekday, weekday);

    if (ctx->debug)
        printf("%i::READ(%i%%) - Weekday:%s, TB: %d\n", ctx->read_counter,
            ctx->read_counter  * 100 / ctx->reads, WEEKDAYS[(int)weekday],
            (int)time);

    for (itr = ctx->inputs; itr; itr = itr->next) {
        Variable *var = itr->data;
        variable_set_value(sml, var, ctx->read_counter, ctx->debug, ctx->rand);
    }

    for (itr = ctx->outputs; itr; itr = itr->next) {
        Variable *var = itr->data;
        variable_set_value(sml, var, ctx->read_counter, ctx->debug, ctx->rand);
    }

    ctx->read_counter++;

    return true;
}
static bool
_read_state_cb(struct sml_object *sml, void *data)
{
    struct sml_variable *temperature_var, *presence_var, *power_var;
    struct sml_variables_list *input_list, *output_list;
    Air_Conditioner_Controller *acc = data;
    float temp, presence, power;

    input_list = sml_get_input_list(sml);
    output_list = sml_get_output_list(sml);

    temperature_var = sml_variables_list_index(sml, input_list,
        VAR_TEMPERATURE);
    presence_var = sml_variables_list_index(sml, input_list, VAR_PRESENCE);
    power_var = sml_variables_list_index(sml, output_list, VAR_POWER);

    if (!_read_sensor_values(acc, &temp, &presence, &power))
        return false;

    sml_variable_set_value(sml, temperature_var, temp);
    sml_variable_set_value(sml, presence_var, presence);
    sml_variable_set_value(sml, power_var, power);

    sml_print_debug(sml, false);
    return true;
}
static void
_set_list_values(struct sml_object *sml, struct sml_variables_list *list)
{
    unsigned int i, len;
    struct sml_variable *sml_variable;

    len = sml_variables_list_get_length(sml, list);
    for (i = 0; i < len; i++) {
        sml_variable = sml_variables_list_index(sml, list, i);
        sml_variable_set_value(sml, sml_variable, rand());
    }
}
static void
variable_set_value(struct sml_object *sml, Variable *var, int reads, bool debug,
    GRand *rand)
{
    Event *event;
    Status_Event *status_event;
    float value;

    event = get_event(var->events, reads);
    if (!event) {
        fprintf(stderr, "Failed to find event %s for reads: %d\n", var->name,
            reads);
        return;
    }
    if (!is_nan_event(event)) {
        if (event == var->last_event) {
            value = event_get_value_with_deviation(rand, var->cur_value,
                event->term, var);
        } else {
            value = event_get_value(event, rand);
            var->last_event = event;
        }
        if (!isnan(value))
            var->guess_value = var->cur_value = value;
    } else
        var->cur_value = var->guess_value;

    status_event = get_status_event(var->status_events, reads);
    if (debug) {
        printf("\tVar: %s %f", var->name, var->cur_value);
        if (event->term)
            printf(" - %s", event->term->name);
        if (status_event)
            printf(status_event->enabled ? " enabled" : " disabled");
        printf("\n");
    }

    sml_variable_set_value(sml, var->sml_var, var->cur_value);
    if (status_event)
        sml_variable_set_enabled(sml, var->sml_var, status_event->enabled);
}
static bool
_read_state_cb(struct sml_object *sml, void *data)
{
    Context *ctx = data;

    if (ctx->first_train) {
        sml_variable_set_value(sml, ctx->offense1, ctx->val_offense1);
        sml_variable_set_value(sml, ctx->defense1, ctx->val_defense1);
        sml_variable_set_value(sml, ctx->offense2, ctx->val_offense2);
        sml_variable_set_value(sml, ctx->defense2, ctx->val_defense2);
        sml_variable_set_value(ctx->sml, ctx->winner, ctx->val_winner);
    } else {
        sml_variable_set_value(sml, ctx->offense1, ctx->val_offense2);
        sml_variable_set_value(sml, ctx->defense1, ctx->val_defense2);
        sml_variable_set_value(sml, ctx->offense2, ctx->val_offense1);
        sml_variable_set_value(sml, ctx->defense2, ctx->val_defense1);
        if (ctx->val_winner == WINNER_NONE)
            sml_variable_set_value(ctx->sml, ctx->winner, WINNER_NONE);
        else if (ctx->val_winner == WINNER1)
            sml_variable_set_value(ctx->sml, ctx->winner, WINNER2);
        else
            sml_variable_set_value(ctx->sml, ctx->winner, WINNER1);
    }


    return true;
}
/*
 * Read sensors values stored in data file
 */
static bool
_read_state_cb(struct sml_object *sml, void *data)
{
    uint16_t i, ind, input_len, output_len, tokens_len;
    float value;
    char line[LINE_LEN];
    char **tokens;
    Context *ctx = data;
    struct sml_variables_list *input_list, *output_list;
    struct sml_variable *sml_variable;
    char var_name[SML_VARIABLE_NAME_MAX_LEN + 1];

    input_list = sml_get_input_list(sml);
    output_list = sml_get_output_list(sml);
    input_len = sml_variables_list_get_length(sml, output_list);
    output_len = sml_variables_list_get_length(sml, output_list);

    if (!_read_line(ctx->f, line, LINE_LEN))
        return false;

    tokens = g_strsplit(line, " ", 0);
    if (!tokens)
        return false;

    tokens_len = g_strv_length(tokens);
    if (tokens_len < input_len + output_len) {
        fprintf(stderr, "Line in file has not enought data\n");
        g_strfreev(tokens);
        return false;
    }

    printf("Reading sensors: Inputs {");
    for (i = 0; i < input_len; i++) {
        sml_variable = sml_variables_list_index(sml, input_list, i);
        value = atof(tokens[i]);
        sml_variable_set_value(sml, sml_variable, value);
        if (i != 0)
            printf(", ");
        if (!sml_variable_get_name(sml, sml_variable, var_name,
            sizeof(var_name)))
            printf("%s: %f", var_name, value);
    }
    printf("}, Outputs {");

    for (i = 0; i < output_len; i++) {
        sml_variable = sml_variables_list_index(sml, output_list, i);
        value = atof(tokens[input_len + i]);
        ctx->outputs[i] = value;
        sml_variable_set_value(sml, sml_variable, value);
        if (i != 0)
            printf(", ");
        if (!sml_variable_get_name(sml, sml_variable, var_name,
            sizeof(var_name)))
            printf("%s: %f", var_name, value);
    }
    printf("}, Expected {");

    for (i = 0; i < output_len; i++) {
        ind = input_len + output_len + i;
        sml_variable = sml_variables_list_index(sml, output_list, i);
        if (i != 0)
            printf(", ");
        if (!sml_variable_get_name(sml, sml_variable, var_name,
            sizeof(var_name)))
            printf("%s: ", var_name);
        if (ind < tokens_len && tokens[ind][0] != 0 && tokens[ind][0] != '?') {
            ctx->expected_outputs[i] = atof(tokens[ind]);
            printf("%f", ctx->expected_outputs[i]);
        } else {
            printf("?");
            ctx->expected_outputs[i] = NAN;
        }
    }
    printf("}\n");
    g_strfreev(tokens);

    for (i = 0; i < output_len; i++)
        ctx->output_state_changed_outputs[i] = NAN;

    ctx->read_count++;
    return true;
}