model 'logpile'

! Description  : The Log Pile
! Source       : www.themadcowcompany.co.uk
! Date written : January 2005
! Written by   : M J Chlond

  uses 'mmxprs'

  parameters
    piece  = 10
    orient = 2
    posn   = 10
    slot   = 5
  end-parameters

  declarations
    PC = 1..piece
    OT = 1..orient
    PS = 1..posn
    SL = 1..slot
    P: array(PC,OT,SL) of integer
    x: array(PC,OT,PS) of mpvar
    y: array(PS,SL) of mpvar
  end-declarations

  P:= [1,0,1,0,0,
       0,0,1,0,1,
       
       1,-1,1,0,0,
       0,0,1,-1,1,

       1,0,0,1,0,
       0,1,0,0,1,

       1,0,-1,0,0,
       0,0,-1,0,1,

       1,0,-1,0,-1,
       -1,0,-1,0,1,

       0,1,0,1,-1,
       -1,1,0,1,0,

       0,1,0,-1,0,
       0,-1,0,1,0,

       -1,1,0,-1,0,
       0,-1,0,1,-1,

       -1,1,-1,0,0,
       0,0,-1,1,-1,

       -1,0,0,-1,-1,
       -1,-1,0,0,-1]
       
  forall(i in PC,j in OT,k in PS) x(i,j,k) is_binary
  forall(k in PS,s in SL) y(k,s) >= -1
    
  ! each piece in one position and one orientation     
  forall(i in PC) pce(i):= sum(j in OT,k in PS) x(i,j,k) = 1  

  ! each position has one piece in one orientation
  forall(k in PS) pos(k):= sum(i in PC,j in OT) x(i,j,k) = 1

  ! each solution cell sums to zero
  forall(i in 1..5,j in 1..5) cz(i,j):= y(i,j)+y(j+5,6-i) = 0
  
  ! solution cells consistent with piece positions
  forall(i in PC,j in OT,k in PS,s in SL) do
    ca(i,j,k,s):= y(k,s) >= P(i,j,s) - 2*(1-x(i,j,k))
    cb(i,j,k,s):= y(k,s) <= P(i,j,s) + 2*(1-x(i,j,k))
  end-do
  
  minimise(0)
 
  forall(k in PS) do
    forall(s in SL)
      write(getsol(y(k,s)),' ')
    writeln
  end-do  

end-model