Here is a Z3 model. Z3 is a theorem prover from Microsoft. The model is very similar to the MIP model proposed earlier.
Enumerating integer solutions in a MIP is not totally trivial (it can be done with some effort [link] or using the "solution pool" technology in advanced MIP solvers). With Z3 this is a bit easier. Even easier could be to use a Constraint Programming (CP) solver: they can enumerate solutions automatically.
Here we go:
from z3 import *
A = [[1, 2, 1], [3, 1, -1]]
b = [20, 12]
n = len(A[0]) # number of variables
m = len(b) # number of constraints
X = [ Int('x%d' % i) for i in range(n) ]
s = Solver()
s.add(And([ X[i] >= 0 for i in range(n) ]))
for i in range(m):
s.add( Sum([ A[i][j]*X[j] for j in range(n) ]) == b[i])
while s.check() == sat:
print(s.model())
sol = [s.model().evaluate(X[i]) for i in range(n)]
forbid = Or([X[i] != sol[i] for i in range(n)])
s.add(forbid)
It solves
x0+2x1+x2 = 20
3x0+x1-x2 = 12
The solutions looks like:
[x2 = 2, x0 = 2, x1 = 8]
[x2 = 7, x1 = 4, x0 = 5]
[x2 = 12, x1 = 0, x0 = 8]
We can print the final model so we can see how the "forbid" constraints were added:
[And(x0 >= 0, x1 >= 0, x2 >= 0),
1*x0 + 2*x1 + 1*x2 == 20,
3*x0 + 1*x1 + -1*x2 == 12,
Or(x0 != 2, x1 != 8, x2 != 2),
Or(x0 != 5, x1 != 4, x2 != 7),
Or(x0 != 8, x1 != 0, x2 != 12)]