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
_output_state_changed_cb(struct sml_object *sml,
    struct sml_variables_list *changed, void *data)
{
    uint16_t i, j, len, changed_len, found = 0;
    struct sml_variable *var, *changed_var;
    struct sml_variables_list *list;
    Context *ctx = data;
    char var_name[SML_VARIABLE_NAME_MAX_LEN + 1];

    printf("SML Change State {");
    list = sml_get_output_list(sml);
    changed_len = sml_variables_list_get_length(sml, changed);
    len = sml_variables_list_get_length(sml, list);
    for (i = 0; i < len; i++) {
        var = sml_variables_list_index(sml, list, i);
        for (j = 0; j < changed_len; j++) {
            changed_var = sml_variables_list_index(sml, list, j);
            if (var == changed_var) {
                ctx->output_state_changed_outputs[i] = sml_variable_get_value(
                    sml, var);
                if (found++ > 0)
                    printf(", ");
                if (!sml_variable_get_name(sml, var, var_name,
                    sizeof(var_name)))
                    printf("%s: %f", var_name,
                        ctx->output_state_changed_outputs[i]);
            }
        }
    }
    printf("}\n");
}
static void
_initialize_context(Context *ctx, struct sml_object *sml)
{
    struct sml_variables_list *output_list = sml_get_output_list(sml);
    uint16_t len = sml_variables_list_get_length(sml, output_list);

    memset(ctx, 0, sizeof(Context));
    ctx->outputs = malloc(sizeof(float) * len);
    ctx->expected_outputs = malloc(sizeof(float) * len);
    ctx->output_state_changed_outputs = malloc(sizeof(float) * len);
    ctx->stats = calloc(1, sizeof(Stat) * len);
}
static bool
_read_state_cb(struct sml_object *sml, void *data)
{
    int *executions = data;

    if (*executions == 0)
        return false;
    (*executions)--;

    struct sml_variables_list *input_list, *output_list;

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

    _set_list_values(sml, input_list);
    _set_list_values(sml, output_list);

    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;
}