Here a solution which will adjust the behaviour of a set of rules which contains "duplicate" rules:
adjust[strategy_, rules_] := Hold@@@GatherBy[rules, First] // Map[With[{vs = #[[All, 2]]}, strategy[RuleDelayed@@{#[[1, 1]], Unevaluated@vs}]]&] cycle[k_ :> vs_] := Module[{i = 0}, k :> vs[[1+Mod[i++, Length@vs]]]] oneshot[k_ :> vs_] := Module[{i = 0}, k :> Module[{ii = ++i}, vs[[ii]] /; ii <= Length[vs]]] padlast[k_ :> vs_] := Module[{i = 0}, k :> vs[[Min[++i, Length[vs]]]]] normal[k_ :> _[v_, ___]] := k :> v
Multiple Strategies
The various strategies are...
... cycle which cycles through the rules repeatedly:
{a, b, a, b, b, b, a, a} /. adjust[cycle, {a -> 1, a -> 2, b -> 3}] (* {1, 3, 2, 3, 3, 3, 1, 2} *)
... padlast which reuses the last rule as "padding":
{a, b, a, b, b, b, a, a} /. adjust[padlast, {a -> 1, a -> 2, b -> 3}] (* {1, 3, 2, 3, 3, 3, 2, 2} *)
... oneshot which just lets the rules run out:
{a, b, a, b, b, b, a, a} /. adjust[oneshot, {a -> 1, a -> 2, b -> 3}] (* {1, 3, 2, b, b, b, a, a} *)
... and normal which is the regular behaviour where extra "duplicates" are ignored:
{a, b, a, b, b, b, a, a} /. adjust[normal, {a -> 1, a -> 2, b -> 3}] (* {1, 3, 1, 3, 3, 3, 1, 1} *)
RuleDelayed Replacements
The solution also supports replacements that use RuleDelayed (:>).
Given:
$rules = { f[x_] :> x, f[x_] :> 10x, f[x_] :> 100x , g[x_] :> -x, g[x_] :> -10x , h[x_] :> Echo["Evaluation Leak!"] }; $exprs = {f[1], g[2], f[3], g[4], f[5], f[6], g[7]};
Then:
$exprs /. adjust[cycle, $rules] (* {1,-2,30,-40,500,6,-7} *) $exprs /. adjust[oneshot, $rules] (* {1,-2,30,-40,500,f[6],g[7]} *) $exprs /. adjust[padlast, $rules] (* {1,-2,30,-40,500,600,-70} *) $exprs /. adjust[normal, $rules] (* {1,-2,3,-4,5,6,-7} *)
Limited Support for Condition
Beware that the exhibited implementation only supports Condition (/;) on the left-hand side of a rule:
Range[10] /. adjust[cycle, {x_ /; x < 7 :> "small", x_ /; x < 7 :> "little"}] (* {small,little,small,little,small,little,7,8,9,10} *)
It does not support conditions on the right-hand side, whether "bare" or nested within a scoping construct:
1 /. adjust[cycle, {x_ :> "small" /; x < 7}] (* incorrect result: small /; 1 < 7 *)
b^a + 2 aversusb^a + x a, in which the orderless property sorts the power term into a different position. Also{a b, b, a}. $\endgroup$