Dynamic Constraints in JuMP

I am working on an iterative solution for a multi-period model. The approach involves solving the model for the initial time period (t=1), then using the outcome (specifically, the values of variable z) as parameters for the subsequent period (t=2), and repeating this process through all periods. A key aspect of this iterative approach is to update a summation within a constraint, turning variables into parameters based on their values from previous iterations, thereby keeping the model linear - the constraint include only a variable z[t] for that specific time period. This means dynamically generating constraints that adapt based on iteration results, with the aim of maintaining a linear model framework.
Below is a simplified version of the problem I am working with. The objective is to iteratively solve the model for each time period, retrieve the z variable values, and then use these values in a summation that replaces z[j] in the constraints. For example, the expression at time t =3, should be effectively equal to:
exp[3] = sum(a[i,t] * x_val[i] * (1 - sum(z_val[j] for j in 1:(3-1))) * z[3] for i in 1:n) so z[3] is the only variable here

function model(a, b, x_val)
    m = Model()  
    @variable(m, 0 <= z[1:T] <= 1)
    @expression(m, exp[t=1:T], t == 1 ? 
        sum(a[i,t] * x_val[i] * z[t] for i in 1:n) : 
        sum(a[i,t] * x_val[i] * (1 - sum(z[j] for j in 1:(t-1))) * z[t] for i in 1:n))
    @constraint(m, iv[t=1:T], exp[t] == b[t])
    optimize!(m)
    return m
end

I am looking for guidance on a logical method to iteratively solve this model, where constraints are dynamically generated by indexing t and converting variables to parameters based on the output from previous iterations Any insights or suggestions on improving the code to achieve this iterative mechanism effectively would be greatly appreciated.

Thank you in advance for your help!

I’m not sure I fully understand what you’re trying to achieve (how will your multistage approach take into account the cost of future decisions? It it just a myopic policy?).

JuMP doesn’t support turning variables into parameters. You’ll need to write a function that takes in a list of prior z values and returns a new z value.

I didn’t test, so I might have made a typo, but this should point you in the right direction.

function create_model(a, b, x_val, z_val)
    model = Model()  
    @variable(model, 0 <= z <= 1)
    @constraint(model, a[:, t]' * x_val * (1 - sum(z_val)) * z[t] == b[t])
    optimize!(model)
    return value(z)
end