2
$\begingroup$

I have an equation, call it l1, that looks like this:

e1 = x*y*z + t*u*v + a*b*c

I was wondering if it would be possible to generate a boolean expression like this from any such given equation:

  ( (x==1 && y == 1 && z==1) && (t==0 && u==0 && v ==0) && (a==0 && b ==0 && c==0) || 
( ( (x==0 && y == 0 && z==0) && (t==1 && u==1 && v ==1) && (a==0 && b ==0 && c==0) ||
 ( (x==0 && y == 0 && z==0) && (t==0 && u==0 && v ==0) && (a==1 && b ==1 && c==1)

I.e., each variable in each term cyclically takes on the value 1 while the others are all zero. Is it possible to flexibly do this in Mathematica. Flexibly, in the sense that some equations may have 4 or 5 or 6 terms, and some of the terms may have 2 variables or 4 variables.

Thank you.

$\endgroup$
4
$\begingroup$

Update: An alternative method inspired by Roman's answer:

f0 = Reduce[{# == 1, ##& @@ Equal @@@ #, ##& @@ Thread[0<=Variables[#]<=1]}, Integers]&;

f0[x y z + t u v + a b c]

(a == 0 && b == 0 && c == 0 && t == 0 && u == 0 && v == 0 && x == 1 && y == 1 && z == 1) ||
(a == 0 && b == 0 && c == 0 && t == 1 && u == 1 && v == 1 && x == 0 && y == 0 && z == 0) ||
(a == 1 && b == 1 && c == 1 && t == 0 && u == 0 && v == 0 && x == 0 && y == 0 && z == 0)

f0[x y + t u v + a b c d;]

(a == 0 && b == 0 && c == 0 && d == 0 && t == 0 && u == 0 && v == 0 && x == 1 && y == 1) ||
(a == 0 && b == 0 && c == 0 && d == 0 && t == 1 && u == 1 && v == 1 && x == 0 && y == 0) ||
(a == 1 && b == 1 && c == 1 && d == 1 && t == 0 && u == 0 && v == 0 && x == 0 && y == 0)

Original answer:

You can use the approach in this answer after pre-processing the input expression to replace Plus with List:

e1 = x y z + t u v + a b c;
l1 = e1 /. Plus -> List

{a b c, t u v, x y z}

Or @@ Inner[Sequence @@ Thread[Equal[List @@ #2, #]] &, 
  IdentityMatrix[Length@l1], l1, And]

(a == 1 && b == 1 && c == 1 && t == 0 && u == 0 && v == 0 && x == 0 && y == 0 && z == 0) ||
(a == 0 && b == 0 && c == 0 && t == 1 && u == 1 && v == 1 && x == 0 && y == 0 && z == 0) ||
(a == 0 && b == 0 && c == 0 && t == 0 && u == 0 && v == 0 && x == 1 && y == 1 && z == 1)

This approach works for arbitrary number of terms in the input expression and arbitrary number of variables in each term:

e2 = x y + t u v + a b c d;
l2 = e2 /. Plus -> List

{a b c d, t u v, x y}

Or @@ Inner[Sequence @@ Thread[Equal[List @@ #2, #]] &, 
  IdentityMatrix[Length@l2], l2, And]

(a == 1 && b == 1 && c == 1 && d == 1 && t == 0 && u == 0 && v == 0 && x == 0 && y == 0) ||
(a == 0 && b == 0 && c == 0 && d == 0 && t == 1 && u == 1 && v == 1 && x == 0 && y == 0) ||
(a == 0 && b == 0 && c == 0 && d == 0 && t == 0 && u == 0 && v == 0 && x == 1 && y == 1)

$\endgroup$
  • $\begingroup$ Thanks @kglr this is excellent! $\endgroup$ – Thomas Moore Oct 26 at 4:20
1
$\begingroup$

As a combination of logical and numerical constraints,

(e1 /. {Times -> Equal, Plus -> And}) &&
e1 == 1 && 
Element[Variables[e1], Integers] && 
And @@ Thread[0 <= Variables[e1] <= 1]

(*    a == b == c && t == u == v && x == y == z &&
      a b c + t u v + x y z == 1 &&
      (a | b | c | t | u | v | x | y | z) \[Element] Integers && 
      0 <= a <= 1 && 0 <= b <= 1 && 0 <= c <= 1 &&
      0 <= t <= 1 && 0 <= u <= 1 && 0 <= v <= 1 &&
      0 <= x <= 1 && 0 <= y <= 1 && 0 <= z <= 1    *)

This gives the right answer:

Solve[%, Variables[e1]]

(*    {{a -> 0, b -> 0, c -> 0, t -> 0, u -> 0, v -> 0, x -> 1, y -> 1, z -> 1},
       {a -> 0, b -> 0, c -> 0, t -> 1, u -> 1, v -> 1, x -> 0, y -> 0, z -> 0},
       {a -> 1, b -> 1, c -> 1, t -> 0, u -> 0, v -> 0, x -> 0, y -> 0, z -> 0}}    *)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.