9
$\begingroup$

I found the necessity for the following procedure and was surprised I couldn't find a built-in function to do the following. I include my solution in case someone needs the same functionality, but if there exists a built in feature that I'm not aware of please feel free to share.

Suppose using Reduce, I have created a set of conditions for a system of equations:

(a == 1 && b == 2 && c == 0)

What is an easy way to convert these equalities into a set of replacement rules so that they may be inserted back into an equation?

a + b x + c x^2

I.e., what is a method for converting the set of conditions shown above into the following form?

{a -> 1, b -> 2, c -> 0}
$\endgroup$
3
  • 3
    $\begingroup$ @SjoerdSmit I seem to have a bad habit of consistently write inequality instead of equality :D $\endgroup$
    – akozi
    Commented Apr 25, 2022 at 14:40
  • 4
    $\begingroup$ I think we have 10 ways of doing it by now :-) $\endgroup$
    – bmf
    Commented Apr 25, 2022 at 15:20
  • 1
    $\begingroup$ That should do for now. $\endgroup$
    – rhermans
    Commented Apr 27, 2022 at 6:59

10 Answers 10

20
$\begingroup$

With:

eqns = (a == 1 && b == 2 && c == 0)

Just use a built-in function:

ToRules[eqns]

{a -> 1, b -> 2, c -> 0}


If, however, you want to do the same using list processing:

TreeForm /@ {eqns, Rule @@@ List @@ eqns}

Enter image description here

$\endgroup$
1
  • 5
    $\begingroup$ Haha! Brilliant, there is a built-in function for that. $\endgroup$
    – rhermans
    Commented Apr 25, 2022 at 14:05
9
$\begingroup$

I expect there will be many solutions, probably the best alternative is to use ToRules, as suggested by @Syed.

Anyhow, here I present you with two other simple ways.

ReplaceAll

If you understand the internal representation (FullForm) of your list, by looking at

FullForm[(a == 1 && b == 2 && c == 0)]
(* And[Equal[a,1],Equal[b,2],Equal[c,0]] *)

then you could use ReplaceAll

ReplaceAll[
   (a == 1 && b == 2 && c == 0)
   ,{And->List,Equal->Rule}
]
(* {a->1,b->2,c->0}  *)

Solve

Another option would be to just Solve it

Solve[(a == 1 && b == 2 && c == 0)]
(* {{a->1,b->2,c->0}}  *)
$\endgroup$
9
$\begingroup$

Another way is the following:

ReplaceAll[Equal -> Rule][Level[eqns, {1}]]
(*{a -> 1, b -> 2, c -> 0}*)
$\endgroup$
2
  • 1
    $\begingroup$ Hello there 10-ways team :) $\endgroup$
    – bmf
    Commented Apr 25, 2022 at 15:57
  • 1
    $\begingroup$ Hi @bmf, the ten ways team is active :) $\endgroup$ Commented Apr 25, 2022 at 16:00
8
$\begingroup$

Another way is to use Block. It uses the same idea that @rhermans suggested as you see; it redefines List and Equal.

rules = Block[{And = List, Equal = Rule}, eqns]

block

$\endgroup$
5
$\begingroup$

My method was to simply use a table to iterate over each element of the collection of equality and re-write them as a replacement rule:

cond = (a == 1 && b == 2 && c == 0)
rule = Table [ cond[[i, 1]] -> cond[[i, 2]], {i, Length[cond]}]
a + b x + c x^2 /. rule
(* 1 + 2 x *)

Which works well to give the desired result.

$\endgroup$
4
$\begingroup$

Since we did all the normal ways, the following is fun.

Extract the values and the parameters from the output of Reduce using Apply and Part and then Thread to create a list of rules:

eqns = (a == 1 && b == 2 && c == 0);

values = Apply[List, eqns[[All, 2]]];
var = Apply[List, eqns[[All, 1]]];

Thread[var -> #] &@values

thread

$\endgroup$
4
$\begingroup$

Similarly, one can go about it in the following manner:

eqns = (a == 1 && b == 2 && c == 0);
values = Apply[List, eqns[[All, 2]]];
var = Apply[List, eqns[[All, 1]]];
Rule @@@ Transpose@{var, values}

res

$\endgroup$
4
$\begingroup$

Another way of obtaining the desired output is:

eqns = (a == 1 && b == 2 && c == 0);
values = Apply[List, eqns[[All, 2]]];
var = Apply[List, eqns[[All, 1]]];
Inner[Rule, var, values, List]

output

$\endgroup$
4
$\begingroup$

The following also works:

eqns = (a == 1 && b == 2 && c == 0);
values = Apply[List, eqns[[All, 2]]];
var = Apply[List, eqns[[All, 1]]];
# -> #2 & @@@ Transpose[{var, values}]

res

$\endgroup$
2
$\begingroup$
eqns = (a == 1 && b == 2 && c == 0);

Using MapApply (new in 13.1)

MapApply[Rule] @ Apply[List] @ eqns

{a -> 1, b -> 2, c -> 0}

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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