Minimizing a nonlinear user function

I would like to know if and how the problem discussed Here can be solved using JuMP’s “powerfull means”

This is the problem of day 24 of the advent of code 2024.

You are asked to “fix” a 45-bit full-adder that has 4 pairs of inverted gates.

The idea that I would like to implement (if possible) is the following.

The final and intermediate gates are in the variable Zk. I build a matrix Az (length(zk), length(zk)) by setting the diagonal (initial configuration) =1.

I define the functions that are needed to test the full-adder.
I give as input a series of powers of two and return the square of the difference with respect to the exact result.
I expect that in some way the optimizer changes configuration (i.e. modifies the matrix Az, appropriately exchanging pairs of gates) looking for the min of my f().
Can it be done?
How?

function parseinp()
    XY,Z=open("input_aoc24_d24.txt") do f 
        split(read(f, String), "\n\n")
    end
    XY=split.(split(XY, "\n"),": ")
    Z=split.(split(Z, "\n")," -> ")
    Z, XY
end



function mapkeyval(kz1,D,Z)
    prl(a,op,b)= op=="OR" ? a||b : op=="AND" ? a && b : xor(a, b)
    v=split.(first.(Z)," ")
    k=last.(Z)
    ikz=findfirst(==(kz1),k)
    l,op,r = v[ikz]
    if l in keys(D) && r in keys(D)
        D[kz1]=prl(D[l],op,D[r])
    elseif l in keys(D)
        ir=findfirst(==(r),k)
        D[kz1]=prl(D[l],op,mapkeyval(k[ir],D,Z))
    elseif r in keys(D)
        il=findfirst(==(l),k)
        D[kz1]=prl(mapkeyval(k[il],D,Z),op,D[r])
    else
        ir=findfirst(==(r),k)
        il=findfirst(==(l),k)
        D[kz1]=prl(mapkeyval(k[il],D,Z),op,mapkeyval(k[ir],D,Z))
    end
end

function swapz(Z,x,y)
    Z[x][2],Z[y][2]=Z[y][2],Z[x][2] 
end


function f(Az,Z,kz,kxy,kx,ky)
    for i in eachindex(Zk)
        for j in i:length(Zk)
            Az[Zk[i],Zk[j]]==1 && swapz(Z,i,j)
        end
    end
    mq=0
    for n in eachindex(kxy)
        D=Dict{String,Bool}()
        for key in kxy
            D[key]=false
        end
        for (i,d) in enumerate(digits(n, base=2))
            D[kx[i]]=d==1
            D[ky[i]]=d==1
        end
        mq+=(2n-reduce((s,c)->s*2+c, mapkeyval(j,D,Z) for j in kz ;init=0))^2
    end
    mq
end 

#########################





Z, XY=parseinp()
kz=sort(filter(e->startswith(e,"z"),Zk),rev=true)
kxy=first.(XY)
kx=[x for x in kxy if startswith(x,"x")]
ky=[x for x in kxy if startswith(x,"y")]


Zk=String.(last.(Z))
Az0=fill(false,length(Zk),length(Zk))
for i in eachindex(Zk)
    Az0[i,i] = true
end
d0=Dict{Tuple{String,String},Bool}()

for I in CartesianIndices(Az0)
    d0[(Zk[I[1]],Zk[I[2]])]=Az0[I[1],I[2]]
end

using JuMP

@variable(MFA, Az[i = Zk,j = Zk],Bin,start = d0[i,j])

@constraint(MFA, c[i=Zk], sum(Az[i,j] for j in Zk) == 1)

#objective(MFA, Min, f)

here you can download the file to do some tests

JuMP is not designed to optimize functions like this.

Take a read of Should you use JuMP? · JuMP?