# Generating replacement rules programatically

I would like to generate sets of replacement rules programatically for predefining some permutations. So a function

MakeRule[cycles_List (* permute cycles *), n_Integer (* rule length *)]


called as

MakeRule[{{2,3}}, 4]


will generate

{e1_, e2_, e3_, e4_} -> {e1, e3, e2, e4}


For the permutations, I have

Permute[l, Cycles[cycles]]


but I cannot find a way of generating the list of patterns. Something subscripted or indexed would be nice as per the example. I have tried:

1) Pattern[Subscript[e, 1], Blank[]]
2) Pattern[Symbol["e1"], Blank[]]
3) Pattern[e[[1]], Blank[]]


I have a feeling I am missing something obvious.

Edit: Apologies for an oversight on my part. The second pattern example works correctly while the first and third do not. Thanks to all who responded.

-
You may find this subsection of my book of interest. – Leonid Shifrin Mar 15 '13 at 21:20
I went through a similar exercise looking at hashing algorithms for seven card poker hands. As the suit and rank sizes are fixed, I did the patterns by hand and let Permutations do the heavy lifting. – Nick Name Mar 16 '13 at 0:24
Nick, for the poker-hand problem I used Orderless myself. – Mr.Wizard Mar 16 '13 at 6:35
@Mr.W, indeed, a handy shortcut for the actual hash. Specifically, I was counting the permuted patterns to check I'd got the binomial coefficients right for the probabilities, and then per draw permuted integer partition counts for the rank encoding. – Nick Name Mar 16 '13 at 10:41

makeRule[e_, cycles_List , n_Integer] := Module[
{vals = Table[Unique[ToString[e]], {n}]},
Map[Pattern[#, Blank[]] &, vals] -> Permute[vals, Cycles[cycles]]
]


Example:

makeRule[e, {{2, 3}}, 4]

(* Out[307]= {e365_, e366_, e367_, e368_} -> {e365, e367, e366, e368} *)


With a bit more work we can get the sequential symbols starting at 1.

makeRule2[e_, cycles_List , n_Integer] := Module[
{vals, estr = ToString[e]},
vals = Table[ToExpression[StringJoin[estr, ToString[j]]], {j, n}];
Map[Pattern[#, Blank[]] &, vals] -> Permute[vals, Cycles[cycles]]
]

In[309]:= makeRule2[e, {{2, 3}}, 4]

(* Out[309]= {e1_, e2_, e3_, e4_} -> {e1, e3, e2, e4} *)

-
Thanks - so a symbol has to be created to use in the pattern? It would be nice to index from 1, but this does the job. – Nick Name Mar 15 '13 at 21:43
It can be done the way you want, but it's a bit more work. See the addendum. – Daniel Lichtblau Mar 15 '13 at 22:20
@DanielLichtblau I naïvely thought one could do Block[{$ModuleNumber = 1}, Unique["x"]] for the addendum, but... what happened was not pretty: Mathematica has detected an internal error: vMessage ENULL (v9). However, it doesn't crash in v7 and v8 (displays a warning). Any thoughts on why that happened? My guess would be that $ModuleNumber is critical to several internal routines and this messed with it and it cannot be Locked` either, since it needs to be incremented. But somehow I don't think that's right (and I'm not convinced by my explanation) – R. M. Mar 15 '13 at 22:26
Wow. No idea. But I'm filing a bug report. – Daniel Lichtblau Mar 15 '13 at 22:33
Thanks for filing :) – R. M. Mar 15 '13 at 22:37