Volume 7, Number 3, May 2007
witness.mod
 
# Model name   : witness.mod
# Description  : Shifty Witnesses puzzle
# Source       : Puzzling Adventures, Dennis E. Shasha
# Date written : 13/11/06
# Written by   : Martin Chlond, Lancashire Business School
# Email        : mchlond@uclan.ac.uk

param m integer > 0;
param n integer > 0; 

set M := 1..m;   # witnesses
set N := 1..n;   # suspects

param d{j in N}; # number of witnesses saying 'has drugs' for each suspect

var v{i in M,j in N} binary;   # v[i,j] = 1 if witness i states truly that suspect j has drugs, else 0
var w{i in M,j in N} binary;   # w[i,j] = 1 if witness i states truly that suspect j has no drugs, else 0
var x{j in N} binary;          # x[j] = 1 if suspect j has drugs, else 0
var y{i in M,j in N} binary;   # y[i,j] = 1 if witness i states that suspect j has drugs, else 0

# number of witness saying 'has drugs' for each suspect consistent with puzzle
witcon{j in N}: sum{i in M} y[i,j] = d[j];

# set tell truth 'has drugs' variables
ttha{i in M,j in N}: y[i,j]+x[j]-v[i,j] <= 1;
tthb{i in M,j in N}: y[i,j]+x[j]-2*v[i,j] >= 0;

# set tell truth 'no drugs' variables
ttna{i in M,j in N}: y[i,j]+x[j]+w[i,j] >= 1;
ttnb{i in M,j in N}: y[i,j]+x[j]+2*w[i,j] <= 2;

# total lies either 8 or 9 (i.e. total truths 41 or 42)
tliea: sum{i in M,j in N} (v[i,j]+w[i,j]) >= 41;
tlieb: sum{i in M,j in N} (v[i,j]+w[i,j]) <= 42;

# more truths regarding 'has drugs' statements
trh: sum{i in M,j in N} v[i,j] - sum{i in M, j in N} w[i,j] >= 1;

solve;


for{j in N} {
  printf x[j];
  printf " ";
}

data;

param m := 5;
param n := 10;

param d := [1] 5,[2] 0,[3] 2,[4] 5,[5] 4,[6] 0,[7] 3,[8] 5,[9] 0,[10] 1;

end;