# Define variable relationships and dynamically update variables

I would like to define a relationship between 3 variables first and then later when I have filled two of the variables with a number, I would like to extract the value of the last value.

For example:

a * b == c; (* Somehow define this *)
Attributes[GetValues] = {HoldAll}
GetValues[known_] := With[known, {a, b, c}]

GetValues[{a = 2, b = 3}] (* => {2, 3, 6} *)
GetValues[{a = 2, c = 10}] (* => {2, 5, 10} *)
GetValues[{b = 10, c = 10}] (* => {1, 10, 10} *)


Only two of the variables will be defined at a time and there should always be only one possible value for the last variable, if the other two values are valid.

You could possible to this with either Solve or Reduce, but how?

-

For very simple examples like your example you could use something like this:

GetValues[known_] := With[known, {a, b, c} /. First[Solve[a*b == c]]]


This works due to the undocumented (?) feature that Solve will work without a second argument and if only one unkown is left it seems to always be doing "the expected thing", e.g.:

Solve[23*x+5==6]


I'd be careful if I'd build something on that feature, though. With only minimal additional effort you can also construct a call to Solve explicitly solving for the remaining variable, which then uses documented behavior (I also added some protection from external definitions of a, b or c):

ClearAll[GetValues];
Attributes[GetValues] = {HoldAll};
GetValues[known_] := Block[{a, b, c},With[known,
{a, b, c} /. Solve @@ {a*b == c, Cases[{a, b, c}, _Symbol]}
]]


Either way: Depending on your requirements and real world relations, might want to add some checking of whether everything worked as intended...

-