Skip to main content
deleted 10 characters in body
Source Link
Feyre
  • 8.7k
  • 2
  • 29
  • 48
boolfind[boolfind[mboolfind[m == n == o && p == q]]q]
boolfind[boolfind[m == n == o && p == q]]
boolfind[m == n == o && p == q]
added 874 characters in body
Source Link
Feyre
  • 8.7k
  • 2
  • 29
  • 48

If you need to accept instances of a single unpaired variable, you need add this to margins, and remove these from the FindInstance[] expression:

boolfind[set_, vars_] := Module[{l, margins},
  l = Range@Length@set;
  If[Depth@set > 3, set = set[[1]]];
  margins = 
   Flatten[{Cases[set /. And -> List, a_ == b_][[All, 1]], 
     Cases[set /. And -> List, a_ != b_] /. Unequal -> List, 
     Select[set /. And -> List, Length[#] == 0 &]}];
  margins = 
   Greater @@ (margins + Table[9 (i - 1), {i, Length@margins}]);
  FindInstance[
   Flatten[{Select[set /. And -> List, Length[#] > 0 &], margins, 
     Thread[vars > -1]}], vars, Reals]]

Then it works:

boolfind[(m == i && o == n && p != q && r), {i, m, n, o, p, q, r}]

{{i -> 40, m -> 40, n -> 30, o -> 30, p -> 20, q -> 10, r -> 0}}

If you need to accept instances of a single unpaired variable, you need add this to margins, and remove these from the FindInstance[] expression:

boolfind[set_, vars_] := Module[{l, margins},
  l = Range@Length@set;
  If[Depth@set > 3, set = set[[1]]];
  margins = 
   Flatten[{Cases[set /. And -> List, a_ == b_][[All, 1]], 
     Cases[set /. And -> List, a_ != b_] /. Unequal -> List, 
     Select[set /. And -> List, Length[#] == 0 &]}];
  margins = 
   Greater @@ (margins + Table[9 (i - 1), {i, Length@margins}]);
  FindInstance[
   Flatten[{Select[set /. And -> List, Length[#] > 0 &], margins, 
     Thread[vars > -1]}], vars, Reals]]

Then it works:

boolfind[(m == i && o == n && p != q && r), {i, m, n, o, p, q, r}]

{{i -> 40, m -> 40, n -> 30, o -> 30, p -> 20, q -> 10, r -> 0}}

Source Link
Feyre
  • 8.7k
  • 2
  • 29
  • 48

You seem to want to do all of this programmatically, this is possible, but not worth the effort unless you have to do this many times.

Suppose our boolean function is stored in set;

set = ((n == n && i == m) || (n == m && i == n)) && ((o == n && 
      i == i) || (o == i && i == n));

It is possible this gives multiple solutions, here we'll only treat the first one. We'll need to extract the variables we're using too.

If[Depth@set > 3, set = set[[1]]];
vars = {i ,m ,n ,o};

We now have the tools to solve any set of bools, all we need now is a programmatic way of introducing the margin:

margins = 
  Flatten[{Cases[set /. And -> List, a_ == b_][[All, 1]], 
    Cases[set /. And -> List, a_ != b_] /. Unequal -> List}];
margins = Greater @@ (margins + Table[9 (i - 1), {i, Length@margins}])

We can then run the FindInstance[], here I also make sure all values are positive:

FindInstance[Flatten[{set, margins, Thread[vars >= -1]}], vars]

{{i -> 0, m -> 0, n -> 10, o -> 10}}

You can turn the whole thing into a function:

boolfind[set_, vars_] := Module[{l, margins},
  l = Range@Length@set;
  If[Depth@set > 3, set = set[[1]]];
  margins = 
   Flatten[{Cases[set /. And -> List, a_ == b_][[All, 1]], 
     Cases[set /. And -> List, a_ != b_] /. Unequal -> List}];
  margins = 
   Greater @@ (margins + Table[9 (i - 1), {i, Length@margins}]);
  FindInstance[Flatten[{set, margins, Thread[vars > -1]}], vars, 
   Reals]]

and run it:

boolfind[boolfind[m == n == o && p == q]]

{{m -> 0, n -> 0, o -> 0, p -> 10, q -> 10}}

boolfind[m == n == o && p == q == x]

{{m -> 10, n -> 10, o -> 10, p -> 0, q -> 0, x -> 0}}

boolfind[(m == i && o == n && p != q && r != t), {i, m, n, o, p, q, r, t}]

{{i -> 50, m -> 50, n -> 40, o -> 40, p -> 30, q -> 20, r -> 10, t -> 0}}

There's some things this doesn't take care of, but the examples you've given work with this.