0
$\begingroup$

I have a rule-transformer that takes a list of rules (and a list generator = {σ[z], σ[-1], σ[1]})

algebra = {σ[z] ** σ[1] :> σ[1],
 σ[z] ** σ[-1] :> -σ[-1],
 σ[1] ** σ[z] :> -σ[1],
 σ[-1] ** σ[z] :> σ[-1],
 σ[1] ** σ[1] -> 0,
 σ[-1] ** σ[-1] -> 0,
 σ[z] ** σ[z] -> Id,
 σ[1] ** σ[-1] -> 1/2 (Id + σ[z]),
 σ[-1] ** σ[1] -> 1/2 (Id - σ[z])
 }

and turn it into

{σ[z][n_] ** σ[1][n_] :> σ[1][n],
σ[z][n_] ** σ[-1][n_] :> -σ[-1][n],
σ[1][n_] ** σ[z][n_] :> -σ[1][n],
σ[-1][n_] ** σ[z][n_] :> σ[-1][n],
σ[1][n_]^2 :> 0,
σ[-1][n_]^2 :> 0,
σ[z][n_]^2 :> 1,
σ[1][n_] ** σ[-1][n_] :> 1/2 (1 + σ[z][n]),
σ[-1][n_] ** σ[1][n_] :> 1/2 (1 - σ[z][n])}

The transformer reads

Transformer = 
  Table[(#[[i]][[1]] /. {$g_ :> $g[n_] /; MemberQ[generators, $g]}) :>
      Evaluate[(#[[i]][[
         2]] /. {gg_ :> gg[n] /; MemberQ[generators, gg]})], {i, 
     Length[#]}] &;

I can call Transformer[algebra] to generate the desired list. However, if I define Transformer by

Transformer[algebra_] := 
 Table[(algebra[[i]][[
       1]] /. {$g_ :> $g[n_] /; MemberQ[generators, $g]}) :> 
    Evaluate[(algebra[[i]][[
        2]] /. {gg_ :> gg[n] /; MemberQ[generators, gg]})], {i, 
    Length[algebra]}] 

calling Transformer[algebra] gives some weird output

{σ[z] ** σ[1] :> σ[1][
   n$], σ[z] ** σ[-1] :> -σ[-1][n$], σ[
    1] ** σ[z] :> -σ[1][n$], σ[-1] ** σ[
    z] :> σ[-1][n$], σ[1]^2 :> 0, σ[-1]^2 :> 
  0, σ[z]^2 :> 1, σ[1] ** σ[-1] :> 
  1/2 (1 + σ[z][n$]), σ[-1] ** σ[1] :> 
  1/2 (1 - σ[z][n$])}

Similarly, if I put the pure function definition of Transformer inside the definition of some other bigger function, the same weird output will generate.

I wonder why the function environment causes such a big difference?

$\endgroup$
2
  • $\begingroup$ Your "weird output" case is because you defined Transformer to take an argument and produce a Function. You didn't actually include the full output, but if you look carefully at your actual output, you'll see that it's a Function expression (you can either see the & at the end or you can look at FullForm and see a Function head. Just remove the & from the end of your definition. $\endgroup$
    – lericr
    Nov 12, 2023 at 15:17
  • $\begingroup$ @lericr you are right. I removed the & and now there is a new output which is still not desirable. Am I using the Evaluate incorrectly? $\endgroup$
    – Lelouch
    Nov 13, 2023 at 0:42

2 Answers 2

0
$\begingroup$

That's due to the renaming mechanism of nested scopings.

When evaluating Transformer2[algebra_] := , the local variable algebra needs to be evaluated in the right side, and there appears a double scoping involving local variables algebra, $g, ..., then the rule

{$g_ :> $g[n_] /; MemberQ[generators, $g]})

is automatically renamed as

{$g$_ :> $g[n$_] /; MemberQ[generators, $g]}

Instead, if you define

Transformer22[algebra_] := 
    Table[
        (rule[[1]] /. {$g_ :> $g[n_] /; MemberQ[generators, $g]}):>
            Evaluate[(rule[[2]] /. {gg_ :> gg[n] /; MemberQ[generators, gg]})],
        {rule,algebra}
    ] 

or just the pure function you have given, the local variable algebra will be replaced by its value and there is no nested scoping during evaluation.

$\endgroup$
0
$\begingroup$

This doesn't really seem to have to do with Function versus SetDelayed, so it might warrant a separate question. Rather then debug the provided code, I'd suggest a different approach.

Whenever you have a construct like Table[..., {i,Length[something]}], you would probably be better off with some sort of Map. But, since what you're really doing is ReplaceAll, you don't need to iterate explicitly at all. But again, you do want a slightly different replacement to the left hand sides than to the right hand sides. But SubsetMap gives us a nifty way to handle such situations. So, I'd proceed like this:

(* create replacement rules *)
lhsRules = Thread[generators -> (Construct[#, n_] & /@ generators)];
rhsRules = Thread[generators -> (Construct[#, n] & /@ generators)];

result = 
  RuleDelayed @@@ 
    (SubsetMap[
       ReplaceAll[rhsRules], 
       SubsetMap[ReplaceAll[lhsRules], Level[#, 1] & /@ algebra, {All, 1}], 
       {All, 2}] /. x_ ** x_ :> x^2)

Now, you use 1 is some places and Id in others, so you'll need to sort that out.

Of course, you can put this into a definition:

Transformer[algebra_] := ...
$\endgroup$
1
  • $\begingroup$ Thanks for the suggestions; I haven't used SubsetMap before. I'll implement something like this in the future code. $\endgroup$
    – Lelouch
    Nov 14, 2023 at 2:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.