Here's a modification of the OP's approach that will transform an expression only if it is a list of list of rules:
{{a -> 5, b -> 4}, {a -> 2, b -> 3}} //
Replace[{r : {__Rule} ..} :> (And @@ Equal @@@ # &) /@ Or[r]]
(* (a == 5 && b == 4) || (a == 2 && b == 3) *)
If we use ReplaceAll
instead of Replace
, then it would potentially transform a subexpression that matched the pattern.
To get something that would transform an expression consisting of a single solution {a -> 5, b -> 4}
or a list of solutions, then the following modification would work:
{a -> 5, b -> 4} //
Replace[
s_List :> (Replace[s,
r : {__Rule} :> And @@ Equal @@@ r, {0, 1}] //
Replace[{sys__And} :> Or[sys]])
]
(* a == 5 && b == 4 *)
{{a -> 5, b -> 4}, {a -> 2, b -> 3}} //
Replace[
s_List :> (Replace[s,
r : {__Rule} :> And @@ Equal @@@ r, {0, 1}] //
Replace[{sys__And} :> Or[sys]])
]
(* (a == 5 && b == 4) || (a == 2 && b == 3) *)
Again, we use Replace
instead of ReplaceAll
to make sure the expression has the correct form of a solution.
Here's another way:
{{a -> 5, b -> 4}, {a -> 2, b -> 3}} // Replace[
sol : {{__Rule} ..} :>
Apply[Or, Apply[And, Apply[Equal, sol, {2}], {1}], {0}]
]
(* (a == 5 && b == 4) || (a == 2 && b == 3) *)
The nested Apply
is really a Fold
operation, but the explicit nesting is shorter than the following Fold
:
{{a -> 5, b -> 4}, {a -> 2, b -> 3}} // Replace[
sol : {{__Rule} ..} :> Fold[
Function[{s, f}, Apply[First@f, s, {Last@f}]],
sol,
Transpose[{{Equal, And, Or}, Range[2, 0, -1]}]]
]
(* (a == 5 && b == 4) || (a == 2 && b == 3) *)
Any of the Replace
methods can be packaged as a function instead of an anonymous operator. For example:
toEquations[sol : {{__Rule} ..}] :=
Apply[Or, Apply[And, Apply[Equal, sol, {2}], {1}], {0}];
... /. Rule->Equal
? $\endgroup$solution // Apply[Or] // MapApply[And] // Apply[Equal, #, {2}] &
this works, but only if there's at least two solutions and at least two rules in each solution, otherwise it doesn't error out but produces completely incorrect output. I'm trying to rewrite it in a way where I can be more sure it isn't doing something wrong. $\endgroup$