# A function that (also) changes a replacement rule

I'd like to write a function operating on a list, returning a list, but also changing a replacement rule. Let's say I have a list of replacement rules:

data={
...
a->3,
...
};


Now I write a function:

f1[{b_,c_}]:={b+1,c+1};


What I would also like this function to do is to change the replacement rule of data list, so that after the function is evaluated (with any list as an input), the variable a would take the value of the evaluated c+1 expression, or f1[[2]] if You will. Seems like an easy task, but somehow confuses me.

Edit:

As an input I would like a list l={2,3}, and {3,4} as an output, and a replacement rule a->3 changed into a->f1[[2]].

In general, my problem is that I want another function later on to access a value produced by f1, but I would like that other function to call this value from external list and not explicitly from f1.

-
Not very clear what you want to achieve... something along {1, 2, a -> 3} /. (a -> _) :> b -> 3? –  Yves Klett Nov 14 '13 at 9:40
I would like f1 to work on list other than data, let's say l={2,3} and to change replacement rule specified in data as well, if that is what You're asking. In other words, as an output i would like to get {3,4} and whenever I call a after the evaluation, I'd like to get 4. –  Wojciech Nov 14 '13 at 9:54
Please give an explicit example of I/O in the question. –  Yves Klett Nov 14 '13 at 9:58
Still unclear to me, since data is a replacement list that does not affect the value of a. But If you want to change the rule for a in the replacement list Yves suggestion can be adapted to do what you need: first compute f1, then change the rule list with data /. Rule[a,_]:>Rule[a,f1[[2]]] and finally use a /. data to get the value. If you want to assign a value to a, why use the replacement list? –  Peltio Nov 14 '13 at 12:09

Let me expand the comment. If the list of replacement rules data is to be considered a global variable, you can access it from within your function and alter its value in this way

data = {a->3, ab->2, ac->1, ad->0};

f1[{b_,c_}]:=Block[{tmp},
tmp = {b+1, c+1};
data = data /. Rule[a,_]:>Rule[a,tmp[[2]]]
]


This will produce a new value for the list of rules data where the rule associated with a is changed.

f1[{2,3}]


{a -> 4, ab -> 2, ac -> 1, ad -> 0}

If you do not wish to see the list of rules, just put a semicolon at the end of the last line of code. You can even have f1 to return the list {b+1,c+1} in this way:

f1[{b_,c_}]:=Block[{tmp},
tmp = {b+1, c+1};
data = data /. Rule[a,_]:>Rule[a,tmp[[2]]];
tmp
]


Once you have evaluated f1,

f1[{2,3}]


{3, 4}

to get the value of a, you will use

a /. data


4

-
Perfect, that's exactly what I needed. I almost figured it out myself, that answer came just in time. Peltio , @Yves Klett I'll make sure to give You some credit in my thesis! –  Wojciech Nov 14 '13 at 12:52
If I would like to change also replacement rule for ab in data list, I can make data = data /. Rule[a,_]:>Rule[a,tmp[[2]]]; data = data /. Rule[ab,_]:>Rule[ab,tmp[[1]]]; inside Block[], is there a shorter way to do that, just in case I want to change more rules? –  Wojciech Nov 15 '13 at 9:21
You can use data = data /. {Rule[a, _] :> Rule[a, tmp[[2]]], Rule[ab, _] :> Rule[ab, tmp[[1]]]}. Of course if you have dozens of such replacements, we could create a more elaborate replacement rule or better yet, a function that accepts the names of the variables whose rules should be changed and the position in the list of the associated new values. –  Peltio Nov 15 '13 at 11:06
Great, thanks a lot! –  Wojciech Nov 15 '13 at 12:24

Simply this?

f1[{b_, c_}] := Module[{a, d},
data = {a -> 8, d -> 7};
{a, d} = {b + 1, c + 1};
{a, d} /. data]
f1[{2, 3}]


(8, 7}

Further to OP's comment ...

data = {a -> 8, d -> 7};
f1[{b_, c_}] := Module[{},
{a, d} = {b + 1, c + 1};
{a, d} /. data]
f1[{2, 3}]


(8, 7}

-
Thanks, but that's not exactly what i was looking for. The replacement rule to be changed has to be defined outside of the function. –  Wojciech Nov 14 '13 at 10:55