5
Cos[a - b] /. {a -> 0, b -> 0}

gives 1

However,

<|1 -> Cos[a - b]|> /. {a -> 0, b -> 0}

gives

<|1 -> Cos[0 - 0]|>

The Cos[0 - 0] does not evaluate.

Even FullSimplify doesn't help

<|1 -> Cos[a - b]|> /. {a -> 0, b -> 0}// FullSimplify

still gives

<|1 -> Cos[0 - 0]|>

How to make the Association expression after replacement evaluated directly(Not shift+Enter)?

matheorem
  • 17,132
  • 8
  • 45
  • 115
  • Oh, I solve this just now. //Normal//Association. So this post needs no answer now :) – matheorem Feb 18 '22 at 07:51
  • Or you can pass the replacement rule inside: <|1 -> Cos[a - b] /. {a -> 0, b -> 0}|> –  Feb 18 '22 at 07:53
  • @DiSp0sablE_H3r0 Thank you for comment. But replacement rule outside is more useful :) – matheorem Feb 18 '22 at 07:54
  • Yes, of course. I can appreciate that. I just mentioned it in case that the expression of interest was not too long. Still, applying Normal is far more elegant. –  Feb 18 '22 at 07:55

1 Answers1

7

Once an association construction expression has been evaluated into an atom, the keys and values of the resulting atom are kept in held form. That is, they are not reevaluated after subsequent replacement rules have been applied.

There are various work-arounds.

Operate upon the Unevaluated Association Construction Expression

If the application permits it, performing the replacement before evaluating the association into an atom is a possibility:

Unevaluated@<|1 -> Cos[a - b]|> /. {a -> 0, b -> 0}
(* <|1 -> 1|> *)

But beware that this strategy will also affect the keys, something that does not normally happen when using ReplaceAll with association atoms:

<| a -> a |> /. a -> 1
(* <| a -> 1 |> *)

Unevaluated@<| a -> a |> /. a -> 1 (* <| 1 -> 1 |> *)

Operate upon the evaluated Association Atom

If we must work with an evaluated Association atom, then we can use Map[ReplaceAll[...]] to force reevaluation of replaced values:

$expr = <| Sin[a - b] -> Cos[a - b] |>;
$rules = {a -> 0, b -> 0};

$expr // Map[ReplaceAll[$rules]] (* <| Sin[a - b] -> 1 |> *)

As noted before, such replacements only affect the values. Should we want affect both the keys and values, then we must use AssociationMap:

$expr // AssociationMap[ReplaceAll[$rules]]
(* <| 0 -> 1 |> *)

Should we wish to perform the replacement upon only a specific key of the association, we can use MapAt:

<| x -> Cos[a - b], y -> Cos[a - b] |> //
  MapAt[ReplaceAll[{a -> 0, b -> 0}], #, Key[x]] &

(* <| x -> 1, y -> Cos[a - b] |> *)

WReach
  • 68,832
  • 4
  • 164
  • 269