 }
 
 __device__ __host__
-double compute_lb_from_expr(expr_t* expr, const fppoly_t* const fp)
+double compute_lb_from_expr(expr_t* expr, double* input_inf, double* input_sup, expr_t** input_lexpr, expr_t** input_uexpr)
 {
         //printf("start\n");
         //fflush(stdout);
-    if((fp->input_lexpr != nullptr) && (fp->input_uexpr != nullptr))
-    {
-        expr = replace_input_poly_cons_in_lexpr(expr, fp);
+    if((input_lexpr != nullptr) && (input_uexpr != nullptr))
+    {
+        expr = replace_input_poly_cons_in_lexpr(expr, input_inf, input_sup, input_lexpr, input_uexpr);
     }
         //expr_print(expr);
     //fflush(stdout);


    else
    {
        elina_double_interval_mul(&tmp1, &tmp2, expr->inf_coeff[0], expr->sup_coeff[0], fp->input_inf[k], fp->input_sup[k]);
        res = create_cst_expr(tmp1, -tmp1);
    }


    }
}


void handle_final_non_relu_layer(fppoly_internal_t* pr, output_abstract_t* out, neuron_t** neurons, const size_t size)
{
    for(size_t i = 0; i < size; i++)
    {
        out->output_inf[i] = neurons[i]->lb;
        out->output_sup[i] = neurons[i]->ub;
    }
}


output_abstract_t* allocate_output_abstract(const size_t num_out_neurons)
{
    output_abstract_t* out = (output_abstract_t*) malloc(sizeof(output_abstract_t));
    out->output_inf = (double*) malloc(num_out_neurons*sizeof(double));
    out->output_sup = (double*) malloc(num_out_neurons*sizeof(double));
    out->lexpr = (expr_t**) malloc(num_out_neurons*sizeof(expr_t*));
    out->uexpr = (expr_t**) malloc(num_out_neurons*sizeof(expr_t*));

    return out;
}

void ffn_handle_last_layer(elina_manager_t* man, elina_abstract0_t* element, const double** weights, const double* bias, const size_t num_out_neurons, const size_t num_in_neurons, const bool has_activation, const activation_type_t activation)
{
    fppoly_t* fp = fppoly_of_abstract0(element);

    if(has_activation)
    {
        fppoly_add_new_layer(fp, num_out_neurons, FFN, activation);
    }
    else
    {
        fppoly_add_new_layer(fp, num_out_neurons, FFN, NONE);
    }

    fp->out = allocate_output_abstract(num_out_neurons);

    neuron_t** out_neurons = fp->layers[fp->numlayers - 1]->neurons;
    fppoly_internal_t* pr = fppoly_init_from_manager(man, ELINA_FUNID_ASSIGN_LINEXPR_ARRAY);

    layer_create_exprs(out_neurons, weights, bias, num_out_neurons, num_in_neurons);

    update_state_using_previous_layers(man, fp, fp->numlayers - 1);

    if(activation == RELU)
    {
