/* Logical design problem in Picat. From H. Paul Williams "Model Building in Mathematical Programming", 4th edition The Logical design problem, sections 12.12, 13.12 and 14.12. This program was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import cp. main => go. go => IVal = 7, MaxI = 1..IVal, IIVal = 3, MaxII = 1..IIVal, JVal = 2, MaxJ = 1..JVal, KVal = 4, MaxK = 1..KVal, Alpha = [[0,0],[0,1],[1,0],[1,1]], In = new_array(IVal,JVal), In :: 0..1, Out = new_array(IVal,KVal), Out :: 0..1, Nor = new_list(IVal), Nor :: 0..1, Number #= sum(Nor), foreach(I in MaxI, J in MaxJ) Nor[I]-In[I,J] #>= 0 end, foreach(I in 1..1) Nor[2]+Nor[3] + sum([In[I,J] : J in MaxJ]) #<= 2 end, foreach(I in 2..2) Nor[4]+Nor[5] + sum([In[I,J] : J in MaxJ]) #<= 2 end, foreach(I in 3..3) Nor[6]+Nor[7] + sum([In[I,J] : J in MaxJ]) #<= 2 end, foreach(K in MaxK, I in MaxII) Out[2*I,K]+Out[I,K] #<= 1 end, foreach(K in MaxK, I in 1..1) Out[3,K]+Out[I,K] #<= 1 end, foreach(K in MaxK, I in 2..2) Out[5,K]+Out[I,K] #<= 1 end, foreach(K in MaxK, I in 3..3) Out[7,K]+Out[I,K] #<= 1 end, foreach(K in MaxK, I in MaxI, J in MaxJ) Alpha[K,J]*In[I,J]+Out[I,K] #<= 1 end, foreach(K in MaxK, I in 1..1) Out[2,K]+Out[3,K]+sum([Alpha[K,J]*In[I,J] : J in MaxJ])+Out[I,K]-Nor[I] #>= 0 end, foreach(K in MaxK, I in 2..2) Out[4,K]+Out[5,K]+sum([Alpha[K,J]*In[I,J] : J in MaxJ]) +Out[I,K]-Nor[I] #>= 0 end, foreach(K in MaxK, I in 3..3) Out[6,K]+Out[7,K]+sum([Alpha[K,J]*In[I,J] : J in MaxJ]) +Out[I,K]-Nor[I] #>= 0 end, foreach(K in MaxK, I in 4..7) sum([Alpha[K,J]*In[I,J] : J in MaxJ])+Out[I,K]-Nor[I] #>= 0 end, foreach(I in MaxI, K in MaxK) Nor[I]-Out[I,K] #>= 0 end, foreach(I in MaxI) Nor[I] #<= 1 end, foreach(I in MaxI, J in MaxJ) In[I,J] #<= 1 end, foreach(I in 2..7, K in MaxK) Out[I,K] #<= 1 end, foreach(I in 1..1, K in 1..1) Out[I,K] #= 0 end, foreach(I in 1..1, K in 2..2) Out[I,K] #= 1 end, foreach(I in 1..1, K in 3..3) Out[I,K] #= 1 end, foreach(I in 1..1, K in 4..4) Out[I,K] #= 0 end, Nor[1] #>= 1, Vars = In ++ Out, solve($[min(Number)],Vars), println(number=Number), println(nor=Nor), println("In:"), foreach(Row in In) println(Row.to_list) end, println("Out:"), foreach(Row in Out) println(Row.to_list) end, nl.